aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/common
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2012-10-23 01:39:08 -0400
committerNicolas Pitre <nicolas.pitre@linaro.org>2013-09-23 18:39:56 -0400
commit108a9640abfada2599b6cb08c7cc00a4eebf8f8f (patch)
treedc4c0456f2cc9732a0b27a48d9a726bb43a2365d /arch/arm/common
parent0577fee283fb385afbcdb78d1f4c398d7326b68f (diff)
ARM: bL_switcher: synchronize the outbound with the inbound
Let's wait for the inbound CPU to come up and snoop some of the outbound CPU cache before bringing the outbound CPU down. That should be more efficient than going down right away. Possible improvements might involve some monitoring of the CCI event counters. Signed-off-by: Nicolas Pitre <nico@linaro.org>
Diffstat (limited to 'arch/arm/common')
-rw-r--r--arch/arm/common/bL_switcher.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/arch/arm/common/bL_switcher.c b/arch/arm/common/bL_switcher.c
index 34316be404d5..aab7c1274885 100644
--- a/arch/arm/common/bL_switcher.c
+++ b/arch/arm/common/bL_switcher.c
@@ -55,9 +55,10 @@ static int read_mpidr(void)
55 * bL switcher core code. 55 * bL switcher core code.
56 */ 56 */
57 57
58static void bL_do_switch(void *_unused) 58static void bL_do_switch(void *_arg)
59{ 59{
60 unsigned ib_mpidr, ib_cpu, ib_cluster; 60 unsigned ib_mpidr, ib_cpu, ib_cluster;
61 long volatile handshake, **handshake_ptr = _arg;
61 62
62 pr_debug("%s\n", __func__); 63 pr_debug("%s\n", __func__);
63 64
@@ -65,6 +66,13 @@ static void bL_do_switch(void *_unused)
65 ib_cpu = MPIDR_AFFINITY_LEVEL(ib_mpidr, 0); 66 ib_cpu = MPIDR_AFFINITY_LEVEL(ib_mpidr, 0);
66 ib_cluster = MPIDR_AFFINITY_LEVEL(ib_mpidr, 1); 67 ib_cluster = MPIDR_AFFINITY_LEVEL(ib_mpidr, 1);
67 68
69 /* Advertise our handshake location */
70 if (handshake_ptr) {
71 handshake = 0;
72 *handshake_ptr = &handshake;
73 } else
74 handshake = -1;
75
68 /* 76 /*
69 * Our state has been saved at this point. Let's release our 77 * Our state has been saved at this point. Let's release our
70 * inbound CPU. 78 * inbound CPU.
@@ -83,6 +91,14 @@ static void bL_do_switch(void *_unused)
83 * we have none. 91 * we have none.
84 */ 92 */
85 93
94 /*
95 * Let's wait until our inbound is alive.
96 */
97 while (!handshake) {
98 wfe();
99 smp_mb();
100 }
101
86 /* Let's put ourself down. */ 102 /* Let's put ourself down. */
87 mcpm_cpu_power_down(); 103 mcpm_cpu_power_down();
88 104
@@ -130,6 +146,7 @@ static int bL_switch_to(unsigned int new_cluster_id)
130 unsigned int ob_mpidr, ob_cpu, ob_cluster, ib_mpidr, ib_cpu, ib_cluster; 146 unsigned int ob_mpidr, ob_cpu, ob_cluster, ib_mpidr, ib_cpu, ib_cluster;
131 struct tick_device *tdev; 147 struct tick_device *tdev;
132 enum clock_event_mode tdev_mode; 148 enum clock_event_mode tdev_mode;
149 long volatile *handshake_ptr;
133 int ret; 150 int ret;
134 151
135 this_cpu = smp_processor_id(); 152 this_cpu = smp_processor_id();
@@ -198,7 +215,7 @@ static int bL_switch_to(unsigned int new_cluster_id)
198 cpu_logical_map(that_cpu) = ob_mpidr; 215 cpu_logical_map(that_cpu) = ob_mpidr;
199 216
200 /* Let's do the actual CPU switch. */ 217 /* Let's do the actual CPU switch. */
201 ret = cpu_suspend(0, bL_switchpoint); 218 ret = cpu_suspend((unsigned long)&handshake_ptr, bL_switchpoint);
202 if (ret > 0) 219 if (ret > 0)
203 panic("%s: cpu_suspend() returned %d\n", __func__, ret); 220 panic("%s: cpu_suspend() returned %d\n", __func__, ret);
204 221
@@ -220,6 +237,9 @@ static int bL_switch_to(unsigned int new_cluster_id)
220 local_fiq_enable(); 237 local_fiq_enable();
221 local_irq_enable(); 238 local_irq_enable();
222 239
240 *handshake_ptr = 1;
241 dsb_sev();
242
223 if (ret) 243 if (ret)
224 pr_err("%s exiting with error %d\n", __func__, ret); 244 pr_err("%s exiting with error %d\n", __func__, ret);
225 return ret; 245 return ret;