aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2011-12-28 02:53:16 -0500
committerPaul Mundt <lethal@linux-sh.org>2012-01-08 20:37:29 -0500
commit1229835ccb6d7ea2b36230121205be95c88eca88 (patch)
tree7b8c0e49cc88b6a554552e8dd70ae52d1baefd76 /arch
parent8b306796995609c281f6d32b3cbaa814551ad5ac (diff)
ARM: mach-shmobile: Flush caches in platform_cpu_die()
Add cache flushing code to the SH-Mobile specific CPU hotplug implementation. While at it, add a cpu mask to make sure the cache flushing code is finished in platform_cpu_die() before letting the SoC-specific code in shmobile_platform_cpu_kill() proceed with turning off power. Without this code CPU hotplug offline fails when cache is enabled on Cortex-A9 based SoCs. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-shmobile/hotplug.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c
index aee3a1088a5a..828d22f3af57 100644
--- a/arch/arm/mach-shmobile/hotplug.c
+++ b/arch/arm/mach-shmobile/hotplug.c
@@ -12,15 +12,43 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/smp.h> 14#include <linux/smp.h>
15#include <linux/cpumask.h>
16#include <linux/delay.h>
15#include <mach/common.h> 17#include <mach/common.h>
18#include <asm/cacheflush.h>
19
20static cpumask_t dead_cpus;
16 21
17int platform_cpu_kill(unsigned int cpu) 22int platform_cpu_kill(unsigned int cpu)
18{ 23{
19 return shmobile_platform_cpu_kill(cpu); 24 int k;
25
26 /* this function is running on another CPU than the offline target,
27 * here we need wait for shutdown code in platform_cpu_die() to
28 * finish before asking SoC-specific code to power off the CPU core.
29 */
30 for (k = 0; k < 1000; k++) {
31 if (cpumask_test_cpu(cpu, &dead_cpus))
32 return shmobile_platform_cpu_kill(cpu);
33
34 mdelay(1);
35 }
36
37 return 0;
20} 38}
21 39
22void platform_cpu_die(unsigned int cpu) 40void platform_cpu_die(unsigned int cpu)
23{ 41{
42 /* hardware shutdown code running on the CPU that is being offlined */
43 flush_cache_all();
44 dsb();
45
46 /* notify platform_cpu_kill() that hardware shutdown is finished */
47 cpumask_set_cpu(cpu, &dead_cpus);
48
49 /* wait for SoC code in platform_cpu_kill() to shut off CPU core
50 * power. CPU bring up starts from the reset vector.
51 */
24 while (1) { 52 while (1) {
25 /* 53 /*
26 * here's the WFI 54 * here's the WFI
@@ -34,6 +62,7 @@ void platform_cpu_die(unsigned int cpu)
34 62
35int platform_cpu_disable(unsigned int cpu) 63int platform_cpu_disable(unsigned int cpu)
36{ 64{
65 cpumask_clear_cpu(cpu, &dead_cpus);
37 /* 66 /*
38 * we don't allow CPU 0 to be shutdown (it is still too special 67 * we don't allow CPU 0 to be shutdown (it is still too special
39 * e.g. clock tick interrupts) 68 * e.g. clock tick interrupts)