[ARM] 4012/1: Clocksource for pxa
authorSascha Hauer <sascha@saschahauer.de>
Tue, 12 Dec 2006 08:21:50 +0000 (09:21 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 13 Dec 2006 14:37:26 +0000 (14:37 +0000)
Add a clocksource driver for pxa2xx systems

Signed-off-by: Luotao Fu <lfu@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-pxa/time.c

index b914668..3775b8f 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/signal.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/clocksource.h>
 
 #include <asm/system.h>
 #include <asm/hardware.h>
@@ -48,27 +49,6 @@ static int pxa_set_rtc(void)
        return 0;
 }
 
-/* IRQs are disabled before entering here from do_gettimeofday() */
-static unsigned long pxa_gettimeoffset (void)
-{
-       long ticks_to_match, elapsed, usec;
-
-       /* Get ticks before next timer match */
-       ticks_to_match = OSMR0 - OSCR;
-
-       /* We need elapsed ticks since last match */
-       elapsed = LATCH - ticks_to_match;
-
-       /* don't get fooled by the workaround in pxa_timer_interrupt() */
-       if (elapsed <= 0)
-               return 0;
-
-       /* Now convert them to usec */
-       usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
-
-       return usec;
-}
-
 #ifdef CONFIG_NO_IDLE_HZ
 static unsigned long initial_match;
 static int match_posponed;
@@ -121,6 +101,20 @@ static struct irqaction pxa_timer_irq = {
        .handler        = pxa_timer_interrupt,
 };
 
+cycle_t pxa_get_cycles(void)
+{
+       return OSCR;
+}
+
+static struct clocksource clocksource_pxa = {
+       .name           = "pxa_timer",
+       .rating         = 200,
+       .read           = pxa_get_cycles,
+       .mask           = CLOCKSOURCE_MASK(32),
+       .shift          = 20,
+       .is_continuous  = 1,
+};
+
 static void __init pxa_timer_init(void)
 {
        struct timespec tv;
@@ -139,6 +133,14 @@ static void __init pxa_timer_init(void)
        OIER = OIER_E0;         /* enable match on timer 0 to cause interrupts */
        OSMR0 = OSCR + LATCH;   /* set initial match */
        local_irq_restore(flags);
+
+       /* on PXA OSCR runs continiously and is not written to, so we can use it
+        * as clock source directly.
+        */
+       clocksource_pxa.mult =
+               clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_pxa.shift);
+       clocksource_register(&clocksource_pxa);
+
 }
 
 #ifdef CONFIG_NO_IDLE_HZ
@@ -211,7 +213,6 @@ struct sys_timer pxa_timer = {
        .init           = pxa_timer_init,
        .suspend        = pxa_timer_suspend,
        .resume         = pxa_timer_resume,
-       .offset         = pxa_gettimeoffset,
 #ifdef CONFIG_NO_IDLE_HZ
        .dyn_tick       = &pxa_dyn_tick,
 #endif