aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Miao <eric.miao@marvell.com>2008-12-17 22:10:32 -0500
committerEric Miao <eric.miao@marvell.com>2008-12-29 04:57:48 -0500
commit6769717d5d51596618f6b143008d8ace11ec8a69 (patch)
tree5f4b4b76211132d79e844314725ba4b9e459bc3c
parent9f1442bbf9fd68d8e190c91ab294131dd5c289ee (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.c16
-rw-r--r--arch/arm/mach-pxa/include/mach/hardware.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/timex.h8
-rw-r--r--arch/arm/mach-pxa/time.c10
-rw-r--r--arch/arm/mach-sa1100/include/mach/hardware.h4
-rw-r--r--drivers/rtc/rtc-sa1100.c12
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
43unsigned 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}
56EXPORT_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 */
292extern unsigned int get_memclk_frequency_10khz(void); 292extern unsigned int get_memclk_frequency_10khz(void);
293 293
294/* return the clock tick rate of the OS timer */
295extern 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
151static void __init pxa_timer_init(void) 150static 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
62static 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
45static unsigned long rtc_freq = 1024; 44static unsigned long rtc_freq = 1024;
45static unsigned long timer_freq;
46static struct rtc_time rtc_alarm; 46static struct rtc_time rtc_alarm;
47static DEFINE_SPINLOCK(sa1100_rtc_lock); 47static 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.