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 @@ #include #include #include +#include #include #include @@ -39,6 +40,21 @@ void clear_reset_status(unsigned int mask) pxa3xx_clear_reset_status(mask); } +unsigned long get_clock_tick_rate(void) +{ + unsigned long clock_tick_rate; + + if (cpu_is_pxa25x()) + clock_tick_rate = 3686400; + else if (machine_is_mainstone()) + clock_tick_rate = 3249600; + else + clock_tick_rate = 3250000; + + return clock_tick_rate; +} +EXPORT_SYMBOL(get_clock_tick_rate); + /* * Get the clock frequency as reflected by CCCR and the turbo flag. * 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 @@ */ extern unsigned int get_memclk_frequency_10khz(void); +/* return the clock tick rate of the OS timer */ +extern unsigned long get_clock_tick_rate(void); #endif #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 @@ * published by the Free Software Foundation. */ +/* Various drivers are still using the constant of CLOCK_TICK_RATE, for + * those drivers to at least work, the definition is provided here. + * + * NOTE: this is no longer accurate when multiple processors and boards + * are selected, newer drivers should not depend on this any more. Use + * either the clocksource/clockevent or get this at run-time by calling + * get_clock_tick_rate() (as defined in generic.c). + */ #if defined(CONFIG_PXA25x) /* 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 @@ #include #include #include -#include /* * This is PXA's sched_clock implementation. This has a resolution @@ -150,18 +149,11 @@ static struct irqaction pxa_ost0_irq = { static void __init pxa_timer_init(void) { - unsigned long clock_tick_rate; + unsigned long clock_tick_rate = get_clock_tick_rate(); OIER = 0; OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; - if (cpu_is_pxa25x()) - clock_tick_rate = 3686400; - else if (machine_is_mainstone()) - clock_tick_rate = 3249600; - else - clock_tick_rate = 3250000; - set_oscr2ns_scale(clock_tick_rate); 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 @@ # define __REG(x) (*((volatile unsigned long *)io_p2v(x))) # define __PREG(x) (io_v2p((unsigned long)&(x))) +static inline unsigned long get_clock_tick_rate(void) +{ + return 3686400; +} #else # 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 @@ #include #endif -#define TIMER_FREQ CLOCK_TICK_RATE #define RTC_DEF_DIVIDER 32768 - 1 #define RTC_DEF_TRIM 0 static unsigned long rtc_freq = 1024; +static unsigned long timer_freq; static struct rtc_time rtc_alarm; static DEFINE_SPINLOCK(sa1100_rtc_lock); @@ -157,7 +157,7 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id) rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); if (rtc_timer1_count == 1) - rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))); + rtc_timer1_count = (rtc_freq * ((1 << 30) / (timer_freq >> 2))); return IRQ_HANDLED; } @@ -166,7 +166,7 @@ static int sa1100_rtc_read_callback(struct device *dev, int data) { if (data & RTC_PF) { /* interpolate missed periods and set match for the next */ - unsigned long period = TIMER_FREQ/rtc_freq; + unsigned long period = timer_freq / rtc_freq; unsigned long oscr = OSCR; unsigned long osmr1 = OSMR1; unsigned long missed = (oscr - osmr1)/period; @@ -263,7 +263,7 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, return 0; case RTC_PIE_ON: spin_lock_irq(&sa1100_rtc_lock); - OSMR1 = TIMER_FREQ/rtc_freq + OSCR; + OSMR1 = timer_freq / rtc_freq + OSCR; OIER |= OIER_E1; rtc_timer1_count = 1; spin_unlock_irq(&sa1100_rtc_lock); @@ -271,7 +271,7 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, case RTC_IRQP_READ: return put_user(rtc_freq, (unsigned long *)arg); case RTC_IRQP_SET: - if (arg < 1 || arg > TIMER_FREQ) + if (arg < 1 || arg > timer_freq) return -EINVAL; rtc_freq = arg; return 0; @@ -352,6 +352,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; + timer_freq = get_clock_tick_rate(); + /* * According to the manual we should be able to let RTTR be zero * and then a default diviser for a 32.768KHz clock is used.