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.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 98d27e646b09..7916311547ca 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -16,11 +16,48 @@
16#include <linux/init.h> 16#include <linux/init.h>
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 20
21#include <asm/div64.h>
22#include <asm/cnt32_to_63.h>
20#include <asm/mach/irq.h> 23#include <asm/mach/irq.h>
21#include <asm/mach/time.h> 24#include <asm/mach/time.h>
22#include <asm/arch/pxa-regs.h> 25#include <asm/arch/pxa-regs.h>
23 26
27/*
28 * This is PXA's sched_clock implementation. This has a resolution
29 * of at least 308 ns and a maximum value of 208 days.
30 *
31 * The return value is guaranteed to be monotonic in that range as
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.
34 */
35
36#define OSCR2NS_SCALE_FACTOR 10
37
38static unsigned long oscr2ns_scale;
39
40static void __init set_oscr2ns_scale(unsigned long oscr_rate)
41{
42 unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR;
43 do_div(v, oscr_rate);
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}
53
54unsigned long long sched_clock(void)
55{
56 unsigned long long v = cnt32_to_63(OSCR);
57 return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR;
58}
59
60
24static irqreturn_t 61static irqreturn_t
25pxa_ost0_interrupt(int irq, void *dev_id) 62pxa_ost0_interrupt(int irq, void *dev_id)
26{ 63{
@@ -152,6 +189,8 @@ static void __init pxa_timer_init(void)
152 OIER = 0; 189 OIER = 0;
153 OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; 190 OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
154 191
192 set_oscr2ns_scale(CLOCK_TICK_RATE);
193
155 ckevt_pxa_osmr0.mult = 194 ckevt_pxa_osmr0.mult =
156 div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); 195 div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
157 ckevt_pxa_osmr0.max_delta_ns = 196 ckevt_pxa_osmr0.max_delta_ns =