static int __init xilinx_timer_init()

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;
}