aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/timex.h7
-rw-r--r--kernel/time.c25
-rw-r--r--kernel/timer.c53
3 files changed, 24 insertions, 61 deletions
diff --git a/include/linux/timex.h b/include/linux/timex.h
index 7e050a2cc35b..04a4a8cb4ed3 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -282,6 +282,13 @@ static inline int ntp_synced(void)
282 return !(time_status & STA_UNSYNC); 282 return !(time_status & STA_UNSYNC);
283} 283}
284 284
285/* Required to safely shift negative values */
286#define shift_right(x, s) ({ \
287 __typeof__(x) __x = (x); \
288 __typeof__(s) __s = (s); \
289 __x < 0 ? -(-__x >> __s) : __x >> __s; \
290})
291
285 292
286#ifdef CONFIG_TIME_INTERPOLATION 293#ifdef CONFIG_TIME_INTERPOLATION
287 294
diff --git a/kernel/time.c b/kernel/time.c
index a3c2100470e1..245d595a13cb 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -338,30 +338,20 @@ int do_adjtimex(struct timex *txc)
338 if (mtemp >= MINSEC) { 338 if (mtemp >= MINSEC) {
339 ltemp = (time_offset / mtemp) << (SHIFT_USEC - 339 ltemp = (time_offset / mtemp) << (SHIFT_USEC -
340 SHIFT_UPDATE); 340 SHIFT_UPDATE);
341 if (ltemp < 0) 341 time_freq += shift_right(ltemp, SHIFT_KH);
342 time_freq -= -ltemp >> SHIFT_KH;
343 else
344 time_freq += ltemp >> SHIFT_KH;
345 } else /* calibration interval too short (p. 12) */ 342 } else /* calibration interval too short (p. 12) */
346 result = TIME_ERROR; 343 result = TIME_ERROR;
347 } else { /* PLL mode */ 344 } else { /* PLL mode */
348 if (mtemp < MAXSEC) { 345 if (mtemp < MAXSEC) {
349 ltemp *= mtemp; 346 ltemp *= mtemp;
350 if (ltemp < 0) 347 time_freq += shift_right(ltemp,(time_constant +
351 time_freq -= -ltemp >> (time_constant +
352 time_constant +
353 SHIFT_KF - SHIFT_USEC);
354 else
355 time_freq += ltemp >> (time_constant +
356 time_constant + 348 time_constant +
357 SHIFT_KF - SHIFT_USEC); 349 SHIFT_KF - SHIFT_USEC));
358 } else /* calibration interval too long (p. 12) */ 350 } else /* calibration interval too long (p. 12) */
359 result = TIME_ERROR; 351 result = TIME_ERROR;
360 } 352 }
361 if (time_freq > time_tolerance) 353 time_freq = min(time_freq, time_tolerance);
362 time_freq = time_tolerance; 354 time_freq = max(time_freq, -time_tolerance);
363 else if (time_freq < -time_tolerance)
364 time_freq = -time_tolerance;
365 } /* STA_PLL || STA_PPSTIME */ 355 } /* STA_PLL || STA_PPSTIME */
366 } /* txc->modes & ADJ_OFFSET */ 356 } /* txc->modes & ADJ_OFFSET */
367 if (txc->modes & ADJ_TICK) { 357 if (txc->modes & ADJ_TICK) {
@@ -384,10 +374,7 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
384 if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT) 374 if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
385 txc->offset = save_adjust; 375 txc->offset = save_adjust;
386 else { 376 else {
387 if (time_offset < 0) 377 txc->offset = shift_right(time_offset, SHIFT_UPDATE);
388 txc->offset = -(-time_offset >> SHIFT_UPDATE);
389 else
390 txc->offset = time_offset >> SHIFT_UPDATE;
391 } 378 }
392 txc->freq = time_freq + pps_freq; 379 txc->freq = time_freq + pps_freq;
393 txc->maxerror = time_maxerror; 380 txc->maxerror = time_maxerror;
diff --git a/kernel/timer.c b/kernel/timer.c
index 6ed1a826e5ce..6b94adb45b03 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -703,23 +703,13 @@ static void second_overflow(void)
703 * the adjustment over not more than the number of 703 * the adjustment over not more than the number of
704 * seconds between updates. 704 * seconds between updates.
705 */ 705 */
706 if (time_offset < 0) {
707 ltemp = -time_offset;
708 if (!(time_status & STA_FLL))
709 ltemp >>= SHIFT_KG + time_constant;
710 if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
711 ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
712 time_offset += ltemp;
713 time_adj = -ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
714 } else {
715 ltemp = time_offset; 706 ltemp = time_offset;
716 if (!(time_status & STA_FLL)) 707 if (!(time_status & STA_FLL))
717 ltemp >>= SHIFT_KG + time_constant; 708 ltemp = shift_right(ltemp, SHIFT_KG + time_constant);
718 if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE) 709 ltemp = min(ltemp, (MAXPHASE / MINSEC) << SHIFT_UPDATE);
719 ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE; 710 ltemp = max(ltemp, -(MAXPHASE / MINSEC) << SHIFT_UPDATE);
720 time_offset -= ltemp; 711 time_offset -= ltemp;
721 time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE); 712 time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
722 }
723 713
724 /* 714 /*
725 * Compute the frequency estimate and additional phase 715 * Compute the frequency estimate and additional phase
@@ -736,39 +726,25 @@ static void second_overflow(void)
736 STA_PPSWANDER | STA_PPSERROR); 726 STA_PPSWANDER | STA_PPSERROR);
737 } 727 }
738 ltemp = time_freq + pps_freq; 728 ltemp = time_freq + pps_freq;
739 if (ltemp < 0) 729 time_adj += shift_right(ltemp,(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE));
740 time_adj -= -ltemp >>
741 (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
742 else
743 time_adj += ltemp >>
744 (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
745 730
746#if HZ == 100 731#if HZ == 100
747 /* Compensate for (HZ==100) != (1 << SHIFT_HZ). 732 /* Compensate for (HZ==100) != (1 << SHIFT_HZ).
748 * Add 25% and 3.125% to get 128.125; => only 0.125% error (p. 14) 733 * Add 25% and 3.125% to get 128.125; => only 0.125% error (p. 14)
749 */ 734 */
750 if (time_adj < 0) 735 time_adj += shift_right(time_adj, 2) + shift_right(time_adj, 5);
751 time_adj -= (-time_adj >> 2) + (-time_adj >> 5);
752 else
753 time_adj += (time_adj >> 2) + (time_adj >> 5);
754#endif 736#endif
755#if HZ == 250 737#if HZ == 250
756 /* Compensate for (HZ==250) != (1 << SHIFT_HZ). 738 /* Compensate for (HZ==250) != (1 << SHIFT_HZ).
757 * Add 1.5625% and 0.78125% to get 255.85938; => only 0.05% error (p. 14) 739 * Add 1.5625% and 0.78125% to get 255.85938; => only 0.05% error (p. 14)
758 */ 740 */
759 if (time_adj < 0) 741 time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
760 time_adj -= (-time_adj >> 6) + (-time_adj >> 7);
761 else
762 time_adj += (time_adj >> 6) + (time_adj >> 7);
763#endif 742#endif
764#if HZ == 1000 743#if HZ == 1000
765 /* Compensate for (HZ==1000) != (1 << SHIFT_HZ). 744 /* Compensate for (HZ==1000) != (1 << SHIFT_HZ).
766 * Add 1.5625% and 0.78125% to get 1023.4375; => only 0.05% error (p. 14) 745 * Add 1.5625% and 0.78125% to get 1023.4375; => only 0.05% error (p. 14)
767 */ 746 */
768 if (time_adj < 0) 747 time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
769 time_adj -= (-time_adj >> 6) + (-time_adj >> 7);
770 else
771 time_adj += (time_adj >> 6) + (time_adj >> 7);
772#endif 748#endif
773} 749}
774 750
@@ -787,10 +763,8 @@ static void update_wall_time_one_tick(void)
787 * Limit the amount of the step to be in the range 763 * Limit the amount of the step to be in the range
788 * -tickadj .. +tickadj 764 * -tickadj .. +tickadj
789 */ 765 */
790 if (time_adjust > tickadj) 766 time_adjust_step = min(time_adjust_step, (long)tickadj);
791 time_adjust_step = tickadj; 767 time_adjust_step = max(time_adjust_step, (long)-tickadj);
792 else if (time_adjust < -tickadj)
793 time_adjust_step = -tickadj;
794 768
795 /* Reduce by this step the amount of time left */ 769 /* Reduce by this step the amount of time left */
796 time_adjust -= time_adjust_step; 770 time_adjust -= time_adjust_step;
@@ -801,13 +775,8 @@ static void update_wall_time_one_tick(void)
801 * advance the tick more. 775 * advance the tick more.
802 */ 776 */
803 time_phase += time_adj; 777 time_phase += time_adj;
804 if (time_phase <= -FINENSEC) { 778 if ((time_phase >= FINENSEC) || (time_phase <= -FINENSEC)) {
805 long ltemp = -time_phase >> (SHIFT_SCALE - 10); 779 long ltemp = shift_right(time_phase, (SHIFT_SCALE - 10));
806 time_phase += ltemp << (SHIFT_SCALE - 10);
807 delta_nsec -= ltemp;
808 }
809 else if (time_phase >= FINENSEC) {
810 long ltemp = time_phase >> (SHIFT_SCALE - 10);
811 time_phase -= ltemp << (SHIFT_SCALE - 10); 780 time_phase -= ltemp << (SHIFT_SCALE - 10);
812 delta_nsec += ltemp; 781 delta_nsec += ltemp;
813 } 782 }