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

Reply via email to