OMAP device has 32k-sync timer which is currently used as a
clocksource in the kernel (omap2plus_defconfig).
The current implementation uses compile time selection between
gp-timer and 32k-sync timer, which breaks multi-omap build for
the devices like AM33xx, where 32k-sync timer is not available.

So use hwmod database lookup mechanism, through which at run-time
we can identify availability of 32k-sync timer on the device,
else fall back to gp-timer.

Signed-off-by: Vaibhav Hiremath <hvaib...@ti.com>
Signed-off-by: Felipe Balbi <ba...@ti.com>
Cc: Benoit Cousson <b-cous...@ti.com>
Cc: Tony Lindgren <t...@atomide.com>
Cc: Paul Walmsley <p...@pwsan.com>
Cc: Tarun Kanti DebBarma <tarun.ka...@ti.com>
---
 arch/arm/mach-omap2/timer.c      |   27 +++++-------
 arch/arm/plat-omap/counter_32k.c |   83 +++++++++++++++++++------------------
 2 files changed, 54 insertions(+), 56 deletions(-)

diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 6eeff0e..b978b39 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -234,21 +234,6 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
 }
 
 /* Clocksource code */
-
-#ifdef CONFIG_OMAP_32K_TIMER
-/*
- * When 32k-timer is enabled, don't use GPTimer for clocksource
- * instead, just leave default clocksource which uses the 32k
- * sync counter.  See clocksource setup in plat-omap/counter_32k.c
- */
-
-static void __init omap2_gp_clocksource_init(int unused, const char *dummy)
-{
-       omap_init_clocksource_32k();
-}
-
-#else
-
 static struct omap_dm_timer clksrc;
 
 /*
@@ -281,6 +266,17 @@ static void __init omap2_gp_clocksource_init(int 
gptimer_id,
 {
        int res;
 
+       /*
+        * First check for availability for 32k-sync timer.
+        *
+        * Return non-zero, means the device doesn't have 32k-sync timer and
+        * execution will fallback to gp-timer.
+        */
+       res = omap_init_clocksource_32k();
+       if (!res)
+               return;
+
+       /* Fall back to gp-timer code */
        res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source);
        BUG_ON(res);
 
@@ -295,7 +291,6 @@ static void __init omap2_gp_clocksource_init(int gptimer_id,
                pr_err("Could not register clocksource %s\n",
                        clocksource_gpt.name);
 }
-#endif
 
 #define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src,                 \
                                clksrc_nr, clksrc_src)                  \
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index 5f0f229..8504bea 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -69,52 +69,55 @@ void read_persistent_clock(struct timespec *ts)
 
 int __init omap_init_clocksource_32k(void)
 {
-       static char err[] __initdata = KERN_ERR
-                       "%s: can't register clocksource!\n";
-
-       if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
-               u32 pbase;
-               unsigned long size = SZ_4K;
-               void __iomem *base;
-               struct clk *sync_32k_ick;
-
-               if (cpu_is_omap16xx()) {
-                       pbase = OMAP16XX_TIMER_32K_SYNCHRONIZED;
-                       size = SZ_1K;
-               } else if (cpu_is_omap2420())
-                       pbase = OMAP2420_32KSYNCT_BASE + 0x10;
-               else if (cpu_is_omap2430())
-                       pbase = OMAP2430_32KSYNCT_BASE + 0x10;
-               else if (cpu_is_omap34xx())
-                       pbase = OMAP3430_32KSYNCT_BASE + 0x10;
-               else if (cpu_is_omap44xx())
-                       pbase = OMAP4430_32KSYNCT_BASE + 0x10;
-               else
+       u32 pbase;
+       unsigned long size = SZ_4K;
+       void __iomem *base;
+       struct clk *sync_32k_ick;
+
+       if (cpu_is_omap16xx()) {
+               pbase = OMAP16XX_TIMER_32K_SYNCHRONIZED;
+               size = SZ_1K;
+       } else if (cpu_class_is_omap2()) {
+               struct omap_hwmod *oh;
+               const char *oh_name = "counter_32k";
+
+               oh = omap_hwmod_lookup(oh_name);
+               if (!oh || oh->slaves_cnt == 0) {
+                       pr_err("Could not lookup %s hwmod\n", oh_name);
                        return -ENODEV;
+               }
+               pbase = oh->slaves[0]->addr->pa_start + 0x10;
+       } else {
+               return -ENODEV;
+       }
 
-               /* For this to work we must have a static mapping in io.c for 
this area */
-               base = ioremap(pbase, size);
-               if (!base)
-                       return -ENODEV;
+       /*
+        * For this to work we must have a static mapping in io.c
+        * for this area
+        */
+       base = ioremap(pbase, size);
+       if (!base)
+               return -ENODEV;
 
-               sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
-               if (!IS_ERR(sync_32k_ick))
-                       clk_enable(sync_32k_ick);
+       sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
+       if (!IS_ERR(sync_32k_ick))
+               clk_enable(sync_32k_ick);
 
-               timer_32k_base = base;
+       timer_32k_base = base;
 
-               /*
-                * 120000 rough estimate from the calculations in
-                * __clocksource_updatefreq_scale.
-                */
-               clocks_calc_mult_shift(&persistent_mult, &persistent_shift,
-                               32768, NSEC_PER_SEC, 120000);
+       /*
+        * 120000 rough estimate from the calculations in
+        * __clocksource_updatefreq_scale.
+        */
+       clocks_calc_mult_shift(&persistent_mult, &persistent_shift,
+                       32768, NSEC_PER_SEC, 120000);
 
-               if (clocksource_mmio_init(base, "32k_counter", 32768, 250, 32,
-                                         clocksource_mmio_readl_up))
-                       printk(err, "32k_counter");
+       if (clocksource_mmio_init(base, "32k_counter", 32768, 250, 32,
+                               clocksource_mmio_readl_up))
+               printk(KERN_ERR "%s: can't register clocksource!\n",
+                               "32k_counter");
+
+       setup_sched_clock(omap_32k_read_sched_clock, 32, 32768);
 
-               setup_sched_clock(omap_32k_read_sched_clock, 32, 32768);
-       }
        return 0;
 }
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to