aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/ntp.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/ntp.c')
-rw-r--r--kernel/time/ntp.c50
1 files changed, 44 insertions, 6 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 8ccce15b4b23..77137bec2aea 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -15,6 +15,13 @@
15#include <asm/div64.h> 15#include <asm/div64.h>
16#include <asm/timex.h> 16#include <asm/timex.h>
17 17
18/*
19 * Timekeeping variables
20 */
21unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */
22unsigned long tick_nsec; /* ACTHZ period (nsec) */
23static u64 tick_length, tick_length_base;
24
18/* Don't completely fail for HZ > 500. */ 25/* Don't completely fail for HZ > 500. */
19int tickadj = 500/HZ ? : 1; /* microsecs */ 26int tickadj = 500/HZ ? : 1; /* microsecs */
20 27
@@ -37,6 +44,36 @@ long time_reftime; /* time at last adjustment (s) */
37long time_adjust; 44long time_adjust;
38long time_next_adjust; 45long time_next_adjust;
39 46
47/**
48 * ntp_clear - Clears the NTP state variables
49 *
50 * Must be called while holding a write on the xtime_lock
51 */
52void ntp_clear(void)
53{
54 time_adjust = 0; /* stop active adjtime() */
55 time_status |= STA_UNSYNC;
56 time_maxerror = NTP_PHASE_LIMIT;
57 time_esterror = NTP_PHASE_LIMIT;
58
59 ntp_update_frequency();
60
61 tick_length = tick_length_base;
62}
63
64#define CLOCK_TICK_OVERFLOW (LATCH * HZ - CLOCK_TICK_RATE)
65#define CLOCK_TICK_ADJUST (((s64)CLOCK_TICK_OVERFLOW * NSEC_PER_SEC) / (s64)CLOCK_TICK_RATE)
66
67void ntp_update_frequency(void)
68{
69 tick_length_base = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << TICK_LENGTH_SHIFT;
70 tick_length_base += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT;
71
72 do_div(tick_length_base, HZ);
73
74 tick_nsec = tick_length_base >> TICK_LENGTH_SHIFT;
75}
76
40/* 77/*
41 * this routine handles the overflow of the microsecond field 78 * this routine handles the overflow of the microsecond field
42 * 79 *
@@ -151,6 +188,7 @@ void second_overflow(void)
151 */ 188 */
152 time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7); 189 time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
153#endif 190#endif
191 tick_length = tick_length_base;
154} 192}
155 193
156/* 194/*
@@ -204,14 +242,13 @@ void update_ntp_one_tick(void)
204 */ 242 */
205u64 current_tick_length(void) 243u64 current_tick_length(void)
206{ 244{
207 long delta_nsec;
208 u64 ret; 245 u64 ret;
209 246
210 /* calculate the finest interval NTP will allow. 247 /* calculate the finest interval NTP will allow.
211 * ie: nanosecond value shifted by (SHIFT_SCALE - 10) 248 * ie: nanosecond value shifted by (SHIFT_SCALE - 10)
212 */ 249 */
213 delta_nsec = tick_nsec + adjtime_adjustment() * 1000; 250 ret = tick_length;
214 ret = (u64)delta_nsec << TICK_LENGTH_SHIFT; 251 ret += (u64)(adjtime_adjustment() * 1000) << TICK_LENGTH_SHIFT;
215 ret += (s64)time_adj << (TICK_LENGTH_SHIFT - (SHIFT_SCALE - 10)); 252 ret += (s64)time_adj << (TICK_LENGTH_SHIFT - (SHIFT_SCALE - 10));
216 253
217 return ret; 254 return ret;
@@ -351,10 +388,11 @@ int do_adjtimex(struct timex *txc)
351 time_freq = max(time_freq, -time_tolerance); 388 time_freq = max(time_freq, -time_tolerance);
352 } /* STA_PLL */ 389 } /* STA_PLL */
353 } /* txc->modes & ADJ_OFFSET */ 390 } /* txc->modes & ADJ_OFFSET */
354 if (txc->modes & ADJ_TICK) { 391 if (txc->modes & ADJ_TICK)
355 tick_usec = txc->tick; 392 tick_usec = txc->tick;
356 tick_nsec = TICK_USEC_TO_NSEC(tick_usec); 393
357 } 394 if (txc->modes & ADJ_TICK)
395 ntp_update_frequency();
358 } /* txc->modes */ 396 } /* txc->modes */
359leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0) 397leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
360 result = TIME_ERROR; 398 result = TIME_ERROR;