summaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/dmtimer.c
diff options
context:
space:
mode:
authorJon Hunter <jon-hunter@ti.com>2012-07-11 13:47:38 -0500
committerJon Hunter <jon-hunter@ti.com>2012-11-16 10:35:05 -0600
commitae6672cb47c8a7652e9aff182eb85a15994c9487 (patch)
tree994f4aa70c4467476a1bc748f4bdf9be3ff93540 /arch/arm/plat-omap/dmtimer.c
parent9dc57643738f9fbe45c10cc062903d5dfda5bdd9 (diff)
downloadblackbird-op-linux-ae6672cb47c8a7652e9aff182eb85a15994c9487.tar.gz
blackbird-op-linux-ae6672cb47c8a7652e9aff182eb85a15994c9487.zip
ARM: OMAP: Clean-up dmtimer reset code
Only OMAP1 devices use the omap_dm_timer_reset() and so require the omap_dm_timer_wait_for_reset() and __omap_dm_timer_reset() functions. Therefore combine these into a single function called omap_dm_timer_reset() and simplify the code. The omap_dm_timer_reset() function is now the only place that is using the omap_dm_timer structure member "sys_stat". Therefore, remove this member and just use the register offset definition to simplify and clean-up the code. The TISTAT register is only present on revision 1 timers and so check for this in the omap_dm_timer_reset() function. Please note that for OMAP1 devices, the TIOCP_CFG register does not have the clock-activity field and so when we reset the timer for an OMAP1 device we only need to configure the idle-mode field in the TIOCP_CFG register. Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Diffstat (limited to 'arch/arm/plat-omap/dmtimer.c')
-rw-r--r--arch/arm/plat-omap/dmtimer.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 9deeb3064d33..4c28452ba078 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -99,32 +99,39 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer)
timer->context.tclr);
}
-static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
+static int omap_dm_timer_reset(struct omap_dm_timer *timer)
{
- int c;
+ u32 l, timeout = 100000;
- if (!timer->sys_stat)
- return;
+ if (timer->revision != 1)
+ return -EINVAL;
- c = 0;
- while (!(__raw_readl(timer->sys_stat) & 1)) {
- c++;
- if (c > 100000) {
- printk(KERN_ERR "Timer failed to reset\n");
- return;
- }
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
+
+ do {
+ l = __omap_dm_timer_read(timer,
+ OMAP_TIMER_V1_SYS_STAT_OFFSET, 0);
+ } while (!l && timeout--);
+
+ if (!timeout) {
+ dev_err(&timer->pdev->dev, "Timer failed to reset\n");
+ return -ETIMEDOUT;
}
-}
-static void omap_dm_timer_reset(struct omap_dm_timer *timer)
-{
- omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
- omap_dm_timer_wait_for_reset(timer);
- __omap_dm_timer_reset(timer, 0, 0);
+ /* Configure timer for smart-idle mode */
+ l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
+ l |= 0x2 << 0x3;
+ __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0);
+
+ timer->posted = 0;
+
+ return 0;
}
int omap_dm_timer_prepare(struct omap_dm_timer *timer)
{
+ int rc;
+
/*
* FIXME: OMAP1 devices do not use the clock framework for dmtimers so
* do not call clk_get() for these devices.
@@ -140,8 +147,13 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer)
omap_dm_timer_enable(timer);
- if (timer->capability & OMAP_TIMER_NEEDS_RESET)
- omap_dm_timer_reset(timer);
+ if (timer->capability & OMAP_TIMER_NEEDS_RESET) {
+ rc = omap_dm_timer_reset(timer);
+ if (rc) {
+ omap_dm_timer_disable(timer);
+ return rc;
+ }
+ }
__omap_dm_timer_enable_posted(timer);
omap_dm_timer_disable(timer);
OpenPOWER on IntegriCloud