diff options
Diffstat (limited to 'arch/arm/kernel/process.c')
-rw-r--r-- | arch/arm/kernel/process.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 282de4826abb..6e8931ccf13e 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -184,30 +184,61 @@ int __init reboot_setup(char *str) | |||
184 | 184 | ||
185 | __setup("reboot=", reboot_setup); | 185 | __setup("reboot=", reboot_setup); |
186 | 186 | ||
187 | /* | ||
188 | * Called by kexec, immediately prior to machine_kexec(). | ||
189 | * | ||
190 | * This must completely disable all secondary CPUs; simply causing those CPUs | ||
191 | * to execute e.g. a RAM-based pin loop is not sufficient. This allows the | ||
192 | * kexec'd kernel to use any and all RAM as it sees fit, without having to | ||
193 | * avoid any code or data used by any SW CPU pin loop. The CPU hotplug | ||
194 | * functionality embodied in disable_nonboot_cpus() to achieve this. | ||
195 | */ | ||
187 | void machine_shutdown(void) | 196 | void machine_shutdown(void) |
188 | { | 197 | { |
189 | #ifdef CONFIG_SMP | 198 | disable_nonboot_cpus(); |
190 | smp_send_stop(); | ||
191 | #endif | ||
192 | } | 199 | } |
193 | 200 | ||
201 | /* | ||
202 | * Halting simply requires that the secondary CPUs stop performing any | ||
203 | * activity (executing tasks, handling interrupts). smp_send_stop() | ||
204 | * achieves this. | ||
205 | */ | ||
194 | void machine_halt(void) | 206 | void machine_halt(void) |
195 | { | 207 | { |
196 | machine_shutdown(); | 208 | smp_send_stop(); |
209 | |||
197 | local_irq_disable(); | 210 | local_irq_disable(); |
198 | while (1); | 211 | while (1); |
199 | } | 212 | } |
200 | 213 | ||
214 | /* | ||
215 | * Power-off simply requires that the secondary CPUs stop performing any | ||
216 | * activity (executing tasks, handling interrupts). smp_send_stop() | ||
217 | * achieves this. When the system power is turned off, it will take all CPUs | ||
218 | * with it. | ||
219 | */ | ||
201 | void machine_power_off(void) | 220 | void machine_power_off(void) |
202 | { | 221 | { |
203 | machine_shutdown(); | 222 | smp_send_stop(); |
223 | |||
204 | if (pm_power_off) | 224 | if (pm_power_off) |
205 | pm_power_off(); | 225 | pm_power_off(); |
206 | } | 226 | } |
207 | 227 | ||
228 | /* | ||
229 | * Restart requires that the secondary CPUs stop performing any activity | ||
230 | * while the primary CPU resets the system. Systems with a single CPU can | ||
231 | * use soft_restart() as their machine descriptor's .restart hook, since that | ||
232 | * will cause the only available CPU to reset. Systems with multiple CPUs must | ||
233 | * provide a HW restart implementation, to ensure that all CPUs reset at once. | ||
234 | * This is required so that any code running after reset on the primary CPU | ||
235 | * doesn't have to co-ordinate with other CPUs to ensure they aren't still | ||
236 | * executing pre-reset code, and using RAM that the primary CPU's code wishes | ||
237 | * to use. Implementing such co-ordination would be essentially impossible. | ||
238 | */ | ||
208 | void machine_restart(char *cmd) | 239 | void machine_restart(char *cmd) |
209 | { | 240 | { |
210 | machine_shutdown(); | 241 | smp_send_stop(); |
211 | 242 | ||
212 | arm_pm_restart(reboot_mode, cmd); | 243 | arm_pm_restart(reboot_mode, cmd); |
213 | 244 | ||