diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-15 16:46:48 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-22 17:44:45 -0500 |
commit | 28bb7bc61a8cd48716d38d9c153fdc524f09870a (patch) | |
tree | 0ac6969dffbe5def2400fc18321789206711465a /arch/arm/mach-mmp | |
parent | 5b0d495c067d843c52fc1f9edbca29d5e9368b10 (diff) |
ARM: mmp: convert sched_clock() to use new infrastructure
Convert mmp to use the new sched_clock() infrastructure for extending
32bit counters to full 64-bit nanoseconds.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-mmp')
-rw-r--r-- | arch/arm/mach-mmp/time.c | 32 |
1 files changed, 11 insertions, 21 deletions
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index a2ea33d04e63..aeb9ae23e6ce 100644 --- a/arch/arm/mach-mmp/time.c +++ b/arch/arm/mach-mmp/time.c | |||
@@ -26,8 +26,8 @@ | |||
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
28 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
29 | #include <linux/cnt32_to_63.h> | ||
30 | 29 | ||
30 | #include <asm/sched_clock.h> | ||
31 | #include <mach/addr-map.h> | 31 | #include <mach/addr-map.h> |
32 | #include <mach/regs-timers.h> | 32 | #include <mach/regs-timers.h> |
33 | #include <mach/regs-apbc.h> | 33 | #include <mach/regs-apbc.h> |
@@ -42,23 +42,7 @@ | |||
42 | #define MAX_DELTA (0xfffffffe) | 42 | #define MAX_DELTA (0xfffffffe) |
43 | #define MIN_DELTA (16) | 43 | #define MIN_DELTA (16) |
44 | 44 | ||
45 | #define TCR2NS_SCALE_FACTOR 10 | 45 | static DEFINE_CLOCK_DATA(cd); |
46 | |||
47 | static unsigned long tcr2ns_scale; | ||
48 | |||
49 | static void __init set_tcr2ns_scale(unsigned long tcr_rate) | ||
50 | { | ||
51 | unsigned long long v = 1000000000ULL << TCR2NS_SCALE_FACTOR; | ||
52 | do_div(v, tcr_rate); | ||
53 | tcr2ns_scale = v; | ||
54 | /* | ||
55 | * We want an even value to automatically clear the top bit | ||
56 | * returned by cnt32_to_63() without an additional run time | ||
57 | * instruction. So if the LSB is 1 then round it up. | ||
58 | */ | ||
59 | if (tcr2ns_scale & 1) | ||
60 | tcr2ns_scale++; | ||
61 | } | ||
62 | 46 | ||
63 | /* | 47 | /* |
64 | * FIXME: the timer needs some delay to stablize the counter capture | 48 | * FIXME: the timer needs some delay to stablize the counter capture |
@@ -77,8 +61,14 @@ static inline uint32_t timer_read(void) | |||
77 | 61 | ||
78 | unsigned long long notrace sched_clock(void) | 62 | unsigned long long notrace sched_clock(void) |
79 | { | 63 | { |
80 | unsigned long long v = cnt32_to_63(timer_read()); | 64 | u32 cyc = timer_read(); |
81 | return (v * tcr2ns_scale) >> TCR2NS_SCALE_FACTOR; | 65 | return cyc_to_sched_clock(&cd, cyc, (u32)~0); |
66 | } | ||
67 | |||
68 | static void notrace mmp_update_sched_clock(void) | ||
69 | { | ||
70 | u32 cyc = timer_read(); | ||
71 | update_sched_clock(&cd, cyc, (u32)~0); | ||
82 | } | 72 | } |
83 | 73 | ||
84 | static irqreturn_t timer_interrupt(int irq, void *dev_id) | 74 | static irqreturn_t timer_interrupt(int irq, void *dev_id) |
@@ -185,7 +175,7 @@ void __init timer_init(int irq) | |||
185 | { | 175 | { |
186 | timer_config(); | 176 | timer_config(); |
187 | 177 | ||
188 | set_tcr2ns_scale(CLOCK_TICK_RATE); | 178 | init_sched_clock(&cd, mmp_update_sched_clock, 32, CLOCK_TICK_RATE); |
189 | 179 | ||
190 | ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift); | 180 | ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift); |
191 | ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt); | 181 | ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt); |