aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r--arch/arm/kernel/smp.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 4619177bcfe6..47ab90563bf4 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -211,6 +211,13 @@ void __cpuinit __cpu_die(unsigned int cpu)
211 } 211 }
212 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); 212 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
213 213
214 /*
215 * platform_cpu_kill() is generally expected to do the powering off
216 * and/or cutting of clocks to the dying CPU. Optionally, this may
217 * be done by the CPU which is dying in preference to supporting
218 * this call, but that means there is _no_ synchronisation between
219 * the requesting CPU and the dying CPU actually losing power.
220 */
214 if (!platform_cpu_kill(cpu)) 221 if (!platform_cpu_kill(cpu))
215 printk("CPU%u: unable to kill\n", cpu); 222 printk("CPU%u: unable to kill\n", cpu);
216} 223}
@@ -230,14 +237,41 @@ void __ref cpu_die(void)
230 idle_task_exit(); 237 idle_task_exit();
231 238
232 local_irq_disable(); 239 local_irq_disable();
233 mb();
234 240
235 /* Tell __cpu_die() that this CPU is now safe to dispose of */ 241 /*
242 * Flush the data out of the L1 cache for this CPU. This must be
243 * before the completion to ensure that data is safely written out
244 * before platform_cpu_kill() gets called - which may disable
245 * *this* CPU and power down its cache.
246 */
247 flush_cache_louis();
248
249 /*
250 * Tell __cpu_die() that this CPU is now safe to dispose of. Once
251 * this returns, power and/or clocks can be removed at any point
252 * from this CPU and its cache by platform_cpu_kill().
253 */
236 RCU_NONIDLE(complete(&cpu_died)); 254 RCU_NONIDLE(complete(&cpu_died));
237 255
238 /* 256 /*
239 * actual CPU shutdown procedure is at least platform (if not 257 * Ensure that the cache lines associated with that completion are
240 * CPU) specific. 258 * written out. This covers the case where _this_ CPU is doing the
259 * powering down, to ensure that the completion is visible to the
260 * CPU waiting for this one.
261 */
262 flush_cache_louis();
263
264 /*
265 * The actual CPU shutdown procedure is at least platform (if not
266 * CPU) specific. This may remove power, or it may simply spin.
267 *
268 * Platforms are generally expected *NOT* to return from this call,
269 * although there are some which do because they have no way to
270 * power down the CPU. These platforms are the _only_ reason we
271 * have a return path which uses the fragment of assembly below.
272 *
273 * The return path should not be used for platforms which can
274 * power off the CPU.
241 */ 275 */
242 if (smp_ops.cpu_die) 276 if (smp_ops.cpu_die)
243 smp_ops.cpu_die(cpu); 277 smp_ops.cpu_die(cpu);