diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 9deeb3064d33733f57e3129be83bab343f6cd90c..4c28452ba07885bab162543e6a664afcdfdd4d30 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); diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 05a36e16f3f40a4e1d1f2ec851760c9149503376..c5c890dabca43c4a1a91c1c9d32dd4d72a0fd4c5 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -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