diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 16:08:50 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 16:08:50 -0700 |
commit | 65a6ec0d72a07f16719e9b7a96e1c4bae044b591 (patch) | |
tree | 344e03a5039a44982c1b78d6113633b21b434820 /arch/arm/mach-pxa/time.c | |
parent | 541010e4b8921cd781ff02ae68028501457045b6 (diff) | |
parent | 0181b61a988424b5cc44fe09e6968142359c815e (diff) |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (95 commits)
[ARM] 4578/1: CM-x270: PCMCIA support
[ARM] 4577/1: ITE 8152 PCI bridge support
[ARM] 4576/1: CM-X270 machine support
[ARM] pxa: Avoid pxa_gpio_mode() in gpio_direction_{in,out}put()
[ARM] pxa: move pxa_set_mode() from pxa2xx_mainstone.c to mainstone.c
[ARM] pxa: move pxa_set_mode() from pxa2xx_lubbock.c to lubbock.c
[ARM] pxa: Make cpu_is_pxaXXX dependent on configuration symbols
[ARM] pxa: PXA3xx base support
[NET] smc91x: fix PXA DMA support code
[SERIAL] Fix console initialisation ordering
[ARM] pxa: tidy up arch/arm/mach-pxa/Makefile
[ARM] Update arch/arm/Kconfig for drivers/Kconfig changes
[ARM] 4600/1: fix kernel build failure with build-id-supporting binutils
[ARM] 4599/1: Preserve ATAG list for use with kexec (2.6.23)
[ARM] Rename consistent_sync() as dma_cache_maint()
[ARM] 4572/1: ep93xx: add cirrus logic edb9307 support
[ARM] 4596/1: S3C2412: Correct IRQs for SDI+CF and add decoding support
[ARM] 4595/1: ns9xxx: define registers as void __iomem * instead of volatile u32
[ARM] 4594/1: ns9xxx: use the new gpio functions
[ARM] 4593/1: ns9xxx: implement generic clockevents
...
Diffstat (limited to 'arch/arm/mach-pxa/time.c')
-rw-r--r-- | arch/arm/mach-pxa/time.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 98d27e646b0..ec4286c7931 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -16,10 +16,48 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/clockchips.h> +#include <linux/sched.h> +#include <asm/div64.h> +#include <asm/cnt32_to_63.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> #include <asm/arch/pxa-regs.h> +#include <asm/mach-types.h> + +/* + * This is PXA's sched_clock implementation. This has a resolution + * of at least 308 ns and a maximum value of 208 days. + * + * The return value is guaranteed to be monotonic in that range as + * long as there is always less than 582 seconds between successive + * calls to sched_clock() which should always be the case in practice. + */ + +#define OSCR2NS_SCALE_FACTOR 10 + +static unsigned long oscr2ns_scale; + +static void __init set_oscr2ns_scale(unsigned long oscr_rate) +{ + unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR; + do_div(v, oscr_rate); + oscr2ns_scale = v; + /* + * We want an even value to automatically clear the top bit + * returned by cnt32_to_63() without an additional run time + * instruction. So if the LSB is 1 then round it up. + */ + if (oscr2ns_scale & 1) + oscr2ns_scale++; +} + +unsigned long long sched_clock(void) +{ + unsigned long long v = cnt32_to_63(OSCR); + return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR; +} + static irqreturn_t pxa_ost0_interrupt(int irq, void *dev_id) @@ -149,18 +187,29 @@ static struct irqaction pxa_ost0_irq = { static void __init pxa_timer_init(void) { + unsigned long clock_tick_rate; + OIER = 0; OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; + if (cpu_is_pxa21x() || 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 = - div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); + div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); ckevt_pxa_osmr0.max_delta_ns = clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); ckevt_pxa_osmr0.min_delta_ns = clockevent_delta2ns(MIN_OSCR_DELTA, &ckevt_pxa_osmr0) + 1; cksrc_pxa_oscr0.mult = - clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_pxa_oscr0.shift); + clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift); setup_irq(IRQ_OST0, &pxa_ost0_irq); |