diff options
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
-rw-r--r-- | arch/arm/mach-omap2/timer.c | 167 |
1 files changed, 72 insertions, 95 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 099e4060afe..7016637b531 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -39,6 +39,8 @@ #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> +#include <linux/platform_device.h> +#include <linux/platform_data/dmtimer-omap.h> #include <asm/mach/time.h> #include <asm/smp_twd.h> @@ -64,20 +66,6 @@ #define OMAP3_32K_SOURCE "omap_32k_fck" #define OMAP4_32K_SOURCE "sys_32k_ck" -#ifdef CONFIG_OMAP_32K_TIMER -#define OMAP2_CLKEV_SOURCE OMAP2_32K_SOURCE -#define OMAP3_CLKEV_SOURCE OMAP3_32K_SOURCE -#define OMAP4_CLKEV_SOURCE OMAP4_32K_SOURCE -#define OMAP3_SECURE_TIMER 12 -#define TIMER_PROP_SECURE "ti,timer-secure" -#else -#define OMAP2_CLKEV_SOURCE OMAP2_MPU_SOURCE -#define OMAP3_CLKEV_SOURCE OMAP3_MPU_SOURCE -#define OMAP4_CLKEV_SOURCE OMAP4_MPU_SOURCE -#define OMAP3_SECURE_TIMER 1 -#define TIMER_PROP_SECURE "ti,timer-alwon" -#endif - #define REALTIME_COUNTER_BASE 0x48243200 #define INCREMENTER_NUMERATOR_OFFSET 0x10 #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 @@ -160,11 +148,6 @@ static struct of_device_id omap_timer_match[] __initdata = { { } }; -static struct of_device_id omap_counter_match[] __initdata = { - { .compatible = "ti,omap-counter32k", }, - { } -}; - /** * omap_get_timer_dt - get a timer using device-tree * @match - device-tree match structure for matching a device type @@ -245,10 +228,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, const char *oh_name; struct device_node *np; struct omap_hwmod *oh; - struct resource irq_rsrc, mem_rsrc; - size_t size; - int res = 0; - int r; + struct resource irq, mem; + int r = 0; if (of_have_populated_dt()) { np = omap_get_timer_dt(omap_timer_match, NULL); @@ -280,20 +261,18 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, if (!of_have_populated_dt()) { r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, - &irq_rsrc); + &irq); if (r) return -ENXIO; - timer->irq = irq_rsrc.start; + timer->irq = irq.start; r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL, - &mem_rsrc); + &mem); if (r) return -ENXIO; - timer->phys_base = mem_rsrc.start; - size = mem_rsrc.end - mem_rsrc.start; /* Static mapping, never released */ - timer->io_base = ioremap(timer->phys_base, size); + timer->io_base = ioremap(mem.start, mem.end - mem.start); } if (!timer->io_base) @@ -310,10 +289,10 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, src = clk_get(NULL, fck_source); if (IS_ERR(src)) { - res = -EINVAL; + r = -EINVAL; } else { - res = clk_set_parent(timer->fclk, src); - if (IS_ERR_VALUE(res)) + r = clk_set_parent(timer->fclk, src); + if (IS_ERR_VALUE(r)) pr_warn("%s: %s cannot set source\n", __func__, oh->name); clk_put(src); @@ -334,7 +313,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, timer->rate = clk_get_rate(timer->fclk); timer->reserved = 1; - return res; + return r; } static void __init omap2_gp_clockevent_init(int gptimer_id, @@ -407,7 +386,11 @@ static u32 notrace dmtimer_read_sched_clock(void) return 0; } -#ifdef CONFIG_OMAP_32K_TIMER +static struct of_device_id omap_counter_match[] __initdata = { + { .compatible = "ti,omap-counter32k", }, + { } +}; + /* Setup free-running counter for clocksource */ static int __init omap2_sync32k_clocksource_init(void) { @@ -468,12 +451,6 @@ static int __init omap2_sync32k_clocksource_init(void) return ret; } -#else -static inline int omap2_sync32k_clocksource_init(void) -{ - return -ENODEV; -} -#endif static void __init omap2_gptimer_clocksource_init(int gptimer_id, const char *fck_source) @@ -499,25 +476,6 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id, gptimer_id, clksrc.rate); } -static void __init omap2_clocksource_init(int gptimer_id, - const char *fck_source) -{ - /* - * First give preference to kernel parameter configuration - * by user (clocksource="gp_timer"). - * - * In case of missing kernel parameter for clocksource, - * first check for availability for 32k-sync timer, in case - * of failure in finding 32k_counter module or registering - * it as clocksource, execution will fallback to gp-timer. - */ - if (use_gptimer_clksrc == true) - omap2_gptimer_clocksource_init(gptimer_id, fck_source); - else if (omap2_sync32k_clocksource_init()) - /* Fall back to gp-timer code */ - omap2_gptimer_clocksource_init(gptimer_id, fck_source); -} - #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER /* * The realtime counter also called master counter, is a free-running @@ -596,52 +554,65 @@ static inline void __init realtime_counter_init(void) {} #endif -#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ +#define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ + clksrc_nr, clksrc_src) \ +static void __init omap##name##_gptimer_timer_init(void) \ +{ \ + omap_dmtimer_init(); \ + omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ + omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \ +} + +#define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ clksrc_nr, clksrc_src) \ -static void __init omap##name##_timer_init(void) \ +static void __init omap##name##_sync32k_timer_init(void) \ { \ omap_dmtimer_init(); \ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ - omap2_clocksource_init((clksrc_nr), clksrc_src); \ + /* Enable the use of clocksource="gp_timer" kernel parameter */ \ + if (use_gptimer_clksrc) \ + omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src);\ + else \ + omap2_sync32k_clocksource_init(); \ } -#define OMAP_SYS_TIMER(name) \ +#define OMAP_SYS_TIMER(name, clksrc) \ struct sys_timer omap##name##_timer = { \ - .init = omap##name##_timer_init, \ + .init = omap##name##_##clksrc##_timer_init, \ }; #ifdef CONFIG_ARCH_OMAP2 -OMAP_SYS_TIMER_INIT(2, 1, OMAP2_CLKEV_SOURCE, "ti,timer-alwon", - 2, OMAP2_MPU_SOURCE) -OMAP_SYS_TIMER(2) -#endif +OMAP_SYS_32K_TIMER_INIT(2, 1, OMAP2_32K_SOURCE, "ti,timer-alwon", + 2, OMAP2_MPU_SOURCE); +OMAP_SYS_TIMER(2, sync32k); +#endif /* CONFIG_ARCH_OMAP2 */ #ifdef CONFIG_ARCH_OMAP3 -OMAP_SYS_TIMER_INIT(3, 1, OMAP3_CLKEV_SOURCE, "ti,timer-alwon", - 2, OMAP3_MPU_SOURCE) -OMAP_SYS_TIMER(3) -OMAP_SYS_TIMER_INIT(3_secure, OMAP3_SECURE_TIMER, OMAP3_CLKEV_SOURCE, - TIMER_PROP_SECURE, 2, OMAP3_MPU_SOURCE) -OMAP_SYS_TIMER(3_secure) -#endif +OMAP_SYS_32K_TIMER_INIT(3, 1, OMAP3_32K_SOURCE, "ti,timer-alwon", + 2, OMAP3_MPU_SOURCE); +OMAP_SYS_TIMER(3, sync32k); +OMAP_SYS_32K_TIMER_INIT(3_secure, 12, OMAP3_32K_SOURCE, "ti,timer-secure", + 2, OMAP3_MPU_SOURCE); +OMAP_SYS_TIMER(3_secure, sync32k); +OMAP_SYS_GP_TIMER_INIT(3_gp, 1, OMAP3_MPU_SOURCE, "ti,timer-alwon", + 2, OMAP3_MPU_SOURCE); +OMAP_SYS_TIMER(3_gp, gptimer); +#endif /* CONFIG_ARCH_OMAP3 */ #ifdef CONFIG_SOC_AM33XX -OMAP_SYS_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon", - 2, OMAP4_MPU_SOURCE) -OMAP_SYS_TIMER(3_am33xx) -#endif +OMAP_SYS_GP_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon", + 2, OMAP4_MPU_SOURCE); +OMAP_SYS_TIMER(3_am33xx, gptimer); +#endif /* CONFIG_SOC_AM33XX */ #ifdef CONFIG_ARCH_OMAP4 +OMAP_SYS_32K_TIMER_INIT(4, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", + 2, OMAP4_MPU_SOURCE); #ifdef CONFIG_LOCAL_TIMERS -static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, - OMAP44XX_LOCAL_TWD_BASE, 29); -#endif - -static void __init omap4_timer_init(void) +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); +static void __init omap4_local_timer_init(void) { - omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE, "ti,timer-alwon"); - omap2_clocksource_init(2, OMAP4_MPU_SOURCE); -#ifdef CONFIG_LOCAL_TIMERS + omap4_sync32k_timer_init(); /* Local timers are not supprted on OMAP4430 ES1.0 */ if (omap_rev() != OMAP4430_REV_ES1_0) { int err; @@ -655,26 +626,32 @@ static void __init omap4_timer_init(void) if (err) pr_err("twd_local_timer_register failed %d\n", err); } -#endif } -OMAP_SYS_TIMER(4) -#endif +#else /* CONFIG_LOCAL_TIMERS */ +static void __init omap4_local_timer_init(void) +{ + omap4_sync32k_timer_init(); +} +#endif /* CONFIG_LOCAL_TIMERS */ +OMAP_SYS_TIMER(4, local); +#endif /* CONFIG_ARCH_OMAP4 */ #ifdef CONFIG_SOC_OMAP5 -static void __init omap5_timer_init(void) +OMAP_SYS_32K_TIMER_INIT(5, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", + 2, OMAP4_MPU_SOURCE); +static void __init omap5_realtime_timer_init(void) { int err; - omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE, "ti,timer-alwon"); - omap2_clocksource_init(2, OMAP4_MPU_SOURCE); + omap5_sync32k_timer_init(); realtime_counter_init(); err = arch_timer_of_register(); if (err) pr_err("%s: arch_timer_register failed %d\n", __func__, err); } -OMAP_SYS_TIMER(5) -#endif +OMAP_SYS_TIMER(5, realtime); +#endif /* CONFIG_SOC_OMAP5 */ /** * omap_timer_init - build and register timer device with an |