]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/arm/mach-sa1100/time.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-sa1100 / time.c
index 74b6e0e570b64e247681d052da44f6dcb645e16b..ae4f3d80416f2a3c617daabb94fbed14ffd27b9f 100644 (file)
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/sched.h>       /* just for sched_clock() - funny that */
 #include <linux/timex.h>
 #include <linux/clockchips.h>
 
 #include <asm/mach/time.h>
+#include <asm/sched_clock.h>
 #include <mach/hardware.h>
 
+/*
+ * This is the SA11x0 sched_clock implementation.
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+/*
+ * Constants generated by clocks_calc_mult_shift(m, s, 3.6864MHz,
+ * NSEC_PER_SEC, 60).
+ * This gives a resolution of about 271ns and a wrap period of about 19min.
+ */
+#define SC_MULT                2275555556u
+#define SC_SHIFT       23
+
+unsigned long long notrace sched_clock(void)
+{
+       u32 cyc = OSCR;
+       return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
+}
+
+static void notrace sa1100_update_sched_clock(void)
+{
+       u32 cyc = OSCR;
+       update_sched_clock(&cd, cyc, (u32)~0);
+}
+
 #define MIN_OSCR_DELTA 2
 
 static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id)
@@ -81,7 +108,6 @@ static struct clocksource cksrc_sa1100_oscr = {
        .rating         = 200,
        .read           = sa1100_read_oscr,
        .mask           = CLOCKSOURCE_MASK(32),
-       .shift          = 20,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -97,6 +123,9 @@ static void __init sa1100_timer_init(void)
        OIER = 0;               /* disable any timer interrupts */
        OSSR = 0xf;             /* clear status on all timers */
 
+       init_fixed_sched_clock(&cd, sa1100_update_sched_clock, 32,
+                              3686400, SC_MULT, SC_SHIFT);
+
        ckevt_sa1100_osmr0.mult =
                div_sc(3686400, NSEC_PER_SEC, ckevt_sa1100_osmr0.shift);
        ckevt_sa1100_osmr0.max_delta_ns =
@@ -105,12 +134,9 @@ static void __init sa1100_timer_init(void)
                clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_sa1100_osmr0) + 1;
        ckevt_sa1100_osmr0.cpumask = cpumask_of(0);
 
-       cksrc_sa1100_oscr.mult =
-               clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_sa1100_oscr.shift);
-
        setup_irq(IRQ_OST0, &sa1100_timer_irq);
 
-       clocksource_register(&cksrc_sa1100_oscr);
+       clocksource_register_hz(&cksrc_sa1100_oscr, CLOCK_TICK_RATE);
        clockevents_register_device(&ckevt_sa1100_osmr0);
 }