Initialize timer early so it can be used in sched_clock straightaway instead of starting with a dummy timer.
To do this, timer hardware initialization is seperated out from clocksource, clockevent and irq setup which come in as part of a "late" init. Signed-off-by: Sekhar Nori <[email protected]> --- arch/arm/mach-davinci/board-da830-evm.c | 1 + arch/arm/mach-davinci/board-da850-evm.c | 1 + arch/arm/mach-davinci/board-dm355-evm.c | 1 + arch/arm/mach-davinci/board-dm355-leopard.c | 1 + arch/arm/mach-davinci/board-dm365-evm.c | 1 + arch/arm/mach-davinci/board-dm644x-evm.c | 1 + arch/arm/mach-davinci/board-dm646x-evm.c | 2 + arch/arm/mach-davinci/board-mityomapl138.c | 1 + arch/arm/mach-davinci/board-neuros-osd2.c | 1 + arch/arm/mach-davinci/board-omapl138-hawk.c | 1 + arch/arm/mach-davinci/board-sffsdr.c | 1 + arch/arm/mach-davinci/board-tnetv107x-evm.c | 1 + arch/arm/mach-davinci/include/mach/common.h | 2 + arch/arm/mach-davinci/time.c | 89 ++++++++++++++------------- 14 files changed, 60 insertions(+), 44 deletions(-) diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 11c3db9..83e194b 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -678,6 +678,7 @@ static void __init da830_evm_map_io(void) MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM") .atag_offset = 0x100, .map_io = da830_evm_map_io, + .init_early = davinci_timer_early_init, .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = da830_evm_init, diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 6659a90..97c23b4 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -1407,6 +1407,7 @@ static void __init da850_evm_map_io(void) MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM") .atag_offset = 0x100, .map_io = da850_evm_map_io, + .init_early = davinci_timer_early_init, .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = da850_evm_init, diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 10107f6..8138cb9 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -353,6 +353,7 @@ static __init void dm355_evm_init(void) MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM") .atag_offset = 0x100, .map_io = dm355_evm_map_io, + .init_early = davinci_timer_early_init, .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = dm355_evm_init, diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index 286243b..5e312e2 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -272,6 +272,7 @@ static __init void dm355_leopard_init(void) MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard") .atag_offset = 0x100, .map_io = dm355_leopard_map_io, + .init_early = davinci_timer_early_init, .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = dm355_leopard_init, diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 46e1f41..e74f4e9 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -614,6 +614,7 @@ static __init void dm365_evm_init(void) MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM") .atag_offset = 0x100, .map_io = dm365_evm_map_io, + .init_early = davinci_timer_early_init, .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = dm365_evm_init, diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 40f6437..8e9caef 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -715,6 +715,7 @@ MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM") /* Maintainer: MontaVista Software <[email protected]> */ .atag_offset = 0x100, .map_io = davinci_evm_map_io, + .init_early = davinci_timer_early_init, .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = davinci_evm_init, diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 309040a..500c092 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -795,6 +795,7 @@ static __init void evm_init(void) MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM") .atag_offset = 0x100, .map_io = davinci_map_io, + .init_early = davinci_timer_early_init, .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = evm_init, @@ -804,6 +805,7 @@ MACHINE_END MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM") .atag_offset = 0x100, .map_io = davinci_map_io, + .init_early = davinci_timer_early_init, .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = evm_init, diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index 3cfff55..2f48d85 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -569,6 +569,7 @@ static void __init mityomapl138_map_io(void) MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808") .atag_offset = 0x100, .map_io = mityomapl138_map_io, + .init_early = davinci_timer_early_init, .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = mityomapl138_init, diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index b5e9aca..118ff8e 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -274,6 +274,7 @@ MACHINE_START(NEUROS_OSD2, "Neuros OSD2") /* Maintainer: Neuros Technologies <[email protected]> */ .atag_offset = 0x100, .map_io = davinci_ntosd2_map_io, + .init_early = davinci_timer_early_init, .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = davinci_ntosd2_init, diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c6701e4..11b3f29 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -340,6 +340,7 @@ static void __init omapl138_hawk_map_io(void) MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard") .atag_offset = 0x100, .map_io = omapl138_hawk_map_io, + .init_early = davinci_timer_early_init, .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = omapl138_hawk_init, diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index d15d161..53c648b 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -153,6 +153,7 @@ MACHINE_START(SFFSDR, "Lyrtech SFFSDR") /* Maintainer: Hugo Villeneuve [email protected] */ .atag_offset = 0x100, .map_io = davinci_sffsdr_map_io, + .init_early = davinci_timer_early_init, .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = davinci_sffsdr_init, diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index f69e40a..df92f24 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -279,6 +279,7 @@ console_initcall(tnetv107x_evm_console_init); MACHINE_START(TNETV107X, "TNETV107X EVM") .atag_offset = 0x100, .map_io = tnetv107x_init, + .init_early = davinci_timer_early_init, .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = tnetv107x_evm_board_init, diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index a57cba2..9f73358 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -37,6 +37,8 @@ struct davinci_timer_info { unsigned int clocksource_id; }; +void __init davinci_timer_early_init(void); + struct davinci_gpio_controller; /* diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index e7d8b52..f307b7d 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -196,13 +196,20 @@ static struct timer_s timers[] = { }, }; -static void __init timer_init(void) +static void __init timer_hw_init(void) { struct davinci_soc_info *soc_info = &davinci_soc_info; struct davinci_timer_instance *dtip = soc_info->timer_info->timers; + struct clk *timer_clk; void __iomem *base[2]; int i; + timer_clk = clk_get(NULL, "timer0"); + BUG_ON(IS_ERR(timer_clk)); + clk_enable(timer_clk); + + davinci_clock_tick_rate = clk_get_rate(timer_clk); + /* Global init of each 64-bit timer as a whole */ for(i=0; i<2; i++) { u32 tgcr; @@ -236,7 +243,6 @@ static void __init timer_init(void) for (i=0; i< ARRAY_SIZE(timers); i++) { struct timer_s *t = &timers[i]; int timer = ID_TO_TIMER(t->id); - u32 irq; t->base = base[timer]; if (!t->base) @@ -246,22 +252,12 @@ static void __init timer_init(void) t->enamode_shift = 6; t->tim_off = TIM12; t->prd_off = PRD12; - irq = dtip[timer].bottom_irq; } else { t->enamode_shift = 22; t->tim_off = TIM34; t->prd_off = PRD34; - irq = dtip[timer].top_irq; - } - - /* Register interrupt */ - t->irqaction.name = t->name; - t->irqaction.dev_id = (void *)t; - - if (t->irqaction.handler != NULL) { - irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq; - setup_irq(irq, &t->irqaction); } + timer32_config(t); } } @@ -275,19 +271,9 @@ static cycle_t read_cycles(struct clocksource *cs) return (cycles_t)timer32_read(t); } -/* - * Kernel assumes that sched_clock can be called early but may not have - * things ready yet. - */ -static cycle_t read_dummy(struct clocksource *cs) -{ - return 0; -} - - static struct clocksource clocksource_davinci = { .rating = 300, - .read = read_dummy, + .read = read_cycles, .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -299,7 +285,7 @@ static DEFINE_CLOCK_DATA(cd); */ unsigned long long notrace sched_clock(void) { - u32 cyc = clocksource_davinci.read(&clocksource_davinci); + u32 cyc = timer32_read(&timers[TID_CLOCKSOURCE]); return cyc_to_sched_clock(&cd, cyc, (u32)~0); } @@ -356,15 +342,13 @@ static struct clock_event_device clockevent_davinci = { }; -static void __init davinci_timer_init(void) +void __init davinci_timer_early_init(void) { - struct clk *timer_clk; struct davinci_soc_info *soc_info = &davinci_soc_info; unsigned int clockevent_id; unsigned int clocksource_id; static char err[] __initdata = KERN_ERR "%s: can't register clocksource!\n"; - int i; clockevent_id = soc_info->timer_info->clockevent_id; clocksource_id = soc_info->timer_info->clocksource_id; @@ -384,26 +368,19 @@ static void __init davinci_timer_init(void) /* Only bottom timers can use compare regs */ if (IS_TIMER_TOP(clockevent_id)) - pr_warning("davinci_timer_init: Invalid use" - " of system timers. Results unpredictable.\n"); + pr_warning("%s: Invalid use of system timers." + " Results unpredictable.\n", __func__); else if ((dtip[event_timer].cmp_off == 0) || (dtip[event_timer].cmp_irq == 0)) - pr_warning("davinci_timer_init: Invalid timer instance" - " setup. Results unpredictable.\n"); + pr_warning("%s: Invalid timer instance setup." + " Results unpredictable.\n", __func__); else { timers[TID_CLOCKEVENT].opts |= TIMER_OPTS_USE_COMPARE; clockevent_davinci.features = CLOCK_EVT_FEAT_ONESHOT; } } - timer_clk = clk_get(NULL, "timer0"); - BUG_ON(IS_ERR(timer_clk)); - clk_enable(timer_clk); - - /* init timer hw */ - timer_init(); - - davinci_clock_tick_rate = clk_get_rate(timer_clk); + timer_hw_init(); /* setup clocksource */ clocksource_davinci.read = read_cycles; @@ -413,6 +390,33 @@ static void __init davinci_timer_init(void) if (clocksource_register_hz(&clocksource_davinci, davinci_clock_tick_rate)) printk(err, clocksource_davinci.name); +} + +static void __init davinci_timer_late_init(void) +{ + struct davinci_soc_info *soc_info = &davinci_soc_info; + struct davinci_timer_instance *dtip = soc_info->timer_info->timers; + int i; + + for (i = 0; i < ARRAY_SIZE(timers); i++) { + struct timer_s *t = &timers[i]; + int timer = ID_TO_TIMER(t->id); + u32 irq; + + if (IS_TIMER_BOT(t->id)) + irq = dtip[timer].bottom_irq; + else + irq = dtip[timer].top_irq; + + /* Register interrupt */ + t->irqaction.name = t->name; + t->irqaction.dev_id = (void *)t; + + if (t->irqaction.handler != NULL) { + irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq; + setup_irq(irq, &t->irqaction); + } + } /* setup clockevent */ clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id]; @@ -424,13 +428,10 @@ static void __init davinci_timer_init(void) clockevent_davinci.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_davinci); - - for (i=0; i< ARRAY_SIZE(timers); i++) - timer32_config(&timers[i]); } struct sys_timer davinci_timer = { - .init = davinci_timer_init, + .init = davinci_timer_late_init, }; -- 1.7.0.4 _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
