diff options
Diffstat (limited to 'kernel/time/ntp.c')
-rw-r--r-- | kernel/time/ntp.c | 454 |
1 files changed, 436 insertions, 18 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index c63116863a80..f6117a4c7cb8 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -14,6 +14,9 @@ | |||
14 | #include <linux/timex.h> | 14 | #include <linux/timex.h> |
15 | #include <linux/time.h> | 15 | #include <linux/time.h> |
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/module.h> | ||
18 | |||
19 | #include "tick-internal.h" | ||
17 | 20 | ||
18 | /* | 21 | /* |
19 | * NTP timekeeping variables: | 22 | * NTP timekeeping variables: |
@@ -74,6 +77,162 @@ static long time_adjust; | |||
74 | /* constant (boot-param configurable) NTP tick adjustment (upscaled) */ | 77 | /* constant (boot-param configurable) NTP tick adjustment (upscaled) */ |
75 | static s64 ntp_tick_adj; | 78 | static s64 ntp_tick_adj; |
76 | 79 | ||
80 | #ifdef CONFIG_NTP_PPS | ||
81 | |||
82 | /* | ||
83 | * The following variables are used when a pulse-per-second (PPS) signal | ||
84 | * is available. They establish the engineering parameters of the clock | ||
85 | * discipline loop when controlled by the PPS signal. | ||
86 | */ | ||
87 | #define PPS_VALID 10 /* PPS signal watchdog max (s) */ | ||
88 | #define PPS_POPCORN 4 /* popcorn spike threshold (shift) */ | ||
89 | #define PPS_INTMIN 2 /* min freq interval (s) (shift) */ | ||
90 | #define PPS_INTMAX 8 /* max freq interval (s) (shift) */ | ||
91 | #define PPS_INTCOUNT 4 /* number of consecutive good intervals to | ||
92 | increase pps_shift or consecutive bad | ||
93 | intervals to decrease it */ | ||
94 | #define PPS_MAXWANDER 100000 /* max PPS freq wander (ns/s) */ | ||
95 | |||
96 | static int pps_valid; /* signal watchdog counter */ | ||
97 | static long pps_tf[3]; /* phase median filter */ | ||
98 | static long pps_jitter; /* current jitter (ns) */ | ||
99 | static struct timespec pps_fbase; /* beginning of the last freq interval */ | ||
100 | static int pps_shift; /* current interval duration (s) (shift) */ | ||
101 | static int pps_intcnt; /* interval counter */ | ||
102 | static s64 pps_freq; /* frequency offset (scaled ns/s) */ | ||
103 | static long pps_stabil; /* current stability (scaled ns/s) */ | ||
104 | |||
105 | /* | ||
106 | * PPS signal quality monitors | ||
107 | */ | ||
108 | static long pps_calcnt; /* calibration intervals */ | ||
109 | static long pps_jitcnt; /* jitter limit exceeded */ | ||
110 | static long pps_stbcnt; /* stability limit exceeded */ | ||
111 | static long pps_errcnt; /* calibration errors */ | ||
112 | |||
113 | |||
114 | /* PPS kernel consumer compensates the whole phase error immediately. | ||
115 | * Otherwise, reduce the offset by a fixed factor times the time constant. | ||
116 | */ | ||
117 | static inline s64 ntp_offset_chunk(s64 offset) | ||
118 | { | ||
119 | if (time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL) | ||
120 | return offset; | ||
121 | else | ||
122 | return shift_right(offset, SHIFT_PLL + time_constant); | ||
123 | } | ||
124 | |||
125 | static inline void pps_reset_freq_interval(void) | ||
126 | { | ||
127 | /* the PPS calibration interval may end | ||
128 | surprisingly early */ | ||
129 | pps_shift = PPS_INTMIN; | ||
130 | pps_intcnt = 0; | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * pps_clear - Clears the PPS state variables | ||
135 | * | ||
136 | * Must be called while holding a write on the xtime_lock | ||
137 | */ | ||
138 | static inline void pps_clear(void) | ||
139 | { | ||
140 | pps_reset_freq_interval(); | ||
141 | pps_tf[0] = 0; | ||
142 | pps_tf[1] = 0; | ||
143 | pps_tf[2] = 0; | ||
144 | pps_fbase.tv_sec = pps_fbase.tv_nsec = 0; | ||
145 | pps_freq = 0; | ||
146 | } | ||
147 | |||
148 | /* Decrease pps_valid to indicate that another second has passed since | ||
149 | * the last PPS signal. When it reaches 0, indicate that PPS signal is | ||
150 | * missing. | ||
151 | * | ||
152 | * Must be called while holding a write on the xtime_lock | ||
153 | */ | ||
154 | static inline void pps_dec_valid(void) | ||
155 | { | ||
156 | if (pps_valid > 0) | ||
157 | pps_valid--; | ||
158 | else { | ||
159 | time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER | | ||
160 | STA_PPSWANDER | STA_PPSERROR); | ||
161 | pps_clear(); | ||
162 | } | ||
163 | } | ||
164 | |||
165 | static inline void pps_set_freq(s64 freq) | ||
166 | { | ||
167 | pps_freq = freq; | ||
168 | } | ||
169 | |||
170 | static inline int is_error_status(int status) | ||
171 | { | ||
172 | return (time_status & (STA_UNSYNC|STA_CLOCKERR)) | ||
173 | /* PPS signal lost when either PPS time or | ||
174 | * PPS frequency synchronization requested | ||
175 | */ | ||
176 | || ((time_status & (STA_PPSFREQ|STA_PPSTIME)) | ||
177 | && !(time_status & STA_PPSSIGNAL)) | ||
178 | /* PPS jitter exceeded when | ||
179 | * PPS time synchronization requested */ | ||
180 | || ((time_status & (STA_PPSTIME|STA_PPSJITTER)) | ||
181 | == (STA_PPSTIME|STA_PPSJITTER)) | ||
182 | /* PPS wander exceeded or calibration error when | ||
183 | * PPS frequency synchronization requested | ||
184 | */ | ||
185 | || ((time_status & STA_PPSFREQ) | ||
186 | && (time_status & (STA_PPSWANDER|STA_PPSERROR))); | ||
187 | } | ||
188 | |||
189 | static inline void pps_fill_timex(struct timex *txc) | ||
190 | { | ||
191 | txc->ppsfreq = shift_right((pps_freq >> PPM_SCALE_INV_SHIFT) * | ||
192 | PPM_SCALE_INV, NTP_SCALE_SHIFT); | ||
193 | txc->jitter = pps_jitter; | ||
194 | if (!(time_status & STA_NANO)) | ||
195 | txc->jitter /= NSEC_PER_USEC; | ||
196 | txc->shift = pps_shift; | ||
197 | txc->stabil = pps_stabil; | ||
198 | txc->jitcnt = pps_jitcnt; | ||
199 | txc->calcnt = pps_calcnt; | ||
200 | txc->errcnt = pps_errcnt; | ||
201 | txc->stbcnt = pps_stbcnt; | ||
202 | } | ||
203 | |||
204 | #else /* !CONFIG_NTP_PPS */ | ||
205 | |||
206 | static inline s64 ntp_offset_chunk(s64 offset) | ||
207 | { | ||
208 | return shift_right(offset, SHIFT_PLL + time_constant); | ||
209 | } | ||
210 | |||
211 | static inline void pps_reset_freq_interval(void) {} | ||
212 | static inline void pps_clear(void) {} | ||
213 | static inline void pps_dec_valid(void) {} | ||
214 | static inline void pps_set_freq(s64 freq) {} | ||
215 | |||
216 | static inline int is_error_status(int status) | ||
217 | { | ||
218 | return status & (STA_UNSYNC|STA_CLOCKERR); | ||
219 | } | ||
220 | |||
221 | static inline void pps_fill_timex(struct timex *txc) | ||
222 | { | ||
223 | /* PPS is not implemented, so these are zero */ | ||
224 | txc->ppsfreq = 0; | ||
225 | txc->jitter = 0; | ||
226 | txc->shift = 0; | ||
227 | txc->stabil = 0; | ||
228 | txc->jitcnt = 0; | ||
229 | txc->calcnt = 0; | ||
230 | txc->errcnt = 0; | ||
231 | txc->stbcnt = 0; | ||
232 | } | ||
233 | |||
234 | #endif /* CONFIG_NTP_PPS */ | ||
235 | |||
77 | /* | 236 | /* |
78 | * NTP methods: | 237 | * NTP methods: |
79 | */ | 238 | */ |
@@ -149,10 +308,18 @@ static void ntp_update_offset(long offset) | |||
149 | time_reftime = get_seconds(); | 308 | time_reftime = get_seconds(); |
150 | 309 | ||
151 | offset64 = offset; | 310 | offset64 = offset; |
152 | freq_adj = (offset64 * secs) << | 311 | freq_adj = ntp_update_offset_fll(offset64, secs); |
153 | (NTP_SCALE_SHIFT - 2 * (SHIFT_PLL + 2 + time_constant)); | ||
154 | 312 | ||
155 | freq_adj += ntp_update_offset_fll(offset64, secs); | 313 | /* |
314 | * Clamp update interval to reduce PLL gain with low | ||
315 | * sampling rate (e.g. intermittent network connection) | ||
316 | * to avoid instability. | ||
317 | */ | ||
318 | if (unlikely(secs > 1 << (SHIFT_PLL + 1 + time_constant))) | ||
319 | secs = 1 << (SHIFT_PLL + 1 + time_constant); | ||
320 | |||
321 | freq_adj += (offset64 * secs) << | ||
322 | (NTP_SCALE_SHIFT - 2 * (SHIFT_PLL + 2 + time_constant)); | ||
156 | 323 | ||
157 | freq_adj = min(freq_adj + time_freq, MAXFREQ_SCALED); | 324 | freq_adj = min(freq_adj + time_freq, MAXFREQ_SCALED); |
158 | 325 | ||
@@ -177,6 +344,9 @@ void ntp_clear(void) | |||
177 | 344 | ||
178 | tick_length = tick_length_base; | 345 | tick_length = tick_length_base; |
179 | time_offset = 0; | 346 | time_offset = 0; |
347 | |||
348 | /* Clear PPS state variables */ | ||
349 | pps_clear(); | ||
180 | } | 350 | } |
181 | 351 | ||
182 | /* | 352 | /* |
@@ -242,16 +412,16 @@ void second_overflow(void) | |||
242 | time_status |= STA_UNSYNC; | 412 | time_status |= STA_UNSYNC; |
243 | } | 413 | } |
244 | 414 | ||
245 | /* | 415 | /* Compute the phase adjustment for the next second */ |
246 | * Compute the phase adjustment for the next second. The offset is | ||
247 | * reduced by a fixed factor times the time constant. | ||
248 | */ | ||
249 | tick_length = tick_length_base; | 416 | tick_length = tick_length_base; |
250 | 417 | ||
251 | delta = shift_right(time_offset, SHIFT_PLL + time_constant); | 418 | delta = ntp_offset_chunk(time_offset); |
252 | time_offset -= delta; | 419 | time_offset -= delta; |
253 | tick_length += delta; | 420 | tick_length += delta; |
254 | 421 | ||
422 | /* Check PPS signal */ | ||
423 | pps_dec_valid(); | ||
424 | |||
255 | if (!time_adjust) | 425 | if (!time_adjust) |
256 | return; | 426 | return; |
257 | 427 | ||
@@ -361,6 +531,8 @@ static inline void process_adj_status(struct timex *txc, struct timespec *ts) | |||
361 | if ((time_status & STA_PLL) && !(txc->status & STA_PLL)) { | 531 | if ((time_status & STA_PLL) && !(txc->status & STA_PLL)) { |
362 | time_state = TIME_OK; | 532 | time_state = TIME_OK; |
363 | time_status = STA_UNSYNC; | 533 | time_status = STA_UNSYNC; |
534 | /* restart PPS frequency calibration */ | ||
535 | pps_reset_freq_interval(); | ||
364 | } | 536 | } |
365 | 537 | ||
366 | /* | 538 | /* |
@@ -410,6 +582,8 @@ static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts | |||
410 | time_freq = txc->freq * PPM_SCALE; | 582 | time_freq = txc->freq * PPM_SCALE; |
411 | time_freq = min(time_freq, MAXFREQ_SCALED); | 583 | time_freq = min(time_freq, MAXFREQ_SCALED); |
412 | time_freq = max(time_freq, -MAXFREQ_SCALED); | 584 | time_freq = max(time_freq, -MAXFREQ_SCALED); |
585 | /* update pps_freq */ | ||
586 | pps_set_freq(time_freq); | ||
413 | } | 587 | } |
414 | 588 | ||
415 | if (txc->modes & ADJ_MAXERROR) | 589 | if (txc->modes & ADJ_MAXERROR) |
@@ -474,6 +648,19 @@ int do_adjtimex(struct timex *txc) | |||
474 | hrtimer_cancel(&leap_timer); | 648 | hrtimer_cancel(&leap_timer); |
475 | } | 649 | } |
476 | 650 | ||
651 | if (txc->modes & ADJ_SETOFFSET) { | ||
652 | struct timespec delta; | ||
653 | delta.tv_sec = txc->time.tv_sec; | ||
654 | delta.tv_nsec = txc->time.tv_usec; | ||
655 | if (!capable(CAP_SYS_TIME)) | ||
656 | return -EPERM; | ||
657 | if (!(txc->modes & ADJ_NANO)) | ||
658 | delta.tv_nsec *= 1000; | ||
659 | result = timekeeping_inject_offset(&delta); | ||
660 | if (result) | ||
661 | return result; | ||
662 | } | ||
663 | |||
477 | getnstimeofday(&ts); | 664 | getnstimeofday(&ts); |
478 | 665 | ||
479 | write_seqlock_irq(&xtime_lock); | 666 | write_seqlock_irq(&xtime_lock); |
@@ -500,7 +687,8 @@ int do_adjtimex(struct timex *txc) | |||
500 | } | 687 | } |
501 | 688 | ||
502 | result = time_state; /* mostly `TIME_OK' */ | 689 | result = time_state; /* mostly `TIME_OK' */ |
503 | if (time_status & (STA_UNSYNC|STA_CLOCKERR)) | 690 | /* check for errors */ |
691 | if (is_error_status(time_status)) | ||
504 | result = TIME_ERROR; | 692 | result = TIME_ERROR; |
505 | 693 | ||
506 | txc->freq = shift_right((time_freq >> PPM_SCALE_INV_SHIFT) * | 694 | txc->freq = shift_right((time_freq >> PPM_SCALE_INV_SHIFT) * |
@@ -514,15 +702,8 @@ int do_adjtimex(struct timex *txc) | |||
514 | txc->tick = tick_usec; | 702 | txc->tick = tick_usec; |
515 | txc->tai = time_tai; | 703 | txc->tai = time_tai; |
516 | 704 | ||
517 | /* PPS is not implemented, so these are zero */ | 705 | /* fill PPS status fields */ |
518 | txc->ppsfreq = 0; | 706 | pps_fill_timex(txc); |
519 | txc->jitter = 0; | ||
520 | txc->shift = 0; | ||
521 | txc->stabil = 0; | ||
522 | txc->jitcnt = 0; | ||
523 | txc->calcnt = 0; | ||
524 | txc->errcnt = 0; | ||
525 | txc->stbcnt = 0; | ||
526 | 707 | ||
527 | write_sequnlock_irq(&xtime_lock); | 708 | write_sequnlock_irq(&xtime_lock); |
528 | 709 | ||
@@ -536,6 +717,243 @@ int do_adjtimex(struct timex *txc) | |||
536 | return result; | 717 | return result; |
537 | } | 718 | } |
538 | 719 | ||
720 | #ifdef CONFIG_NTP_PPS | ||
721 | |||
722 | /* actually struct pps_normtime is good old struct timespec, but it is | ||
723 | * semantically different (and it is the reason why it was invented): | ||
724 | * pps_normtime.nsec has a range of ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] | ||
725 | * while timespec.tv_nsec has a range of [0, NSEC_PER_SEC) */ | ||
726 | struct pps_normtime { | ||
727 | __kernel_time_t sec; /* seconds */ | ||
728 | long nsec; /* nanoseconds */ | ||
729 | }; | ||
730 | |||
731 | /* normalize the timestamp so that nsec is in the | ||
732 | ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] interval */ | ||
733 | static inline struct pps_normtime pps_normalize_ts(struct timespec ts) | ||
734 | { | ||
735 | struct pps_normtime norm = { | ||
736 | .sec = ts.tv_sec, | ||
737 | .nsec = ts.tv_nsec | ||
738 | }; | ||
739 | |||
740 | if (norm.nsec > (NSEC_PER_SEC >> 1)) { | ||
741 | norm.nsec -= NSEC_PER_SEC; | ||
742 | norm.sec++; | ||
743 | } | ||
744 | |||
745 | return norm; | ||
746 | } | ||
747 | |||
748 | /* get current phase correction and jitter */ | ||
749 | static inline long pps_phase_filter_get(long *jitter) | ||
750 | { | ||
751 | *jitter = pps_tf[0] - pps_tf[1]; | ||
752 | if (*jitter < 0) | ||
753 | *jitter = -*jitter; | ||
754 | |||
755 | /* TODO: test various filters */ | ||
756 | return pps_tf[0]; | ||
757 | } | ||
758 | |||
759 | /* add the sample to the phase filter */ | ||
760 | static inline void pps_phase_filter_add(long err) | ||
761 | { | ||
762 | pps_tf[2] = pps_tf[1]; | ||
763 | pps_tf[1] = pps_tf[0]; | ||
764 | pps_tf[0] = err; | ||
765 | } | ||
766 | |||
767 | /* decrease frequency calibration interval length. | ||
768 | * It is halved after four consecutive unstable intervals. | ||
769 | */ | ||
770 | static inline void pps_dec_freq_interval(void) | ||
771 | { | ||
772 | if (--pps_intcnt <= -PPS_INTCOUNT) { | ||
773 | pps_intcnt = -PPS_INTCOUNT; | ||
774 | if (pps_shift > PPS_INTMIN) { | ||
775 | pps_shift--; | ||
776 | pps_intcnt = 0; | ||
777 | } | ||
778 | } | ||
779 | } | ||
780 | |||
781 | /* increase frequency calibration interval length. | ||
782 | * It is doubled after four consecutive stable intervals. | ||
783 | */ | ||
784 | static inline void pps_inc_freq_interval(void) | ||
785 | { | ||
786 | if (++pps_intcnt >= PPS_INTCOUNT) { | ||
787 | pps_intcnt = PPS_INTCOUNT; | ||
788 | if (pps_shift < PPS_INTMAX) { | ||
789 | pps_shift++; | ||
790 | pps_intcnt = 0; | ||
791 | } | ||
792 | } | ||
793 | } | ||
794 | |||
795 | /* update clock frequency based on MONOTONIC_RAW clock PPS signal | ||
796 | * timestamps | ||
797 | * | ||
798 | * At the end of the calibration interval the difference between the | ||
799 | * first and last MONOTONIC_RAW clock timestamps divided by the length | ||
800 | * of the interval becomes the frequency update. If the interval was | ||
801 | * too long, the data are discarded. | ||
802 | * Returns the difference between old and new frequency values. | ||
803 | */ | ||
804 | static long hardpps_update_freq(struct pps_normtime freq_norm) | ||
805 | { | ||
806 | long delta, delta_mod; | ||
807 | s64 ftemp; | ||
808 | |||
809 | /* check if the frequency interval was too long */ | ||
810 | if (freq_norm.sec > (2 << pps_shift)) { | ||
811 | time_status |= STA_PPSERROR; | ||
812 | pps_errcnt++; | ||
813 | pps_dec_freq_interval(); | ||
814 | pr_err("hardpps: PPSERROR: interval too long - %ld s\n", | ||
815 | freq_norm.sec); | ||
816 | return 0; | ||
817 | } | ||
818 | |||
819 | /* here the raw frequency offset and wander (stability) is | ||
820 | * calculated. If the wander is less than the wander threshold | ||
821 | * the interval is increased; otherwise it is decreased. | ||
822 | */ | ||
823 | ftemp = div_s64(((s64)(-freq_norm.nsec)) << NTP_SCALE_SHIFT, | ||
824 | freq_norm.sec); | ||
825 | delta = shift_right(ftemp - pps_freq, NTP_SCALE_SHIFT); | ||
826 | pps_freq = ftemp; | ||
827 | if (delta > PPS_MAXWANDER || delta < -PPS_MAXWANDER) { | ||
828 | pr_warning("hardpps: PPSWANDER: change=%ld\n", delta); | ||
829 | time_status |= STA_PPSWANDER; | ||
830 | pps_stbcnt++; | ||
831 | pps_dec_freq_interval(); | ||
832 | } else { /* good sample */ | ||
833 | pps_inc_freq_interval(); | ||
834 | } | ||
835 | |||
836 | /* the stability metric is calculated as the average of recent | ||
837 | * frequency changes, but is used only for performance | ||
838 | * monitoring | ||
839 | */ | ||
840 | delta_mod = delta; | ||
841 | if (delta_mod < 0) | ||
842 | delta_mod = -delta_mod; | ||
843 | pps_stabil += (div_s64(((s64)delta_mod) << | ||
844 | (NTP_SCALE_SHIFT - SHIFT_USEC), | ||
845 | NSEC_PER_USEC) - pps_stabil) >> PPS_INTMIN; | ||
846 | |||
847 | /* if enabled, the system clock frequency is updated */ | ||
848 | if ((time_status & STA_PPSFREQ) != 0 && | ||
849 | (time_status & STA_FREQHOLD) == 0) { | ||
850 | time_freq = pps_freq; | ||
851 | ntp_update_frequency(); | ||
852 | } | ||
853 | |||
854 | return delta; | ||
855 | } | ||
856 | |||
857 | /* correct REALTIME clock phase error against PPS signal */ | ||
858 | static void hardpps_update_phase(long error) | ||
859 | { | ||
860 | long correction = -error; | ||
861 | long jitter; | ||
862 | |||
863 | /* add the sample to the median filter */ | ||
864 | pps_phase_filter_add(correction); | ||
865 | correction = pps_phase_filter_get(&jitter); | ||
866 | |||
867 | /* Nominal jitter is due to PPS signal noise. If it exceeds the | ||
868 | * threshold, the sample is discarded; otherwise, if so enabled, | ||
869 | * the time offset is updated. | ||
870 | */ | ||
871 | if (jitter > (pps_jitter << PPS_POPCORN)) { | ||
872 | pr_warning("hardpps: PPSJITTER: jitter=%ld, limit=%ld\n", | ||
873 | jitter, (pps_jitter << PPS_POPCORN)); | ||
874 | time_status |= STA_PPSJITTER; | ||
875 | pps_jitcnt++; | ||
876 | } else if (time_status & STA_PPSTIME) { | ||
877 | /* correct the time using the phase offset */ | ||
878 | time_offset = div_s64(((s64)correction) << NTP_SCALE_SHIFT, | ||
879 | NTP_INTERVAL_FREQ); | ||
880 | /* cancel running adjtime() */ | ||
881 | time_adjust = 0; | ||
882 | } | ||
883 | /* update jitter */ | ||
884 | pps_jitter += (jitter - pps_jitter) >> PPS_INTMIN; | ||
885 | } | ||
886 | |||
887 | /* | ||
888 | * hardpps() - discipline CPU clock oscillator to external PPS signal | ||
889 | * | ||
890 | * This routine is called at each PPS signal arrival in order to | ||
891 | * discipline the CPU clock oscillator to the PPS signal. It takes two | ||
892 | * parameters: REALTIME and MONOTONIC_RAW clock timestamps. The former | ||
893 | * is used to correct clock phase error and the latter is used to | ||
894 | * correct the frequency. | ||
895 | * | ||
896 | * This code is based on David Mills's reference nanokernel | ||
897 | * implementation. It was mostly rewritten but keeps the same idea. | ||
898 | */ | ||
899 | void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) | ||
900 | { | ||
901 | struct pps_normtime pts_norm, freq_norm; | ||
902 | unsigned long flags; | ||
903 | |||
904 | pts_norm = pps_normalize_ts(*phase_ts); | ||
905 | |||
906 | write_seqlock_irqsave(&xtime_lock, flags); | ||
907 | |||
908 | /* clear the error bits, they will be set again if needed */ | ||
909 | time_status &= ~(STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR); | ||
910 | |||
911 | /* indicate signal presence */ | ||
912 | time_status |= STA_PPSSIGNAL; | ||
913 | pps_valid = PPS_VALID; | ||
914 | |||
915 | /* when called for the first time, | ||
916 | * just start the frequency interval */ | ||
917 | if (unlikely(pps_fbase.tv_sec == 0)) { | ||
918 | pps_fbase = *raw_ts; | ||
919 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
920 | return; | ||
921 | } | ||
922 | |||
923 | /* ok, now we have a base for frequency calculation */ | ||
924 | freq_norm = pps_normalize_ts(timespec_sub(*raw_ts, pps_fbase)); | ||
925 | |||
926 | /* check that the signal is in the range | ||
927 | * [1s - MAXFREQ us, 1s + MAXFREQ us], otherwise reject it */ | ||
928 | if ((freq_norm.sec == 0) || | ||
929 | (freq_norm.nsec > MAXFREQ * freq_norm.sec) || | ||
930 | (freq_norm.nsec < -MAXFREQ * freq_norm.sec)) { | ||
931 | time_status |= STA_PPSJITTER; | ||
932 | /* restart the frequency calibration interval */ | ||
933 | pps_fbase = *raw_ts; | ||
934 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
935 | pr_err("hardpps: PPSJITTER: bad pulse\n"); | ||
936 | return; | ||
937 | } | ||
938 | |||
939 | /* signal is ok */ | ||
940 | |||
941 | /* check if the current frequency interval is finished */ | ||
942 | if (freq_norm.sec >= (1 << pps_shift)) { | ||
943 | pps_calcnt++; | ||
944 | /* restart the frequency calibration interval */ | ||
945 | pps_fbase = *raw_ts; | ||
946 | hardpps_update_freq(freq_norm); | ||
947 | } | ||
948 | |||
949 | hardpps_update_phase(pts_norm.nsec); | ||
950 | |||
951 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
952 | } | ||
953 | EXPORT_SYMBOL(hardpps); | ||
954 | |||
955 | #endif /* CONFIG_NTP_PPS */ | ||
956 | |||
539 | static int __init ntp_tick_adj_setup(char *str) | 957 | static int __init ntp_tick_adj_setup(char *str) |
540 | { | 958 | { |
541 | ntp_tick_adj = simple_strtol(str, NULL, 0); | 959 | ntp_tick_adj = simple_strtol(str, NULL, 0); |