diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/kernel/smp.c | 42 | ||||
-rw-r--r-- | arch/arm/mach-exynos/hotplug.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-highbank/hotplug.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-imx/hotplug.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-msm/hotplug.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap-hotplug.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-prima2/hotplug.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-realview/hotplug.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/smp-sh73a0.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-spear13xx/hotplug.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/common.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/hotplug.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/platsmp.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-ux500/hotplug.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/hotplug.c | 2 |
15 files changed, 38 insertions, 47 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 1f2ccccaf009..4231034b8128 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); |
diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c index c3f825b27947..af90cfa2f826 100644 --- a/arch/arm/mach-exynos/hotplug.c +++ b/arch/arm/mach-exynos/hotplug.c | |||
@@ -28,7 +28,6 @@ static inline void cpu_enter_lowpower_a9(void) | |||
28 | { | 28 | { |
29 | unsigned int v; | 29 | unsigned int v; |
30 | 30 | ||
31 | flush_cache_all(); | ||
32 | asm volatile( | 31 | asm volatile( |
33 | " mcr p15, 0, %1, c7, c5, 0\n" | 32 | " mcr p15, 0, %1, c7, c5, 0\n" |
34 | " mcr p15, 0, %1, c7, c10, 4\n" | 33 | " mcr p15, 0, %1, c7, c10, 4\n" |
diff --git a/arch/arm/mach-highbank/hotplug.c b/arch/arm/mach-highbank/hotplug.c index 890cae23c12a..a019e4e86e51 100644 --- a/arch/arm/mach-highbank/hotplug.c +++ b/arch/arm/mach-highbank/hotplug.c | |||
@@ -14,7 +14,6 @@ | |||
14 | * this program. If not, see <http://www.gnu.org/licenses/>. | 14 | * this program. If not, see <http://www.gnu.org/licenses/>. |
15 | */ | 15 | */ |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | |||
18 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
19 | 18 | ||
20 | #include "core.h" | 19 | #include "core.h" |
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 361a253e2b63..5e91112dcbee 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c | |||
@@ -11,7 +11,6 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <asm/cacheflush.h> | ||
15 | #include <asm/cp15.h> | 14 | #include <asm/cp15.h> |
16 | 15 | ||
17 | #include "common.h" | 16 | #include "common.h" |
@@ -20,7 +19,6 @@ static inline void cpu_enter_lowpower(void) | |||
20 | { | 19 | { |
21 | unsigned int v; | 20 | unsigned int v; |
22 | 21 | ||
23 | flush_cache_all(); | ||
24 | asm volatile( | 22 | asm volatile( |
25 | "mcr p15, 0, %1, c7, c5, 0\n" | 23 | "mcr p15, 0, %1, c7, c5, 0\n" |
26 | " mcr p15, 0, %1, c7, c10, 4\n" | 24 | " mcr p15, 0, %1, c7, c10, 4\n" |
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c index 750446feb444..326a87261f9a 100644 --- a/arch/arm/mach-msm/hotplug.c +++ b/arch/arm/mach-msm/hotplug.c | |||
@@ -10,16 +10,12 @@ | |||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/smp.h> | 11 | #include <linux/smp.h> |
12 | 12 | ||
13 | #include <asm/cacheflush.h> | ||
14 | #include <asm/smp_plat.h> | 13 | #include <asm/smp_plat.h> |
15 | 14 | ||
16 | #include "common.h" | 15 | #include "common.h" |
17 | 16 | ||
18 | static inline void cpu_enter_lowpower(void) | 17 | static inline void cpu_enter_lowpower(void) |
19 | { | 18 | { |
20 | /* Just flush the cache. Changing the coherency is not yet | ||
21 | * available on msm. */ | ||
22 | flush_cache_all(); | ||
23 | } | 19 | } |
24 | 20 | ||
25 | static inline void cpu_leave_lowpower(void) | 21 | static inline void cpu_leave_lowpower(void) |
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index e712d1725a8b..ceb30a59bf28 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c | |||
@@ -35,9 +35,6 @@ void __ref omap4_cpu_die(unsigned int cpu) | |||
35 | unsigned int boot_cpu = 0; | 35 | unsigned int boot_cpu = 0; |
36 | void __iomem *base = omap_get_wakeupgen_base(); | 36 | void __iomem *base = omap_get_wakeupgen_base(); |
37 | 37 | ||
38 | flush_cache_all(); | ||
39 | dsb(); | ||
40 | |||
41 | /* | 38 | /* |
42 | * we're ready for shutdown now, so do it | 39 | * we're ready for shutdown now, so do it |
43 | */ | 40 | */ |
diff --git a/arch/arm/mach-prima2/hotplug.c b/arch/arm/mach-prima2/hotplug.c index f4b17cbababd..0ab2f8bae28e 100644 --- a/arch/arm/mach-prima2/hotplug.c +++ b/arch/arm/mach-prima2/hotplug.c | |||
@@ -10,13 +10,10 @@ | |||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/smp.h> | 11 | #include <linux/smp.h> |
12 | 12 | ||
13 | #include <asm/cacheflush.h> | ||
14 | #include <asm/smp_plat.h> | 13 | #include <asm/smp_plat.h> |
15 | 14 | ||
16 | static inline void platform_do_lowpower(unsigned int cpu) | 15 | static inline void platform_do_lowpower(unsigned int cpu) |
17 | { | 16 | { |
18 | flush_cache_all(); | ||
19 | |||
20 | /* we put the platform to just WFI */ | 17 | /* we put the platform to just WFI */ |
21 | for (;;) { | 18 | for (;;) { |
22 | __asm__ __volatile__("dsb\n\t" "wfi\n\t" | 19 | __asm__ __volatile__("dsb\n\t" "wfi\n\t" |
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c index 53818e5cd3ad..ac22dd41b135 100644 --- a/arch/arm/mach-realview/hotplug.c +++ b/arch/arm/mach-realview/hotplug.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/smp.h> | 13 | #include <linux/smp.h> |
14 | 14 | ||
15 | #include <asm/cacheflush.h> | ||
16 | #include <asm/cp15.h> | 15 | #include <asm/cp15.h> |
17 | #include <asm/smp_plat.h> | 16 | #include <asm/smp_plat.h> |
18 | 17 | ||
@@ -20,7 +19,6 @@ static inline void cpu_enter_lowpower(void) | |||
20 | { | 19 | { |
21 | unsigned int v; | 20 | unsigned int v; |
22 | 21 | ||
23 | flush_cache_all(); | ||
24 | asm volatile( | 22 | asm volatile( |
25 | " mcr p15, 0, %1, c7, c5, 0\n" | 23 | " mcr p15, 0, %1, c7, c5, 0\n" |
26 | " mcr p15, 0, %1, c7, c10, 4\n" | 24 | " mcr p15, 0, %1, c7, c10, 4\n" |
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index acb46a94ccdf..2f1ef1bc805d 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c | |||
@@ -119,14 +119,6 @@ static int sh73a0_cpu_kill(unsigned int cpu) | |||
119 | 119 | ||
120 | static void sh73a0_cpu_die(unsigned int cpu) | 120 | static void sh73a0_cpu_die(unsigned int cpu) |
121 | { | 121 | { |
122 | /* | ||
123 | * The ARM MPcore does not issue a cache coherency request for the L1 | ||
124 | * cache when powering off single CPUs. We must take care of this and | ||
125 | * further caches. | ||
126 | */ | ||
127 | dsb(); | ||
128 | flush_cache_all(); | ||
129 | |||
130 | /* Set power off mode. This takes the CPU out of the MP cluster */ | 122 | /* Set power off mode. This takes the CPU out of the MP cluster */ |
131 | scu_power_mode(scu_base_addr(), SCU_PM_POWEROFF); | 123 | scu_power_mode(scu_base_addr(), SCU_PM_POWEROFF); |
132 | 124 | ||
diff --git a/arch/arm/mach-spear13xx/hotplug.c b/arch/arm/mach-spear13xx/hotplug.c index a7d2dd11a4f2..d97749c642ce 100644 --- a/arch/arm/mach-spear13xx/hotplug.c +++ b/arch/arm/mach-spear13xx/hotplug.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
16 | #include <asm/cacheflush.h> | ||
17 | #include <asm/cp15.h> | 16 | #include <asm/cp15.h> |
18 | #include <asm/smp_plat.h> | 17 | #include <asm/smp_plat.h> |
19 | 18 | ||
@@ -21,7 +20,6 @@ static inline void cpu_enter_lowpower(void) | |||
21 | { | 20 | { |
22 | unsigned int v; | 21 | unsigned int v; |
23 | 22 | ||
24 | flush_cache_all(); | ||
25 | asm volatile( | 23 | asm volatile( |
26 | " mcr p15, 0, %1, c7, c5, 0\n" | 24 | " mcr p15, 0, %1, c7, c5, 0\n" |
27 | " dsb\n" | 25 | " dsb\n" |
diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h index 32f8eb3fe344..5900cc44f780 100644 --- a/arch/arm/mach-tegra/common.h +++ b/arch/arm/mach-tegra/common.h | |||
@@ -2,4 +2,3 @@ extern struct smp_operations tegra_smp_ops; | |||
2 | 2 | ||
3 | extern int tegra_cpu_kill(unsigned int cpu); | 3 | extern int tegra_cpu_kill(unsigned int cpu); |
4 | extern void tegra_cpu_die(unsigned int cpu); | 4 | extern void tegra_cpu_die(unsigned int cpu); |
5 | extern int tegra_cpu_disable(unsigned int cpu); | ||
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c index a599f6e36dea..e8323bc95770 100644 --- a/arch/arm/mach-tegra/hotplug.c +++ b/arch/arm/mach-tegra/hotplug.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
13 | #include <linux/clk/tegra.h> | 13 | #include <linux/clk/tegra.h> |
14 | 14 | ||
15 | #include <asm/cacheflush.h> | ||
16 | #include <asm/smp_plat.h> | 15 | #include <asm/smp_plat.h> |
17 | 16 | ||
18 | #include "sleep.h" | 17 | #include "sleep.h" |
@@ -47,15 +46,6 @@ void __ref tegra_cpu_die(unsigned int cpu) | |||
47 | BUG(); | 46 | BUG(); |
48 | } | 47 | } |
49 | 48 | ||
50 | int tegra_cpu_disable(unsigned int cpu) | ||
51 | { | ||
52 | /* | ||
53 | * we don't allow CPU 0 to be shutdown (it is still too special | ||
54 | * e.g. clock tick interrupts) | ||
55 | */ | ||
56 | return cpu == 0 ? -EPERM : 0; | ||
57 | } | ||
58 | |||
59 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | 49 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC |
60 | extern void tegra20_hotplug_shutdown(void); | 50 | extern void tegra20_hotplug_shutdown(void); |
61 | void __init tegra20_hotplug_init(void) | 51 | void __init tegra20_hotplug_init(void) |
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 2c6b3d55213b..ec33ec86aad9 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c | |||
@@ -192,6 +192,5 @@ struct smp_operations tegra_smp_ops __initdata = { | |||
192 | #ifdef CONFIG_HOTPLUG_CPU | 192 | #ifdef CONFIG_HOTPLUG_CPU |
193 | .cpu_kill = tegra_cpu_kill, | 193 | .cpu_kill = tegra_cpu_kill, |
194 | .cpu_die = tegra_cpu_die, | 194 | .cpu_die = tegra_cpu_die, |
195 | .cpu_disable = tegra_cpu_disable, | ||
196 | #endif | 195 | #endif |
197 | }; | 196 | }; |
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c index 2f6af259015d..1c55a55dd89e 100644 --- a/arch/arm/mach-ux500/hotplug.c +++ b/arch/arm/mach-ux500/hotplug.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/smp.h> | 13 | #include <linux/smp.h> |
14 | 14 | ||
15 | #include <asm/cacheflush.h> | ||
16 | #include <asm/smp_plat.h> | 15 | #include <asm/smp_plat.h> |
17 | 16 | ||
18 | #include <mach/setup.h> | 17 | #include <mach/setup.h> |
@@ -24,8 +23,6 @@ | |||
24 | */ | 23 | */ |
25 | void __ref ux500_cpu_die(unsigned int cpu) | 24 | void __ref ux500_cpu_die(unsigned int cpu) |
26 | { | 25 | { |
27 | flush_cache_all(); | ||
28 | |||
29 | /* directly enter low power state, skipping secure registers */ | 26 | /* directly enter low power state, skipping secure registers */ |
30 | for (;;) { | 27 | for (;;) { |
31 | __asm__ __volatile__("dsb\n\t" "wfi\n\t" | 28 | __asm__ __volatile__("dsb\n\t" "wfi\n\t" |
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c index a141b98d84fe..f0ce6b8f5e71 100644 --- a/arch/arm/mach-vexpress/hotplug.c +++ b/arch/arm/mach-vexpress/hotplug.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/smp.h> | 13 | #include <linux/smp.h> |
14 | 14 | ||
15 | #include <asm/cacheflush.h> | ||
16 | #include <asm/smp_plat.h> | 15 | #include <asm/smp_plat.h> |
17 | #include <asm/cp15.h> | 16 | #include <asm/cp15.h> |
18 | 17 | ||
@@ -20,7 +19,6 @@ static inline void cpu_enter_lowpower(void) | |||
20 | { | 19 | { |
21 | unsigned int v; | 20 | unsigned int v; |
22 | 21 | ||
23 | flush_cache_all(); | ||
24 | asm volatile( | 22 | asm volatile( |
25 | "mcr p15, 0, %1, c7, c5, 0\n" | 23 | "mcr p15, 0, %1, c7, c5, 0\n" |
26 | " mcr p15, 0, %1, c7, c10, 4\n" | 24 | " mcr p15, 0, %1, c7, c10, 4\n" |