]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
ARM: call machine_shutdown() from machine_halt(), etc
authorRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 26 Jul 2010 12:31:27 +0000 (13:31 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 27 Jul 2010 09:48:43 +0000 (10:48 +0100)
x86 calls machine_shutdown() from the various machine_*() calls which
take the machine down ready for halting, restarting, etc, and uses
this to bring the system safely to a point where those actions can be
performed.  Such actions are stopping the secondary CPUs.

So, change the ARM implementation of these to reflect what x86 does.

This solves kexec problems on ARM SMP platforms, where the secondary
CPUs were left running across the kexec call.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/kernel/machine_kexec.c
arch/arm/kernel/process.c
arch/arm/kernel/smp.c

index 3b4872c2da8e51055acad62564c4e6a220e8000b..df5958f6864fcde5cb3b8f1957f1cc589e0edd2e 100644 (file)
@@ -37,10 +37,6 @@ void machine_kexec_cleanup(struct kimage *image)
 {
 }
 
-void machine_shutdown(void)
-{
-}
-
 void machine_crash_shutdown(struct pt_regs *regs)
 {
 }
index aaf51159203af6b721bc8710c3ab5a6bab61cd77..2e2ec97cc50caeaae9b212705bb632aed057c446 100644 (file)
@@ -198,19 +198,29 @@ int __init reboot_setup(char *str)
 
 __setup("reboot=", reboot_setup);
 
-void machine_halt(void)
+void machine_shutdown(void)
 {
+#ifdef CONFIG_SMP
+       smp_send_stop();
+#endif
 }
 
+void machine_halt(void)
+{
+       machine_shutdown();
+       while (1);
+}
 
 void machine_power_off(void)
 {
+       machine_shutdown();
        if (pm_power_off)
                pm_power_off();
 }
 
 void machine_restart(char *cmd)
 {
+       machine_shutdown();
        arm_pm_restart(reboot_mode, cmd);
 }
 
index 0170e248a1dd413829e1099a02762661a0d2ac87..40dc74f2b27f3362f8739f5e9898963dd27a221b 100644 (file)
@@ -471,10 +471,13 @@ static DEFINE_SPINLOCK(stop_lock);
  */
 static void ipi_cpu_stop(unsigned int cpu)
 {
-       spin_lock(&stop_lock);
-       printk(KERN_CRIT "CPU%u: stopping\n", cpu);
-       dump_stack();
-       spin_unlock(&stop_lock);
+       if (system_state == SYSTEM_BOOTING ||
+           system_state == SYSTEM_RUNNING) {
+               spin_lock(&stop_lock);
+               printk(KERN_CRIT "CPU%u: stopping\n", cpu);
+               dump_stack();
+               spin_unlock(&stop_lock);
+       }
 
        set_cpu_online(cpu, false);