diff options
author | Jon Hunter <jon-hunter@ti.com> | 2012-07-11 14:47:38 -0400 |
---|---|---|
committer | Jon Hunter <jon-hunter@ti.com> | 2012-11-16 11:35:05 -0500 |
commit | ae6672cb47c8a7652e9aff182eb85a15994c9487 (patch) | |
tree | 994f4aa70c4467476a1bc748f4bdf9be3ff93540 /arch/arm | |
parent | 9dc57643738f9fbe45c10cc062903d5dfda5bdd9 (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.c | 50 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/dmtimer.h | 23 |
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 | ||
102 | static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer) | 102 | static 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 | ||
119 | static 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 | ||
126 | int omap_dm_timer_prepare(struct omap_dm_timer *timer) | 131 | int 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 */ | ||
341 | static 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 |