in timer-lpc32xx.c [159:218]
static int __init lpc32xx_clocksource_init(struct device_node *np)
{
void __iomem *base;
unsigned long rate;
struct clk *clk;
int ret;
clk = of_clk_get_by_name(np, "timerclk");
if (IS_ERR(clk)) {
pr_err("clock get failed (%ld)\n", PTR_ERR(clk));
return PTR_ERR(clk);
}
ret = clk_prepare_enable(clk);
if (ret) {
pr_err("clock enable failed (%d)\n", ret);
goto err_clk_enable;
}
base = of_iomap(np, 0);
if (!base) {
pr_err("unable to map registers\n");
ret = -EADDRNOTAVAIL;
goto err_iomap;
}
/*
* Disable and reset timer then set it to free running timer
* mode (CTCR) with no prescaler (PR) or match operations (MCR).
* After setup the timer is released from reset and enabled.
*/
writel_relaxed(LPC32XX_TIMER_TCR_CRST, base + LPC32XX_TIMER_TCR);
writel_relaxed(0, base + LPC32XX_TIMER_PR);
writel_relaxed(0, base + LPC32XX_TIMER_MCR);
writel_relaxed(0, base + LPC32XX_TIMER_CTCR);
writel_relaxed(LPC32XX_TIMER_TCR_CEN, base + LPC32XX_TIMER_TCR);
rate = clk_get_rate(clk);
ret = clocksource_mmio_init(base + LPC32XX_TIMER_TC, "lpc3220 timer",
rate, 300, 32, clocksource_mmio_readl_up);
if (ret) {
pr_err("failed to init clocksource (%d)\n", ret);
goto err_clocksource_init;
}
clocksource_timer_counter = base + LPC32XX_TIMER_TC;
lpc32xx_delay_timer.freq = rate;
register_current_timer_delay(&lpc32xx_delay_timer);
sched_clock_register(lpc32xx_read_sched_clock, 32, rate);
return 0;
err_clocksource_init:
iounmap(base);
err_iomap:
clk_disable_unprepare(clk);
err_clk_enable:
clk_put(clk);
return ret;
}