diff options
author | Arnd Bergmann <arnd@arndb.de> | 2013-05-06 17:43:45 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2013-05-06 17:43:45 -0400 |
commit | 442a33ebce9e02a2dd6662f16c9f2aad834d0115 (patch) | |
tree | ca8654a286f61da917318645cab9e061095ecdba /arch/arm/mach-omap2/timer.c | |
parent | a94d236dc355f374857ee4e6e78b7dec8a0f29e3 (diff) | |
parent | f31c2f1c68aff83277eddc6798adf3438e9c680a (diff) |
Merge branch 'late/clksrc' into late/cleanup
There is no reason to keep the clksrc cleanups separate from the
other cleanups, and this resolves some merge conflicts.
Conflicts:
arch/arm/mach-spear/spear13xx.c
drivers/irqchip/Makefile
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
-rw-r--r-- | arch/arm/mach-omap2/timer.c | 133 |
1 files changed, 65 insertions, 68 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index d00d89c93f1c..fdf1c039062c 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <asm/smp_twd.h> | 46 | #include <asm/smp_twd.h> |
47 | #include <asm/sched_clock.h> | 47 | #include <asm/sched_clock.h> |
48 | 48 | ||
49 | #include <asm/arch_timer.h> | ||
50 | #include "omap_hwmod.h" | 49 | #include "omap_hwmod.h" |
51 | #include "omap_device.h" | 50 | #include "omap_device.h" |
52 | #include <plat/counter-32k.h> | 51 | #include <plat/counter-32k.h> |
@@ -57,16 +56,6 @@ | |||
57 | #include "common.h" | 56 | #include "common.h" |
58 | #include "powerdomain.h" | 57 | #include "powerdomain.h" |
59 | 58 | ||
60 | /* Parent clocks, eventually these will come from the clock framework */ | ||
61 | |||
62 | #define OMAP2_MPU_SOURCE "sys_ck" | ||
63 | #define OMAP3_MPU_SOURCE OMAP2_MPU_SOURCE | ||
64 | #define OMAP4_MPU_SOURCE "sys_clkin_ck" | ||
65 | #define OMAP5_MPU_SOURCE "sys_clkin" | ||
66 | #define OMAP2_32K_SOURCE "func_32k_ck" | ||
67 | #define OMAP3_32K_SOURCE "omap_32k_fck" | ||
68 | #define OMAP4_32K_SOURCE "sys_32k_ck" | ||
69 | |||
70 | #define REALTIME_COUNTER_BASE 0x48243200 | 59 | #define REALTIME_COUNTER_BASE 0x48243200 |
71 | #define INCREMENTER_NUMERATOR_OFFSET 0x10 | 60 | #define INCREMENTER_NUMERATOR_OFFSET 0x10 |
72 | #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 | 61 | #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 |
@@ -130,7 +119,6 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode, | |||
130 | } | 119 | } |
131 | 120 | ||
132 | static struct clock_event_device clockevent_gpt = { | 121 | static struct clock_event_device clockevent_gpt = { |
133 | .name = "gp_timer", | ||
134 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 122 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
135 | .rating = 300, | 123 | .rating = 300, |
136 | .set_next_event = omap2_gp_timer_set_next_event, | 124 | .set_next_event = omap2_gp_timer_set_next_event, |
@@ -171,6 +159,12 @@ static struct device_node * __init omap_get_timer_dt(struct of_device_id *match, | |||
171 | if (property && !of_get_property(np, property, NULL)) | 159 | if (property && !of_get_property(np, property, NULL)) |
172 | continue; | 160 | continue; |
173 | 161 | ||
162 | if (!property && (of_get_property(np, "ti,timer-alwon", NULL) || | ||
163 | of_get_property(np, "ti,timer-dsp", NULL) || | ||
164 | of_get_property(np, "ti,timer-pwm", NULL) || | ||
165 | of_get_property(np, "ti,timer-secure", NULL))) | ||
166 | continue; | ||
167 | |||
174 | of_add_property(np, &device_disabled); | 168 | of_add_property(np, &device_disabled); |
175 | return np; | 169 | return np; |
176 | } | 170 | } |
@@ -215,16 +209,17 @@ static u32 __init omap_dm_timer_get_errata(void) | |||
215 | } | 209 | } |
216 | 210 | ||
217 | static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | 211 | static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, |
218 | int gptimer_id, | 212 | const char *fck_source, |
219 | const char *fck_source, | 213 | const char *property, |
220 | const char *property, | 214 | const char **timer_name, |
221 | int posted) | 215 | int posted) |
222 | { | 216 | { |
223 | char name[10]; /* 10 = sizeof("gptXX_Xck0") */ | 217 | char name[10]; /* 10 = sizeof("gptXX_Xck0") */ |
224 | const char *oh_name; | 218 | const char *oh_name; |
225 | struct device_node *np; | 219 | struct device_node *np; |
226 | struct omap_hwmod *oh; | 220 | struct omap_hwmod *oh; |
227 | struct resource irq, mem; | 221 | struct resource irq, mem; |
222 | struct clk *src; | ||
228 | int r = 0; | 223 | int r = 0; |
229 | 224 | ||
230 | if (of_have_populated_dt()) { | 225 | if (of_have_populated_dt()) { |
@@ -244,10 +239,10 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | |||
244 | 239 | ||
245 | of_node_put(np); | 240 | of_node_put(np); |
246 | } else { | 241 | } else { |
247 | if (omap_dm_timer_reserve_systimer(gptimer_id)) | 242 | if (omap_dm_timer_reserve_systimer(timer->id)) |
248 | return -ENODEV; | 243 | return -ENODEV; |
249 | 244 | ||
250 | sprintf(name, "timer%d", gptimer_id); | 245 | sprintf(name, "timer%d", timer->id); |
251 | oh_name = name; | 246 | oh_name = name; |
252 | } | 247 | } |
253 | 248 | ||
@@ -255,6 +250,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | |||
255 | if (!oh) | 250 | if (!oh) |
256 | return -ENODEV; | 251 | return -ENODEV; |
257 | 252 | ||
253 | *timer_name = oh->name; | ||
254 | |||
258 | if (!of_have_populated_dt()) { | 255 | if (!of_have_populated_dt()) { |
259 | r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, | 256 | r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, |
260 | &irq); | 257 | &irq); |
@@ -277,24 +274,24 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | |||
277 | /* After the dmtimer is using hwmod these clocks won't be needed */ | 274 | /* After the dmtimer is using hwmod these clocks won't be needed */ |
278 | timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); | 275 | timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); |
279 | if (IS_ERR(timer->fclk)) | 276 | if (IS_ERR(timer->fclk)) |
280 | return -ENODEV; | 277 | return PTR_ERR(timer->fclk); |
281 | 278 | ||
282 | /* FIXME: Need to remove hard-coded test on timer ID */ | 279 | src = clk_get(NULL, fck_source); |
283 | if (gptimer_id != 12) { | 280 | if (IS_ERR(src)) |
284 | struct clk *src; | 281 | return PTR_ERR(src); |
285 | 282 | ||
286 | src = clk_get(NULL, fck_source); | 283 | if (clk_get_parent(timer->fclk) != src) { |
287 | if (IS_ERR(src)) { | 284 | r = clk_set_parent(timer->fclk, src); |
288 | r = -EINVAL; | 285 | if (r < 0) { |
289 | } else { | 286 | pr_warn("%s: %s cannot set source\n", __func__, |
290 | r = clk_set_parent(timer->fclk, src); | 287 | oh->name); |
291 | if (IS_ERR_VALUE(r)) | ||
292 | pr_warn("%s: %s cannot set source\n", | ||
293 | __func__, oh->name); | ||
294 | clk_put(src); | 288 | clk_put(src); |
289 | return r; | ||
295 | } | 290 | } |
296 | } | 291 | } |
297 | 292 | ||
293 | clk_put(src); | ||
294 | |||
298 | omap_hwmod_setup_one(oh_name); | 295 | omap_hwmod_setup_one(oh_name); |
299 | omap_hwmod_enable(oh); | 296 | omap_hwmod_enable(oh); |
300 | __omap_dm_timer_init_regs(timer); | 297 | __omap_dm_timer_init_regs(timer); |
@@ -318,6 +315,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
318 | { | 315 | { |
319 | int res; | 316 | int res; |
320 | 317 | ||
318 | clkev.id = gptimer_id; | ||
321 | clkev.errata = omap_dm_timer_get_errata(); | 319 | clkev.errata = omap_dm_timer_get_errata(); |
322 | 320 | ||
323 | /* | 321 | /* |
@@ -327,8 +325,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
327 | */ | 325 | */ |
328 | __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); | 326 | __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); |
329 | 327 | ||
330 | res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property, | 328 | res = omap_dm_timer_init_one(&clkev, fck_source, property, |
331 | OMAP_TIMER_POSTED); | 329 | &clockevent_gpt.name, OMAP_TIMER_POSTED); |
332 | BUG_ON(res); | 330 | BUG_ON(res); |
333 | 331 | ||
334 | omap2_gp_timer_irq.dev_id = &clkev; | 332 | omap2_gp_timer_irq.dev_id = &clkev; |
@@ -342,8 +340,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
342 | 3, /* Timer internal resynch latency */ | 340 | 3, /* Timer internal resynch latency */ |
343 | 0xffffffff); | 341 | 0xffffffff); |
344 | 342 | ||
345 | pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", | 343 | pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, |
346 | gptimer_id, clkev.rate); | 344 | clkev.rate); |
347 | } | 345 | } |
348 | 346 | ||
349 | /* Clocksource code */ | 347 | /* Clocksource code */ |
@@ -360,7 +358,6 @@ static cycle_t clocksource_read_cycles(struct clocksource *cs) | |||
360 | } | 358 | } |
361 | 359 | ||
362 | static struct clocksource clocksource_gpt = { | 360 | static struct clocksource clocksource_gpt = { |
363 | .name = "gp_timer", | ||
364 | .rating = 300, | 361 | .rating = 300, |
365 | .read = clocksource_read_cycles, | 362 | .read = clocksource_read_cycles, |
366 | .mask = CLOCKSOURCE_MASK(32), | 363 | .mask = CLOCKSOURCE_MASK(32), |
@@ -443,13 +440,16 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) | |||
443 | } | 440 | } |
444 | 441 | ||
445 | static void __init omap2_gptimer_clocksource_init(int gptimer_id, | 442 | static void __init omap2_gptimer_clocksource_init(int gptimer_id, |
446 | const char *fck_source) | 443 | const char *fck_source, |
444 | const char *property) | ||
447 | { | 445 | { |
448 | int res; | 446 | int res; |
449 | 447 | ||
448 | clksrc.id = gptimer_id; | ||
450 | clksrc.errata = omap_dm_timer_get_errata(); | 449 | clksrc.errata = omap_dm_timer_get_errata(); |
451 | 450 | ||
452 | res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL, | 451 | res = omap_dm_timer_init_one(&clksrc, fck_source, property, |
452 | &clocksource_gpt.name, | ||
453 | OMAP_TIMER_NONPOSTED); | 453 | OMAP_TIMER_NONPOSTED); |
454 | BUG_ON(res); | 454 | BUG_ON(res); |
455 | 455 | ||
@@ -462,8 +462,8 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id, | |||
462 | pr_err("Could not register clocksource %s\n", | 462 | pr_err("Could not register clocksource %s\n", |
463 | clocksource_gpt.name); | 463 | clocksource_gpt.name); |
464 | else | 464 | else |
465 | pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", | 465 | pr_info("OMAP clocksource: %s at %lu Hz\n", |
466 | gptimer_id, clksrc.rate); | 466 | clocksource_gpt.name, clksrc.rate); |
467 | } | 467 | } |
468 | 468 | ||
469 | #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER | 469 | #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER |
@@ -488,7 +488,7 @@ static void __init realtime_counter_init(void) | |||
488 | pr_err("%s: ioremap failed\n", __func__); | 488 | pr_err("%s: ioremap failed\n", __func__); |
489 | return; | 489 | return; |
490 | } | 490 | } |
491 | sys_clk = clk_get(NULL, OMAP5_MPU_SOURCE); | 491 | sys_clk = clk_get(NULL, "sys_clkin"); |
492 | if (IS_ERR(sys_clk)) { | 492 | if (IS_ERR(sys_clk)) { |
493 | pr_err("%s: failed to get system clock handle\n", __func__); | 493 | pr_err("%s: failed to get system clock handle\n", __func__); |
494 | iounmap(base); | 494 | iounmap(base); |
@@ -545,18 +545,19 @@ static inline void __init realtime_counter_init(void) | |||
545 | #endif | 545 | #endif |
546 | 546 | ||
547 | #define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ | 547 | #define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ |
548 | clksrc_nr, clksrc_src) \ | 548 | clksrc_nr, clksrc_src, clksrc_prop) \ |
549 | void __init omap##name##_gptimer_timer_init(void) \ | 549 | void __init omap##name##_gptimer_timer_init(void) \ |
550 | { \ | 550 | { \ |
551 | if (omap_clk_init) \ | 551 | if (omap_clk_init) \ |
552 | omap_clk_init(); \ | 552 | omap_clk_init(); \ |
553 | omap_dmtimer_init(); \ | 553 | omap_dmtimer_init(); \ |
554 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ | 554 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ |
555 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \ | 555 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \ |
556 | clksrc_prop); \ | ||
556 | } | 557 | } |
557 | 558 | ||
558 | #define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ | 559 | #define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ |
559 | clksrc_nr, clksrc_src) \ | 560 | clksrc_nr, clksrc_src, clksrc_prop) \ |
560 | void __init omap##name##_sync32k_timer_init(void) \ | 561 | void __init omap##name##_sync32k_timer_init(void) \ |
561 | { \ | 562 | { \ |
562 | if (omap_clk_init) \ | 563 | if (omap_clk_init) \ |
@@ -565,33 +566,35 @@ void __init omap##name##_sync32k_timer_init(void) \ | |||
565 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ | 566 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ |
566 | /* Enable the use of clocksource="gp_timer" kernel parameter */ \ | 567 | /* Enable the use of clocksource="gp_timer" kernel parameter */ \ |
567 | if (use_gptimer_clksrc) \ | 568 | if (use_gptimer_clksrc) \ |
568 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src);\ | 569 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \ |
570 | clksrc_prop); \ | ||
569 | else \ | 571 | else \ |
570 | omap2_sync32k_clocksource_init(); \ | 572 | omap2_sync32k_clocksource_init(); \ |
571 | } | 573 | } |
572 | 574 | ||
573 | #ifdef CONFIG_ARCH_OMAP2 | 575 | #ifdef CONFIG_ARCH_OMAP2 |
574 | OMAP_SYS_32K_TIMER_INIT(2, 1, OMAP2_32K_SOURCE, "ti,timer-alwon", | 576 | OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon", |
575 | 2, OMAP2_MPU_SOURCE); | 577 | 2, "timer_sys_ck", NULL); |
576 | #endif /* CONFIG_ARCH_OMAP2 */ | 578 | #endif /* CONFIG_ARCH_OMAP2 */ |
577 | 579 | ||
578 | #ifdef CONFIG_ARCH_OMAP3 | 580 | #ifdef CONFIG_ARCH_OMAP3 |
579 | OMAP_SYS_32K_TIMER_INIT(3, 1, OMAP3_32K_SOURCE, "ti,timer-alwon", | 581 | OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon", |
580 | 2, OMAP3_MPU_SOURCE); | 582 | 2, "timer_sys_ck", NULL); |
581 | OMAP_SYS_32K_TIMER_INIT(3_secure, 12, OMAP3_32K_SOURCE, "ti,timer-secure", | 583 | OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure", |
582 | 2, OMAP3_MPU_SOURCE); | 584 | 2, "timer_sys_ck", NULL); |
583 | OMAP_SYS_GP_TIMER_INIT(3_gp, 1, OMAP3_MPU_SOURCE, "ti,timer-alwon", | ||
584 | 2, OMAP3_MPU_SOURCE); | ||
585 | #endif /* CONFIG_ARCH_OMAP3 */ | 585 | #endif /* CONFIG_ARCH_OMAP3 */ |
586 | 586 | ||
587 | #ifdef CONFIG_SOC_AM33XX | 587 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) |
588 | OMAP_SYS_GP_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon", | 588 | OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL, |
589 | 2, OMAP4_MPU_SOURCE); | 589 | 1, "timer_sys_ck", "ti,timer-alwon"); |
590 | #endif /* CONFIG_SOC_AM33XX */ | 590 | #endif |
591 | |||
592 | #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) | ||
593 | static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon", | ||
594 | 2, "sys_clkin_ck", NULL); | ||
595 | #endif | ||
591 | 596 | ||
592 | #ifdef CONFIG_ARCH_OMAP4 | 597 | #ifdef CONFIG_ARCH_OMAP4 |
593 | OMAP_SYS_32K_TIMER_INIT(4, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", | ||
594 | 2, OMAP4_MPU_SOURCE); | ||
595 | #ifdef CONFIG_LOCAL_TIMERS | 598 | #ifdef CONFIG_LOCAL_TIMERS |
596 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); | 599 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); |
597 | void __init omap4_local_timer_init(void) | 600 | void __init omap4_local_timer_init(void) |
@@ -602,7 +605,7 @@ void __init omap4_local_timer_init(void) | |||
602 | int err; | 605 | int err; |
603 | 606 | ||
604 | if (of_have_populated_dt()) { | 607 | if (of_have_populated_dt()) { |
605 | twd_local_timer_of_register(); | 608 | clocksource_of_init(); |
606 | return; | 609 | return; |
607 | } | 610 | } |
608 | 611 | ||
@@ -620,18 +623,12 @@ void __init omap4_local_timer_init(void) | |||
620 | #endif /* CONFIG_ARCH_OMAP4 */ | 623 | #endif /* CONFIG_ARCH_OMAP4 */ |
621 | 624 | ||
622 | #ifdef CONFIG_SOC_OMAP5 | 625 | #ifdef CONFIG_SOC_OMAP5 |
623 | OMAP_SYS_32K_TIMER_INIT(5, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", | ||
624 | 2, OMAP5_MPU_SOURCE); | ||
625 | void __init omap5_realtime_timer_init(void) | 626 | void __init omap5_realtime_timer_init(void) |
626 | { | 627 | { |
627 | int err; | 628 | omap4_sync32k_timer_init(); |
628 | |||
629 | omap5_sync32k_timer_init(); | ||
630 | realtime_counter_init(); | 629 | realtime_counter_init(); |
631 | 630 | ||
632 | err = arch_timer_of_register(); | 631 | clocksource_of_init(); |
633 | if (err) | ||
634 | pr_err("%s: arch_timer_register failed %d\n", __func__, err); | ||
635 | } | 632 | } |
636 | #endif /* CONFIG_SOC_OMAP5 */ | 633 | #endif /* CONFIG_SOC_OMAP5 */ |
637 | 634 | ||