aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-07-26 08:31:27 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-07-27 05:48:43 -0400
commit3d3f78d752bfada5b6041f2f7bd0833d8bdf7a4a (patch)
tree14365f6ef64f10095c3080cdabb9b8cd0a51d671
parent5388a6b266e9c3357353332ba0cd5549082887f1 (diff)
ARM: call machine_shutdown() from machine_halt(), etc
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>
-rw-r--r--arch/arm/kernel/machine_kexec.c4
-rw-r--r--arch/arm/kernel/process.c12
-rw-r--r--arch/arm/kernel/smp.c11
3 files changed, 18 insertions, 9 deletions
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 3b4872c2da8e..df5958f6864f 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -37,10 +37,6 @@ void machine_kexec_cleanup(struct kimage *image)
37{ 37{
38} 38}
39 39
40void machine_shutdown(void)
41{
42}
43
44void machine_crash_shutdown(struct pt_regs *regs) 40void machine_crash_shutdown(struct pt_regs *regs)
45{ 41{
46} 42}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index aaf51159203a..2e2ec97cc50c 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -198,19 +198,29 @@ int __init reboot_setup(char *str)
198 198
199__setup("reboot=", reboot_setup); 199__setup("reboot=", reboot_setup);
200 200
201void machine_halt(void) 201void machine_shutdown(void)
202{ 202{
203#ifdef CONFIG_SMP
204 smp_send_stop();
205#endif
203} 206}
204 207
208void machine_halt(void)
209{
210 machine_shutdown();
211 while (1);
212}
205 213
206void machine_power_off(void) 214void machine_power_off(void)
207{ 215{
216 machine_shutdown();
208 if (pm_power_off) 217 if (pm_power_off)
209 pm_power_off(); 218 pm_power_off();
210} 219}
211 220
212void machine_restart(char *cmd) 221void machine_restart(char *cmd)
213{ 222{
223 machine_shutdown();
214 arm_pm_restart(reboot_mode, cmd); 224 arm_pm_restart(reboot_mode, cmd);
215} 225}
216 226
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 0170e248a1dd..40dc74f2b27f 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -471,10 +471,13 @@ static DEFINE_SPINLOCK(stop_lock);
471 */ 471 */
472static void ipi_cpu_stop(unsigned int cpu) 472static void ipi_cpu_stop(unsigned int cpu)
473{ 473{
474 spin_lock(&stop_lock); 474 if (system_state == SYSTEM_BOOTING ||
475 printk(KERN_CRIT "CPU%u: stopping\n", cpu); 475 system_state == SYSTEM_RUNNING) {
476 dump_stack(); 476 spin_lock(&stop_lock);
477 spin_unlock(&stop_lock); 477 printk(KERN_CRIT "CPU%u: stopping\n", cpu);
478 dump_stack();
479 spin_unlock(&stop_lock);
480 }
478 481
479 set_cpu_online(cpu, false); 482 set_cpu_online(cpu, false);
480 483