aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@solidboot.com>2006-06-26 19:16:23 -0400
committerTony Lindgren <tony@atomide.com>2006-06-26 19:16:23 -0400
commit83379c81f6f05a6e80db66ae33378feb4cbca6b3 (patch)
tree77d1c1b535ec0708df1325ddb0474aa878aba332 /arch/arm
parent7df3450e5c22ba3969e4253dce0d7807dd210bf0 (diff)
ARM: OMAP: Update dmtimers
- Initialize timer outside of spinlock to reduce the time the spinlock is held - Do clk_get to the source clocks during initialization to avoid sleeping later - New function to set counter register Signed-off-by: Timo Teras <timo.teras@solidboot.com> Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/plat-omap/dmtimer.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index bfccebc77515..804a53534370 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -107,6 +107,14 @@ static struct omap_dm_timer dm_timers[] = {
107 { .phys_base = 0x4808a000, .irq = INT_24XX_GPTIMER12 }, 107 { .phys_base = 0x4808a000, .irq = INT_24XX_GPTIMER12 },
108}; 108};
109 109
110static const char *dm_source_names[] = {
111 "sys_ck",
112 "func_32k_ck",
113 "alt_ck"
114};
115
116static struct clk *dm_source_clocks[3];
117
110#else 118#else
111 119
112#error OMAP architecture not supported! 120#error OMAP architecture not supported!
@@ -114,7 +122,6 @@ static struct omap_dm_timer dm_timers[] = {
114#endif 122#endif
115 123
116static const int dm_timer_count = ARRAY_SIZE(dm_timers); 124static const int dm_timer_count = ARRAY_SIZE(dm_timers);
117
118static spinlock_t dm_timer_lock; 125static spinlock_t dm_timer_lock;
119 126
120static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg) 127static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg)
@@ -159,9 +166,8 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
159 omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l); 166 omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
160} 167}
161 168
162static void omap_dm_timer_reserve(struct omap_dm_timer *timer) 169static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
163{ 170{
164 timer->reserved = 1;
165#ifdef CONFIG_ARCH_OMAP2 171#ifdef CONFIG_ARCH_OMAP2
166 clk_enable(timer->iclk); 172 clk_enable(timer->iclk);
167 clk_enable(timer->fclk); 173 clk_enable(timer->fclk);
@@ -181,11 +187,14 @@ struct omap_dm_timer *omap_dm_timer_request(void)
181 continue; 187 continue;
182 188
183 timer = &dm_timers[i]; 189 timer = &dm_timers[i];
184 omap_dm_timer_reserve(timer); 190 timer->reserved = 1;
185 break; 191 break;
186 } 192 }
187 spin_unlock_irqrestore(&dm_timer_lock, flags); 193 spin_unlock_irqrestore(&dm_timer_lock, flags);
188 194
195 if (timer != NULL)
196 omap_dm_timer_prepare(timer);
197
189 return timer; 198 return timer;
190} 199}
191 200
@@ -204,9 +213,11 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
204 } 213 }
205 214
206 timer = &dm_timers[id-1]; 215 timer = &dm_timers[id-1];
207 omap_dm_timer_reserve(timer); 216 timer->reserved = 1;
208 spin_unlock_irqrestore(&dm_timer_lock, flags); 217 spin_unlock_irqrestore(&dm_timer_lock, flags);
209 218
219 omap_dm_timer_prepare(timer);
220
210 return timer; 221 return timer;
211} 222}
212 223
@@ -318,21 +329,12 @@ void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
318 329
319void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) 330void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
320{ 331{
321 static const char *source_timers[] = {
322 "sys_ck",
323 "func_32k_ck",
324 "alt_ck"
325 };
326 struct clk *parent;
327
328 if (source < 0 || source >= 3) 332 if (source < 0 || source >= 3)
329 return; 333 return;
330 334
331 parent = clk_get(NULL, source_timers[source]);
332 clk_disable(timer->fclk); 335 clk_disable(timer->fclk);
333 clk_set_parent(timer->fclk, parent); 336 clk_set_parent(timer->fclk, dm_source_clocks[source]);
334 clk_enable(timer->fclk); 337 clk_enable(timer->fclk);
335 clk_put(parent);
336 338
337 /* When the functional clock disappears, too quick writes seem to 339 /* When the functional clock disappears, too quick writes seem to
338 * cause an abort. */ 340 * cause an abort. */
@@ -362,7 +364,7 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
362 u32 l; 364 u32 l;
363 365
364 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 366 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
365 if (enable) 367 if (enable)
366 l |= OMAP_TIMER_CTRL_CE; 368 l |= OMAP_TIMER_CTRL_CE;
367 else 369 else
368 l &= ~OMAP_TIMER_CTRL_CE; 370 l &= ~OMAP_TIMER_CTRL_CE;
@@ -421,6 +423,11 @@ unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
421 return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); 423 return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
422} 424}
423 425
426void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
427{
428 return omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
429}
430
424int omap_dm_timers_active(void) 431int omap_dm_timers_active(void)
425{ 432{
426 int i; 433 int i;
@@ -445,6 +452,13 @@ int omap_dm_timer_init(void)
445 return -ENODEV; 452 return -ENODEV;
446 453
447 spin_lock_init(&dm_timer_lock); 454 spin_lock_init(&dm_timer_lock);
455#ifdef CONFIG_ARCH_OMAP2
456 for (i = 0; i < ARRAY_SIZE(dm_source_names); i++) {
457 dm_source_clocks[i] = clk_get(NULL, dm_source_names[i]);
458 BUG_ON(dm_source_clocks[i] == NULL);
459 }
460#endif
461
448 for (i = 0; i < dm_timer_count; i++) { 462 for (i = 0; i < dm_timer_count; i++) {
449#ifdef CONFIG_ARCH_OMAP2 463#ifdef CONFIG_ARCH_OMAP2
450 char clk_name[16]; 464 char clk_name[16];