aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;