summaryrefslogtreecommitdiff
path: root/arch/arm/kernel
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>2012-04-12 15:43:39 -0700
commiteff62a8af891cfdbe28c1abe28f42a9279bead87 (patch)
tree9012fa2aa74ce489324d3a05bcca592e8725627f /arch/arm/kernel
parentbfd6bf03805103c4d1af9f884308a7faae3dbea4 (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/arm/kernel')
-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 66bf5928444..bad28deb698 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) {