aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)