diff options
author | Eric Miao <eric.miao@marvell.com> | 2008-12-17 22:10:32 -0500 |
---|---|---|
committer | Eric Miao <eric.miao@marvell.com> | 2008-12-29 04:57:48 -0500 |
commit | 6769717d5d51596618f6b143008d8ace11ec8a69 (patch) | |
tree | 5f4b4b76211132d79e844314725ba4b9e459bc3c | |
parent | 9f1442bbf9fd68d8e190c91ab294131dd5c289ee (diff) |
[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>
-rw-r--r-- | arch/arm/mach-pxa/generic.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-pxa/include/mach/hardware.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-pxa/include/mach/timex.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-pxa/time.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/include/mach/hardware.h | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-sa1100.c | 12 |
6 files changed, 38 insertions, 14 deletions
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 85ed0b33331f..0ccc91c92c44 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/system.h> | 24 | #include <asm/system.h> |
25 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
26 | #include <asm/mach/map.h> | 26 | #include <asm/mach/map.h> |
27 | #include <asm/mach-types.h> | ||
27 | 28 | ||
28 | #include <mach/pxa-regs.h> | 29 | #include <mach/pxa-regs.h> |
29 | #include <mach/reset.h> | 30 | #include <mach/reset.h> |
@@ -39,6 +40,21 @@ void clear_reset_status(unsigned int mask) | |||
39 | pxa3xx_clear_reset_status(mask); | 40 | pxa3xx_clear_reset_status(mask); |
40 | } | 41 | } |
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); | ||
57 | |||
42 | /* | 58 | /* |
43 | * Get the clock frequency as reflected by CCCR and the turbo flag. | 59 | * Get the clock frequency as reflected by CCCR and the turbo flag. |
44 | * We assume these values have been applied via a fcs. | 60 | * We assume these values have been applied via a fcs. |
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h index e2d6784aa7ef..c666796911cb 100644 --- a/arch/arm/mach-pxa/include/mach/hardware.h +++ b/arch/arm/mach-pxa/include/mach/hardware.h | |||
@@ -291,6 +291,8 @@ | |||
291 | */ | 291 | */ |
292 | extern unsigned int get_memclk_frequency_10khz(void); | 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 | #endif | 296 | #endif |
295 | 297 | ||
296 | #if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) | 298 | #if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) |
diff --git a/arch/arm/mach-pxa/include/mach/timex.h b/arch/arm/mach-pxa/include/mach/timex.h index b05fc6683c47..af6760a50e1a 100644 --- a/arch/arm/mach-pxa/include/mach/timex.h +++ b/arch/arm/mach-pxa/include/mach/timex.h | |||
@@ -10,6 +10,14 @@ | |||
10 | * published by the Free Software Foundation. | 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 | #if defined(CONFIG_PXA25x) | 22 | #if defined(CONFIG_PXA25x) |
15 | /* PXA250/210 timer base */ | 23 | /* PXA250/210 timer base */ |
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index f8a9a62959e5..986d494a1834 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <asm/mach/irq.h> | 23 | #include <asm/mach/irq.h> |
24 | #include <asm/mach/time.h> | 24 | #include <asm/mach/time.h> |
25 | #include <mach/pxa-regs.h> | 25 | #include <mach/pxa-regs.h> |
26 | #include <asm/mach-types.h> | ||
27 | 26 | ||
28 | /* | 27 | /* |
29 | * This is PXA's sched_clock implementation. This has a resolution | 28 | * This is PXA's sched_clock implementation. This has a resolution |
@@ -150,18 +149,11 @@ static struct irqaction pxa_ost0_irq = { | |||
150 | 149 | ||
151 | static void __init pxa_timer_init(void) | 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 | OIER = 0; | 154 | OIER = 0; |
156 | OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; | 155 | OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; |
157 | 156 | ||
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 | |||
165 | set_oscr2ns_scale(clock_tick_rate); | 157 | set_oscr2ns_scale(clock_tick_rate); |
166 | 158 | ||
167 | ckevt_pxa_osmr0.mult = | 159 | ckevt_pxa_osmr0.mult = |
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h index b70846c096aa..60711822b125 100644 --- a/arch/arm/mach-sa1100/include/mach/hardware.h +++ b/arch/arm/mach-sa1100/include/mach/hardware.h | |||
@@ -59,6 +59,10 @@ | |||
59 | # define __REG(x) (*((volatile unsigned long *)io_p2v(x))) | 59 | # define __REG(x) (*((volatile unsigned long *)io_p2v(x))) |
60 | # define __PREG(x) (io_v2p((unsigned long)&(x))) | 60 | # define __PREG(x) (io_v2p((unsigned long)&(x))) |
61 | 61 | ||
62 | static inline unsigned long get_clock_tick_rate(void) | ||
63 | { | ||
64 | return 3686400; | ||
65 | } | ||
62 | #else | 66 | #else |
63 | 67 | ||
64 | # define __REG(x) io_p2v(x) | 68 | # define __REG(x) io_p2v(x) |
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 66a9bb85bbe8..d26a5f82aaba 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -38,11 +38,11 @@ | |||
38 | #include <mach/pxa-regs.h> | 38 | #include <mach/pxa-regs.h> |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #define TIMER_FREQ CLOCK_TICK_RATE | ||
42 | #define RTC_DEF_DIVIDER 32768 - 1 | 41 | #define RTC_DEF_DIVIDER 32768 - 1 |
43 | #define RTC_DEF_TRIM 0 | 42 | #define RTC_DEF_TRIM 0 |
44 | 43 | ||
45 | static unsigned long rtc_freq = 1024; | 44 | static unsigned long rtc_freq = 1024; |
45 | static unsigned long timer_freq; | ||
46 | static struct rtc_time rtc_alarm; | 46 | static struct rtc_time rtc_alarm; |
47 | static DEFINE_SPINLOCK(sa1100_rtc_lock); | 47 | static DEFINE_SPINLOCK(sa1100_rtc_lock); |
48 | 48 | ||
@@ -157,7 +157,7 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id) | |||
157 | rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); | 157 | rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); |
158 | 158 | ||
159 | if (rtc_timer1_count == 1) | 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 | return IRQ_HANDLED; | 162 | return IRQ_HANDLED; |
163 | } | 163 | } |
@@ -166,7 +166,7 @@ static int sa1100_rtc_read_callback(struct device *dev, int data) | |||
166 | { | 166 | { |
167 | if (data & RTC_PF) { | 167 | if (data & RTC_PF) { |
168 | /* interpolate missed periods and set match for the next */ | 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 | unsigned long oscr = OSCR; | 170 | unsigned long oscr = OSCR; |
171 | unsigned long osmr1 = OSMR1; | 171 | unsigned long osmr1 = OSMR1; |
172 | unsigned long missed = (oscr - osmr1)/period; | 172 | unsigned long missed = (oscr - osmr1)/period; |
@@ -263,7 +263,7 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
263 | return 0; | 263 | return 0; |
264 | case RTC_PIE_ON: | 264 | case RTC_PIE_ON: |
265 | spin_lock_irq(&sa1100_rtc_lock); | 265 | spin_lock_irq(&sa1100_rtc_lock); |
266 | OSMR1 = TIMER_FREQ/rtc_freq + OSCR; | 266 | OSMR1 = timer_freq / rtc_freq + OSCR; |
267 | OIER |= OIER_E1; | 267 | OIER |= OIER_E1; |
268 | rtc_timer1_count = 1; | 268 | rtc_timer1_count = 1; |
269 | spin_unlock_irq(&sa1100_rtc_lock); | 269 | spin_unlock_irq(&sa1100_rtc_lock); |
@@ -271,7 +271,7 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
271 | case RTC_IRQP_READ: | 271 | case RTC_IRQP_READ: |
272 | return put_user(rtc_freq, (unsigned long *)arg); | 272 | return put_user(rtc_freq, (unsigned long *)arg); |
273 | case RTC_IRQP_SET: | 273 | case RTC_IRQP_SET: |
274 | if (arg < 1 || arg > TIMER_FREQ) | 274 | if (arg < 1 || arg > timer_freq) |
275 | return -EINVAL; | 275 | return -EINVAL; |
276 | rtc_freq = arg; | 276 | rtc_freq = arg; |
277 | return 0; | 277 | return 0; |
@@ -352,6 +352,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
352 | { | 352 | { |
353 | struct rtc_device *rtc; | 353 | struct rtc_device *rtc; |
354 | 354 | ||
355 | timer_freq = get_clock_tick_rate(); | ||
356 | |||
355 | /* | 357 | /* |
356 | * According to the manual we should be able to let RTTR be zero | 358 | * According to the manual we should be able to let RTTR be zero |
357 | * and then a default diviser for a 32.768KHz clock is used. | 359 | * and then a default diviser for a 32.768KHz clock is used. |