aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 @@
18#include <linux/signal.h> 18#include <linux/signal.h>
19#include <linux/errno.h> 19#include <linux/errno.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/clocksource.h>
21 22
22#include <asm/system.h> 23#include <asm/system.h>
23#include <asm/hardware.h> 24#include <asm/hardware.h>
@@ -48,27 +49,6 @@ static int pxa_set_rtc(void)
48 return 0; 49 return 0;
49} 50}
50 51
51/* IRQs are disabled before entering here from do_gettimeofday() */
52static unsigned long pxa_gettimeoffset (void)
53{
54 long ticks_to_match, elapsed, usec;
55
56 /* Get ticks before next timer match */
57 ticks_to_match = OSMR0 - OSCR;
58
59 /* We need elapsed ticks since last match */
60 elapsed = LATCH - ticks_to_match;
61
62 /* don't get fooled by the workaround in pxa_timer_interrupt() */
63 if (elapsed <= 0)
64 return 0;
65
66 /* Now convert them to usec */
67 usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
68
69 return usec;
70}
71
72#ifdef CONFIG_NO_IDLE_HZ 52#ifdef CONFIG_NO_IDLE_HZ
73static unsigned long initial_match; 53static unsigned long initial_match;
74static int match_posponed; 54static int match_posponed;
@@ -121,6 +101,20 @@ static struct irqaction pxa_timer_irq = {
121 .handler = pxa_timer_interrupt, 101 .handler = pxa_timer_interrupt,
122}; 102};
123 103
104cycle_t pxa_get_cycles(void)
105{
106 return OSCR;
107}
108
109static struct clocksource clocksource_pxa = {
110 .name = "pxa_timer",
111 .rating = 200,
112 .read = pxa_get_cycles,
113 .mask = CLOCKSOURCE_MASK(32),
114 .shift = 20,
115 .is_continuous = 1,
116};
117
124static void __init pxa_timer_init(void) 118static void __init pxa_timer_init(void)
125{ 119{
126 struct timespec tv; 120 struct timespec tv;
@@ -139,6 +133,14 @@ static void __init pxa_timer_init(void)
139 OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ 133 OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */
140 OSMR0 = OSCR + LATCH; /* set initial match */ 134 OSMR0 = OSCR + LATCH; /* set initial match */
141 local_irq_restore(flags); 135 local_irq_restore(flags);
136
137 /* on PXA OSCR runs continiously and is not written to, so we can use it
138 * as clock source directly.
139 */
140 clocksource_pxa.mult =
141 clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_pxa.shift);
142 clocksource_register(&clocksource_pxa);
143
142} 144}
143 145
144#ifdef CONFIG_NO_IDLE_HZ 146#ifdef CONFIG_NO_IDLE_HZ
@@ -211,7 +213,6 @@ struct sys_timer pxa_timer = {
211 .init = pxa_timer_init, 213 .init = pxa_timer_init,
212 .suspend = pxa_timer_suspend, 214 .suspend = pxa_timer_suspend,
213 .resume = pxa_timer_resume, 215 .resume = pxa_timer_resume,
214 .offset = pxa_gettimeoffset,
215#ifdef CONFIG_NO_IDLE_HZ 216#ifdef CONFIG_NO_IDLE_HZ
216 .dyn_tick = &pxa_dyn_tick, 217 .dyn_tick = &pxa_dyn_tick,
217#endif 218#endif