aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm/mcpm.h
diff options
context:
space:
mode:
authorDave Martin <dave.martin@linaro.org>2013-10-01 14:58:17 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-10-29 07:07:15 -0400
commit0de0d64675259bf21d06b18985318ffb66a5218f (patch)
tree06f797f0632d681d537e867d1e6a1bc69a9fa135 /arch/arm/include/asm/mcpm.h
parent1e5660999aa7703654ec345caaf06b83415dbdff (diff)
ARM: 7848/1: mcpm: Implement cpu_kill() to synchronise on powerdown
CPU hotplug and kexec rely on smp_ops.cpu_kill(), which is supposed to wait for the CPU to park or power down, and perform the last rites (such as disabling clocks etc., where the platform doesn't do this automatically). kexec in particular is unsafe without performing this synchronisation to park secondaries. Without it, the secondaries might not be parked when kexec trashes the kernel. There is no generic way to do this synchronisation, so a new mcpm platform_ops method power_down_finish() is added by this patch. The new method is mandatory. A platform which provides no way to detect when CPUs are parked is likely broken. Signed-off-by: Dave Martin <Dave.Martin@arm.com> Reviewed-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/include/asm/mcpm.h')
-rw-r--r--arch/arm/include/asm/mcpm.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/arm/include/asm/mcpm.h b/arch/arm/include/asm/mcpm.h
index fc82a88f5b69..1cf26010a6f3 100644
--- a/arch/arm/include/asm/mcpm.h
+++ b/arch/arm/include/asm/mcpm.h
@@ -81,10 +81,40 @@ int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster);
81 * 81 *
82 * This will return if mcpm_platform_register() has not been called 82 * This will return if mcpm_platform_register() has not been called
83 * previously in which case the caller should take appropriate action. 83 * previously in which case the caller should take appropriate action.
84 *
85 * On success, the CPU is not guaranteed to be truly halted until
86 * mcpm_cpu_power_down_finish() subsequently returns non-zero for the
87 * specified cpu. Until then, other CPUs should make sure they do not
88 * trash memory the target CPU might be executing/accessing.
84 */ 89 */
85void mcpm_cpu_power_down(void); 90void mcpm_cpu_power_down(void);
86 91
87/** 92/**
93 * mcpm_cpu_power_down_finish - wait for a specified CPU to halt, and
94 * make sure it is powered off
95 *
96 * @cpu: CPU number within given cluster
97 * @cluster: cluster number for the CPU
98 *
99 * Call this function to ensure that a pending powerdown has taken
100 * effect and the CPU is safely parked before performing non-mcpm
101 * operations that may affect the CPU (such as kexec trashing the
102 * kernel text).
103 *
104 * It is *not* necessary to call this function if you only need to
105 * serialise a pending powerdown with mcpm_cpu_power_up() or a wakeup
106 * event.
107 *
108 * Do not call this function unless the specified CPU has already
109 * called mcpm_cpu_power_down() or has committed to doing so.
110 *
111 * @return:
112 * - zero if the CPU is in a safely parked state
113 * - nonzero otherwise (e.g., timeout)
114 */
115int mcpm_cpu_power_down_finish(unsigned int cpu, unsigned int cluster);
116
117/**
88 * mcpm_cpu_suspend - bring the calling CPU in a suspended state 118 * mcpm_cpu_suspend - bring the calling CPU in a suspended state
89 * 119 *
90 * @expected_residency: duration in microseconds the CPU is expected 120 * @expected_residency: duration in microseconds the CPU is expected
@@ -126,6 +156,7 @@ int mcpm_cpu_powered_up(void);
126struct mcpm_platform_ops { 156struct mcpm_platform_ops {
127 int (*power_up)(unsigned int cpu, unsigned int cluster); 157 int (*power_up)(unsigned int cpu, unsigned int cluster);
128 void (*power_down)(void); 158 void (*power_down)(void);
159 int (*power_down_finish)(unsigned int cpu, unsigned int cluster);
129 void (*suspend)(u64); 160 void (*suspend)(u64);
130 void (*powered_up)(void); 161 void (*powered_up)(void);
131}; 162};