[target] "b" (WARMBOOT_TRAMP));
}
-static inline void kb_wait(void)
-{
- int i;
-
- for (i=0; i<0x10000; i++)
- if ((inb_p(0x64) & 0x02) == 0)
- break;
-}
-
-void machine_shutdown(void)
-{
- /* Stop the cpus and apics */
#ifdef CONFIG_SMP
- int reboot_cpu_id;
-
- /* The boot cpu is always logical cpu 0 */
- reboot_cpu_id = 0;
-
- /* Make certain the cpu I'm about to reboot on is online */
- if (!cpu_isset(reboot_cpu_id, cpu_online_map)) {
- reboot_cpu_id = smp_processor_id();
+static void smp_halt(void)
+{
+ int cpuid = safe_smp_processor_id();
+ static int first_entry = 1;
+
+ if (first_entry) {
+ first_entry = 0;
+ smp_call_function((void *)machine_restart, NULL, 1, 0);
+ }
+
+ smp_stop_cpu();
+
+ /* AP calling this. Just halt */
+ if (cpuid != boot_cpu_id) {
+ for (;;)
+ asm("hlt");
}
- /* Make certain I only run on the appropriate processor */
- set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id));
-
- /* O.K Now that I'm on the appropriate processor,
- * stop all of the others.
- */
- smp_send_stop();
-#endif
-
- local_irq_disable();
-
-#ifndef CONFIG_SMP
- disable_local_APIC();
+ /* Wait for all other CPUs to have run smp_stop_cpu */
+ while (!cpus_empty(cpu_online_map))
+ rep_nop();
+}
#endif
- disable_IO_APIC();
+static inline void kb_wait(void)
+{
+ int i;
- local_irq_enable();
+ for (i=0; i<0x10000; i++)
+ if ((inb_p(0x64) & 0x02) == 0)
+ break;
}
void machine_restart(char * __unused)
{
int i;
- machine_shutdown();
+#ifdef CONFIG_SMP
+ smp_halt();
+#endif
local_irq_disable();