in omap_remoteproc.c [312:438]
static int omap_rproc_enable_timers(struct rproc *rproc, bool configure)
{
int i;
int ret = 0;
struct platform_device *tpdev;
struct dmtimer_platform_data *tpdata;
const struct omap_dm_timer_ops *timer_ops;
struct omap_rproc *oproc = rproc->priv;
struct omap_rproc_timer *timers = oproc->timers;
struct device *dev = rproc->dev.parent;
struct device_node *np = NULL;
int num_timers = oproc->num_timers + oproc->num_wd_timers;
if (!num_timers)
return 0;
if (!configure)
goto start_timers;
for (i = 0; i < num_timers; i++) {
if (i < oproc->num_timers)
np = of_parse_phandle(dev->of_node, "ti,timers", i);
else
np = of_parse_phandle(dev->of_node,
"ti,watchdog-timers",
(i - oproc->num_timers));
if (!np) {
ret = -ENXIO;
dev_err(dev, "device node lookup for timer at index %d failed: %d\n",
i < oproc->num_timers ? i :
i - oproc->num_timers, ret);
goto free_timers;
}
tpdev = of_find_device_by_node(np);
if (!tpdev) {
ret = -ENODEV;
dev_err(dev, "could not get timer platform device\n");
goto put_node;
}
tpdata = dev_get_platdata(&tpdev->dev);
put_device(&tpdev->dev);
if (!tpdata) {
ret = -EINVAL;
dev_err(dev, "dmtimer pdata structure NULL\n");
goto put_node;
}
timer_ops = tpdata->timer_ops;
if (!timer_ops || !timer_ops->request_by_node ||
!timer_ops->set_source || !timer_ops->set_load ||
!timer_ops->free || !timer_ops->start ||
!timer_ops->stop || !timer_ops->get_irq ||
!timer_ops->write_status) {
ret = -EINVAL;
dev_err(dev, "device does not have required timer ops\n");
goto put_node;
}
timers[i].irq = -1;
timers[i].timer_ops = timer_ops;
ret = omap_rproc_request_timer(dev, np, &timers[i]);
if (ret) {
dev_err(dev, "request for timer %p failed: %d\n", np,
ret);
goto put_node;
}
of_node_put(np);
if (i >= oproc->num_timers) {
timers[i].irq = omap_rproc_get_timer_irq(&timers[i]);
if (timers[i].irq < 0) {
dev_err(dev, "get_irq for timer %p failed: %d\n",
np, timers[i].irq);
ret = -EBUSY;
goto free_timers;
}
ret = request_irq(timers[i].irq,
omap_rproc_watchdog_isr, IRQF_SHARED,
"rproc-wdt", rproc);
if (ret) {
dev_err(dev, "error requesting irq for timer %p\n",
np);
omap_rproc_release_timer(&timers[i]);
timers[i].odt = NULL;
timers[i].timer_ops = NULL;
timers[i].irq = -1;
goto free_timers;
}
}
}
start_timers:
for (i = 0; i < num_timers; i++) {
ret = omap_rproc_start_timer(&timers[i]);
if (ret) {
dev_err(dev, "start timer %p failed failed: %d\n", np,
ret);
break;
}
}
if (ret) {
while (i >= 0) {
omap_rproc_stop_timer(&timers[i]);
i--;
}
goto put_node;
}
return 0;
put_node:
if (configure)
of_node_put(np);
free_timers:
while (i--) {
if (i >= oproc->num_timers)
free_irq(timers[i].irq, rproc);
omap_rproc_release_timer(&timers[i]);
timers[i].odt = NULL;
timers[i].timer_ops = NULL;
timers[i].irq = -1;
}
return ret;
}