aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2012-07-26 14:08:42 +0100
committerJon Medhurst <tixy@linaro.org>2012-08-07 10:59:31 +0100
commitda2e6d929a6b9b76581a4f5721535a2738be9083 (patch)
treec0802348c5e2aded60d9cc7fb6babb96ea627cfa
parent72c03a558df6beb6a34ed2fcd95cb317721b8e4f (diff)
This patch defines C1 as disabled by default on TC2. If the state is later enabled but deep shutdown states are required to be enabled on a cluster basis, a coupled barrier must be added to the coupled enter function so that coupled CPUs cannot exit the polling C1 state while other ones are still entering. This patch fixes a race in C1 code where one CPU exits a coupled C-state while another one, part of the coupled mask is still selecting the coupled C-state value. This can cause some CPUs to select the -1 state index which triggers an undefined instruction fault. The added coupled C-state barrier fixes the issue by forcing coupled C-states to be entered and exited at the same time by all CPUs even if cluster shutdown is disabled. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Jon Medhurst <tixy@linaro.org>
-rw-r--r--arch/arm/mach-vexpress/cpuidle-tc2.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/arm/mach-vexpress/cpuidle-tc2.c b/arch/arm/mach-vexpress/cpuidle-tc2.c
index 11030b5c0ec4..6205044d531a 100644
--- a/arch/arm/mach-vexpress/cpuidle-tc2.c
+++ b/arch/arm/mach-vexpress/cpuidle-tc2.c
@@ -72,6 +72,7 @@ static struct cpuidle_state tc2_cpuidle_set[] __initdata = {
CPUIDLE_FLAG_COUPLED,
.name = "C1",
.desc = "ARM power down",
+ .disabled = 1,
},
};
@@ -138,8 +139,11 @@ static int tc2_enter_coupled(struct cpuidle_device *dev,
/* Used to keep track of the total time in idle */
getnstimeofday(&ts_preidle);
- if (!cpu_isset(cluster, cluster_mask))
+ if (!cpu_isset(cluster, cluster_mask)) {
+ cpuidle_coupled_parallel_barrier(dev,
+ &abort_barrier[cluster]);
goto shallow_out;
+ }
BUG_ON(!irqs_disabled());