ARM: OMAP: Clean-up dmtimer reset code
authorJon Hunter <jon-hunter@ti.com>
Wed, 11 Jul 2012 18:47:38 +0000 (13:47 -0500)
committerJon Hunter <jon-hunter@ti.com>
Fri, 16 Nov 2012 16:35:05 +0000 (10:35 -0600)
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>
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/include/plat/dmtimer.h

index 9deeb3064d33733f57e3129be83bab343f6cd90c..4c28452ba07885bab162543e6a664afcdfdd4d30 100644 (file)
@@ -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);
index 05a36e16f3f40a4e1d1f2ec851760c9149503376..c5c890dabca43c4a1a91c1c9d32dd4d72a0fd4c5 100644 (file)
@@ -267,7 +267,6 @@ struct omap_dm_timer {
        struct clk *fclk;
 
        void __iomem    *io_base;
-       void __iomem    *sys_stat;      /* TISTAT timer status */
        void __iomem    *irq_stat;      /* TISR/IRQSTATUS interrupt status */
        void __iomem    *irq_ena;       /* irq enable */
        void __iomem    *irq_dis;       /* irq disable, only on v2 ip */
@@ -317,8 +316,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
        tidr = __raw_readl(timer->io_base);
        if (!(tidr >> 16)) {
                timer->revision = 1;
-               timer->sys_stat = timer->io_base +
-                               OMAP_TIMER_V1_SYS_STAT_OFFSET;
                timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET;
                timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
                timer->irq_dis = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
@@ -326,7 +323,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
                timer->func_base = timer->io_base;
        } else {
                timer->revision = 2;
-               timer->sys_stat = NULL;
                timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS;
                timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET;
                timer->irq_dis = timer->io_base + OMAP_TIMER_V2_IRQENABLE_CLR;
@@ -337,25 +333,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
        }
 }
 
-/* Assumes the source clock has been set by caller */
-static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer,
-                                       int autoidle, int wakeup)
-{
-       u32 l;
-
-       l = __raw_readl(timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
-       l |= 0x02 << 3;  /* Set to smart-idle mode */
-       l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */
-
-       if (autoidle)
-               l |= 0x1 << 0;
-
-       if (wakeup)
-               l |= 1 << 2;
-
-       __raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
-}
-
 /*
  * __omap_dm_timer_enable_posted - enables write posted mode
  * @timer:      pointer to timer instance handle