summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@flint.arm.linux.org.uk>2003-08-05 01:15:49 +0100
committerRussell King <rmk@flint.arm.linux.org.uk>2003-08-05 01:15:49 +0100
commitb11c4177489d13071123b6df3f4bf794e4f4da08 (patch)
tree2573a2b2d8854e1b81c309cbf26b2da55fa841b1
parent6f461593c987f394be3a6fc6411cc4bc6b5c19df (diff)
[ARM] Fix do_settimeofday()
ARM seems to have missed an update for the time keeping code; this cset fixes a problem where the altering the system time changes the reported uptime.
-rw-r--r--arch/arm/kernel/time.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index ad9c47e9427e..8916a723d261 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -174,6 +174,9 @@ void do_gettimeofday(struct timeval *tv)
int do_settimeofday(struct timespec *tv)
{
+ time_t wtm_sec, sec = tv->tv_sec;
+ long wtm_nsec, nsec = tv->tv_nsec;
+
if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
return -EINVAL;
@@ -184,21 +187,21 @@ int do_settimeofday(struct timespec *tv)
* wall time. Discover what correction gettimeofday() would have
* done, and then undo it!
*/
- tv->tv_nsec -= 1000 * (gettimeoffset() +
- (jiffies - wall_jiffies) * USECS_PER_JIFFY);
+ nsec -= gettimeoffset() * NSEC_PER_USEC;
+ nsec -= (jiffies - wall_jiffies) * TICK_NSEC;
- while (tv->tv_nsec < 0) {
- tv->tv_nsec += NSEC_PER_SEC;
- tv->tv_sec--;
- }
+ wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
+ wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+
+ set_normalized_timespec(&xtime, sec, nsec);
+ set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
- xtime.tv_sec = tv->tv_sec;
- xtime.tv_nsec = tv->tv_nsec;
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
write_sequnlock_irq(&xtime_lock);
+ clock_was_set();
return 0;
}