static int __init dmtimer_systimer_setup()

in timer-ti-dm-systimer.c [362:426]


static int __init dmtimer_systimer_setup(struct device_node *np,
					 struct dmtimer_systimer *t)
{
	unsigned long rate;
	u8 regbase;
	int error;

	if (!of_device_is_compatible(np->parent, "ti,sysc"))
		return -EINVAL;

	t->base = of_iomap(np, 0);
	if (!t->base)
		return -ENXIO;

	/*
	 * Enable optional assigned-clock-parents configured at the timer
	 * node level. For regular device drivers, this is done automatically
	 * by bus related code such as platform_drv_probe().
	 */
	error = of_clk_set_defaults(np, false);
	if (error < 0)
		pr_err("%s: clock source init failed: %i\n", __func__, error);

	/* For ti-sysc, we have timer clocks at the parent module level */
	error = dmtimer_systimer_init_clock(t, np->parent, "fck", &rate);
	if (error)
		goto err_unmap;

	t->rate = rate;

	error = dmtimer_systimer_init_clock(t, np->parent, "ick", &rate);
	if (error)
		goto err_unmap;

	if (dmtimer_systimer_revision1(t)) {
		t->irq_stat = OMAP_TIMER_V1_STAT_OFFSET;
		t->irq_ena = OMAP_TIMER_V1_INT_EN_OFFSET;
		t->pend = _OMAP_TIMER_WRITE_PEND_OFFSET;
		regbase = 0;
	} else {
		t->irq_stat = OMAP_TIMER_V2_IRQSTATUS;
		t->irq_ena = OMAP_TIMER_V2_IRQENABLE_SET;
		regbase = OMAP_TIMER_V2_FUNC_OFFSET;
		t->pend = regbase + _OMAP_TIMER_WRITE_PEND_OFFSET;
	}

	t->sysc = OMAP_TIMER_OCP_CFG_OFFSET;
	t->load = regbase + _OMAP_TIMER_LOAD_OFFSET;
	t->counter = regbase + _OMAP_TIMER_COUNTER_OFFSET;
	t->ctrl = regbase + _OMAP_TIMER_CTRL_OFFSET;
	t->wakeup = regbase + _OMAP_TIMER_WAKEUP_EN_OFFSET;
	t->ifctrl = regbase + _OMAP_TIMER_IF_CTRL_OFFSET;

	dmtimer_systimer_reset(t);
	dmtimer_systimer_enable(t);
	pr_debug("dmtimer rev %08x sysc %08x\n", readl_relaxed(t->base),
		 readl_relaxed(t->base + t->sysc));

	return 0;

err_unmap:
	iounmap(t->base);

	return error;
}