]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/arm/mach-tegra/timer.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 / mach-tegra / timer.c
index 9057d6fd1d31d441dcc99c234c2d838c91e65a72..7b8ad1f98f447c5a6f5694d53388b9502ed972d2 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/sched.h>
 #include <linux/time.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/clocksource.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/cnt32_to_63.h>
 
 #include <asm/mach/time.h>
 #include <asm/localtimer.h>
+#include <asm/sched_clock.h>
 
 #include <mach/iomap.h>
 #include <mach/irqs.h>
@@ -91,7 +92,7 @@ static void tegra_timer_set_mode(enum clock_event_mode mode,
 
 static cycle_t tegra_clocksource_read(struct clocksource *cs)
 {
-       return cnt32_to_63(timer_readl(TIMERUS_CNTR_1US));
+       return timer_readl(TIMERUS_CNTR_1US);
 }
 
 static struct clock_event_device tegra_clockevent = {
@@ -106,14 +107,29 @@ static struct clocksource tegra_clocksource = {
        .name   = "timer_us",
        .rating = 300,
        .read   = tegra_clocksource_read,
-       .mask   = 0x7FFFFFFFFFFFFFFFULL,
+       .mask   = CLOCKSOURCE_MASK(32),
        .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-unsigned long long sched_clock(void)
+static DEFINE_CLOCK_DATA(cd);
+
+/*
+ * Constants generated by clocks_calc_mult_shift(m, s, 1MHz, NSEC_PER_SEC, 60).
+ * This gives a resolution of about 1us and a wrap period of about 1h11min.
+ */
+#define SC_MULT                4194304000u
+#define SC_SHIFT       22
+
+unsigned long long notrace sched_clock(void)
 {
-       return clocksource_cyc2ns(tegra_clocksource.read(&tegra_clocksource),
-               tegra_clocksource.mult, tegra_clocksource.shift);
+       u32 cyc = timer_readl(TIMERUS_CNTR_1US);
+       return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
+}
+
+static void notrace tegra_update_sched_clock(void)
+{
+       u32 cyc = timer_readl(TIMERUS_CNTR_1US);
+       update_sched_clock(&cd, cyc, (u32)~0);
 }
 
 static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
@@ -158,6 +174,9 @@ static void __init tegra_init_timer(void)
                WARN(1, "Unknown clock rate");
        }
 
+       init_fixed_sched_clock(&cd, tegra_update_sched_clock, 32,
+                              1000000, SC_MULT, SC_SHIFT);
+
        if (clocksource_register_hz(&tegra_clocksource, 1000000)) {
                printk(KERN_ERR "Failed to register clocksource\n");
                BUG();