aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-01-09 05:09:06 -0800
committerDavid S. Miller <davem@davemloft.net>2008-01-12 21:52:15 -0800
commit000775c50a19fa899121115f57f355c7f26e4346 (patch)
tree52692a18ac958a419e8765b9e150786433c58c11 /arch
parentMerge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb (diff)
downloadlinux-dev-000775c50a19fa899121115f57f355c7f26e4346.tar.xz
linux-dev-000775c50a19fa899121115f57f355c7f26e4346.zip
[SPARC]: Make gettimeofday() monotonic again.
When we switched away from the optimized C version things stopped being monotonic. The problem is that if we run this with interrupts disabled, we can see the interrupt pending because the counter reached the limit value. When this happens the counter has bit 31 set, and the low bits start counting again from zero. Reported by Martin Habets. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/kernel/time.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 45cb7c5286d7..00b393c3a4a0 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -436,7 +436,14 @@ void __init time_init(void)
static inline unsigned long do_gettimeoffset(void)
{
- return (*master_l10_counter >> 10) & 0x1fffff;
+ unsigned long val = *master_l10_counter;
+ unsigned long usec = (val >> 10) & 0x1fffff;
+
+ /* Limit hit? */
+ if (val & 0x80000000)
+ usec += 1000000 / HZ;
+
+ return usec;
}
/* Ok, my cute asm atomicity trick doesn't work anymore.