diff options
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
-rw-r--r-- | arch/arm/mach-omap2/timer.c | 97 |
1 files changed, 17 insertions, 80 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 840929bd9dae..2ff6d41ec6c6 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -69,11 +69,6 @@ | |||
69 | #define OMAP3_SECURE_TIMER 1 | 69 | #define OMAP3_SECURE_TIMER 1 |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | /* MAX_GPTIMER_ID: number of GPTIMERs on the chip */ | ||
73 | #define MAX_GPTIMER_ID 12 | ||
74 | |||
75 | static u32 sys_timer_reserved; | ||
76 | |||
77 | /* Clockevent code */ | 72 | /* Clockevent code */ |
78 | 73 | ||
79 | static struct omap_dm_timer clkev; | 74 | static struct omap_dm_timer clkev; |
@@ -135,6 +130,7 @@ static struct clock_event_device clockevent_gpt = { | |||
135 | .name = "gp_timer", | 130 | .name = "gp_timer", |
136 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 131 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
137 | .shift = 32, | 132 | .shift = 32, |
133 | .rating = 300, | ||
138 | .set_next_event = omap2_gp_timer_set_next_event, | 134 | .set_next_event = omap2_gp_timer_set_next_event, |
139 | .set_mode = omap2_gp_timer_set_mode, | 135 | .set_mode = omap2_gp_timer_set_mode, |
140 | }; | 136 | }; |
@@ -173,14 +169,14 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | |||
173 | return -ENXIO; | 169 | return -ENXIO; |
174 | 170 | ||
175 | /* After the dmtimer is using hwmod these clocks won't be needed */ | 171 | /* After the dmtimer is using hwmod these clocks won't be needed */ |
176 | sprintf(name, "gpt%d_fck", gptimer_id); | 172 | timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); |
177 | timer->fclk = clk_get(NULL, name); | ||
178 | if (IS_ERR(timer->fclk)) | 173 | if (IS_ERR(timer->fclk)) |
179 | return -ENODEV; | 174 | return -ENODEV; |
180 | 175 | ||
181 | omap_hwmod_enable(oh); | 176 | omap_hwmod_enable(oh); |
182 | 177 | ||
183 | sys_timer_reserved |= (1 << (gptimer_id - 1)); | 178 | if (omap_dm_timer_reserve_systimer(gptimer_id)) |
179 | return -ENODEV; | ||
184 | 180 | ||
185 | if (gptimer_id != 12) { | 181 | if (gptimer_id != 12) { |
186 | struct clk *src; | 182 | struct clk *src; |
@@ -228,7 +224,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
228 | clockevent_delta2ns(3, &clockevent_gpt); | 224 | clockevent_delta2ns(3, &clockevent_gpt); |
229 | /* Timer internal resynch latency. */ | 225 | /* Timer internal resynch latency. */ |
230 | 226 | ||
231 | clockevent_gpt.cpumask = cpumask_of(0); | 227 | clockevent_gpt.cpumask = cpu_possible_mask; |
228 | clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev); | ||
232 | clockevents_register_device(&clockevent_gpt); | 229 | clockevents_register_device(&clockevent_gpt); |
233 | 230 | ||
234 | pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", | 231 | pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", |
@@ -368,6 +365,11 @@ OMAP_SYS_TIMER_INIT(3_secure, OMAP3_SECURE_TIMER, OMAP3_CLKEV_SOURCE, | |||
368 | OMAP_SYS_TIMER(3_secure) | 365 | OMAP_SYS_TIMER(3_secure) |
369 | #endif | 366 | #endif |
370 | 367 | ||
368 | #ifdef CONFIG_SOC_AM33XX | ||
369 | OMAP_SYS_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, 2, OMAP4_MPU_SOURCE) | ||
370 | OMAP_SYS_TIMER(3_am33xx) | ||
371 | #endif | ||
372 | |||
371 | #ifdef CONFIG_ARCH_OMAP4 | 373 | #ifdef CONFIG_ARCH_OMAP4 |
372 | #ifdef CONFIG_LOCAL_TIMERS | 374 | #ifdef CONFIG_LOCAL_TIMERS |
373 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, | 375 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, |
@@ -393,65 +395,10 @@ static void __init omap4_timer_init(void) | |||
393 | OMAP_SYS_TIMER(4) | 395 | OMAP_SYS_TIMER(4) |
394 | #endif | 396 | #endif |
395 | 397 | ||
396 | /** | 398 | #ifdef CONFIG_SOC_OMAP5 |
397 | * omap2_dm_timer_set_src - change the timer input clock source | 399 | OMAP_SYS_TIMER_INIT(5, 1, OMAP4_CLKEV_SOURCE, 2, OMAP4_MPU_SOURCE) |
398 | * @pdev: timer platform device pointer | 400 | OMAP_SYS_TIMER(5) |
399 | * @source: array index of parent clock source | 401 | #endif |
400 | */ | ||
401 | static int omap2_dm_timer_set_src(struct platform_device *pdev, int source) | ||
402 | { | ||
403 | int ret; | ||
404 | struct dmtimer_platform_data *pdata = pdev->dev.platform_data; | ||
405 | struct clk *fclk, *parent; | ||
406 | char *parent_name = NULL; | ||
407 | |||
408 | fclk = clk_get(&pdev->dev, "fck"); | ||
409 | if (IS_ERR_OR_NULL(fclk)) { | ||
410 | dev_err(&pdev->dev, "%s: %d: clk_get() FAILED\n", | ||
411 | __func__, __LINE__); | ||
412 | return -EINVAL; | ||
413 | } | ||
414 | |||
415 | switch (source) { | ||
416 | case OMAP_TIMER_SRC_SYS_CLK: | ||
417 | parent_name = "sys_ck"; | ||
418 | break; | ||
419 | |||
420 | case OMAP_TIMER_SRC_32_KHZ: | ||
421 | parent_name = "32k_ck"; | ||
422 | break; | ||
423 | |||
424 | case OMAP_TIMER_SRC_EXT_CLK: | ||
425 | if (pdata->timer_ip_version == OMAP_TIMER_IP_VERSION_1) { | ||
426 | parent_name = "alt_ck"; | ||
427 | break; | ||
428 | } | ||
429 | dev_err(&pdev->dev, "%s: %d: invalid clk src.\n", | ||
430 | __func__, __LINE__); | ||
431 | clk_put(fclk); | ||
432 | return -EINVAL; | ||
433 | } | ||
434 | |||
435 | parent = clk_get(&pdev->dev, parent_name); | ||
436 | if (IS_ERR_OR_NULL(parent)) { | ||
437 | dev_err(&pdev->dev, "%s: %d: clk_get() %s FAILED\n", | ||
438 | __func__, __LINE__, parent_name); | ||
439 | clk_put(fclk); | ||
440 | return -EINVAL; | ||
441 | } | ||
442 | |||
443 | ret = clk_set_parent(fclk, parent); | ||
444 | if (IS_ERR_VALUE(ret)) { | ||
445 | dev_err(&pdev->dev, "%s: clk_set_parent() to %s FAILED\n", | ||
446 | __func__, parent_name); | ||
447 | ret = -EINVAL; | ||
448 | } | ||
449 | |||
450 | clk_put(parent); | ||
451 | clk_put(fclk); | ||
452 | |||
453 | return ret; | ||
454 | } | ||
455 | 402 | ||
456 | /** | 403 | /** |
457 | * omap_timer_init - build and register timer device with an | 404 | * omap_timer_init - build and register timer device with an |
@@ -473,7 +420,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) | |||
473 | struct dmtimer_platform_data *pdata; | 420 | struct dmtimer_platform_data *pdata; |
474 | struct platform_device *pdev; | 421 | struct platform_device *pdev; |
475 | struct omap_timer_capability_dev_attr *timer_dev_attr; | 422 | struct omap_timer_capability_dev_attr *timer_dev_attr; |
476 | struct powerdomain *pwrdm; | ||
477 | 423 | ||
478 | pr_debug("%s: %s\n", __func__, oh->name); | 424 | pr_debug("%s: %s\n", __func__, oh->name); |
479 | 425 | ||
@@ -501,18 +447,9 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) | |||
501 | */ | 447 | */ |
502 | sscanf(oh->name, "timer%2d", &id); | 448 | sscanf(oh->name, "timer%2d", &id); |
503 | 449 | ||
504 | pdata->set_timer_src = omap2_dm_timer_set_src; | 450 | if (timer_dev_attr) |
505 | pdata->timer_ip_version = oh->class->rev; | 451 | pdata->timer_capability = timer_dev_attr->timer_capability; |
506 | 452 | ||
507 | /* Mark clocksource and clockevent timers as reserved */ | ||
508 | if ((sys_timer_reserved >> (id - 1)) & 0x1) | ||
509 | pdata->reserved = 1; | ||
510 | |||
511 | pwrdm = omap_hwmod_get_pwrdm(oh); | ||
512 | pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); | ||
513 | #ifdef CONFIG_PM | ||
514 | pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; | ||
515 | #endif | ||
516 | pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata), | 453 | pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata), |
517 | NULL, 0, 0); | 454 | NULL, 0, 0); |
518 | 455 | ||