static int omap_dm_timer_probe()

in timer-ti-dm.c [777:862]


static int omap_dm_timer_probe(struct platform_device *pdev)
{
	unsigned long flags;
	struct omap_dm_timer *timer;
	struct device *dev = &pdev->dev;
	const struct dmtimer_platform_data *pdata;
	int ret;

	pdata = of_device_get_match_data(dev);
	if (!pdata)
		pdata = dev_get_platdata(dev);
	else
		dev->platform_data = (void *)pdata;

	if (!pdata) {
		dev_err(dev, "%s: no platform data.\n", __func__);
		return -ENODEV;
	}

	timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL);
	if (!timer)
		return  -ENOMEM;

	timer->irq = platform_get_irq(pdev, 0);
	if (timer->irq < 0)
		return timer->irq;

	timer->fclk = ERR_PTR(-ENODEV);
	timer->io_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(timer->io_base))
		return PTR_ERR(timer->io_base);

	platform_set_drvdata(pdev, timer);

	if (dev->of_node) {
		if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
			timer->capability |= OMAP_TIMER_ALWON;
		if (of_find_property(dev->of_node, "ti,timer-dsp", NULL))
			timer->capability |= OMAP_TIMER_HAS_DSP_IRQ;
		if (of_find_property(dev->of_node, "ti,timer-pwm", NULL))
			timer->capability |= OMAP_TIMER_HAS_PWM;
		if (of_find_property(dev->of_node, "ti,timer-secure", NULL))
			timer->capability |= OMAP_TIMER_SECURE;
	} else {
		timer->id = pdev->id;
		timer->capability = pdata->timer_capability;
		timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
	}

	if (!(timer->capability & OMAP_TIMER_ALWON)) {
		timer->nb.notifier_call = omap_timer_context_notifier;
		cpu_pm_register_notifier(&timer->nb);
	}

	if (pdata)
		timer->errata = pdata->timer_errata;

	timer->pdev = pdev;

	pm_runtime_enable(dev);

	if (!timer->reserved) {
		ret = pm_runtime_get_sync(dev);
		if (ret < 0) {
			dev_err(dev, "%s: pm_runtime_get_sync failed!\n",
				__func__);
			goto err_get_sync;
		}
		__omap_dm_timer_init_regs(timer);
		pm_runtime_put(dev);
	}

	/* add the timer element to the list */
	spin_lock_irqsave(&dm_timer_lock, flags);
	list_add_tail(&timer->node, &omap_timer_list);
	spin_unlock_irqrestore(&dm_timer_lock, flags);

	dev_dbg(dev, "Device Probed.\n");

	return 0;

err_get_sync:
	pm_runtime_put_noidle(dev);
	pm_runtime_disable(dev);
	return ret;
}