This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / arch / x86_64 / kernel / reboot.c
index ce78914..3dac339 100644 (file)
@@ -91,54 +91,47 @@ static void reboot_warm(void)
                      [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();