|
@@ -184,30 +184,61 @@ int __init reboot_setup(char *str)
|
|
|
|
|
|
__setup("reboot=", reboot_setup);
|
|
|
|
|
|
+/*
|
|
|
+ * Called by kexec, immediately prior to machine_kexec().
|
|
|
+ *
|
|
|
+ * This must completely disable all secondary CPUs; simply causing those CPUs
|
|
|
+ * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
|
|
|
+ * kexec'd kernel to use any and all RAM as it sees fit, without having to
|
|
|
+ * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
|
|
|
+ * functionality embodied in disable_nonboot_cpus() to achieve this.
|
|
|
+ */
|
|
|
void machine_shutdown(void)
|
|
|
{
|
|
|
-#ifdef CONFIG_SMP
|
|
|
- smp_send_stop();
|
|
|
-#endif
|
|
|
+ disable_nonboot_cpus();
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Halting simply requires that the secondary CPUs stop performing any
|
|
|
+ * activity (executing tasks, handling interrupts). smp_send_stop()
|
|
|
+ * achieves this.
|
|
|
+ */
|
|
|
void machine_halt(void)
|
|
|
{
|
|
|
- machine_shutdown();
|
|
|
+ smp_send_stop();
|
|
|
+
|
|
|
local_irq_disable();
|
|
|
while (1);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Power-off simply requires that the secondary CPUs stop performing any
|
|
|
+ * activity (executing tasks, handling interrupts). smp_send_stop()
|
|
|
+ * achieves this. When the system power is turned off, it will take all CPUs
|
|
|
+ * with it.
|
|
|
+ */
|
|
|
void machine_power_off(void)
|
|
|
{
|
|
|
- machine_shutdown();
|
|
|
+ smp_send_stop();
|
|
|
+
|
|
|
if (pm_power_off)
|
|
|
pm_power_off();
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Restart requires that the secondary CPUs stop performing any activity
|
|
|
+ * while the primary CPU resets the system. Systems with a single CPU can
|
|
|
+ * use soft_restart() as their machine descriptor's .restart hook, since that
|
|
|
+ * will cause the only available CPU to reset. Systems with multiple CPUs must
|
|
|
+ * provide a HW restart implementation, to ensure that all CPUs reset at once.
|
|
|
+ * This is required so that any code running after reset on the primary CPU
|
|
|
+ * doesn't have to co-ordinate with other CPUs to ensure they aren't still
|
|
|
+ * executing pre-reset code, and using RAM that the primary CPU's code wishes
|
|
|
+ * to use. Implementing such co-ordination would be essentially impossible.
|
|
|
+ */
|
|
|
void machine_restart(char *cmd)
|
|
|
{
|
|
|
- machine_shutdown();
|
|
|
+ smp_send_stop();
|
|
|
|
|
|
arm_pm_restart(reboot_mode, cmd);
|
|
|
|