static int __init oxnas_rps_timer_init()

in timer-oxnas-rps.c [212:283]


static int __init oxnas_rps_timer_init(struct device_node *np)
{
	struct oxnas_rps_timer *rps;
	void __iomem *base;
	int ret;

	rps = kzalloc(sizeof(*rps), GFP_KERNEL);
	if (!rps)
		return -ENOMEM;

	rps->clk = of_clk_get(np, 0);
	if (IS_ERR(rps->clk)) {
		ret = PTR_ERR(rps->clk);
		goto err_alloc;
	}

	ret = clk_prepare_enable(rps->clk);
	if (ret)
		goto err_clk;

	base = of_iomap(np, 0);
	if (!base) {
		ret = -ENXIO;
		goto err_clk_prepare;
	}

	rps->irq = irq_of_parse_and_map(np, 0);
	if (rps->irq < 0) {
		ret = -EINVAL;
		goto err_iomap;
	}

	rps->clkevt_base = base + TIMER1_REG_OFFSET;
	rps->clksrc_base = base + TIMER2_REG_OFFSET;

	/* Disable timers */
	writel_relaxed(0, rps->clkevt_base + TIMER_CTRL_REG);
	writel_relaxed(0, rps->clksrc_base + TIMER_CTRL_REG);
	writel_relaxed(0, rps->clkevt_base + TIMER_LOAD_REG);
	writel_relaxed(0, rps->clksrc_base + TIMER_LOAD_REG);
	writel_relaxed(0, rps->clkevt_base + TIMER_CLRINT_REG);
	writel_relaxed(0, rps->clksrc_base + TIMER_CLRINT_REG);

	ret = request_irq(rps->irq, oxnas_rps_timer_irq,
			  IRQF_TIMER | IRQF_IRQPOLL,
			  "rps-timer", rps);
	if (ret)
		goto err_iomap;

	ret = oxnas_rps_clocksource_init(rps);
	if (ret)
		goto err_irqreq;

	ret = oxnas_rps_clockevent_init(rps);
	if (ret)
		goto err_irqreq;

	return 0;

err_irqreq:
	free_irq(rps->irq, rps);
err_iomap:
	iounmap(base);
err_clk_prepare:
	clk_disable_unprepare(rps->clk);
err_clk:
	clk_put(rps->clk);
err_alloc:
	kfree(rps);

	return ret;
}