summaryrefslogtreecommitdiffstats
path: root/arch/mips64/sgi-ip27/ip27-timer.c
diff options
context:
space:
mode:
authorUlf Carlsson <md1ulfc@mdstud.chalmers.se>2000-05-19 02:00:00 +0000
committerUlf Carlsson <md1ulfc@mdstud.chalmers.se>2000-05-19 02:00:00 +0000
commitac599b8199968fd92e0d986f8cfdebb535b8887c (patch)
treec96965ce352f8e7e7877e35a829e31bba3960d5e /arch/mips64/sgi-ip27/ip27-timer.c
parentff456a3329ebcf2c630b08a3c1da166f4950da08 (diff)
ip27-timer.c: Use the realtime clock for do_gettimeofday and do_settimeofday
to get microsecond precision.
Diffstat (limited to 'arch/mips64/sgi-ip27/ip27-timer.c')
-rw-r--r--arch/mips64/sgi-ip27/ip27-timer.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c
index d5a1ed058..eb6a1bb37 100644
--- a/arch/mips64/sgi-ip27/ip27-timer.c
+++ b/arch/mips64/sgi-ip27/ip27-timer.c
@@ -39,6 +39,7 @@ static unsigned long ct_cur; /* What counter should be at next timer irq */
static long last_rtc_update = 0; /* Last time the rtc clock got updated */
extern rwlock_t xtime_lock;
+extern volatile unsigned long lost_ticks;
static int set_rtc_mmss(unsigned long nowtime)
@@ -158,19 +159,50 @@ again:
write_unlock(&xtime_lock);
}
+unsigned long inline do_gettimeoffset(void)
+{
+ unsigned long ct_cur1 = LOCAL_HUB_L(PI_RT_COUNT) + CYCLES_PER_JIFFY;
+ return (ct_cur1 - ct_cur) * NSEC_PER_CYCLE / 1000;
+}
+
void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
+ unsigned long usec, sec;
read_lock_irqsave(&xtime_lock, flags);
- *tv = xtime;
+ usec = do_gettimeoffset();
+ {
+ unsigned long lost = lost_ticks;
+ if (lost)
+ usec += lost * (1000000 / HZ);
+ }
+ sec = xtime.tv_sec;
+ usec += xtime.tv_usec;
read_unlock_irqrestore(&xtime_lock, flags);
+
+ while (usec >= 1000000) {
+ usec -= 1000000;
+ sec++;
+ }
+
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
}
void do_settimeofday(struct timeval *tv)
{
write_lock_irq(&xtime_lock);
+ tv->tv_usec -= do_gettimeoffset();
+ tv->tv_usec -= lost_ticks * (1000000 / HZ);
+
+ while (tv->tv_usec < 0) {
+ tv->tv_usec += 1000000;
+ tv->tv_sec--;
+ }
+
xtime = *tv;
+ time_adjust = 0; /* stop active adjtime() */
time_state = TIME_BAD;
time_maxerror = MAXPHASE;
time_esterror = MAXPHASE;