aboutsummaryrefslogtreecommitdiff
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-05-13 19:03:35 -0400
commitc3d132aedfc0ad6e4cfb679084cf3fba68bd7e87 (patch)
treeb52afa76214e3bd2903778fe0f0617e9ec414a3b
parentcc1b20049cd8d2f3bc2fb9d736281410b6f96fc3 (diff)
ARM: bL_switcher: synchronize the outbound with the inbound
Let's wait for the inbound to come up and snoop some of our cache. That should be a bit more efficient than going down right away. Monitoring the CCI event counters could be a better approach eventually. Signed-off-by: Nicolas Pitre <nico@linaro.org>
-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 fe13ce456afb..bead7d0e97cc 100644
--- a/arch/arm/common/bL_switcher.c
+++ b/arch/arm/common/bL_switcher.c
@@ -52,9 +52,10 @@ static int read_mpidr(void)
* bL switcher core code.
*/
-static void bL_do_switch(void *_unused)
+static void bL_do_switch(void *_arg)
{
unsigned mpidr, cpuid, clusterid, ob_cluster, ib_cluster;
+ long volatile handshake, **handshake_ptr = _arg;
pr_debug("%s\n", __func__);
@@ -64,6 +65,13 @@ static void bL_do_switch(void *_unused)
ob_cluster = clusterid;
ib_cluster = clusterid ^ 1;
+ /* Advertise our handshake location */
+ if (handshake_ptr) {
+ handshake = 0;
+ *handshake_ptr = &handshake;
+ } else
+ handshake = -1;
+
/*
* Our state has been saved at this point. Let's release our
* inbound CPU.
@@ -82,6 +90,14 @@ static void bL_do_switch(void *_unused)
* we have none.
*/
+ /*
+ * Let's wait until our inbound is alive.
+ */
+ while (!handshake) {
+ wfe();
+ smp_mb();
+ }
+
/* Let's put ourself down. */
mcpm_cpu_power_down();
@@ -127,6 +143,7 @@ static int bL_switch_to(unsigned int new_cluster_id)
unsigned int mpidr, cpuid, clusterid, ob_cluster, ib_cluster, this_cpu;
struct tick_device *tdev;
enum clock_event_mode tdev_mode;
+ long volatile *handshake_ptr;
int ret;
mpidr = read_mpidr();
@@ -196,7 +213,7 @@ static int bL_switch_to(unsigned int new_cluster_id)
sizeof(cpu_logical_map(this_cpu)));
/* Let's do the actual CPU switch. */
- ret = cpu_suspend(0, bL_switchpoint);
+ ret = cpu_suspend((unsigned long)&handshake_ptr, bL_switchpoint);
if (ret > 0)
panic("%s: cpu_suspend() returned %d\n", __func__, ret);
@@ -220,6 +237,9 @@ static int bL_switch_to(unsigned int new_cluster_id)
local_fiq_enable();
local_irq_enable();
+ *handshake_ptr = 1;
+ dsb_sev();
+
if (ret)
pr_err("%s exiting with error %d\n", __func__, ret);
return ret;