in kernel/timer.c [246:323]
static int __init xilinx_timer_init(struct device_node *timer)
{
struct clk *clk;
static int initialized;
u32 irq;
u32 timer_num = 1;
int ret;
if (initialized)
return -EINVAL;
initialized = 1;
timer_baseaddr = of_iomap(timer, 0);
if (!timer_baseaddr) {
pr_err("ERROR: invalid timer base address\n");
return -ENXIO;
}
write_fn = timer_write32;
read_fn = timer_read32;
write_fn(TCSR_MDT, timer_baseaddr + TCSR0);
if (!(read_fn(timer_baseaddr + TCSR0) & TCSR_MDT)) {
write_fn = timer_write32_be;
read_fn = timer_read32_be;
}
irq = irq_of_parse_and_map(timer, 0);
if (irq <= 0) {
pr_err("Failed to parse and map irq");
return -EINVAL;
}
of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num);
if (timer_num) {
pr_err("Please enable two timers in HW\n");
return -EINVAL;
}
pr_info("%pOF: irq=%d\n", timer, irq);
clk = of_clk_get(timer, 0);
if (IS_ERR(clk)) {
pr_err("ERROR: timer CCF input clock not found\n");
/* If there is clock-frequency property than use it */
of_property_read_u32(timer, "clock-frequency",
&timer_clock_freq);
} else {
timer_clock_freq = clk_get_rate(clk);
}
if (!timer_clock_freq) {
pr_err("ERROR: Using CPU clock frequency\n");
timer_clock_freq = cpuinfo.cpu_clock_freq;
}
freq_div_hz = timer_clock_freq / HZ;
ret = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer",
&clockevent_xilinx_timer);
if (ret) {
pr_err("Failed to setup IRQ");
return ret;
}
ret = xilinx_clocksource_init();
if (ret)
return ret;
ret = xilinx_clockevent_init();
if (ret)
return ret;
sched_clock_register(xilinx_clock_read, 32, timer_clock_freq);
return 0;
}