diff options
-rw-r--r-- | arch/arm/mach-pxa/time.c | 45 |
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() */ | ||
52 | static 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 |
73 | static unsigned long initial_match; | 53 | static unsigned long initial_match; |
74 | static int match_posponed; | 54 | static 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 | ||
104 | cycle_t pxa_get_cycles(void) | ||
105 | { | ||
106 | return OSCR; | ||
107 | } | ||
108 | |||
109 | static 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 | |||
124 | static void __init pxa_timer_init(void) | 118 | static 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 |