aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorJon Hunter <jon-hunter@ti.com>2012-07-11 14:47:38 -0400
committerJon Hunter <jon-hunter@ti.com>2012-11-16 11:35:05 -0500
commitae6672cb47c8a7652e9aff182eb85a15994c9487 (patch)
tree994f4aa70c4467476a1bc748f4bdf9be3ff93540 /arch/arm
parent9dc57643738f9fbe45c10cc062903d5dfda5bdd9 (diff)
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')
-rw-r--r--arch/arm/plat-omap/dmtimer.c50
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h23
2 files changed, 31 insertions, 42 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)
99 timer->context.tclr); 99 timer->context.tclr);
100} 100}
101 101
102static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer) 102static int omap_dm_timer_reset(struct omap_dm_timer *timer)
103{ 103{
104 int c; 104 u32 l, timeout = 100000;
105 105
106 if (!timer->sys_stat) 106 if (timer->revision != 1)
107 return; 107 return -EINVAL;
108 108
109 c = 0; 109 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
110 while (!(__raw_readl(timer->sys_stat) & 1)) { 110
111 c++; 111 do {
112 if (c > 100000) { 112 l = __omap_dm_timer_read(timer,
113 printk(KERN_ERR "Timer failed to reset\n"); 113 OMAP_TIMER_V1_SYS_STAT_OFFSET, 0);
114 return; 114 } while (!l && timeout--);
115 } 115
116 if (!timeout) {
117 dev_err(&timer->pdev->dev, "Timer failed to reset\n");
118 return -ETIMEDOUT;
116 } 119 }
117}
118 120
119static void omap_dm_timer_reset(struct omap_dm_timer *timer) 121 /* Configure timer for smart-idle mode */
120{ 122 l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
121 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); 123 l |= 0x2 << 0x3;
122 omap_dm_timer_wait_for_reset(timer); 124 __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0);
123 __omap_dm_timer_reset(timer, 0, 0); 125
126 timer->posted = 0;
127
128 return 0;
124} 129}
125 130
126int omap_dm_timer_prepare(struct omap_dm_timer *timer) 131int omap_dm_timer_prepare(struct omap_dm_timer *timer)
127{ 132{
133 int rc;
134
128 /* 135 /*
129 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so 136 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
130 * do not call clk_get() for these devices. 137 * do not call clk_get() for these devices.
@@ -140,8 +147,13 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer)
140 147
141 omap_dm_timer_enable(timer); 148 omap_dm_timer_enable(timer);
142 149
143 if (timer->capability & OMAP_TIMER_NEEDS_RESET) 150 if (timer->capability & OMAP_TIMER_NEEDS_RESET) {
144 omap_dm_timer_reset(timer); 151 rc = omap_dm_timer_reset(timer);
152 if (rc) {
153 omap_dm_timer_disable(timer);
154 return rc;
155 }
156 }
145 157
146 __omap_dm_timer_enable_posted(timer); 158 __omap_dm_timer_enable_posted(timer);
147 omap_dm_timer_disable(timer); 159 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 05a36e16f3f4..c5c890dabca4 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 {
267 struct clk *fclk; 267 struct clk *fclk;
268 268
269 void __iomem *io_base; 269 void __iomem *io_base;
270 void __iomem *sys_stat; /* TISTAT timer status */
271 void __iomem *irq_stat; /* TISR/IRQSTATUS interrupt status */ 270 void __iomem *irq_stat; /* TISR/IRQSTATUS interrupt status */
272 void __iomem *irq_ena; /* irq enable */ 271 void __iomem *irq_ena; /* irq enable */
273 void __iomem *irq_dis; /* irq disable, only on v2 ip */ 272 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)
317 tidr = __raw_readl(timer->io_base); 316 tidr = __raw_readl(timer->io_base);
318 if (!(tidr >> 16)) { 317 if (!(tidr >> 16)) {
319 timer->revision = 1; 318 timer->revision = 1;
320 timer->sys_stat = timer->io_base +
321 OMAP_TIMER_V1_SYS_STAT_OFFSET;
322 timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET; 319 timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET;
323 timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET; 320 timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
324 timer->irq_dis = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET; 321 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)
326 timer->func_base = timer->io_base; 323 timer->func_base = timer->io_base;
327 } else { 324 } else {
328 timer->revision = 2; 325 timer->revision = 2;
329 timer->sys_stat = NULL;
330 timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS; 326 timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS;
331 timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET; 327 timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET;
332 timer->irq_dis = timer->io_base + OMAP_TIMER_V2_IRQENABLE_CLR; 328 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)
337 } 333 }
338} 334}
339 335
340/* Assumes the source clock has been set by caller */
341static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer,
342 int autoidle, int wakeup)
343{
344 u32 l;
345
346 l = __raw_readl(timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
347 l |= 0x02 << 3; /* Set to smart-idle mode */
348 l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */
349
350 if (autoidle)
351 l |= 0x1 << 0;
352
353 if (wakeup)
354 l |= 1 << 2;
355
356 __raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
357}
358
359/* 336/*
360 * __omap_dm_timer_enable_posted - enables write posted mode 337 * __omap_dm_timer_enable_posted - enables write posted mode
361 * @timer: pointer to timer instance handle 338 * @timer: pointer to timer instance handle