aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorArve Hjønnevåg <arve@android.com>2012-03-28 21:03:13 -0700
committerArve Hjønnevåg <arve@android.com>2013-04-29 14:42:44 -0700
commit175f670a92a8c27bd06604855aa39e50b42075ee (patch)
treece003b90e7f2b26a2a368cdb7d8a529d905ee958 /arch
parent1619e57670557b5b9cc3a0fc099d457c57da51b6 (diff)
ARM: etm: Wait for etm/ptm(s) to stop before requesting PowerDown
When PowerDown was requested at the same time as ProgBit, the formatter flush command that follows could get stuck. Change-Id: Iafb665f61f055819e64ca1dcb60398c656f593e4 Signed-off-by: Arve Hjønnevåg <arve@android.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/etm.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 60450545bc3..136a8962547 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -200,11 +200,13 @@ static int trace_stop_etm(struct tracectx *t, int id)
etm_unlock(t, id);
- etm_writel(t, id, 0x441, ETMR_CTRL);
+ etm_writel(t, id, 0x440, ETMR_CTRL);
while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
;
if (!timeout) {
- dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
+ dev_err(t->dev,
+ "etm%d: Waiting for progbit to assert timed out\n",
+ id);
etm_lock(t, id);
return -EFAULT;
}
@@ -213,18 +215,36 @@ static int trace_stop_etm(struct tracectx *t, int id)
return 0;
}
+static int trace_power_down_etm(struct tracectx *t, int id)
+{
+ unsigned long timeout = TRACER_TIMEOUT;
+ etm_unlock(t, id);
+ while (!(etm_readl(t, id, ETMR_STATUS) & ETMST_PROGBIT) && --timeout)
+ ;
+ if (!timeout) {
+ dev_err(t->dev, "etm%d: Waiting for status progbit to assert timed out\n",
+ id);
+ etm_lock(t, id);
+ return -EFAULT;
+ }
+
+ etm_writel(t, id, 0x441, ETMR_CTRL);
+
+ etm_lock(t, id);
+ return 0;
+}
+
static int trace_stop(struct tracectx *t)
{
int id;
- int ret;
unsigned long timeout = TRACER_TIMEOUT;
u32 etb_fc = t->etb_fc;
- for (id = 0; id < t->etm_regs_count; id++) {
- ret = trace_stop_etm(t, id);
- if (ret)
- return ret;
- }
+ for (id = 0; id < t->etm_regs_count; id++)
+ trace_stop_etm(t, id);
+
+ for (id = 0; id < t->etm_regs_count; id++)
+ trace_power_down_etm(t, id);
etb_unlock(t);
if (etb_fc) {