ntp: Add ADJ_SETOFFSET mode bit
authorRichard Cochran <richardcochran@gmail.com>
Tue, 1 Feb 2011 13:52:20 +0000 (13:52 +0000)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 2 Feb 2011 14:28:18 +0000 (15:28 +0100)
This patch adds a new mode bit into the timex structure. When set, the bit
instructs the kernel to add the given time value to the current time.

Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
Acked-by: John Stultz <johnstul@us.ibm.com>
LKML-Reference: <20110201134320.688829863@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
include/linux/timex.h
kernel/time/ntp.c

index d23999f9499d3798a8d5776da0cab3c7bc0e18df..aa60fe7b6ed646f623253c24403e233654d71025 100644 (file)
@@ -73,7 +73,7 @@ struct timex {
        long tolerance;         /* clock frequency tolerance (ppm)
                                 * (read only)
                                 */
-       struct timeval time;    /* (read only) */
+       struct timeval time;    /* (read only, except for ADJ_SETOFFSET) */
        long tick;              /* (modified) usecs between clock ticks */
 
        long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
@@ -102,6 +102,7 @@ struct timex {
 #define ADJ_STATUS             0x0010  /* clock status */
 #define ADJ_TIMECONST          0x0020  /* pll time constant */
 #define ADJ_TAI                        0x0080  /* set TAI offset */
+#define ADJ_SETOFFSET          0x0100  /* add 'time' to current time */
 #define ADJ_MICRO              0x1000  /* select microsecond resolution */
 #define ADJ_NANO               0x2000  /* select nanosecond resolution */
 #define ADJ_TICK               0x4000  /* tick value */
index ed8cfdf16983fce8ad31bbd10ae59c036d8c5204..5ac593267a26aa5ef4d2309c18908453a61133d4 100644 (file)
@@ -648,6 +648,17 @@ int do_adjtimex(struct timex *txc)
                        hrtimer_cancel(&leap_timer);
        }
 
+       if (txc->modes & ADJ_SETOFFSET) {
+               struct timespec delta;
+               if ((unsigned long)txc->time.tv_usec >= NSEC_PER_SEC)
+                       return -EINVAL;
+               delta.tv_sec  = txc->time.tv_sec;
+               delta.tv_nsec = txc->time.tv_usec;
+               if (!(txc->modes & ADJ_NANO))
+                       delta.tv_nsec *= 1000;
+               timekeeping_inject_offset(&delta);
+       }
+
        getnstimeofday(&ts);
 
        write_seqlock_irq(&xtime_lock);