]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/arm/plat-omap/counter_32k.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / arch / arm / plat-omap / counter_32k.c
index 8722a136f3a5bee844f5643dd195c95f077db666..862dda95d61d2085c2bbc5e77b866f166b1e4ca3 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
-#include <linux/io.h>
 #include <linux/err.h>
+#include <linux/io.h>
+#include <linux/sched.h>
+
+#include <asm/sched_clock.h>
 
 #include <plat/common.h>
 #include <plat/board.h>
@@ -33,8 +36,6 @@
 
 #define OMAP16XX_TIMER_32K_SYNCHRONIZED                0xfffbc410
 
-#if !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX))
-
 #include <linux/clocksource.h>
 
 /*
@@ -45,7 +46,7 @@
 static u32 offset_32k __read_mostly;
 
 #ifdef CONFIG_ARCH_OMAP16XX
-static cycle_t omap16xx_32k_read(struct clocksource *cs)
+static cycle_t notrace omap16xx_32k_read(struct clocksource *cs)
 {
        return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
 }
@@ -54,7 +55,7 @@ static cycle_t omap16xx_32k_read(struct clocksource *cs)
 #endif
 
 #ifdef CONFIG_ARCH_OMAP2420
-static cycle_t omap2420_32k_read(struct clocksource *cs)
+static cycle_t notrace omap2420_32k_read(struct clocksource *cs)
 {
        return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
 }
@@ -63,7 +64,7 @@ static cycle_t omap2420_32k_read(struct clocksource *cs)
 #endif
 
 #ifdef CONFIG_ARCH_OMAP2430
-static cycle_t omap2430_32k_read(struct clocksource *cs)
+static cycle_t notrace omap2430_32k_read(struct clocksource *cs)
 {
        return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
@@ -72,7 +73,7 @@ static cycle_t omap2430_32k_read(struct clocksource *cs)
 #endif
 
 #ifdef CONFIG_ARCH_OMAP3
-static cycle_t omap34xx_32k_read(struct clocksource *cs)
+static cycle_t notrace omap34xx_32k_read(struct clocksource *cs)
 {
        return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
@@ -81,7 +82,7 @@ static cycle_t omap34xx_32k_read(struct clocksource *cs)
 #endif
 
 #ifdef CONFIG_ARCH_OMAP4
-static cycle_t omap44xx_32k_read(struct clocksource *cs)
+static cycle_t notrace omap44xx_32k_read(struct clocksource *cs)
 {
        return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
@@ -93,7 +94,7 @@ static cycle_t omap44xx_32k_read(struct clocksource *cs)
  * Kernel assumes that sched_clock can be called early but may not have
  * things ready yet.
  */
-static cycle_t omap_32k_read_dummy(struct clocksource *cs)
+static cycle_t notrace omap_32k_read_dummy(struct clocksource *cs)
 {
        return 0;
 }
@@ -103,7 +104,6 @@ static struct clocksource clocksource_32k = {
        .rating         = 250,
        .read           = omap_32k_read_dummy,
        .mask           = CLOCKSOURCE_MASK(32),
-       .shift          = 10,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -111,10 +111,37 @@ static struct clocksource clocksource_32k = {
  * Returns current time from boot in nsecs. It's OK for this to wrap
  * around for now, as it's just a relative time stamp.
  */
-unsigned long long sched_clock(void)
+static DEFINE_CLOCK_DATA(cd);
+
+/*
+ * Constants generated by clocks_calc_mult_shift(m, s, 32768, NSEC_PER_SEC, 60).
+ * This gives a resolution of about 30us and a wrap period of about 36hrs.
+ */
+#define SC_MULT                4000000000u
+#define SC_SHIFT       17
+
+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 clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
-                                 clocksource_32k.mult, clocksource_32k.shift);
+       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);
+       update_sched_clock(&cd, cyc, (u32)~0);
 }
 
 /**
@@ -143,7 +170,7 @@ void read_persistent_clock(struct timespec *ts)
        *ts = *tsp;
 }
 
-static int __init omap_init_clocksource_32k(void)
+int __init omap_init_clocksource_32k(void)
 {
        static char err[] __initdata = KERN_ERR
                        "%s: can't register clocksource!\n";
@@ -168,17 +195,13 @@ static int __init omap_init_clocksource_32k(void)
                if (!IS_ERR(sync_32k_ick))
                        clk_enable(sync_32k_ick);
 
-               clocksource_32k.mult = clocksource_hz2mult(32768,
-                                           clocksource_32k.shift);
-
                offset_32k = clocksource_32k.read(&clocksource_32k);
 
-               if (clocksource_register(&clocksource_32k))
+               if (clocksource_register_hz(&clocksource_32k, 32768))
                        printk(err, clocksource_32k.name);
+
+               init_fixed_sched_clock(&cd, omap_update_sched_clock, 32,
+                                      32768, SC_MULT, SC_SHIFT);
        }
        return 0;
 }
-arch_initcall(omap_init_clocksource_32k);
-
-#endif /* !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX)) */
-