diff options
-rw-r--r-- | arch/powerpc/kernel/time.c | 2 | ||||
-rw-r--r-- | include/linux/timex.h | 11 | ||||
-rw-r--r-- | kernel/time/ntp.c | 30 |
3 files changed, 21 insertions, 22 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 3b26fbd6bec9..c146af995854 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -1007,8 +1007,6 @@ void __init time_init(void) | |||
1007 | vdso_data->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; | 1007 | vdso_data->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; |
1008 | vdso_data->tb_to_xs = tb_to_xs; | 1008 | vdso_data->tb_to_xs = tb_to_xs; |
1009 | 1009 | ||
1010 | time_freq = 0; | ||
1011 | |||
1012 | write_sequnlock_irqrestore(&xtime_lock, flags); | 1010 | write_sequnlock_irqrestore(&xtime_lock, flags); |
1013 | 1011 | ||
1014 | /* Register the clocksource, if we're not running on iSeries */ | 1012 | /* Register the clocksource, if we're not running on iSeries */ |
diff --git a/include/linux/timex.h b/include/linux/timex.h index 3c49d173bf39..48c3376dce71 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -86,11 +86,14 @@ | |||
86 | */ | 86 | */ |
87 | #define SHIFT_UPDATE (SHIFT_HZ + 1) /* time offset scale (shift) */ | 87 | #define SHIFT_UPDATE (SHIFT_HZ + 1) /* time offset scale (shift) */ |
88 | #define SHIFT_USEC 16 /* frequency offset scale (shift) */ | 88 | #define SHIFT_USEC 16 /* frequency offset scale (shift) */ |
89 | #define SHIFT_NSEC 12 /* kernel frequency offset scale */ | 89 | #define PPM_SCALE (NSEC_PER_USEC << (TICK_LENGTH_SHIFT - SHIFT_USEC)) |
90 | #define PPM_SCALE_INV_SHIFT 20 | ||
91 | #define PPM_SCALE_INV ((1ll << (PPM_SCALE_INV_SHIFT + TICK_LENGTH_SHIFT)) / \ | ||
92 | PPM_SCALE + 1) | ||
90 | 93 | ||
91 | #define MAXPHASE 512000L /* max phase error (us) */ | 94 | #define MAXPHASE 512000L /* max phase error (us) */ |
92 | #define MAXFREQ (512L << SHIFT_USEC) /* max frequency error (ppm) */ | 95 | #define MAXFREQ 500000 /* max frequency error (ns/s) */ |
93 | #define MAXFREQ_NSEC (512000L << SHIFT_NSEC) /* max frequency error (ppb) */ | 96 | #define MAXFREQ_SCALED ((s64)MAXFREQ << TICK_LENGTH_SHIFT) |
94 | #define MINSEC 256 /* min interval between updates (s) */ | 97 | #define MINSEC 256 /* min interval between updates (s) */ |
95 | #define MAXSEC 2048 /* max interval between updates (s) */ | 98 | #define MAXSEC 2048 /* max interval between updates (s) */ |
96 | #define NTP_PHASE_LIMIT (MAXPHASE << 5) /* beyond max. dispersion */ | 99 | #define NTP_PHASE_LIMIT (MAXPHASE << 5) /* beyond max. dispersion */ |
@@ -209,8 +212,6 @@ extern int time_status; /* clock synchronization status bits */ | |||
209 | extern long time_maxerror; /* maximum error */ | 212 | extern long time_maxerror; /* maximum error */ |
210 | extern long time_esterror; /* estimated error */ | 213 | extern long time_esterror; /* estimated error */ |
211 | 214 | ||
212 | extern long time_freq; /* frequency offset (scaled ppm) */ | ||
213 | |||
214 | extern long time_adjust; /* The amount of adjtime left */ | 215 | extern long time_adjust; /* The amount of adjtime left */ |
215 | 216 | ||
216 | extern void ntp_clear(void); | 217 | extern void ntp_clear(void); |
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 3fc81066d7f1..c6ae0c249891 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -39,7 +39,7 @@ static s64 time_offset; /* time adjustment (ns) */ | |||
39 | static long time_constant = 2; /* pll time constant */ | 39 | static long time_constant = 2; /* pll time constant */ |
40 | long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */ | 40 | long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */ |
41 | long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */ | 41 | long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */ |
42 | long time_freq; /* frequency offset (scaled ppm)*/ | 42 | static s64 time_freq; /* frequency offset (scaled ns/s)*/ |
43 | static long time_reftime; /* time at last adjustment (s) */ | 43 | static long time_reftime; /* time at last adjustment (s) */ |
44 | long time_adjust; | 44 | long time_adjust; |
45 | static long ntp_tick_adj; | 45 | static long ntp_tick_adj; |
@@ -49,7 +49,7 @@ static void ntp_update_frequency(void) | |||
49 | u64 second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) | 49 | u64 second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) |
50 | << TICK_LENGTH_SHIFT; | 50 | << TICK_LENGTH_SHIFT; |
51 | second_length += (s64)ntp_tick_adj << TICK_LENGTH_SHIFT; | 51 | second_length += (s64)ntp_tick_adj << TICK_LENGTH_SHIFT; |
52 | second_length += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC); | 52 | second_length += time_freq; |
53 | 53 | ||
54 | tick_length_base = second_length; | 54 | tick_length_base = second_length; |
55 | 55 | ||
@@ -86,16 +86,16 @@ static void ntp_update_offset(long offset) | |||
86 | time_reftime = xtime.tv_sec; | 86 | time_reftime = xtime.tv_sec; |
87 | 87 | ||
88 | freq_adj = time_offset * mtemp; | 88 | freq_adj = time_offset * mtemp; |
89 | freq_adj = shift_right(freq_adj, time_constant * 2 + | 89 | freq_adj <<= TICK_LENGTH_SHIFT - 2 * (SHIFT_PLL + 2 + time_constant); |
90 | (SHIFT_PLL + 2) * 2 - SHIFT_NSEC); | ||
91 | time_status &= ~STA_MODE; | 90 | time_status &= ~STA_MODE; |
92 | if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { | 91 | if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { |
93 | freq_adj += div_s64(time_offset << (SHIFT_NSEC - SHIFT_FLL), mtemp); | 92 | freq_adj += div_s64(time_offset << (TICK_LENGTH_SHIFT - SHIFT_FLL), |
93 | mtemp); | ||
94 | time_status |= STA_MODE; | 94 | time_status |= STA_MODE; |
95 | } | 95 | } |
96 | freq_adj += time_freq; | 96 | freq_adj += time_freq; |
97 | freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC); | 97 | freq_adj = min(freq_adj, MAXFREQ_SCALED); |
98 | time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC); | 98 | time_freq = max(freq_adj, -MAXFREQ_SCALED); |
99 | time_offset = div_s64(time_offset, NTP_INTERVAL_FREQ); | 99 | time_offset = div_s64(time_offset, NTP_INTERVAL_FREQ); |
100 | time_offset <<= SHIFT_UPDATE; | 100 | time_offset <<= SHIFT_UPDATE; |
101 | } | 101 | } |
@@ -131,7 +131,7 @@ void second_overflow(void) | |||
131 | long time_adj; | 131 | long time_adj; |
132 | 132 | ||
133 | /* Bump the maxerror field */ | 133 | /* Bump the maxerror field */ |
134 | time_maxerror += MAXFREQ >> SHIFT_USEC; | 134 | time_maxerror += MAXFREQ / NSEC_PER_USEC; |
135 | if (time_maxerror > NTP_PHASE_LIMIT) { | 135 | if (time_maxerror > NTP_PHASE_LIMIT) { |
136 | time_maxerror = NTP_PHASE_LIMIT; | 136 | time_maxerror = NTP_PHASE_LIMIT; |
137 | time_status |= STA_UNSYNC; | 137 | time_status |= STA_UNSYNC; |
@@ -323,10 +323,9 @@ int do_adjtimex(struct timex *txc) | |||
323 | time_status &= ~STA_NANO; | 323 | time_status &= ~STA_NANO; |
324 | 324 | ||
325 | if (txc->modes & ADJ_FREQUENCY) { | 325 | if (txc->modes & ADJ_FREQUENCY) { |
326 | time_freq = min(txc->freq, MAXFREQ); | 326 | time_freq = (s64)txc->freq * PPM_SCALE; |
327 | time_freq = min(time_freq, -MAXFREQ); | 327 | time_freq = min(time_freq, MAXFREQ_SCALED); |
328 | time_freq = ((s64)time_freq * NSEC_PER_USEC) | 328 | time_freq = max(time_freq, -MAXFREQ_SCALED); |
329 | >> (SHIFT_USEC - SHIFT_NSEC); | ||
330 | } | 329 | } |
331 | 330 | ||
332 | if (txc->modes & ADJ_MAXERROR) | 331 | if (txc->modes & ADJ_MAXERROR) |
@@ -369,14 +368,15 @@ int do_adjtimex(struct timex *txc) | |||
369 | if (!(time_status & STA_NANO)) | 368 | if (!(time_status & STA_NANO)) |
370 | txc->offset /= NSEC_PER_USEC; | 369 | txc->offset /= NSEC_PER_USEC; |
371 | } | 370 | } |
372 | txc->freq = (time_freq / NSEC_PER_USEC) << | 371 | txc->freq = shift_right((s32)(time_freq >> PPM_SCALE_INV_SHIFT) * |
373 | (SHIFT_USEC - SHIFT_NSEC); | 372 | (s64)PPM_SCALE_INV, |
373 | TICK_LENGTH_SHIFT); | ||
374 | txc->maxerror = time_maxerror; | 374 | txc->maxerror = time_maxerror; |
375 | txc->esterror = time_esterror; | 375 | txc->esterror = time_esterror; |
376 | txc->status = time_status; | 376 | txc->status = time_status; |
377 | txc->constant = time_constant; | 377 | txc->constant = time_constant; |
378 | txc->precision = 1; | 378 | txc->precision = 1; |
379 | txc->tolerance = MAXFREQ; | 379 | txc->tolerance = MAXFREQ_SCALED / PPM_SCALE; |
380 | txc->tick = tick_usec; | 380 | txc->tick = tick_usec; |
381 | 381 | ||
382 | /* PPS is not implemented, so these are zero */ | 382 | /* PPS is not implemented, so these are zero */ |