aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-pxa/time.c')
-rw-r--r--arch/arm/mach-pxa/time.c35
1 files changed, 10 insertions, 25 deletions
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 293e40aeaf29..e7f64d9b4f2d 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -17,11 +17,11 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/clockchips.h> 18#include <linux/clockchips.h>
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/cnt32_to_63.h>
21 20
22#include <asm/div64.h> 21#include <asm/div64.h>
23#include <asm/mach/irq.h> 22#include <asm/mach/irq.h>
24#include <asm/mach/time.h> 23#include <asm/mach/time.h>
24#include <asm/sched_clock.h>
25#include <mach/regs-ost.h> 25#include <mach/regs-ost.h>
26 26
27/* 27/*
@@ -32,29 +32,18 @@
32 * long as there is always less than 582 seconds between successive 32 * long as there is always less than 582 seconds between successive
33 * calls to sched_clock() which should always be the case in practice. 33 * calls to sched_clock() which should always be the case in practice.
34 */ 34 */
35static DEFINE_CLOCK_DATA(cd);
35 36
36#define OSCR2NS_SCALE_FACTOR 10 37unsigned long long notrace sched_clock(void)
37
38static unsigned long oscr2ns_scale;
39
40static void __init set_oscr2ns_scale(unsigned long oscr_rate)
41{ 38{
42 unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR; 39 u32 cyc = OSCR;
43 do_div(v, oscr_rate); 40 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
44 oscr2ns_scale = v;
45 /*
46 * We want an even value to automatically clear the top bit
47 * returned by cnt32_to_63() without an additional run time
48 * instruction. So if the LSB is 1 then round it up.
49 */
50 if (oscr2ns_scale & 1)
51 oscr2ns_scale++;
52} 41}
53 42
54unsigned long long sched_clock(void) 43static void notrace pxa_update_sched_clock(void)
55{ 44{
56 unsigned long long v = cnt32_to_63(OSCR); 45 u32 cyc = OSCR;
57 return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR; 46 update_sched_clock(&cd, cyc, (u32)~0);
58} 47}
59 48
60 49
@@ -127,7 +116,6 @@ static struct clocksource cksrc_pxa_oscr0 = {
127 .rating = 200, 116 .rating = 200,
128 .read = pxa_read_oscr, 117 .read = pxa_read_oscr,
129 .mask = CLOCKSOURCE_MASK(32), 118 .mask = CLOCKSOURCE_MASK(32),
130 .shift = 20,
131 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 119 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
132}; 120};
133 121
@@ -145,7 +133,7 @@ static void __init pxa_timer_init(void)
145 OIER = 0; 133 OIER = 0;
146 OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; 134 OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
147 135
148 set_oscr2ns_scale(clock_tick_rate); 136 init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate);
149 137
150 ckevt_pxa_osmr0.mult = 138 ckevt_pxa_osmr0.mult =
151 div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); 139 div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
@@ -155,12 +143,9 @@ static void __init pxa_timer_init(void)
155 clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1; 143 clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1;
156 ckevt_pxa_osmr0.cpumask = cpumask_of(0); 144 ckevt_pxa_osmr0.cpumask = cpumask_of(0);
157 145
158 cksrc_pxa_oscr0.mult =
159 clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift);
160
161 setup_irq(IRQ_OST0, &pxa_ost0_irq); 146 setup_irq(IRQ_OST0, &pxa_ost0_irq);
162 147
163 clocksource_register(&cksrc_pxa_oscr0); 148 clocksource_register_hz(&cksrc_pxa_oscr0, clock_tick_rate);
164 clockevents_register_device(&ckevt_pxa_osmr0); 149 clockevents_register_device(&ckevt_pxa_osmr0);
165} 150}
166 151