diff options
author | Nicolas Pitre <nico@cam.org> | 2006-12-04 20:25:47 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-12-07 16:06:50 +0000 |
commit | 2f1675c11a0a214855ff6cba23aca239eef7a5fb (patch) | |
tree | dd5b3d6dee3037023b0d3b832202433e8d87cfa2 | |
parent | 838ccbc35eae5b44d47724e5f694dbec4a26d269 (diff) | |
download | op-kernel-dev-2f1675c11a0a214855ff6cba23aca239eef7a5fb.zip op-kernel-dev-2f1675c11a0a214855ff6cba23aca239eef7a5fb.tar.gz |
[ARM] 3979/1: extend the SA11x0 sched_clock implementation from 32 to 63 bit period
This provides a 63 bit clock counter guaranteed to be monotonic over a
period of 370 days instead of a clock wrap every 19.4 minutes, as long
as sched_clock() is called at least once every 9.7 minutes which
shouldn't be a problem in practice.
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/mach-sa1100/generic.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 4575f31..e510295 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -20,6 +20,7 @@ #include <linux/platform_device.h> #include <asm/div64.h> +#include <asm/cnt32_to_63.h> #include <asm/hardware.h> #include <asm/system.h> #include <asm/pgtable.h> @@ -118,15 +119,21 @@ EXPORT_SYMBOL(cpufreq_get); /* * This is the SA11x0 sched_clock implementation. This has - * a resolution of 271ns, and a maximum value of 1165s. + * a resolution of 271ns, and a maximum value of 32025597s (370 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 this function. + * * ( * 1E9 / 3686400 => * 78125 / 288) */ unsigned long long sched_clock(void) { - unsigned long long v; + unsigned long long v = cnt32_to_63(OSCR); - v = (unsigned long long)OSCR * 78125; - do_div(v, 288); + /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */ + v *= 78125<<1; + do_div(v, 288<<1); return v; } |