aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/timer.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2017-06-12 03:07:44 -0400
committerTony Lindgren <tony@atomide.com>2017-06-12 03:07:44 -0400
commit018b732458ac39c4858d9840c0e32310bc0930dd (patch)
tree84f178b1fe40e67eeb8dc523686f73a02dc5cb00 /arch/arm/mach-omap2/timer.c
parentc76e4d2e50068ddd82fe18f86d05a33733877059 (diff)
parent0e78b1218df37f1a1834dff853d967444e332bab (diff)
Merge branch 'omap-for-v4.13/legacy-v2' into omap-for-v4.13/soc-v3
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
-rw-r--r--arch/arm/mach-omap2/timer.c169
1 files changed, 19 insertions, 150 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 70670dfd7135..ce982d193046 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -252,37 +252,27 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
252 const char **timer_name, 252 const char **timer_name,
253 int posted) 253 int posted)
254{ 254{
255 char name[10]; /* 10 = sizeof("gptXX_Xck0") */
256 const char *oh_name = NULL; 255 const char *oh_name = NULL;
257 struct device_node *np; 256 struct device_node *np;
258 struct omap_hwmod *oh; 257 struct omap_hwmod *oh;
259 struct resource irq, mem;
260 struct clk *src; 258 struct clk *src;
261 int r = 0; 259 int r = 0;
262 260
263 if (of_have_populated_dt()) { 261 np = omap_get_timer_dt(omap_timer_match, property);
264 np = omap_get_timer_dt(omap_timer_match, property); 262 if (!np)
265 if (!np) 263 return -ENODEV;
266 return -ENODEV;
267 264
268 of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); 265 of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
269 if (!oh_name) 266 if (!oh_name)
270 return -ENODEV; 267 return -ENODEV;
271 268
272 timer->irq = irq_of_parse_and_map(np, 0); 269 timer->irq = irq_of_parse_and_map(np, 0);
273 if (!timer->irq) 270 if (!timer->irq)
274 return -ENXIO; 271 return -ENXIO;
275 272
276 timer->io_base = of_iomap(np, 0); 273 timer->io_base = of_iomap(np, 0);
277 274
278 of_node_put(np); 275 of_node_put(np);
279 } else {
280 if (omap_dm_timer_reserve_systimer(timer->id))
281 return -ENODEV;
282
283 sprintf(name, "timer%d", timer->id);
284 oh_name = name;
285 }
286 276
287 oh = omap_hwmod_lookup(oh_name); 277 oh = omap_hwmod_lookup(oh_name);
288 if (!oh) 278 if (!oh)
@@ -290,22 +280,6 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
290 280
291 *timer_name = oh->name; 281 *timer_name = oh->name;
292 282
293 if (!of_have_populated_dt()) {
294 r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL,
295 &irq);
296 if (r)
297 return -ENXIO;
298 timer->irq = irq.start;
299
300 r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL,
301 &mem);
302 if (r)
303 return -ENXIO;
304
305 /* Static mapping, never released */
306 timer->io_base = ioremap(mem.start, mem.end - mem.start);
307 }
308
309 if (!timer->io_base) 283 if (!timer->io_base)
310 return -ENXIO; 284 return -ENXIO;
311 285
@@ -433,18 +407,15 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
433 const char *oh_name = "counter_32k"; 407 const char *oh_name = "counter_32k";
434 408
435 /* 409 /*
436 * If device-tree is present, then search the DT blob 410 * See if the 32kHz counter is supported.
437 * to see if the 32kHz counter is supported.
438 */ 411 */
439 if (of_have_populated_dt()) { 412 np = omap_get_timer_dt(omap_counter_match, NULL);
440 np = omap_get_timer_dt(omap_counter_match, NULL); 413 if (!np)
441 if (!np) 414 return -ENODEV;
442 return -ENODEV; 415
443 416 of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
444 of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); 417 if (!oh_name)
445 if (!oh_name) 418 return -ENODEV;
446 return -ENODEV;
447 }
448 419
449 /* 420 /*
450 * First check hwmod data is available for sync32k counter 421 * First check hwmod data is available for sync32k counter
@@ -462,18 +433,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
462 return ret; 433 return ret;
463 } 434 }
464 435
465 if (!of_have_populated_dt()) {
466 void __iomem *vbase;
467
468 vbase = omap_hwmod_get_mpu_rt_va(oh);
469
470 ret = omap_init_clocksource_32k(vbase);
471 if (ret) {
472 pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n",
473 __func__, ret);
474 omap_hwmod_idle(oh);
475 }
476 }
477 return ret; 436 return ret;
478} 437}
479 438
@@ -689,96 +648,6 @@ void __init omap5_realtime_timer_init(void)
689#endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */ 648#endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */
690 649
691/** 650/**
692 * omap_timer_init - build and register timer device with an
693 * associated timer hwmod
694 * @oh: timer hwmod pointer to be used to build timer device
695 * @user: parameter that can be passed from calling hwmod API
696 *
697 * Called by omap_hwmod_for_each_by_class to register each of the timer
698 * devices present in the system. The number of timer devices is known
699 * by parsing through the hwmod database for a given class name. At the
700 * end of function call memory is allocated for timer device and it is
701 * registered to the framework ready to be proved by the driver.
702 */
703static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
704{
705 int id;
706 int ret = 0;
707 char *name = "omap_timer";
708 struct dmtimer_platform_data *pdata;
709 struct platform_device *pdev;
710 struct omap_timer_capability_dev_attr *timer_dev_attr;
711
712 pr_debug("%s: %s\n", __func__, oh->name);
713
714 /* on secure device, do not register secure timer */
715 timer_dev_attr = oh->dev_attr;
716 if (omap_type() != OMAP2_DEVICE_TYPE_GP && timer_dev_attr)
717 if (timer_dev_attr->timer_capability == OMAP_TIMER_SECURE)
718 return ret;
719
720 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
721 if (!pdata) {
722 pr_err("%s: No memory for [%s]\n", __func__, oh->name);
723 return -ENOMEM;
724 }
725
726 /*
727 * Extract the IDs from name field in hwmod database
728 * and use the same for constructing ids' for the
729 * timer devices. In a way, we are avoiding usage of
730 * static variable witin the function to do the same.
731 * CAUTION: We have to be careful and make sure the
732 * name in hwmod database does not change in which case
733 * we might either make corresponding change here or
734 * switch back static variable mechanism.
735 */
736 sscanf(oh->name, "timer%2d", &id);
737
738 if (timer_dev_attr)
739 pdata->timer_capability = timer_dev_attr->timer_capability;
740
741 pdata->timer_errata = omap_dm_timer_get_errata();
742 pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
743
744 pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata));
745
746 if (IS_ERR(pdev)) {
747 pr_err("%s: Can't build omap_device for %s: %s.\n",
748 __func__, name, oh->name);
749 ret = -EINVAL;
750 }
751
752 kfree(pdata);
753
754 return ret;
755}
756
757/**
758 * omap2_dm_timer_init - top level regular device initialization
759 *
760 * Uses dedicated hwmod api to parse through hwmod database for
761 * given class name and then build and register the timer device.
762 */
763static int __init omap2_dm_timer_init(void)
764{
765 int ret;
766
767 /* If dtb is there, the devices will be created dynamically */
768 if (of_have_populated_dt())
769 return -ENODEV;
770
771 ret = omap_hwmod_for_each_by_class("timer", omap_timer_init, NULL);
772 if (unlikely(ret)) {
773 pr_err("%s: device registration failed.\n", __func__);
774 return -EINVAL;
775 }
776
777 return 0;
778}
779omap_arch_initcall(omap2_dm_timer_init);
780
781/**
782 * omap2_override_clocksource - clocksource override with user configuration 651 * omap2_override_clocksource - clocksource override with user configuration
783 * 652 *
784 * Allows user to override default clocksource, using kernel parameter 653 * Allows user to override default clocksource, using kernel parameter