|
@@ -53,9 +53,6 @@ static int time_state = TIME_OK;
|
|
|
/* clock status bits: */
|
|
|
static int time_status = STA_UNSYNC;
|
|
|
|
|
|
-/* TAI offset (secs): */
|
|
|
-static long time_tai;
|
|
|
-
|
|
|
/* time adjustment (nsecs): */
|
|
|
static s64 time_offset;
|
|
|
|
|
@@ -415,7 +412,6 @@ int second_overflow(unsigned long secs)
|
|
|
else if (secs % 86400 == 0) {
|
|
|
leap = -1;
|
|
|
time_state = TIME_OOP;
|
|
|
- time_tai++;
|
|
|
printk(KERN_NOTICE
|
|
|
"Clock: inserting leap second 23:59:60 UTC\n");
|
|
|
}
|
|
@@ -425,7 +421,6 @@ int second_overflow(unsigned long secs)
|
|
|
time_state = TIME_OK;
|
|
|
else if ((secs + 1) % 86400 == 0) {
|
|
|
leap = 1;
|
|
|
- time_tai--;
|
|
|
time_state = TIME_WAIT;
|
|
|
printk(KERN_NOTICE
|
|
|
"Clock: deleting leap second 23:59:59 UTC\n");
|
|
@@ -579,7 +574,9 @@ static inline void process_adj_status(struct timex *txc, struct timespec *ts)
|
|
|
* Called with ntp_lock held, so we can access and modify
|
|
|
* all the global NTP state:
|
|
|
*/
|
|
|
-static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts)
|
|
|
+static inline void process_adjtimex_modes(struct timex *txc,
|
|
|
+ struct timespec *ts,
|
|
|
+ s32 *time_tai)
|
|
|
{
|
|
|
if (txc->modes & ADJ_STATUS)
|
|
|
process_adj_status(txc, ts);
|
|
@@ -613,7 +610,7 @@ static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts
|
|
|
}
|
|
|
|
|
|
if (txc->modes & ADJ_TAI && txc->constant > 0)
|
|
|
- time_tai = txc->constant;
|
|
|
+ *time_tai = txc->constant;
|
|
|
|
|
|
if (txc->modes & ADJ_OFFSET)
|
|
|
ntp_update_offset(txc->offset);
|
|
@@ -632,6 +629,7 @@ static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts
|
|
|
int do_adjtimex(struct timex *txc)
|
|
|
{
|
|
|
struct timespec ts;
|
|
|
+ u32 time_tai, orig_tai;
|
|
|
int result;
|
|
|
|
|
|
/* Validate the data before disabling interrupts */
|
|
@@ -671,6 +669,7 @@ int do_adjtimex(struct timex *txc)
|
|
|
}
|
|
|
|
|
|
getnstimeofday(&ts);
|
|
|
+ orig_tai = time_tai = timekeeping_get_tai_offset();
|
|
|
|
|
|
raw_spin_lock_irq(&ntp_lock);
|
|
|
|
|
@@ -687,7 +686,7 @@ int do_adjtimex(struct timex *txc)
|
|
|
|
|
|
/* If there are input parameters, then process them: */
|
|
|
if (txc->modes)
|
|
|
- process_adjtimex_modes(txc, &ts);
|
|
|
+ process_adjtimex_modes(txc, &ts, &time_tai);
|
|
|
|
|
|
txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
|
|
|
NTP_SCALE_SHIFT);
|
|
@@ -716,6 +715,9 @@ int do_adjtimex(struct timex *txc)
|
|
|
|
|
|
raw_spin_unlock_irq(&ntp_lock);
|
|
|
|
|
|
+ if (time_tai != orig_tai)
|
|
|
+ timekeeping_set_tai_offset(time_tai);
|
|
|
+
|
|
|
txc->time.tv_sec = ts.tv_sec;
|
|
|
txc->time.tv_usec = ts.tv_nsec;
|
|
|
if (!(time_status & STA_NANO))
|