aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/smp.c42
-rw-r--r--arch/arm/mach-exynos/hotplug.c1
-rw-r--r--arch/arm/mach-highbank/hotplug.c1
-rw-r--r--arch/arm/mach-imx/hotplug.c2
-rw-r--r--arch/arm/mach-msm/hotplug.c4
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c3
-rw-r--r--arch/arm/mach-prima2/hotplug.c3
-rw-r--r--arch/arm/mach-realview/hotplug.c2
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c8
-rw-r--r--arch/arm/mach-spear13xx/hotplug.c2
-rw-r--r--arch/arm/mach-tegra/common.h1
-rw-r--r--arch/arm/mach-tegra/hotplug.c10
-rw-r--r--arch/arm/mach-tegra/platsmp.c1
-rw-r--r--arch/arm/mach-ux500/hotplug.c3
-rw-r--r--arch/arm/mach-vexpress/hotplug.c2
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
18static inline void cpu_enter_lowpower(void) 17static 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
25static inline void cpu_leave_lowpower(void) 21static 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
16static inline void platform_do_lowpower(unsigned int cpu) 15static 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
120static void sh73a0_cpu_die(unsigned int cpu) 120static 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
3extern int tegra_cpu_kill(unsigned int cpu); 3extern int tegra_cpu_kill(unsigned int cpu);
4extern void tegra_cpu_die(unsigned int cpu); 4extern void tegra_cpu_die(unsigned int cpu);
5extern 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
50int 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
60extern void tegra20_hotplug_shutdown(void); 50extern void tegra20_hotplug_shutdown(void);
61void __init tegra20_hotplug_init(void) 51void __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 */
25void __ref ux500_cpu_die(unsigned int cpu) 24void __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"