diff options
| author | Nicolas Pitre <nico@cam.org> | 2006-12-04 14:29:21 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-12-07 11:06:53 -0500 |
| commit | 752bee178ee107aa3dd87a9aeba970444034c6fb (patch) | |
| tree | 7bc5f554781182c88602c2dd43ddd664a32aac24 | |
| parent | 2f1675c11a0a214855ff6cba23aca239eef7a5fb (diff) | |
[ARM] 3980/1: extend the ARM Versatile sched_clock implementation from 32 to 63 bit
period
This provides a 63 bit clock counter guaranteed to be monotonic over a
period of 35583 days instead of a clock wrap every 179 seconds, as long
as sched_clock() is called at least once every 89 seconds. This should
not be a problem in practice, although a kernel timer could be scheduled
every 80 seconds for example simply to call sched_clock() making sure
top bits are always synchronized if need be.
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-versatile/core.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 3b8576111c16..998b398df30e 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/amba/bus.h> | 27 | #include <linux/amba/bus.h> |
| 28 | #include <linux/amba/clcd.h> | 28 | #include <linux/amba/clcd.h> |
| 29 | 29 | ||
| 30 | #include <asm/cnt32_to_63.h> | ||
| 30 | #include <asm/system.h> | 31 | #include <asm/system.h> |
| 31 | #include <asm/hardware.h> | 32 | #include <asm/hardware.h> |
| 32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
| @@ -228,14 +229,19 @@ void __init versatile_map_io(void) | |||
| 228 | 229 | ||
| 229 | /* | 230 | /* |
| 230 | * This is the Versatile sched_clock implementation. This has | 231 | * This is the Versatile sched_clock implementation. This has |
| 231 | * a resolution of 41.7ns, and a maximum value of about 179s. | 232 | * a resolution of 41.7ns, and a maximum value of about 35583 days. |
| 233 | * | ||
| 234 | * The return value is guaranteed to be monotonic in that range as | ||
| 235 | * long as there is always less than 89 seconds between successive | ||
| 236 | * calls to this function. | ||
| 232 | */ | 237 | */ |
| 233 | unsigned long long sched_clock(void) | 238 | unsigned long long sched_clock(void) |
| 234 | { | 239 | { |
| 235 | unsigned long long v; | 240 | unsigned long long v = cnt32_to_63(readl(VERSATILE_REFCOUNTER)); |
| 236 | 241 | ||
| 237 | v = (unsigned long long)readl(VERSATILE_REFCOUNTER) * 125; | 242 | /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */ |
| 238 | do_div(v, 3); | 243 | v *= 125<<1; |
| 244 | do_div(v, 3<<1); | ||
| 239 | 245 | ||
| 240 | return v; | 246 | return v; |
| 241 | } | 247 | } |
