aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorRoman Zippel <zippel@linux-m68k.org>2006-10-01 02:28:27 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:27 -0400
commit04b617e71e363e640e88be1e43f53fa6a3afef9f (patch)
treeb59e8e75e4671bc5e10f4fcaace85d4658d4d0f0 /kernel/time
parent97eebe138caaf78354b1fad233e63bafdcc4fd54 (diff)
[PATCH] ntp: convert time_freq to nsec value
This converts time_freq to a scaled nsec value and adds around 6bit of extra resolution. This pushes the time_freq to its 32bit limits so the calculatons have to be done with 64bit. Signed-off-by: Roman Zippel <zippel@linux-m68k.org> Cc: john stultz <johnstul@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/ntp.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index af7563f5d4e2..9137b54613e0 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -66,7 +66,7 @@ void ntp_update_frequency(void)
66{ 66{
67 tick_length_base = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << TICK_LENGTH_SHIFT; 67 tick_length_base = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << TICK_LENGTH_SHIFT;
68 tick_length_base += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT; 68 tick_length_base += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT;
69 tick_length_base += ((s64)time_freq * NSEC_PER_USEC) << (TICK_LENGTH_SHIFT - SHIFT_USEC); 69 tick_length_base += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC);
70 70
71 do_div(tick_length_base, HZ); 71 do_div(tick_length_base, HZ);
72 72
@@ -200,6 +200,7 @@ void __attribute__ ((weak)) notify_arch_cmos_timer(void)
200int do_adjtimex(struct timex *txc) 200int do_adjtimex(struct timex *txc)
201{ 201{
202 long ltemp, mtemp, save_adjust; 202 long ltemp, mtemp, save_adjust;
203 s64 freq_adj;
203 int result; 204 int result;
204 205
205 /* In order to modify anything, you gotta be super-user! */ 206 /* In order to modify anything, you gotta be super-user! */
@@ -245,7 +246,7 @@ int do_adjtimex(struct timex *txc)
245 result = -EINVAL; 246 result = -EINVAL;
246 goto leave; 247 goto leave;
247 } 248 }
248 time_freq = txc->freq; 249 time_freq = ((s64)txc->freq * NSEC_PER_USEC) >> (SHIFT_USEC - SHIFT_NSEC);
249 } 250 }
250 251
251 if (txc->modes & ADJ_MAXERROR) { 252 if (txc->modes & ADJ_MAXERROR) {
@@ -278,14 +279,14 @@ int do_adjtimex(struct timex *txc)
278 time_adjust = txc->offset; 279 time_adjust = txc->offset;
279 } 280 }
280 else if (time_status & STA_PLL) { 281 else if (time_status & STA_PLL) {
281 ltemp = txc->offset; 282 ltemp = txc->offset * NSEC_PER_USEC;
282 283
283 /* 284 /*
284 * Scale the phase adjustment and 285 * Scale the phase adjustment and
285 * clamp to the operating range. 286 * clamp to the operating range.
286 */ 287 */
287 time_offset = min(ltemp, MAXPHASE); 288 time_offset = min(ltemp, MAXPHASE * NSEC_PER_USEC);
288 time_offset = max(time_offset, -MAXPHASE); 289 time_offset = max(time_offset, -MAXPHASE * NSEC_PER_USEC);
289 290
290 /* 291 /*
291 * Select whether the frequency is to be controlled 292 * Select whether the frequency is to be controlled
@@ -297,24 +298,31 @@ int do_adjtimex(struct timex *txc)
297 time_reftime = xtime.tv_sec; 298 time_reftime = xtime.tv_sec;
298 mtemp = xtime.tv_sec - time_reftime; 299 mtemp = xtime.tv_sec - time_reftime;
299 time_reftime = xtime.tv_sec; 300 time_reftime = xtime.tv_sec;
301 freq_adj = 0;
300 if (time_status & STA_FLL) { 302 if (time_status & STA_FLL) {
301 if (mtemp >= MINSEC) { 303 if (mtemp >= MINSEC) {
302 ltemp = ((time_offset << 12) / mtemp) << (SHIFT_USEC - 12); 304 freq_adj = (s64)time_offset << (SHIFT_NSEC - SHIFT_KH);
303 time_freq += shift_right(ltemp, SHIFT_KH); 305 if (time_offset < 0) {
306 freq_adj = -freq_adj;
307 do_div(freq_adj, mtemp);
308 freq_adj = -freq_adj;
309 } else
310 do_div(freq_adj, mtemp);
304 } else /* calibration interval too short (p. 12) */ 311 } else /* calibration interval too short (p. 12) */
305 result = TIME_ERROR; 312 result = TIME_ERROR;
306 } else { /* PLL mode */ 313 } else { /* PLL mode */
307 if (mtemp < MAXSEC) { 314 if (mtemp < MAXSEC) {
308 ltemp *= mtemp; 315 freq_adj = (s64)ltemp * mtemp;
309 time_freq += shift_right(ltemp,(time_constant + 316 freq_adj = shift_right(freq_adj,(time_constant +
310 time_constant + 317 time_constant +
311 SHIFT_KF - SHIFT_USEC)); 318 SHIFT_KF - SHIFT_NSEC));
312 } else /* calibration interval too long (p. 12) */ 319 } else /* calibration interval too long (p. 12) */
313 result = TIME_ERROR; 320 result = TIME_ERROR;
314 } 321 }
315 time_freq = min(time_freq, MAXFREQ); 322 freq_adj += time_freq;
316 time_freq = max(time_freq, -MAXFREQ); 323 freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC);
317 time_offset = (time_offset * NSEC_PER_USEC / HZ) << SHIFT_UPDATE; 324 time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC);
325 time_offset = (time_offset / HZ) << SHIFT_UPDATE;
318 } /* STA_PLL */ 326 } /* STA_PLL */
319 } /* txc->modes & ADJ_OFFSET */ 327 } /* txc->modes & ADJ_OFFSET */
320 if (txc->modes & ADJ_TICK) 328 if (txc->modes & ADJ_TICK)
@@ -330,7 +338,7 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
330 txc->offset = save_adjust; 338 txc->offset = save_adjust;
331 else 339 else
332 txc->offset = shift_right(time_offset, SHIFT_UPDATE) * HZ / 1000; 340 txc->offset = shift_right(time_offset, SHIFT_UPDATE) * HZ / 1000;
333 txc->freq = time_freq; 341 txc->freq = (time_freq / NSEC_PER_USEC) << (SHIFT_USEC - SHIFT_NSEC);
334 txc->maxerror = time_maxerror; 342 txc->maxerror = time_maxerror;
335 txc->esterror = time_esterror; 343 txc->esterror = time_esterror;
336 txc->status = time_status; 344 txc->status = time_status;