diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-08 00:40:39 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-08 00:40:39 +0100 |
commit | ea14fad0d416354a4e9bb1a04f32acba706f9548 (patch) | |
tree | 2c8acc5331f189aef1d40ddce3f40d6be9314e77 /arch/arm/mach-pxa/generic.c | |
parent | Merge branch 'release' of master.kernel.org:/pub/scm/linux/kernel/git/aegl/li... (diff) | |
parent | [ARM] Merge individual ARM sub-trees (diff) | |
download | linux-ea14fad0d416354a4e9bb1a04f32acba706f9548.tar.xz linux-ea14fad0d416354a4e9bb1a04f32acba706f9548.zip |
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (76 commits)
[ARM] 4002/1: S3C24XX: leave parent IRQs unmasked
[ARM] 4001/1: S3C24XX: shorten reboot time
[ARM] 3983/2: remove unused argument to __bug()
[ARM] 4000/1: Osiris: add third serial port in
[ARM] 3999/1: RX3715: suspend to RAM support
[ARM] 3998/1: VR1000: LED platform devices
[ARM] 3995/1: iop13xx: add iop13xx support
[ARM] 3968/1: iop13xx: add iop13xx_defconfig
[ARM] Update mach-types
[ARM] Allow gcc to optimise arm_add_memory a little more
[ARM] 3991/1: i.MX/MX1 high resolution time source
[ARM] 3990/1: i.MX/MX1 more precise PLL decode
[ARM] 3986/1: H1940: suspend to RAM support
[ARM] 3985/1: ixp4xx clocksource cleanup
[ARM] 3984/1: ixp4xx/nslu2: Fix disk LED numbering (take 2)
[ARM] 3994/1: ixp23xx: fix handling of pci master aborts
[ARM] 3981/1: sched_clock for PXA2xx
[ARM] 3980/1: extend the ARM Versatile sched_clock implementation from 32 to 63 bit
[ARM] 3979/1: extend the SA11x0 sched_clock implementation from 32 to 63 bit period
[ARM] 3978/1: macro to provide a 63-bit value from a 32-bit hardware counter
...
Diffstat (limited to 'arch/arm/mach-pxa/generic.c')
-rw-r--r-- | arch/arm/mach-pxa/generic.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 45fb2c3bcf82..6ae605857ca9 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -25,6 +25,10 @@ #include <linux/pm.h> #include <linux/string.h> +#include <linux/sched.h> +#include <asm/cnt32_to_63.h> +#include <asm/div64.h> + #include <asm/hardware.h> #include <asm/irq.h> #include <asm/system.h> @@ -41,6 +45,62 @@ #include "generic.h" /* + * This is the PXA2xx sched_clock implementation. This has a resolution + * of at least 308ns and a maximum value that depends on the value of + * CLOCK_TICK_RATE. + * + * 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 this function. + */ +unsigned long long sched_clock(void) +{ + unsigned long long v = cnt32_to_63(OSCR); + /* Note: top bit ov v needs cleared unless multiplier is even. */ + +#if CLOCK_TICK_RATE == 3686400 + /* 1E9 / 3686400 => 78125 / 288, max value = 32025597s (370 days). */ + /* The <<1 is used to get rid of tick.hi top bit */ + v *= 78125<<1; + do_div(v, 288<<1); +#elif CLOCK_TICK_RATE == 3250000 + /* 1E9 / 3250000 => 4000 / 13, max value = 709490156s (8211 days) */ + v *= 4000; + do_div(v, 13); +#elif CLOCK_TICK_RATE == 3249600 + /* 1E9 / 3249600 => 625000 / 2031, max value = 4541295s (52 days) */ + v *= 625000; + do_div(v, 2031); +#else +#warning "consider fixing sched_clock for your value of CLOCK_TICK_RATE" + /* + * 96-bit math to perform tick * NSEC_PER_SEC / CLOCK_TICK_RATE for + * any value of CLOCK_TICK_RATE. Max value is in the 80 thousand + * years range which is nice, but with higher computation cost. + */ + { + union { + unsigned long long val; + struct { unsigned long lo, hi; }; + } x; + unsigned long long y; + + x.val = v; + x.hi &= 0x7fffffff; + y = (unsigned long long)x.lo * NSEC_PER_SEC; + x.lo = y; + y = (y >> 32) + (unsigned long long)x.hi * NSEC_PER_SEC; + x.hi = do_div(y, CLOCK_TICK_RATE); + do_div(x.val, CLOCK_TICK_RATE); + x.hi += y; + v = x.val; + } +#endif + + return v; +} + +/* * Handy function to set GPIO alternate functions */ |