#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/clocksource.h>
#include <asm/system.h>
#include <asm/hardware.h>
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;
.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;
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
.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