aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTarun Kanti DebBarma <tarun.kanti@ti.com>2011-09-20 07:30:20 -0400
committerTony Lindgren <tony@atomide.com>2011-09-21 18:50:31 -0400
commit3392cdd33a0419e3226910a08b8bdc43b56c95d0 (patch)
treea5cf298efd7c9d3fc0a19e713ff7926bcbb938e9
parentdf28472a1b28f5d2a6e5cf66265aa328995fde6b (diff)
ARM: OMAP: dmtimer: switch-over to platform device driver
Register timer devices by going through hwmod database using hwmod API. The driver probes each of the registered devices. Functionality which are already performed by hwmod framework are removed from timer code. New set of timers present on OMAP4 are now supported. Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com> Acked-by: Cousson, Benoit <b-cousson@ti.com> [tony@atomide.com: folded in spinlock changes, left out is_omap2] Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--arch/arm/mach-omap2/timer.c20
-rw-r--r--arch/arm/plat-omap/dmtimer.c346
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h5
3 files changed, 123 insertions, 248 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index b2829ee0c4e4..9c2f58895a16 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -478,3 +478,23 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
478 478
479 return ret; 479 return ret;
480} 480}
481
482/**
483 * omap2_dm_timer_init - top level regular device initialization
484 *
485 * Uses dedicated hwmod api to parse through hwmod database for
486 * given class name and then build and register the timer device.
487 */
488static int __init omap2_dm_timer_init(void)
489{
490 int ret;
491
492 ret = omap_hwmod_for_each_by_class("timer", omap_timer_init, NULL);
493 if (unlikely(ret)) {
494 pr_err("%s: device registration failed.\n", __func__);
495 return -EINVAL;
496 }
497
498 return 0;
499}
500arch_initcall(omap2_dm_timer_init);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 92d5aff9b2e9..601920860597 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -36,120 +36,22 @@
36 */ 36 */
37 37
38#include <linux/io.h> 38#include <linux/io.h>
39#include <linux/module.h>
40#include <linux/slab.h> 39#include <linux/slab.h>
41#include <mach/hardware.h> 40#include <linux/err.h>
42#include <plat/dmtimer.h>
43#include <mach/irqs.h>
44
45static int dm_timer_count;
46
47#ifdef CONFIG_ARCH_OMAP2
48static struct omap_dm_timer omap2_dm_timers[] = {
49 { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
50 { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
51 { .phys_base = 0x48078000, .irq = INT_24XX_GPTIMER3 },
52 { .phys_base = 0x4807a000, .irq = INT_24XX_GPTIMER4 },
53 { .phys_base = 0x4807c000, .irq = INT_24XX_GPTIMER5 },
54 { .phys_base = 0x4807e000, .irq = INT_24XX_GPTIMER6 },
55 { .phys_base = 0x48080000, .irq = INT_24XX_GPTIMER7 },
56 { .phys_base = 0x48082000, .irq = INT_24XX_GPTIMER8 },
57 { .phys_base = 0x48084000, .irq = INT_24XX_GPTIMER9 },
58 { .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
59 { .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
60 { .phys_base = 0x4808a000, .irq = INT_24XX_GPTIMER12 },
61};
62
63static const char *omap2_dm_source_names[] __initdata = {
64 "sys_ck",
65 "func_32k_ck",
66 "alt_ck",
67 NULL
68};
69
70static struct clk *omap2_dm_source_clocks[3];
71static const int omap2_dm_timer_count = ARRAY_SIZE(omap2_dm_timers);
72
73#else
74#define omap2_dm_timers NULL
75#define omap2_dm_timer_count 0
76#define omap2_dm_source_names NULL
77#define omap2_dm_source_clocks NULL
78#endif /* CONFIG_ARCH_OMAP2 */
79
80#ifdef CONFIG_ARCH_OMAP3
81static struct omap_dm_timer omap3_dm_timers[] = {
82 { .phys_base = 0x48318000, .irq = INT_24XX_GPTIMER1 },
83 { .phys_base = 0x49032000, .irq = INT_24XX_GPTIMER2 },
84 { .phys_base = 0x49034000, .irq = INT_24XX_GPTIMER3 },
85 { .phys_base = 0x49036000, .irq = INT_24XX_GPTIMER4 },
86 { .phys_base = 0x49038000, .irq = INT_24XX_GPTIMER5 },
87 { .phys_base = 0x4903A000, .irq = INT_24XX_GPTIMER6 },
88 { .phys_base = 0x4903C000, .irq = INT_24XX_GPTIMER7 },
89 { .phys_base = 0x4903E000, .irq = INT_24XX_GPTIMER8 },
90 { .phys_base = 0x49040000, .irq = INT_24XX_GPTIMER9 },
91 { .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
92 { .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
93 { .phys_base = 0x48304000, .irq = INT_34XX_GPT12_IRQ },
94};
95
96static const char *omap3_dm_source_names[] __initdata = {
97 "sys_ck",
98 "omap_32k_fck",
99 NULL
100};
101
102static struct clk *omap3_dm_source_clocks[2];
103static const int omap3_dm_timer_count = ARRAY_SIZE(omap3_dm_timers);
104
105#else
106#define omap3_dm_timers NULL
107#define omap3_dm_timer_count 0
108#define omap3_dm_source_names NULL
109#define omap3_dm_source_clocks NULL
110#endif /* CONFIG_ARCH_OMAP3 */
111
112#ifdef CONFIG_ARCH_OMAP4
113static struct omap_dm_timer omap4_dm_timers[] = {
114 { .phys_base = 0x4a318000, .irq = OMAP44XX_IRQ_GPT1 },
115 { .phys_base = 0x48032000, .irq = OMAP44XX_IRQ_GPT2 },
116 { .phys_base = 0x48034000, .irq = OMAP44XX_IRQ_GPT3 },
117 { .phys_base = 0x48036000, .irq = OMAP44XX_IRQ_GPT4 },
118 { .phys_base = 0x40138000, .irq = OMAP44XX_IRQ_GPT5 },
119 { .phys_base = 0x4013a000, .irq = OMAP44XX_IRQ_GPT6 },
120 { .phys_base = 0x4013a000, .irq = OMAP44XX_IRQ_GPT7 },
121 { .phys_base = 0x4013e000, .irq = OMAP44XX_IRQ_GPT8 },
122 { .phys_base = 0x4803e000, .irq = OMAP44XX_IRQ_GPT9 },
123 { .phys_base = 0x48086000, .irq = OMAP44XX_IRQ_GPT10 },
124 { .phys_base = 0x48088000, .irq = OMAP44XX_IRQ_GPT11 },
125 { .phys_base = 0x4a320000, .irq = OMAP44XX_IRQ_GPT12 },
126};
127static const char *omap4_dm_source_names[] __initdata = {
128 "sys_clkin_ck",
129 "sys_32k_ck",
130 NULL
131};
132static struct clk *omap4_dm_source_clocks[2];
133static const int omap4_dm_timer_count = ARRAY_SIZE(omap4_dm_timers);
134 41
135#else 42#include <plat/dmtimer.h>
136#define omap4_dm_timers NULL
137#define omap4_dm_timer_count 0
138#define omap4_dm_source_names NULL
139#define omap4_dm_source_clocks NULL
140#endif /* CONFIG_ARCH_OMAP4 */
141
142static struct omap_dm_timer *dm_timers;
143static const char **dm_source_names;
144static struct clk **dm_source_clocks;
145 43
146static spinlock_t dm_timer_lock;
147static LIST_HEAD(omap_timer_list); 44static LIST_HEAD(omap_timer_list);
45static DEFINE_SPINLOCK(dm_timer_lock);
148 46
149/* 47/**
150 * Reads timer registers in posted and non-posted mode. The posted mode bit 48 * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
151 * is encoded in reg. Note that in posted mode write pending bit must be 49 * @timer: timer pointer over which read operation to perform
152 * checked. Otherwise a read of a non completed write will produce an error. 50 * @reg: lowest byte holds the register offset
51 *
52 * The posted mode bit is encoded in reg. Note that in posted mode write
53 * pending bit must be checked. Otherwise a read of a non completed write
54 * will produce an error.
153 */ 55 */
154static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg) 56static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
155{ 57{
@@ -157,11 +59,15 @@ static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
157 return __omap_dm_timer_read(timer, reg, timer->posted); 59 return __omap_dm_timer_read(timer, reg, timer->posted);
158} 60}
159 61
160/* 62/**
161 * Writes timer registers in posted and non-posted mode. The posted mode bit 63 * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode
162 * is encoded in reg. Note that in posted mode the write pending bit must be 64 * @timer: timer pointer over which write operation is to perform
163 * checked. Otherwise a write on a register which has a pending write will be 65 * @reg: lowest byte holds the register offset
164 * lost. 66 * @value: data to write into the register
67 *
68 * The posted mode bit is encoded in reg. Note that in posted mode the write
69 * pending bit must be checked. Otherwise a write on a register which has a
70 * pending write will be lost.
165 */ 71 */
166static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, 72static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
167 u32 value) 73 u32 value)
@@ -189,53 +95,65 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
189 95
190static void omap_dm_timer_reset(struct omap_dm_timer *timer) 96static void omap_dm_timer_reset(struct omap_dm_timer *timer)
191{ 97{
192 int autoidle = 0, wakeup = 0; 98 if (timer->pdev->id != 1) {
193
194 if (!cpu_class_is_omap2() || timer != &dm_timers[0]) {
195 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); 99 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
196 omap_dm_timer_wait_for_reset(timer); 100 omap_dm_timer_wait_for_reset(timer);
197 } 101 }
198 omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
199
200 /* Enable autoidle on OMAP2+ */
201 if (cpu_class_is_omap2())
202 autoidle = 1;
203
204 /*
205 * Enable wake-up on OMAP2 CPUs.
206 */
207 if (cpu_class_is_omap2())
208 wakeup = 1;
209 102
210 __omap_dm_timer_reset(timer, autoidle, wakeup); 103 __omap_dm_timer_reset(timer, 0, 0);
211 timer->posted = 1; 104 timer->posted = 1;
212} 105}
213 106
214void omap_dm_timer_prepare(struct omap_dm_timer *timer) 107int omap_dm_timer_prepare(struct omap_dm_timer *timer)
215{ 108{
109 struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
110 int ret;
111
112 timer->fclk = clk_get(&timer->pdev->dev, "fck");
113 if (WARN_ON_ONCE(IS_ERR_OR_NULL(timer->fclk))) {
114 timer->fclk = NULL;
115 dev_err(&timer->pdev->dev, ": No fclk handle.\n");
116 return -EINVAL;
117 }
118
216 omap_dm_timer_enable(timer); 119 omap_dm_timer_enable(timer);
217 omap_dm_timer_reset(timer); 120
121 if (pdata->needs_manual_reset)
122 omap_dm_timer_reset(timer);
123
124 ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
125
126 timer->posted = 1;
127 return ret;
218} 128}
219 129
220struct omap_dm_timer *omap_dm_timer_request(void) 130struct omap_dm_timer *omap_dm_timer_request(void)
221{ 131{
222 struct omap_dm_timer *timer = NULL; 132 struct omap_dm_timer *timer = NULL, *t;
223 unsigned long flags; 133 unsigned long flags;
224 int i; 134 int ret = 0;
225 135
226 spin_lock_irqsave(&dm_timer_lock, flags); 136 spin_lock_irqsave(&dm_timer_lock, flags);
227 for (i = 0; i < dm_timer_count; i++) { 137 list_for_each_entry(t, &omap_timer_list, node) {
228 if (dm_timers[i].reserved) 138 if (t->reserved)
229 continue; 139 continue;
230 140
231 timer = &dm_timers[i]; 141 timer = t;
232 timer->reserved = 1; 142 timer->reserved = 1;
233 break; 143 break;
234 } 144 }
145
146 if (timer) {
147 ret = omap_dm_timer_prepare(timer);
148 if (ret) {
149 timer->reserved = 0;
150 timer = NULL;
151 }
152 }
235 spin_unlock_irqrestore(&dm_timer_lock, flags); 153 spin_unlock_irqrestore(&dm_timer_lock, flags);
236 154
237 if (timer != NULL) 155 if (!timer)
238 omap_dm_timer_prepare(timer); 156 pr_debug("%s: timer request failed!\n", __func__);
239 157
240 return timer; 158 return timer;
241} 159}
@@ -243,23 +161,30 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request);
243 161
244struct omap_dm_timer *omap_dm_timer_request_specific(int id) 162struct omap_dm_timer *omap_dm_timer_request_specific(int id)
245{ 163{
246 struct omap_dm_timer *timer; 164 struct omap_dm_timer *timer = NULL, *t;
247 unsigned long flags; 165 unsigned long flags;
166 int ret = 0;
248 167
249 spin_lock_irqsave(&dm_timer_lock, flags); 168 spin_lock_irqsave(&dm_timer_lock, flags);
250 if (id <= 0 || id > dm_timer_count || dm_timers[id-1].reserved) { 169 list_for_each_entry(t, &omap_timer_list, node) {
251 spin_unlock_irqrestore(&dm_timer_lock, flags); 170 if (t->pdev->id == id && !t->reserved) {
252 printk("BUG: warning at %s:%d/%s(): unable to get timer %d\n", 171 timer = t;
253 __FILE__, __LINE__, __func__, id); 172 timer->reserved = 1;
254 dump_stack(); 173 break;
255 return NULL; 174 }
256 } 175 }
257 176
258 timer = &dm_timers[id-1]; 177 if (timer) {
259 timer->reserved = 1; 178 ret = omap_dm_timer_prepare(timer);
179 if (ret) {
180 timer->reserved = 0;
181 timer = NULL;
182 }
183 }
260 spin_unlock_irqrestore(&dm_timer_lock, flags); 184 spin_unlock_irqrestore(&dm_timer_lock, flags);
261 185
262 omap_dm_timer_prepare(timer); 186 if (!timer)
187 pr_debug("%s: timer%d request failed!\n", __func__, id);
263 188
264 return timer; 189 return timer;
265} 190}
@@ -267,9 +192,8 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
267 192
268void omap_dm_timer_free(struct omap_dm_timer *timer) 193void omap_dm_timer_free(struct omap_dm_timer *timer)
269{ 194{
270 omap_dm_timer_enable(timer);
271 omap_dm_timer_reset(timer);
272 omap_dm_timer_disable(timer); 195 omap_dm_timer_disable(timer);
196 clk_put(timer->fclk);
273 197
274 WARN_ON(!timer->reserved); 198 WARN_ON(!timer->reserved);
275 timer->reserved = 0; 199 timer->reserved = 0;
@@ -278,15 +202,15 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_free);
278 202
279void omap_dm_timer_enable(struct omap_dm_timer *timer) 203void omap_dm_timer_enable(struct omap_dm_timer *timer)
280{ 204{
205 struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
206
281 if (timer->enabled) 207 if (timer->enabled)
282 return; 208 return;
283 209
284#ifdef CONFIG_ARCH_OMAP2PLUS 210 if (!pdata->needs_manual_reset) {
285 if (cpu_class_is_omap2()) {
286 clk_enable(timer->fclk); 211 clk_enable(timer->fclk);
287 clk_enable(timer->iclk); 212 clk_enable(timer->iclk);
288 } 213 }
289#endif
290 214
291 timer->enabled = 1; 215 timer->enabled = 1;
292} 216}
@@ -294,15 +218,15 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
294 218
295void omap_dm_timer_disable(struct omap_dm_timer *timer) 219void omap_dm_timer_disable(struct omap_dm_timer *timer)
296{ 220{
221 struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
222
297 if (!timer->enabled) 223 if (!timer->enabled)
298 return; 224 return;
299 225
300#ifdef CONFIG_ARCH_OMAP2PLUS 226 if (!pdata->needs_manual_reset) {
301 if (cpu_class_is_omap2()) {
302 clk_disable(timer->iclk); 227 clk_disable(timer->iclk);
303 clk_disable(timer->fclk); 228 clk_disable(timer->fclk);
304 } 229 }
305#endif
306 230
307 timer->enabled = 0; 231 timer->enabled = 0;
308} 232}
@@ -322,24 +246,29 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
322 */ 246 */
323__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) 247__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
324{ 248{
325 int i; 249 int i = 0;
250 struct omap_dm_timer *timer = NULL;
251 unsigned long flags;
326 252
327 /* If ARMXOR cannot be idled this function call is unnecessary */ 253 /* If ARMXOR cannot be idled this function call is unnecessary */
328 if (!(inputmask & (1 << 1))) 254 if (!(inputmask & (1 << 1)))
329 return inputmask; 255 return inputmask;
330 256
331 /* If any active timer is using ARMXOR return modified mask */ 257 /* If any active timer is using ARMXOR return modified mask */
332 for (i = 0; i < dm_timer_count; i++) { 258 spin_lock_irqsave(&dm_timer_lock, flags);
259 list_for_each_entry(timer, &omap_timer_list, node) {
333 u32 l; 260 u32 l;
334 261
335 l = omap_dm_timer_read_reg(&dm_timers[i], OMAP_TIMER_CTRL_REG); 262 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
336 if (l & OMAP_TIMER_CTRL_ST) { 263 if (l & OMAP_TIMER_CTRL_ST) {
337 if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0) 264 if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
338 inputmask &= ~(1 << 1); 265 inputmask &= ~(1 << 1);
339 else 266 else
340 inputmask &= ~(1 << 2); 267 inputmask &= ~(1 << 2);
341 } 268 }
269 i++;
342 } 270 }
271 spin_unlock_irqrestore(&dm_timer_lock, flags);
343 272
344 return inputmask; 273 return inputmask;
345} 274}
@@ -384,10 +313,10 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_start);
384void omap_dm_timer_stop(struct omap_dm_timer *timer) 313void omap_dm_timer_stop(struct omap_dm_timer *timer)
385{ 314{
386 unsigned long rate = 0; 315 unsigned long rate = 0;
316 struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
387 317
388#ifdef CONFIG_ARCH_OMAP2PLUS 318 if (!pdata->needs_manual_reset)
389 rate = clk_get_rate(timer->fclk); 319 rate = clk_get_rate(timer->fclk);
390#endif
391 320
392 __omap_dm_timer_stop(timer, timer->posted, rate); 321 __omap_dm_timer_stop(timer, timer->posted, rate);
393} 322}
@@ -395,15 +324,17 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
395 324
396int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) 325int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
397{ 326{
327 int ret;
328 struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
329
398 if (source < 0 || source >= 3) 330 if (source < 0 || source >= 3)
399 return -EINVAL; 331 return -EINVAL;
400 332
401#ifdef CONFIG_ARCH_OMAP2PLUS 333 omap_dm_timer_disable(timer);
402 return __omap_dm_timer_set_source(timer->fclk, 334 ret = pdata->set_timer_src(timer->pdev, source);
403 dm_source_clocks[source]); 335 omap_dm_timer_enable(timer);
404#else 336
405 return 0; 337 return ret;
406#endif
407} 338}
408EXPORT_SYMBOL_GPL(omap_dm_timer_set_source); 339EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
409 340
@@ -526,13 +457,9 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
526 457
527int omap_dm_timers_active(void) 458int omap_dm_timers_active(void)
528{ 459{
529 int i; 460 struct omap_dm_timer *timer;
530
531 for (i = 0; i < dm_timer_count; i++) {
532 struct omap_dm_timer *timer;
533
534 timer = &dm_timers[i];
535 461
462 list_for_each_entry(timer, &omap_timer_list, node) {
536 if (!timer->enabled) 463 if (!timer->enabled)
537 continue; 464 continue;
538 465
@@ -602,7 +529,6 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
602 timer->id = pdev->id; 529 timer->id = pdev->id;
603 timer->irq = irq->start; 530 timer->irq = irq->start;
604 timer->pdev = pdev; 531 timer->pdev = pdev;
605 __omap_dm_timer_init_regs(timer);
606 532
607 /* add the timer element to the list */ 533 /* add the timer element to the list */
608 spin_lock_irqsave(&dm_timer_lock, flags); 534 spin_lock_irqsave(&dm_timer_lock, flags);
@@ -675,73 +601,3 @@ MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
675MODULE_LICENSE("GPL"); 601MODULE_LICENSE("GPL");
676MODULE_ALIAS("platform:" DRIVER_NAME); 602MODULE_ALIAS("platform:" DRIVER_NAME);
677MODULE_AUTHOR("Texas Instruments Inc"); 603MODULE_AUTHOR("Texas Instruments Inc");
678
679static int __init omap_dm_timer_init(void)
680{
681 struct omap_dm_timer *timer;
682 int i, map_size = SZ_8K; /* Module 4KB + L4 4KB except on omap1 */
683
684 if (!cpu_class_is_omap2())
685 return -ENODEV;
686
687 spin_lock_init(&dm_timer_lock);
688
689 if (cpu_is_omap24xx()) {
690 dm_timers = omap2_dm_timers;
691 dm_timer_count = omap2_dm_timer_count;
692 dm_source_names = omap2_dm_source_names;
693 dm_source_clocks = omap2_dm_source_clocks;
694 } else if (cpu_is_omap34xx()) {
695 dm_timers = omap3_dm_timers;
696 dm_timer_count = omap3_dm_timer_count;
697 dm_source_names = omap3_dm_source_names;
698 dm_source_clocks = omap3_dm_source_clocks;
699 } else if (cpu_is_omap44xx()) {
700 dm_timers = omap4_dm_timers;
701 dm_timer_count = omap4_dm_timer_count;
702 dm_source_names = omap4_dm_source_names;
703 dm_source_clocks = omap4_dm_source_clocks;
704
705 pr_err("dmtimers disabled for omap4 until hwmod conversion\n");
706 return -ENODEV;
707 }
708
709 if (cpu_class_is_omap2())
710 for (i = 0; dm_source_names[i] != NULL; i++)
711 dm_source_clocks[i] = clk_get(NULL, dm_source_names[i]);
712
713 if (cpu_is_omap243x())
714 dm_timers[0].phys_base = 0x49018000;
715
716 for (i = 0; i < dm_timer_count; i++) {
717 timer = &dm_timers[i];
718
719 /* Static mapping, never released */
720 timer->io_base = ioremap(timer->phys_base, map_size);
721 BUG_ON(!timer->io_base);
722
723#ifdef CONFIG_ARCH_OMAP2PLUS
724 if (cpu_class_is_omap2()) {
725 char clk_name[16];
726 sprintf(clk_name, "gpt%d_ick", i + 1);
727 timer->iclk = clk_get(NULL, clk_name);
728 sprintf(clk_name, "gpt%d_fck", i + 1);
729 timer->fclk = clk_get(NULL, clk_name);
730 }
731
732 /* One or two timers may be set up early for sys_timer */
733 if (sys_timer_reserved & (1 << i)) {
734 timer->reserved = 1;
735 timer->posted = 1;
736 continue;
737 }
738#endif
739 omap_dm_timer_enable(timer);
740 __omap_dm_timer_init_regs(timer);
741 omap_dm_timer_disable(timer);
742 }
743
744 return 0;
745}
746
747arch_initcall(omap_dm_timer_init);
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 98f186e178c5..2ac7538541b2 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -231,9 +231,8 @@ struct omap_dm_timer {
231 unsigned long phys_base; 231 unsigned long phys_base;
232 int id; 232 int id;
233 int irq; 233 int irq;
234#ifdef CONFIG_ARCH_OMAP2PLUS
235 struct clk *iclk, *fclk; 234 struct clk *iclk, *fclk;
236#endif 235
237 void __iomem *io_base; 236 void __iomem *io_base;
238 void __iomem *sys_stat; /* TISTAT timer status */ 237 void __iomem *sys_stat; /* TISTAT timer status */
239 void __iomem *irq_stat; /* TISR/IRQSTATUS interrupt status */ 238 void __iomem *irq_stat; /* TISR/IRQSTATUS interrupt status */
@@ -251,7 +250,7 @@ struct omap_dm_timer {
251}; 250};
252 251
253extern u32 sys_timer_reserved; 252extern u32 sys_timer_reserved;
254void omap_dm_timer_prepare(struct omap_dm_timer *timer); 253int omap_dm_timer_prepare(struct omap_dm_timer *timer);
255 254
256static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg, 255static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg,
257 int posted) 256 int posted)