示例#1
0
void __init gemini_timer_init(void)
{
	unsigned int tick_rate, reg_v;

	reg_v = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS));
	tick_rate = REG_TO_AHB_SPEED(reg_v) * 1000000;

	printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000);

	tick_rate /= 6;		/* APB bus run AHB*(1/6) */

	switch(reg_v & CPU_AHB_RATIO_MASK) {
	case CPU_AHB_1_1:
		printk(KERN_CONT "(1/1)\n");
		break;
	case CPU_AHB_3_2:
		printk(KERN_CONT "(3/2)\n");
		break;
	case CPU_AHB_24_13:
		printk(KERN_CONT "(24/13)\n");
		break;
	case CPU_AHB_2_1:
		printk(KERN_CONT "(2/1)\n");
		break;
	}

	/*
	 * Make irqs happen for the system timer
	 */
	setup_irq(IRQ_TIMER2, &gemini_timer_irq);
	/* Start the timer */
	__raw_writel(tick_rate / HZ, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE)));
	__raw_writel(tick_rate / HZ, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE)));
	__raw_writel(TIMER_2_CR_ENABLE | TIMER_2_CR_INT, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
}
static int __init gemini_timer_of_init(struct device_node *np)
{
	static struct regmap *map;
	int ret;
	u32 val;

	map = syscon_regmap_lookup_by_phandle(np, "syscon");
	if (IS_ERR(map)) {
		pr_err("Can't get regmap for syscon handle\n");
		return -ENODEV;
	}
	ret = regmap_read(map, GLOBAL_STATUS, &val);
	if (ret) {
		pr_err("Can't read syscon status register\n");
		return -ENXIO;
	}

	tick_rate = REG_TO_AHB_SPEED(val) * 1000000;
	pr_info("Bus: %dMHz ", tick_rate / 1000000);

	tick_rate /= 6;		/* APB bus run AHB*(1/6) */

	switch (val & CPU_AHB_RATIO_MASK) {
	case CPU_AHB_1_1:
		pr_cont("(1/1)\n");
		break;
	case CPU_AHB_3_2:
		pr_cont("(3/2)\n");
		break;
	case CPU_AHB_24_13:
		pr_cont("(24/13)\n");
		break;
	case CPU_AHB_2_1:
		pr_cont("(2/1)\n");
		break;
	}

	return fttmr010_timer_common_init(np);
}