|
@@ -66,41 +66,47 @@ static int __init reboot_setup(char *str)
|
|
|
|
|
|
__setup("reboot=", reboot_setup);
|
|
|
|
|
|
-#ifdef CONFIG_SMP
|
|
|
-static void smp_halt(void)
|
|
|
+static inline void kb_wait(void)
|
|
|
{
|
|
|
- int cpuid = safe_smp_processor_id();
|
|
|
- static int first_entry = 1;
|
|
|
+ int i;
|
|
|
|
|
|
- if (reboot_force)
|
|
|
- return;
|
|
|
+ for (i=0; i<0x10000; i++)
|
|
|
+ if ((inb_p(0x64) & 0x02) == 0)
|
|
|
+ break;
|
|
|
+}
|
|
|
|
|
|
- if (first_entry) {
|
|
|
- first_entry = 0;
|
|
|
- smp_call_function((void *)machine_restart, NULL, 1, 0);
|
|
|
- }
|
|
|
-
|
|
|
- smp_stop_cpu();
|
|
|
+void machine_shutdown(void)
|
|
|
+{
|
|
|
+ /* Stop the cpus and apics */
|
|
|
+#ifdef CONFIG_SMP
|
|
|
+ int reboot_cpu_id;
|
|
|
|
|
|
- /* AP calling this. Just halt */
|
|
|
- if (cpuid != boot_cpu_id) {
|
|
|
- for (;;)
|
|
|
- asm("hlt");
|
|
|
+ /* 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();
|
|
|
}
|
|
|
|
|
|
- /* Wait for all other CPUs to have run smp_stop_cpu */
|
|
|
- while (!cpus_empty(cpu_online_map))
|
|
|
- rep_nop();
|
|
|
-}
|
|
|
+ /* 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
|
|
|
|
|
|
-static inline void kb_wait(void)
|
|
|
-{
|
|
|
- int i;
|
|
|
+ local_irq_disable();
|
|
|
|
|
|
- for (i=0; i<0x10000; i++)
|
|
|
- if ((inb_p(0x64) & 0x02) == 0)
|
|
|
- break;
|
|
|
+#ifndef CONFIG_SMP
|
|
|
+ disable_local_APIC();
|
|
|
+#endif
|
|
|
+
|
|
|
+ disable_IO_APIC();
|
|
|
+
|
|
|
+ local_irq_enable();
|
|
|
}
|
|
|
|
|
|
void machine_restart(char * __unused)
|
|
@@ -109,9 +115,7 @@ void machine_restart(char * __unused)
|
|
|
|
|
|
printk("machine restart\n");
|
|
|
|
|
|
-#ifdef CONFIG_SMP
|
|
|
- smp_halt();
|
|
|
-#endif
|
|
|
+ machine_shutdown();
|
|
|
|
|
|
if (!reboot_force) {
|
|
|
local_irq_disable();
|