]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - sitara-epos/sitara-epos-kernel.git/commitdiff
omap1: Fix sched_clock implementation when both MPU timer and 32K timer are used
authorTony Lindgren <tony@atomide.com>
Wed, 19 Jan 2011 01:00:00 +0000 (17:00 -0800)
committerTony Lindgren <tony@atomide.com>
Wed, 19 Jan 2011 18:38:46 +0000 (10:38 -0800)
Earlier patches select HAVE_SCHED_CLOCK for omaps. To have working sched_clock
also for MPU timer, we need to implement it in a way where the right one gets
selected during the runtime.

Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap1/time.c
arch/arm/plat-omap/counter_32k.c
arch/arm/plat-omap/include/plat/common.h

index b03f34d55d88a08b8a045f3132a9865fac0c92ff..f83fc335c613db6e3ac14e7fcf2cf15cd6af5a45 100644 (file)
@@ -219,6 +219,24 @@ static struct clocksource clocksource_mpu = {
 
 static DEFINE_CLOCK_DATA(cd);
 
+static inline unsigned long long notrace _omap_mpu_sched_clock(void)
+{
+       u32 cyc = mpu_read(&clocksource_mpu);
+       return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+#ifndef CONFIG_OMAP_32K_TIMER
+unsigned long long notrace sched_clock(void)
+{
+       return _omap_mpu_sched_clock();
+}
+#else
+static unsigned long long notrace omap_mpu_sched_clock(void)
+{
+       return _omap_mpu_sched_clock();
+}
+#endif
+
 static void notrace mpu_update_sched_clock(void)
 {
        u32 cyc = mpu_read(&clocksource_mpu);
@@ -262,6 +280,30 @@ static inline void omap_mpu_timer_init(void)
 }
 #endif /* CONFIG_OMAP_MPU_TIMER */
 
+#if defined(CONFIG_OMAP_MPU_TIMER) && defined(CONFIG_OMAP_32K_TIMER)
+static unsigned long long (*preferred_sched_clock)(void);
+
+unsigned long long notrace sched_clock(void)
+{
+       if (!preferred_sched_clock)
+               return 0;
+
+       return preferred_sched_clock();
+}
+
+static inline void preferred_sched_clock_init(bool use_32k_sched_clock)
+{
+       if (use_32k_sched_clock)
+               preferred_sched_clock = omap_32k_sched_clock;
+       else
+               preferred_sched_clock = omap_mpu_sched_clock;
+}
+#else
+static inline void preferred_sched_clock_init(bool use_32k_sched_clcok)
+{
+}
+#endif
+
 static inline int omap_32k_timer_usable(void)
 {
        int res = false;
@@ -283,8 +325,12 @@ static inline int omap_32k_timer_usable(void)
  */
 static void __init omap_timer_init(void)
 {
-       if (!omap_32k_timer_usable())
+       if (omap_32k_timer_usable()) {
+               preferred_sched_clock_init(1);
+       } else {
                omap_mpu_timer_init();
+               preferred_sched_clock_init(0);
+       }
 }
 
 struct sys_timer omap_timer = {
index 5d7b08b5a13ab16a69ac4620cd552787159f25df..862dda95d61d2085c2bbc5e77b866f166b1e4ca3 100644 (file)
@@ -120,12 +120,24 @@ static DEFINE_CLOCK_DATA(cd);
 #define SC_MULT                4000000000u
 #define SC_SHIFT       17
 
-unsigned long long notrace sched_clock(void)
+static inline unsigned long long notrace _omap_32k_sched_clock(void)
 {
        u32 cyc = clocksource_32k.read(&clocksource_32k);
        return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
 }
 
+#ifndef CONFIG_OMAP_MPU_TIMER
+unsigned long long notrace sched_clock(void)
+{
+       return _omap_32k_sched_clock();
+}
+#else
+unsigned long long notrace omap_32k_sched_clock(void)
+{
+       return _omap_32k_sched_clock();
+}
+#endif
+
 static void notrace omap_update_sched_clock(void)
 {
        u32 cyc = clocksource_32k.read(&clocksource_32k);
index ef683e01701b6eaf0c66b22bb81a24be5d150d2d..29b2afb4288f2bde34d42659e461791027e6e4fc 100644 (file)
@@ -37,6 +37,7 @@ extern void omap_map_common_io(void);
 extern struct sys_timer omap_timer;
 extern bool omap_32k_timer_init(void);
 extern int __init omap_init_clocksource_32k(void);
+extern unsigned long long notrace omap_32k_sched_clock(void);
 
 extern void omap_reserve(void);