aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-12-15 16:46:48 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-12-22 17:44:45 -0500
commit28bb7bc61a8cd48716d38d9c153fdc524f09870a (patch)
tree0ac6969dffbe5def2400fc18321789206711465a /arch
parent5b0d495c067d843c52fc1f9edbca29d5e9368b10 (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')
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/mach-mmp/time.c32
2 files changed, 12 insertions, 21 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 6f58bce687f3..0208e1e9ed79 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -513,6 +513,7 @@ config ARCH_MMP
513 select ARCH_REQUIRE_GPIOLIB 513 select ARCH_REQUIRE_GPIOLIB
514 select COMMON_CLKDEV 514 select COMMON_CLKDEV
515 select GENERIC_CLOCKEVENTS 515 select GENERIC_CLOCKEVENTS
516 select HAVE_SCHED_CLOCK
516 select TICK_ONESHOT 517 select TICK_ONESHOT
517 select PLAT_PXA 518 select PLAT_PXA
518 select SPARSE_IRQ 519 select SPARSE_IRQ
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 45static DEFINE_CLOCK_DATA(cd);
46
47static unsigned long tcr2ns_scale;
48
49static 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
78unsigned long long notrace sched_clock(void) 62unsigned 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
68static 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
84static irqreturn_t timer_interrupt(int irq, void *dev_id) 74static 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);