summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <sascha@saschahauer.de>2006-12-12 09:21:50 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-12-13 14:37:26 +0000
commitc80204e5d67d1452ac0b761d980f1651dc2c66dc (patch)
tree78ca0812db8fe4729c804efd6e1c5acb18ca3031 /arch
parentda2c12a279ae225f3d4696f76cb3b32a5bec5bfb (diff)
downloadlinux-c80204e5d67d1452ac0b761d980f1651dc2c66dc.tar.gz
[ARM] 4012/1: Clocksource for pxa
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-pxa/time.c45
1 files changed, 23 insertions, 22 deletions
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index b91466861029..3775b8f38429 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -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