]> err.no Git - linux-2.6/blobdiff - kernel/time/ntp.c
Merge branch 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linvil...
[linux-2.6] / kernel / time / ntp.c
index 9137b54613e0b9c2871c63b016bac4c81d046b68..3afeaa3a73f998dd422e1518c6c4256749207538 100644 (file)
@@ -30,17 +30,31 @@ static u64 tick_length, tick_length_base;
  * phase-lock loop variables
  */
 /* TIME_ERROR prevents overwriting the CMOS clock */
-int time_state = TIME_OK;              /* clock synchronization status */
+static int time_state = TIME_OK;       /* clock synchronization status */
 int time_status = STA_UNSYNC;          /* clock status bits            */
-long time_offset;                      /* time adjustment (ns)         */
-long time_constant = 2;                        /* pll time constant            */
-long time_precision = 1;               /* clock precision (us)         */
+static long time_offset;               /* time adjustment (ns)         */
+static long time_constant = 2;         /* pll time constant            */
 long time_maxerror = NTP_PHASE_LIMIT;  /* maximum error (us)           */
 long time_esterror = NTP_PHASE_LIMIT;  /* estimated error (us)         */
 long time_freq;                                /* frequency offset (scaled ppm)*/
-long time_reftime;                     /* time at last adjustment (s)  */
+static long time_reftime;              /* time at last adjustment (s)  */
 long time_adjust;
 
+#define CLOCK_TICK_OVERFLOW    (LATCH * HZ - CLOCK_TICK_RATE)
+#define CLOCK_TICK_ADJUST      (((s64)CLOCK_TICK_OVERFLOW * NSEC_PER_SEC) / \
+                                       (s64)CLOCK_TICK_RATE)
+
+static void ntp_update_frequency(void)
+{
+       tick_length_base = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << TICK_LENGTH_SHIFT;
+       tick_length_base += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT;
+       tick_length_base += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC);
+
+       do_div(tick_length_base, HZ);
+
+       tick_nsec = tick_length_base >> TICK_LENGTH_SHIFT;
+}
+
 /**
  * ntp_clear - Clears the NTP state variables
  *
@@ -59,20 +73,6 @@ void ntp_clear(void)
        time_offset = 0;
 }
 
-#define CLOCK_TICK_OVERFLOW    (LATCH * HZ - CLOCK_TICK_RATE)
-#define CLOCK_TICK_ADJUST      (((s64)CLOCK_TICK_OVERFLOW * NSEC_PER_SEC) / (s64)CLOCK_TICK_RATE)
-
-void ntp_update_frequency(void)
-{
-       tick_length_base = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << TICK_LENGTH_SHIFT;
-       tick_length_base += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT;
-       tick_length_base += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC);
-
-       do_div(tick_length_base, HZ);
-
-       tick_nsec = tick_length_base >> TICK_LENGTH_SHIFT;
-}
-
 /*
  * this routine handles the overflow of the microsecond field
  *
@@ -145,18 +145,11 @@ void second_overflow(void)
        }
 
        /*
-        * Compute the phase adjustment for the next second. In PLL mode, the
-        * offset is reduced by a fixed factor times the time constant. In FLL
-        * mode the offset is used directly. In either mode, the maximum phase
-        * adjustment for each second is clamped so as to spread the adjustment
-        * over not more than the number of seconds between updates.
+        * Compute the phase adjustment for the next second. The offset is
+        * reduced by a fixed factor times the time constant.
         */
        tick_length = tick_length_base;
-       time_adj = time_offset;
-       if (!(time_status & STA_FLL))
-               time_adj = shift_right(time_adj, SHIFT_KG + time_constant);
-       time_adj = min(time_adj, -((MAXPHASE / HZ) << SHIFT_UPDATE) / MINSEC);
-       time_adj = max(time_adj, ((MAXPHASE / HZ) << SHIFT_UPDATE) / MINSEC);
+       time_adj = shift_right(time_offset, SHIFT_PLL + time_constant);
        time_offset -= time_adj;
        tick_length += (s64)time_adj << (TICK_LENGTH_SHIFT - SHIFT_UPDATE);
 
@@ -168,9 +161,9 @@ void second_overflow(void)
                        time_adjust += MAX_TICKADJ;
                        tick_length -= MAX_TICKADJ_SCALED;
                } else {
-                       time_adjust = 0;
                        tick_length += (s64)(time_adjust * NSEC_PER_USEC /
                                             HZ) << TICK_LENGTH_SHIFT;
+                       time_adjust = 0;
                }
        }
 }
@@ -200,7 +193,7 @@ void __attribute__ ((weak)) notify_arch_cmos_timer(void)
 int do_adjtimex(struct timex *txc)
 {
        long ltemp, mtemp, save_adjust;
-       s64 freq_adj;
+       s64 freq_adj, temp64;
        int result;
 
        /* In order to modify anything, you gotta be super-user! */
@@ -270,7 +263,7 @@ int do_adjtimex(struct timex *txc)
                    result = -EINVAL;
                    goto leave;
                }
-               time_constant = txc->constant;
+               time_constant = min(txc->constant + 4, (long)MAXTC);
            }
 
            if (txc->modes & ADJ_OFFSET) {      /* values checked earlier */
@@ -298,26 +291,20 @@ int do_adjtimex(struct timex *txc)
                        time_reftime = xtime.tv_sec;
                    mtemp = xtime.tv_sec - time_reftime;
                    time_reftime = xtime.tv_sec;
-                   freq_adj = 0;
-                   if (time_status & STA_FLL) {
-                       if (mtemp >= MINSEC) {
-                           freq_adj = (s64)time_offset << (SHIFT_NSEC - SHIFT_KH);
-                           if (time_offset < 0) {
-                               freq_adj = -freq_adj;
-                               do_div(freq_adj, mtemp);
-                               freq_adj = -freq_adj;
-                           } else
-                               do_div(freq_adj, mtemp);
-                       } else /* calibration interval too short (p. 12) */
-                               result = TIME_ERROR;
-                   } else {    /* PLL mode */
-                       if (mtemp < MAXSEC) {
-                           freq_adj = (s64)ltemp * mtemp;
-                           freq_adj = shift_right(freq_adj,(time_constant +
-                                                      time_constant +
-                                                      SHIFT_KF - SHIFT_NSEC));
-                       } else /* calibration interval too long (p. 12) */
-                               result = TIME_ERROR;
+
+                   freq_adj = (s64)time_offset * mtemp;
+                   freq_adj = shift_right(freq_adj, time_constant * 2 +
+                                          (SHIFT_PLL + 2) * 2 - SHIFT_NSEC);
+                   if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) {
+                       temp64 = (s64)time_offset << (SHIFT_NSEC - SHIFT_FLL);
+                       if (time_offset < 0) {
+                           temp64 = -temp64;
+                           do_div(temp64, mtemp);
+                           freq_adj -= temp64;
+                       } else {
+                           do_div(temp64, mtemp);
+                           freq_adj += temp64;
+                       }
                    }
                    freq_adj += time_freq;
                    freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC);
@@ -343,7 +330,7 @@ leave:      if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
        txc->esterror      = time_esterror;
        txc->status        = time_status;
        txc->constant      = time_constant;
-       txc->precision     = time_precision;
+       txc->precision     = 1;
        txc->tolerance     = MAXFREQ;
        txc->tick          = tick_usec;