Commit 6769717d5d51596618f6b143008d8ace11ec8a69
1 parent
9f1442bbf9
Exists in
master
and in
7 other branches
[ARM] rtc-sa1100: don't assume CLOCK_TICK_RATE to be a constant
As Nicolas and Russell pointed out, CLOCK_TICK_RATE is no more a constant on PXA when multiple processors and platforms are selected, change TIMER_FREQ in rtc-sa1100.c into a variable. Since the code to decide the clock tick rate is re-used from timer.c, introduce a common get_clock_tick_rate() for this. Signed-off-by: Eric Miao <eric.miao@marvell.com> Acked-by: Nicolas Pitre <nico@marvell.com>
Showing 6 changed files with 38 additions and 14 deletions Side-by-side Diff
arch/arm/mach-pxa/generic.c
... | ... | @@ -24,6 +24,7 @@ |
24 | 24 | #include <asm/system.h> |
25 | 25 | #include <asm/pgtable.h> |
26 | 26 | #include <asm/mach/map.h> |
27 | +#include <asm/mach-types.h> | |
27 | 28 | |
28 | 29 | #include <mach/pxa-regs.h> |
29 | 30 | #include <mach/reset.h> |
... | ... | @@ -38,6 +39,21 @@ |
38 | 39 | if (cpu_is_pxa3xx()) |
39 | 40 | pxa3xx_clear_reset_status(mask); |
40 | 41 | } |
42 | + | |
43 | +unsigned long get_clock_tick_rate(void) | |
44 | +{ | |
45 | + unsigned long clock_tick_rate; | |
46 | + | |
47 | + if (cpu_is_pxa25x()) | |
48 | + clock_tick_rate = 3686400; | |
49 | + else if (machine_is_mainstone()) | |
50 | + clock_tick_rate = 3249600; | |
51 | + else | |
52 | + clock_tick_rate = 3250000; | |
53 | + | |
54 | + return clock_tick_rate; | |
55 | +} | |
56 | +EXPORT_SYMBOL(get_clock_tick_rate); | |
41 | 57 | |
42 | 58 | /* |
43 | 59 | * Get the clock frequency as reflected by CCCR and the turbo flag. |
arch/arm/mach-pxa/include/mach/hardware.h
... | ... | @@ -291,6 +291,8 @@ |
291 | 291 | */ |
292 | 292 | extern unsigned int get_memclk_frequency_10khz(void); |
293 | 293 | |
294 | +/* return the clock tick rate of the OS timer */ | |
295 | +extern unsigned long get_clock_tick_rate(void); | |
294 | 296 | #endif |
295 | 297 | |
296 | 298 | #if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) |
arch/arm/mach-pxa/include/mach/timex.h
... | ... | @@ -10,6 +10,14 @@ |
10 | 10 | * published by the Free Software Foundation. |
11 | 11 | */ |
12 | 12 | |
13 | +/* Various drivers are still using the constant of CLOCK_TICK_RATE, for | |
14 | + * those drivers to at least work, the definition is provided here. | |
15 | + * | |
16 | + * NOTE: this is no longer accurate when multiple processors and boards | |
17 | + * are selected, newer drivers should not depend on this any more. Use | |
18 | + * either the clocksource/clockevent or get this at run-time by calling | |
19 | + * get_clock_tick_rate() (as defined in generic.c). | |
20 | + */ | |
13 | 21 | |
14 | 22 | #if defined(CONFIG_PXA25x) |
15 | 23 | /* PXA250/210 timer base */ |
arch/arm/mach-pxa/time.c
... | ... | @@ -23,7 +23,6 @@ |
23 | 23 | #include <asm/mach/irq.h> |
24 | 24 | #include <asm/mach/time.h> |
25 | 25 | #include <mach/pxa-regs.h> |
26 | -#include <asm/mach-types.h> | |
27 | 26 | |
28 | 27 | /* |
29 | 28 | * This is PXA's sched_clock implementation. This has a resolution |
30 | 29 | |
... | ... | @@ -150,17 +149,10 @@ |
150 | 149 | |
151 | 150 | static void __init pxa_timer_init(void) |
152 | 151 | { |
153 | - unsigned long clock_tick_rate; | |
152 | + unsigned long clock_tick_rate = get_clock_tick_rate(); | |
154 | 153 | |
155 | 154 | OIER = 0; |
156 | 155 | OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; |
157 | - | |
158 | - if (cpu_is_pxa25x()) | |
159 | - clock_tick_rate = 3686400; | |
160 | - else if (machine_is_mainstone()) | |
161 | - clock_tick_rate = 3249600; | |
162 | - else | |
163 | - clock_tick_rate = 3250000; | |
164 | 156 | |
165 | 157 | set_oscr2ns_scale(clock_tick_rate); |
166 | 158 |
arch/arm/mach-sa1100/include/mach/hardware.h
drivers/rtc/rtc-sa1100.c
... | ... | @@ -38,11 +38,11 @@ |
38 | 38 | #include <mach/pxa-regs.h> |
39 | 39 | #endif |
40 | 40 | |
41 | -#define TIMER_FREQ CLOCK_TICK_RATE | |
42 | 41 | #define RTC_DEF_DIVIDER 32768 - 1 |
43 | 42 | #define RTC_DEF_TRIM 0 |
44 | 43 | |
45 | 44 | static unsigned long rtc_freq = 1024; |
45 | +static unsigned long timer_freq; | |
46 | 46 | static struct rtc_time rtc_alarm; |
47 | 47 | static DEFINE_SPINLOCK(sa1100_rtc_lock); |
48 | 48 | |
... | ... | @@ -157,7 +157,7 @@ |
157 | 157 | rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); |
158 | 158 | |
159 | 159 | if (rtc_timer1_count == 1) |
160 | - rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))); | |
160 | + rtc_timer1_count = (rtc_freq * ((1 << 30) / (timer_freq >> 2))); | |
161 | 161 | |
162 | 162 | return IRQ_HANDLED; |
163 | 163 | } |
... | ... | @@ -166,7 +166,7 @@ |
166 | 166 | { |
167 | 167 | if (data & RTC_PF) { |
168 | 168 | /* interpolate missed periods and set match for the next */ |
169 | - unsigned long period = TIMER_FREQ/rtc_freq; | |
169 | + unsigned long period = timer_freq / rtc_freq; | |
170 | 170 | unsigned long oscr = OSCR; |
171 | 171 | unsigned long osmr1 = OSMR1; |
172 | 172 | unsigned long missed = (oscr - osmr1)/period; |
... | ... | @@ -263,7 +263,7 @@ |
263 | 263 | return 0; |
264 | 264 | case RTC_PIE_ON: |
265 | 265 | spin_lock_irq(&sa1100_rtc_lock); |
266 | - OSMR1 = TIMER_FREQ/rtc_freq + OSCR; | |
266 | + OSMR1 = timer_freq / rtc_freq + OSCR; | |
267 | 267 | OIER |= OIER_E1; |
268 | 268 | rtc_timer1_count = 1; |
269 | 269 | spin_unlock_irq(&sa1100_rtc_lock); |
... | ... | @@ -271,7 +271,7 @@ |
271 | 271 | case RTC_IRQP_READ: |
272 | 272 | return put_user(rtc_freq, (unsigned long *)arg); |
273 | 273 | case RTC_IRQP_SET: |
274 | - if (arg < 1 || arg > TIMER_FREQ) | |
274 | + if (arg < 1 || arg > timer_freq) | |
275 | 275 | return -EINVAL; |
276 | 276 | rtc_freq = arg; |
277 | 277 | return 0; |
... | ... | @@ -351,6 +351,8 @@ |
351 | 351 | static int sa1100_rtc_probe(struct platform_device *pdev) |
352 | 352 | { |
353 | 353 | struct rtc_device *rtc; |
354 | + | |
355 | + timer_freq = get_clock_tick_rate(); | |
354 | 356 | |
355 | 357 | /* |
356 | 358 | * According to the manual we should be able to let RTTR be zero |