|
@@ -252,37 +252,27 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
|
|
const char **timer_name,
|
|
const char **timer_name,
|
|
int posted)
|
|
int posted)
|
|
{
|
|
{
|
|
- char name[10]; /* 10 = sizeof("gptXX_Xck0") */
|
|
|
|
const char *oh_name = NULL;
|
|
const char *oh_name = NULL;
|
|
struct device_node *np;
|
|
struct device_node *np;
|
|
struct omap_hwmod *oh;
|
|
struct omap_hwmod *oh;
|
|
- struct resource irq, mem;
|
|
|
|
struct clk *src;
|
|
struct clk *src;
|
|
int r = 0;
|
|
int r = 0;
|
|
|
|
|
|
- if (of_have_populated_dt()) {
|
|
|
|
- np = omap_get_timer_dt(omap_timer_match, property);
|
|
|
|
- if (!np)
|
|
|
|
- return -ENODEV;
|
|
|
|
|
|
+ np = omap_get_timer_dt(omap_timer_match, property);
|
|
|
|
+ if (!np)
|
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
- of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
|
|
|
|
- if (!oh_name)
|
|
|
|
- return -ENODEV;
|
|
|
|
|
|
+ of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
|
|
|
|
+ if (!oh_name)
|
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
- timer->irq = irq_of_parse_and_map(np, 0);
|
|
|
|
- if (!timer->irq)
|
|
|
|
- return -ENXIO;
|
|
|
|
|
|
+ timer->irq = irq_of_parse_and_map(np, 0);
|
|
|
|
+ if (!timer->irq)
|
|
|
|
+ return -ENXIO;
|
|
|
|
|
|
- timer->io_base = of_iomap(np, 0);
|
|
|
|
|
|
+ timer->io_base = of_iomap(np, 0);
|
|
|
|
|
|
- of_node_put(np);
|
|
|
|
- } else {
|
|
|
|
- if (omap_dm_timer_reserve_systimer(timer->id))
|
|
|
|
- return -ENODEV;
|
|
|
|
-
|
|
|
|
- sprintf(name, "timer%d", timer->id);
|
|
|
|
- oh_name = name;
|
|
|
|
- }
|
|
|
|
|
|
+ of_node_put(np);
|
|
|
|
|
|
oh = omap_hwmod_lookup(oh_name);
|
|
oh = omap_hwmod_lookup(oh_name);
|
|
if (!oh)
|
|
if (!oh)
|
|
@@ -290,22 +280,6 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
|
|
|
|
|
|
*timer_name = oh->name;
|
|
*timer_name = oh->name;
|
|
|
|
|
|
- if (!of_have_populated_dt()) {
|
|
|
|
- r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL,
|
|
|
|
- &irq);
|
|
|
|
- if (r)
|
|
|
|
- return -ENXIO;
|
|
|
|
- timer->irq = irq.start;
|
|
|
|
-
|
|
|
|
- r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL,
|
|
|
|
- &mem);
|
|
|
|
- if (r)
|
|
|
|
- return -ENXIO;
|
|
|
|
-
|
|
|
|
- /* Static mapping, never released */
|
|
|
|
- timer->io_base = ioremap(mem.start, mem.end - mem.start);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (!timer->io_base)
|
|
if (!timer->io_base)
|
|
return -ENXIO;
|
|
return -ENXIO;
|
|
|
|
|
|
@@ -433,18 +407,15 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
|
|
const char *oh_name = "counter_32k";
|
|
const char *oh_name = "counter_32k";
|
|
|
|
|
|
/*
|
|
/*
|
|
- * If device-tree is present, then search the DT blob
|
|
|
|
- * to see if the 32kHz counter is supported.
|
|
|
|
|
|
+ * See if the 32kHz counter is supported.
|
|
*/
|
|
*/
|
|
- if (of_have_populated_dt()) {
|
|
|
|
- np = omap_get_timer_dt(omap_counter_match, NULL);
|
|
|
|
- if (!np)
|
|
|
|
- return -ENODEV;
|
|
|
|
-
|
|
|
|
- of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
|
|
|
|
- if (!oh_name)
|
|
|
|
- return -ENODEV;
|
|
|
|
- }
|
|
|
|
|
|
+ np = omap_get_timer_dt(omap_counter_match, NULL);
|
|
|
|
+ if (!np)
|
|
|
|
+ return -ENODEV;
|
|
|
|
+
|
|
|
|
+ of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
|
|
|
|
+ if (!oh_name)
|
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
/*
|
|
/*
|
|
* First check hwmod data is available for sync32k counter
|
|
* First check hwmod data is available for sync32k counter
|
|
@@ -462,18 +433,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
- if (!of_have_populated_dt()) {
|
|
|
|
- void __iomem *vbase;
|
|
|
|
-
|
|
|
|
- vbase = omap_hwmod_get_mpu_rt_va(oh);
|
|
|
|
-
|
|
|
|
- ret = omap_init_clocksource_32k(vbase);
|
|
|
|
- if (ret) {
|
|
|
|
- pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n",
|
|
|
|
- __func__, ret);
|
|
|
|
- omap_hwmod_idle(oh);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -688,96 +647,6 @@ void __init omap5_realtime_timer_init(void)
|
|
}
|
|
}
|
|
#endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */
|
|
#endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */
|
|
|
|
|
|
-/**
|
|
|
|
- * omap_timer_init - build and register timer device with an
|
|
|
|
- * associated timer hwmod
|
|
|
|
- * @oh: timer hwmod pointer to be used to build timer device
|
|
|
|
- * @user: parameter that can be passed from calling hwmod API
|
|
|
|
- *
|
|
|
|
- * Called by omap_hwmod_for_each_by_class to register each of the timer
|
|
|
|
- * devices present in the system. The number of timer devices is known
|
|
|
|
- * by parsing through the hwmod database for a given class name. At the
|
|
|
|
- * end of function call memory is allocated for timer device and it is
|
|
|
|
- * registered to the framework ready to be proved by the driver.
|
|
|
|
- */
|
|
|
|
-static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
|
|
|
|
-{
|
|
|
|
- int id;
|
|
|
|
- int ret = 0;
|
|
|
|
- char *name = "omap_timer";
|
|
|
|
- struct dmtimer_platform_data *pdata;
|
|
|
|
- struct platform_device *pdev;
|
|
|
|
- struct omap_timer_capability_dev_attr *timer_dev_attr;
|
|
|
|
-
|
|
|
|
- pr_debug("%s: %s\n", __func__, oh->name);
|
|
|
|
-
|
|
|
|
- /* on secure device, do not register secure timer */
|
|
|
|
- timer_dev_attr = oh->dev_attr;
|
|
|
|
- if (omap_type() != OMAP2_DEVICE_TYPE_GP && timer_dev_attr)
|
|
|
|
- if (timer_dev_attr->timer_capability == OMAP_TIMER_SECURE)
|
|
|
|
- return ret;
|
|
|
|
-
|
|
|
|
- pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
|
|
|
|
- if (!pdata) {
|
|
|
|
- pr_err("%s: No memory for [%s]\n", __func__, oh->name);
|
|
|
|
- return -ENOMEM;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Extract the IDs from name field in hwmod database
|
|
|
|
- * and use the same for constructing ids' for the
|
|
|
|
- * timer devices. In a way, we are avoiding usage of
|
|
|
|
- * static variable witin the function to do the same.
|
|
|
|
- * CAUTION: We have to be careful and make sure the
|
|
|
|
- * name in hwmod database does not change in which case
|
|
|
|
- * we might either make corresponding change here or
|
|
|
|
- * switch back static variable mechanism.
|
|
|
|
- */
|
|
|
|
- sscanf(oh->name, "timer%2d", &id);
|
|
|
|
-
|
|
|
|
- if (timer_dev_attr)
|
|
|
|
- pdata->timer_capability = timer_dev_attr->timer_capability;
|
|
|
|
-
|
|
|
|
- pdata->timer_errata = omap_dm_timer_get_errata();
|
|
|
|
- pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
|
|
|
|
-
|
|
|
|
- pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata));
|
|
|
|
-
|
|
|
|
- if (IS_ERR(pdev)) {
|
|
|
|
- pr_err("%s: Can't build omap_device for %s: %s.\n",
|
|
|
|
- __func__, name, oh->name);
|
|
|
|
- ret = -EINVAL;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- kfree(pdata);
|
|
|
|
-
|
|
|
|
- return ret;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * omap2_dm_timer_init - top level regular device initialization
|
|
|
|
- *
|
|
|
|
- * Uses dedicated hwmod api to parse through hwmod database for
|
|
|
|
- * given class name and then build and register the timer device.
|
|
|
|
- */
|
|
|
|
-static int __init omap2_dm_timer_init(void)
|
|
|
|
-{
|
|
|
|
- int ret;
|
|
|
|
-
|
|
|
|
- /* If dtb is there, the devices will be created dynamically */
|
|
|
|
- if (of_have_populated_dt())
|
|
|
|
- return -ENODEV;
|
|
|
|
-
|
|
|
|
- ret = omap_hwmod_for_each_by_class("timer", omap_timer_init, NULL);
|
|
|
|
- if (unlikely(ret)) {
|
|
|
|
- pr_err("%s: device registration failed.\n", __func__);
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-omap_arch_initcall(omap2_dm_timer_init);
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* omap2_override_clocksource - clocksource override with user configuration
|
|
* omap2_override_clocksource - clocksource override with user configuration
|
|
*
|
|
*
|