diff options
Diffstat (limited to 'arch/arm/mach-mmp')
-rw-r--r-- | arch/arm/mach-mmp/clock.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-mmp/time.c | 39 |
2 files changed, 14 insertions, 27 deletions
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h index 016ae94691c..9b027d7491f 100644 --- a/arch/arm/mach-mmp/clock.h +++ b/arch/arm/mach-mmp/clock.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <asm/clkdev.h> | 9 | #include <linux/clkdev.h> |
10 | 10 | ||
11 | struct clkops { | 11 | struct clkops { |
12 | void (*enable)(struct clk *); | 12 | void (*enable)(struct clk *); |
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index 66528193f93..aeb9ae23e6c 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 |
@@ -75,10 +59,16 @@ static inline uint32_t timer_read(void) | |||
75 | return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0)); | 59 | return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0)); |
76 | } | 60 | } |
77 | 61 | ||
78 | unsigned long long 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) |
@@ -146,7 +136,6 @@ static cycle_t clksrc_read(struct clocksource *cs) | |||
146 | 136 | ||
147 | static struct clocksource cksrc = { | 137 | static struct clocksource cksrc = { |
148 | .name = "clocksource", | 138 | .name = "clocksource", |
149 | .shift = 20, | ||
150 | .rating = 200, | 139 | .rating = 200, |
151 | .read = clksrc_read, | 140 | .read = clksrc_read, |
152 | .mask = CLOCKSOURCE_MASK(32), | 141 | .mask = CLOCKSOURCE_MASK(32), |
@@ -186,17 +175,15 @@ void __init timer_init(int irq) | |||
186 | { | 175 | { |
187 | timer_config(); | 176 | timer_config(); |
188 | 177 | ||
189 | set_tcr2ns_scale(CLOCK_TICK_RATE); | 178 | init_sched_clock(&cd, mmp_update_sched_clock, 32, CLOCK_TICK_RATE); |
190 | 179 | ||
191 | 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); |
192 | ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt); | 181 | ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt); |
193 | ckevt.min_delta_ns = clockevent_delta2ns(MIN_DELTA, &ckevt); | 182 | ckevt.min_delta_ns = clockevent_delta2ns(MIN_DELTA, &ckevt); |
194 | ckevt.cpumask = cpumask_of(0); | 183 | ckevt.cpumask = cpumask_of(0); |
195 | 184 | ||
196 | cksrc.mult = clocksource_hz2mult(CLOCK_TICK_RATE, cksrc.shift); | ||
197 | |||
198 | setup_irq(irq, &timer_irq); | 185 | setup_irq(irq, &timer_irq); |
199 | 186 | ||
200 | clocksource_register(&cksrc); | 187 | clocksource_register_hz(&cksrc, CLOCK_TICK_RATE); |
201 | clockevents_register_device(&ckevt); | 188 | clockevents_register_device(&ckevt); |
202 | } | 189 | } |