aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
-rw-r--r--arch/arm/mach-omap2/timer.c97
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
75static u32 sys_timer_reserved;
76
77/* Clockevent code */ 72/* Clockevent code */
78 73
79static struct omap_dm_timer clkev; 74static 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,
368OMAP_SYS_TIMER(3_secure) 365OMAP_SYS_TIMER(3_secure)
369#endif 366#endif
370 367
368#ifdef CONFIG_SOC_AM33XX
369OMAP_SYS_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, 2, OMAP4_MPU_SOURCE)
370OMAP_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
373static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 375static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
@@ -393,65 +395,10 @@ static void __init omap4_timer_init(void)
393OMAP_SYS_TIMER(4) 395OMAP_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 399OMAP_SYS_TIMER_INIT(5, 1, OMAP4_CLKEV_SOURCE, 2, OMAP4_MPU_SOURCE)
398 * @pdev: timer platform device pointer 400OMAP_SYS_TIMER(5)
399 * @source: array index of parent clock source 401#endif
400 */
401static 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