xref: /linux-6.15/kernel/time/ntp.c (revision f66b0acf)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
24c7ee8deSjohn stultz /*
34c7ee8deSjohn stultz  * NTP state machine interfaces and logic.
44c7ee8deSjohn stultz  *
54c7ee8deSjohn stultz  * This code was mainly moved from kernel/timer.c and kernel/time.c
64c7ee8deSjohn stultz  * Please see those files for relevant copyright info and historical
74c7ee8deSjohn stultz  * changelogs.
84c7ee8deSjohn stultz  */
9aa0ac365SAlexey Dobriyan #include <linux/capability.h>
107dffa3c6SRoman Zippel #include <linux/clocksource.h>
11eb3f938fSMaciej W. Rozycki #include <linux/workqueue.h>
1253bbfa9eSIngo Molnar #include <linux/hrtimer.h>
1353bbfa9eSIngo Molnar #include <linux/jiffies.h>
1453bbfa9eSIngo Molnar #include <linux/math64.h>
1553bbfa9eSIngo Molnar #include <linux/timex.h>
1653bbfa9eSIngo Molnar #include <linux/time.h>
1753bbfa9eSIngo Molnar #include <linux/mm.h>
18025b40abSAlexander Gordeev #include <linux/module.h>
19023f333aSJason Gunthorpe #include <linux/rtc.h>
207e8eda73SOndrej Mosnacek #include <linux/audit.h>
214c7ee8deSjohn stultz 
22aa6f9c59SJohn Stultz #include "ntp_internal.h"
230af86465SDengChao #include "timekeeping_internal.h"
240af86465SDengChao 
2568f66f97SThomas Gleixner /**
2668f66f97SThomas Gleixner  * struct ntp_data - Structure holding all NTP related state
2768f66f97SThomas Gleixner  * @tick_usec:		USER_HZ period in microseconds
28ec93ec22SThomas Gleixner  * @tick_length:	Adjusted tick length
29ec93ec22SThomas Gleixner  * @tick_length_base:	Base value for @tick_length
30bee18a23SThomas Gleixner  * @time_state:		State of the clock synchronization
31bee18a23SThomas Gleixner  * @time_status:	Clock status bits
32d5143554SThomas Gleixner  * @time_offset:	Time adjustment in nanoseconds
33d5143554SThomas Gleixner  * @time_constant:	PLL time constant
347891cf29SThomas Gleixner  * @time_maxerror:	Maximum error in microseconds holding the NTP sync distance
357891cf29SThomas Gleixner  *			(NTP dispersion + delay / 2)
367891cf29SThomas Gleixner  * @time_esterror:	Estimated error in microseconds holding NTP dispersion
37161b8ec2SThomas Gleixner  * @time_freq:		Frequency offset scaled nsecs/secs
38161b8ec2SThomas Gleixner  * @time_reftime:	Time at last adjustment in seconds
39bb6400a2SThomas Gleixner  * @time_adjust:	Adjustment value
40bb6400a2SThomas Gleixner  * @ntp_tick_adj:	Constant boot-param configurable NTP tick adjustment (upscaled)
4175d956b9SThomas Gleixner  * @ntp_next_leap_sec:	Second value of the next pending leapsecond, or TIME64_MAX if no leap
42a076b214SJohn Stultz  *
43931a177fSThomas Gleixner  * @pps_valid:		PPS signal watchdog counter
445cc953b8SThomas Gleixner  * @pps_tf:		PPS phase median filter
459d7130dfSThomas Gleixner  * @pps_jitter:		PPS current jitter in nanoseconds
46db45e9bcSThomas Gleixner  * @pps_fbase:		PPS beginning of the last freq interval
47b1c89a76SThomas Gleixner  * @pps_shift:		PPS current interval duration in seconds (shift value)
48b1c89a76SThomas Gleixner  * @pps_intcnt:		PPS interval counter
4912850b46SThomas Gleixner  * @pps_freq:		PPS frequency offset in scaled ns/s
5012850b46SThomas Gleixner  * @pps_stabil:		PPS current stability in scaled ns/s
516fadb4a6SThomas Gleixner  * @pps_calcnt:		PPS monitor: calibration intervals
526fadb4a6SThomas Gleixner  * @pps_jitcnt:		PPS monitor: jitter limit exceeded
536fadb4a6SThomas Gleixner  * @pps_stbcnt:		PPS monitor: stability limit exceeded
546fadb4a6SThomas Gleixner  * @pps_errcnt:		PPS monitor: calibration errors
55931a177fSThomas Gleixner  *
5668f66f97SThomas Gleixner  * Protected by the timekeeping locks.
57b0ee7556SRoman Zippel  */
5868f66f97SThomas Gleixner struct ntp_data {
5968f66f97SThomas Gleixner 	unsigned long		tick_usec;
60ec93ec22SThomas Gleixner 	u64			tick_length;
61ec93ec22SThomas Gleixner 	u64			tick_length_base;
62bee18a23SThomas Gleixner 	int			time_state;
63bee18a23SThomas Gleixner 	int			time_status;
64d5143554SThomas Gleixner 	s64			time_offset;
65d5143554SThomas Gleixner 	long			time_constant;
667891cf29SThomas Gleixner 	long			time_maxerror;
677891cf29SThomas Gleixner 	long			time_esterror;
68161b8ec2SThomas Gleixner 	s64			time_freq;
69161b8ec2SThomas Gleixner 	time64_t		time_reftime;
70bb6400a2SThomas Gleixner 	long			time_adjust;
71bb6400a2SThomas Gleixner 	s64			ntp_tick_adj;
7275d956b9SThomas Gleixner 	time64_t		ntp_next_leap_sec;
73931a177fSThomas Gleixner #ifdef CONFIG_NTP_PPS
74931a177fSThomas Gleixner 	int			pps_valid;
755cc953b8SThomas Gleixner 	long			pps_tf[3];
769d7130dfSThomas Gleixner 	long			pps_jitter;
77db45e9bcSThomas Gleixner 	struct timespec64	pps_fbase;
78b1c89a76SThomas Gleixner 	int			pps_shift;
79b1c89a76SThomas Gleixner 	int			pps_intcnt;
8012850b46SThomas Gleixner 	s64			pps_freq;
8112850b46SThomas Gleixner 	long			pps_stabil;
826fadb4a6SThomas Gleixner 	long			pps_calcnt;
836fadb4a6SThomas Gleixner 	long			pps_jitcnt;
846fadb4a6SThomas Gleixner 	long			pps_stbcnt;
856fadb4a6SThomas Gleixner 	long			pps_errcnt;
86931a177fSThomas Gleixner #endif
8768f66f97SThomas Gleixner };
8853bbfa9eSIngo Molnar 
8968f66f97SThomas Gleixner static struct ntp_data tk_ntp_data = {
9068f66f97SThomas Gleixner 	.tick_usec		= USER_TICK_USEC,
91bee18a23SThomas Gleixner 	.time_state		= TIME_OK,
92bee18a23SThomas Gleixner 	.time_status		= STA_UNSYNC,
93d5143554SThomas Gleixner 	.time_constant		= 2,
947891cf29SThomas Gleixner 	.time_maxerror		= NTP_PHASE_LIMIT,
957891cf29SThomas Gleixner 	.time_esterror		= NTP_PHASE_LIMIT,
9675d956b9SThomas Gleixner 	.ntp_next_leap_sec	= TIME64_MAX,
9768f66f97SThomas Gleixner };
9853bbfa9eSIngo Molnar 
9990bf361cSJohn Stultz #define SECS_PER_DAY		86400
100bbd12676SIngo Molnar #define MAX_TICKADJ		500LL		/* usecs */
10153bbfa9eSIngo Molnar #define MAX_TICKADJ_SCALED \
102bbd12676SIngo Molnar 	(((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ)
103d897a4abSMiroslav Lichvar #define MAX_TAI_OFFSET		100000
1044c7ee8deSjohn stultz 
105025b40abSAlexander Gordeev #ifdef CONFIG_NTP_PPS
106025b40abSAlexander Gordeev 
107025b40abSAlexander Gordeev /*
108025b40abSAlexander Gordeev  * The following variables are used when a pulse-per-second (PPS) signal
109025b40abSAlexander Gordeev  * is available. They establish the engineering parameters of the clock
110025b40abSAlexander Gordeev  * discipline loop when controlled by the PPS signal.
111025b40abSAlexander Gordeev  */
112025b40abSAlexander Gordeev #define PPS_VALID	10	/* PPS signal watchdog max (s) */
113025b40abSAlexander Gordeev #define PPS_POPCORN	4	/* popcorn spike threshold (shift) */
114025b40abSAlexander Gordeev #define PPS_INTMIN	2	/* min freq interval (s) (shift) */
115025b40abSAlexander Gordeev #define PPS_INTMAX	8	/* max freq interval (s) (shift) */
116025b40abSAlexander Gordeev #define PPS_INTCOUNT	4	/* number of consecutive good intervals to
117025b40abSAlexander Gordeev 				   increase pps_shift or consecutive bad
118025b40abSAlexander Gordeev 				   intervals to decrease it */
119025b40abSAlexander Gordeev #define PPS_MAXWANDER	100000	/* max PPS freq wander (ns/s) */
120025b40abSAlexander Gordeev 
121025b40abSAlexander Gordeev /*
122a0581cdbSThomas Gleixner  * PPS kernel consumer compensates the whole phase error immediately.
123025b40abSAlexander Gordeev  * Otherwise, reduce the offset by a fixed factor times the time constant.
124025b40abSAlexander Gordeev  */
ntp_offset_chunk(struct ntp_data * ntpdata,s64 offset)125bee18a23SThomas Gleixner static inline s64 ntp_offset_chunk(struct ntp_data *ntpdata, s64 offset)
126025b40abSAlexander Gordeev {
127bee18a23SThomas Gleixner 	if (ntpdata->time_status & STA_PPSTIME && ntpdata->time_status & STA_PPSSIGNAL)
128025b40abSAlexander Gordeev 		return offset;
129025b40abSAlexander Gordeev 	else
130d5143554SThomas Gleixner 		return shift_right(offset, SHIFT_PLL + ntpdata->time_constant);
131025b40abSAlexander Gordeev }
132025b40abSAlexander Gordeev 
pps_reset_freq_interval(struct ntp_data * ntpdata)133b1c89a76SThomas Gleixner static inline void pps_reset_freq_interval(struct ntp_data *ntpdata)
134025b40abSAlexander Gordeev {
135a0581cdbSThomas Gleixner 	/* The PPS calibration interval may end surprisingly early */
136b1c89a76SThomas Gleixner 	ntpdata->pps_shift = PPS_INTMIN;
137b1c89a76SThomas Gleixner 	ntpdata->pps_intcnt = 0;
138025b40abSAlexander Gordeev }
139025b40abSAlexander Gordeev 
140025b40abSAlexander Gordeev /**
141025b40abSAlexander Gordeev  * pps_clear - Clears the PPS state variables
1425cc953b8SThomas Gleixner  * @ntpdata:	Pointer to ntp data
143025b40abSAlexander Gordeev  */
pps_clear(struct ntp_data * ntpdata)1445cc953b8SThomas Gleixner static inline void pps_clear(struct ntp_data *ntpdata)
145025b40abSAlexander Gordeev {
146b1c89a76SThomas Gleixner 	pps_reset_freq_interval(ntpdata);
1475cc953b8SThomas Gleixner 	ntpdata->pps_tf[0] = 0;
1485cc953b8SThomas Gleixner 	ntpdata->pps_tf[1] = 0;
1495cc953b8SThomas Gleixner 	ntpdata->pps_tf[2] = 0;
150db45e9bcSThomas Gleixner 	ntpdata->pps_fbase.tv_sec = ntpdata->pps_fbase.tv_nsec = 0;
15112850b46SThomas Gleixner 	ntpdata->pps_freq = 0;
152025b40abSAlexander Gordeev }
153025b40abSAlexander Gordeev 
154a0581cdbSThomas Gleixner /*
155a0581cdbSThomas Gleixner  * Decrease pps_valid to indicate that another second has passed since the
156a0581cdbSThomas Gleixner  * last PPS signal. When it reaches 0, indicate that PPS signal is missing.
157025b40abSAlexander Gordeev  */
pps_dec_valid(struct ntp_data * ntpdata)158bee18a23SThomas Gleixner static inline void pps_dec_valid(struct ntp_data *ntpdata)
159025b40abSAlexander Gordeev {
160931a177fSThomas Gleixner 	if (ntpdata->pps_valid > 0) {
161931a177fSThomas Gleixner 		ntpdata->pps_valid--;
162931a177fSThomas Gleixner 	} else {
163bee18a23SThomas Gleixner 		ntpdata->time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
164025b40abSAlexander Gordeev 					  STA_PPSWANDER | STA_PPSERROR);
1655cc953b8SThomas Gleixner 		pps_clear(ntpdata);
166025b40abSAlexander Gordeev 	}
167025b40abSAlexander Gordeev }
168025b40abSAlexander Gordeev 
pps_set_freq(struct ntp_data * ntpdata)16912850b46SThomas Gleixner static inline void pps_set_freq(struct ntp_data *ntpdata)
170025b40abSAlexander Gordeev {
17112850b46SThomas Gleixner 	ntpdata->pps_freq = ntpdata->time_freq;
172025b40abSAlexander Gordeev }
173025b40abSAlexander Gordeev 
is_error_status(int status)17448c3c65fSThomas Gleixner static inline bool is_error_status(int status)
175025b40abSAlexander Gordeev {
176ea54bca3SGeorge Spelvin 	return (status & (STA_UNSYNC|STA_CLOCKERR))
177a0581cdbSThomas Gleixner 		/*
178a0581cdbSThomas Gleixner 		 * PPS signal lost when either PPS time or PPS frequency
179a0581cdbSThomas Gleixner 		 * synchronization requested
180025b40abSAlexander Gordeev 		 */
181ea54bca3SGeorge Spelvin 		|| ((status & (STA_PPSFREQ|STA_PPSTIME))
182ea54bca3SGeorge Spelvin 			&& !(status & STA_PPSSIGNAL))
183a0581cdbSThomas Gleixner 		/*
184a0581cdbSThomas Gleixner 		 * PPS jitter exceeded when PPS time synchronization
185a0581cdbSThomas Gleixner 		 * requested
186a0581cdbSThomas Gleixner 		 */
187ea54bca3SGeorge Spelvin 		|| ((status & (STA_PPSTIME|STA_PPSJITTER))
188025b40abSAlexander Gordeev 			== (STA_PPSTIME|STA_PPSJITTER))
189a0581cdbSThomas Gleixner 		/*
190a0581cdbSThomas Gleixner 		 * PPS wander exceeded or calibration error when PPS
191a0581cdbSThomas Gleixner 		 * frequency synchronization requested
192025b40abSAlexander Gordeev 		 */
193ea54bca3SGeorge Spelvin 		|| ((status & STA_PPSFREQ)
194ea54bca3SGeorge Spelvin 			&& (status & (STA_PPSWANDER|STA_PPSERROR)));
195025b40abSAlexander Gordeev }
196025b40abSAlexander Gordeev 
pps_fill_timex(struct ntp_data * ntpdata,struct __kernel_timex * txc)197bee18a23SThomas Gleixner static inline void pps_fill_timex(struct ntp_data *ntpdata, struct __kernel_timex *txc)
198025b40abSAlexander Gordeev {
19912850b46SThomas Gleixner 	txc->ppsfreq	   = shift_right((ntpdata->pps_freq >> PPM_SCALE_INV_SHIFT) *
200025b40abSAlexander Gordeev 					 PPM_SCALE_INV, NTP_SCALE_SHIFT);
2019d7130dfSThomas Gleixner 	txc->jitter	   = ntpdata->pps_jitter;
202bee18a23SThomas Gleixner 	if (!(ntpdata->time_status & STA_NANO))
2039d7130dfSThomas Gleixner 		txc->jitter = ntpdata->pps_jitter / NSEC_PER_USEC;
204b1c89a76SThomas Gleixner 	txc->shift	   = ntpdata->pps_shift;
20512850b46SThomas Gleixner 	txc->stabil	   = ntpdata->pps_stabil;
2066fadb4a6SThomas Gleixner 	txc->jitcnt	   = ntpdata->pps_jitcnt;
2076fadb4a6SThomas Gleixner 	txc->calcnt	   = ntpdata->pps_calcnt;
2086fadb4a6SThomas Gleixner 	txc->errcnt	   = ntpdata->pps_errcnt;
2096fadb4a6SThomas Gleixner 	txc->stbcnt	   = ntpdata->pps_stbcnt;
210025b40abSAlexander Gordeev }
211025b40abSAlexander Gordeev 
212025b40abSAlexander Gordeev #else /* !CONFIG_NTP_PPS */
213025b40abSAlexander Gordeev 
ntp_offset_chunk(struct ntp_data * ntpdata,s64 offset)214d5143554SThomas Gleixner static inline s64 ntp_offset_chunk(struct ntp_data *ntpdata, s64 offset)
215025b40abSAlexander Gordeev {
216d5143554SThomas Gleixner 	return shift_right(offset, SHIFT_PLL + ntpdata->time_constant);
217025b40abSAlexander Gordeev }
218025b40abSAlexander Gordeev 
pps_reset_freq_interval(struct ntp_data * ntpdata)219b1c89a76SThomas Gleixner static inline void pps_reset_freq_interval(struct ntp_data *ntpdata) {}
pps_clear(struct ntp_data * ntpdata)2205cc953b8SThomas Gleixner static inline void pps_clear(struct ntp_data *ntpdata) {}
pps_dec_valid(struct ntp_data * ntpdata)221bee18a23SThomas Gleixner static inline void pps_dec_valid(struct ntp_data *ntpdata) {}
pps_set_freq(struct ntp_data * ntpdata)22212850b46SThomas Gleixner static inline void pps_set_freq(struct ntp_data *ntpdata) {}
223025b40abSAlexander Gordeev 
is_error_status(int status)22448c3c65fSThomas Gleixner static inline bool is_error_status(int status)
225025b40abSAlexander Gordeev {
226025b40abSAlexander Gordeev 	return status & (STA_UNSYNC|STA_CLOCKERR);
227025b40abSAlexander Gordeev }
228025b40abSAlexander Gordeev 
pps_fill_timex(struct ntp_data * ntpdata,struct __kernel_timex * txc)229bee18a23SThomas Gleixner static inline void pps_fill_timex(struct ntp_data *ntpdata, struct __kernel_timex *txc)
230025b40abSAlexander Gordeev {
231025b40abSAlexander Gordeev 	/* PPS is not implemented, so these are zero */
232025b40abSAlexander Gordeev 	txc->ppsfreq	   = 0;
233025b40abSAlexander Gordeev 	txc->jitter	   = 0;
234025b40abSAlexander Gordeev 	txc->shift	   = 0;
235025b40abSAlexander Gordeev 	txc->stabil	   = 0;
236025b40abSAlexander Gordeev 	txc->jitcnt	   = 0;
237025b40abSAlexander Gordeev 	txc->calcnt	   = 0;
238025b40abSAlexander Gordeev 	txc->errcnt	   = 0;
239025b40abSAlexander Gordeev 	txc->stbcnt	   = 0;
240025b40abSAlexander Gordeev }
241025b40abSAlexander Gordeev 
242025b40abSAlexander Gordeev #endif /* CONFIG_NTP_PPS */
243025b40abSAlexander Gordeev 
2449ce616aaSIngo Molnar /*
245a849a027SThomas Gleixner  * Update tick_length and tick_length_base, based on tick_usec, ntp_tick_adj and
246a849a027SThomas Gleixner  * time_freq:
2479ce616aaSIngo Molnar  */
ntp_update_frequency(struct ntp_data * ntpdata)24868f66f97SThomas Gleixner static void ntp_update_frequency(struct ntp_data *ntpdata)
24970bc42f9SAdrian Bunk {
25068f66f97SThomas Gleixner 	u64 second_length, new_base, tick_usec = (u64)ntpdata->tick_usec;
2519ce616aaSIngo Molnar 
25268f66f97SThomas Gleixner 	second_length		 = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << NTP_SCALE_SHIFT;
2539ce616aaSIngo Molnar 
254bb6400a2SThomas Gleixner 	second_length		+= ntpdata->ntp_tick_adj;
255161b8ec2SThomas Gleixner 	second_length		+= ntpdata->time_freq;
25670bc42f9SAdrian Bunk 
257bc26c31dSIngo Molnar 	new_base		 = div_u64(second_length, NTP_INTERVAL_FREQ);
258fdcedf7bSjohn stultz 
259fdcedf7bSjohn stultz 	/*
260a0581cdbSThomas Gleixner 	 * Don't wait for the next second_overflow, apply the change to the
261a0581cdbSThomas Gleixner 	 * tick length immediately:
262fdcedf7bSjohn stultz 	 */
263ec93ec22SThomas Gleixner 	ntpdata->tick_length		+= new_base - ntpdata->tick_length_base;
264ec93ec22SThomas Gleixner 	ntpdata->tick_length_base	 = new_base;
26570bc42f9SAdrian Bunk }
26670bc42f9SAdrian Bunk 
ntp_update_offset_fll(struct ntp_data * ntpdata,s64 offset64,long secs)267bee18a23SThomas Gleixner static inline s64 ntp_update_offset_fll(struct ntp_data *ntpdata, s64 offset64, long secs)
268f939890bSIngo Molnar {
269bee18a23SThomas Gleixner 	ntpdata->time_status &= ~STA_MODE;
270f939890bSIngo Molnar 
271f939890bSIngo Molnar 	if (secs < MINSEC)
272478b7aabSIngo Molnar 		return 0;
273f939890bSIngo Molnar 
274bee18a23SThomas Gleixner 	if (!(ntpdata->time_status & STA_FLL) && (secs <= MAXSEC))
275478b7aabSIngo Molnar 		return 0;
276f939890bSIngo Molnar 
277bee18a23SThomas Gleixner 	ntpdata->time_status |= STA_MODE;
278f939890bSIngo Molnar 
279a078c6d0SSasha Levin 	return div64_long(offset64 << (NTP_SCALE_SHIFT - SHIFT_FLL), secs);
280f939890bSIngo Molnar }
281f939890bSIngo Molnar 
ntp_update_offset(struct ntp_data * ntpdata,long offset)282bee18a23SThomas Gleixner static void ntp_update_offset(struct ntp_data *ntpdata, long offset)
283ee9851b2SRoman Zippel {
284136bccbcSThomas Gleixner 	s64 freq_adj, offset64;
285136bccbcSThomas Gleixner 	long secs, real_secs;
286ee9851b2SRoman Zippel 
287bee18a23SThomas Gleixner 	if (!(ntpdata->time_status & STA_PLL))
288ee9851b2SRoman Zippel 		return;
289ee9851b2SRoman Zippel 
290bee18a23SThomas Gleixner 	if (!(ntpdata->time_status & STA_NANO)) {
29152d189f1SSasha Levin 		/* Make sure the multiplication below won't overflow */
29252d189f1SSasha Levin 		offset = clamp(offset, -USEC_PER_SEC, USEC_PER_SEC);
2939f14f669SRoman Zippel 		offset *= NSEC_PER_USEC;
29452d189f1SSasha Levin 	}
295ee9851b2SRoman Zippel 
296a0581cdbSThomas Gleixner 	/* Scale the phase adjustment and clamp to the operating range. */
29752d189f1SSasha Levin 	offset = clamp(offset, -MAXPHASE, MAXPHASE);
298ee9851b2SRoman Zippel 
299ee9851b2SRoman Zippel 	/*
300ee9851b2SRoman Zippel 	 * Select how the frequency is to be controlled
301ee9851b2SRoman Zippel 	 * and in which mode (PLL or FLL).
302ee9851b2SRoman Zippel 	 */
303136bccbcSThomas Gleixner 	real_secs = __ktime_get_real_seconds();
304161b8ec2SThomas Gleixner 	secs = (long)(real_secs - ntpdata->time_reftime);
305bee18a23SThomas Gleixner 	if (unlikely(ntpdata->time_status & STA_FREQHOLD))
306c7986acbSIngo Molnar 		secs = 0;
307c7986acbSIngo Molnar 
308161b8ec2SThomas Gleixner 	ntpdata->time_reftime = real_secs;
309ee9851b2SRoman Zippel 
310f939890bSIngo Molnar 	offset64    = offset;
311bee18a23SThomas Gleixner 	freq_adj    = ntp_update_offset_fll(ntpdata, offset64, secs);
312f939890bSIngo Molnar 
3138af3c153SMiroslav Lichvar 	/*
3148af3c153SMiroslav Lichvar 	 * Clamp update interval to reduce PLL gain with low
3158af3c153SMiroslav Lichvar 	 * sampling rate (e.g. intermittent network connection)
3168af3c153SMiroslav Lichvar 	 * to avoid instability.
3178af3c153SMiroslav Lichvar 	 */
318d5143554SThomas Gleixner 	if (unlikely(secs > 1 << (SHIFT_PLL + 1 + ntpdata->time_constant)))
319d5143554SThomas Gleixner 		secs = 1 << (SHIFT_PLL + 1 + ntpdata->time_constant);
3208af3c153SMiroslav Lichvar 
3218af3c153SMiroslav Lichvar 	freq_adj    += (offset64 * secs) <<
322d5143554SThomas Gleixner 			(NTP_SCALE_SHIFT - 2 * (SHIFT_PLL + 2 + ntpdata->time_constant));
323f939890bSIngo Molnar 
324161b8ec2SThomas Gleixner 	freq_adj    = min(freq_adj + ntpdata->time_freq, MAXFREQ_SCALED);
325f939890bSIngo Molnar 
326161b8ec2SThomas Gleixner 	ntpdata->time_freq   = max(freq_adj, -MAXFREQ_SCALED);
3279f14f669SRoman Zippel 
328d5143554SThomas Gleixner 	ntpdata->time_offset = div_s64(offset64 << NTP_SCALE_SHIFT, NTP_INTERVAL_FREQ);
329ee9851b2SRoman Zippel }
330ee9851b2SRoman Zippel 
__ntp_clear(struct ntp_data * ntpdata)33168f66f97SThomas Gleixner static void __ntp_clear(struct ntp_data *ntpdata)
332b0ee7556SRoman Zippel {
333a0581cdbSThomas Gleixner 	/* Stop active adjtime() */
334bb6400a2SThomas Gleixner 	ntpdata->time_adjust	= 0;
335bee18a23SThomas Gleixner 	ntpdata->time_status	|= STA_UNSYNC;
3367891cf29SThomas Gleixner 	ntpdata->time_maxerror	= NTP_PHASE_LIMIT;
3377891cf29SThomas Gleixner 	ntpdata->time_esterror	= NTP_PHASE_LIMIT;
338b0ee7556SRoman Zippel 
33968f66f97SThomas Gleixner 	ntp_update_frequency(ntpdata);
340b0ee7556SRoman Zippel 
341ec93ec22SThomas Gleixner 	ntpdata->tick_length	= ntpdata->tick_length_base;
342d5143554SThomas Gleixner 	ntpdata->time_offset	= 0;
343025b40abSAlexander Gordeev 
34475d956b9SThomas Gleixner 	ntpdata->ntp_next_leap_sec = TIME64_MAX;
345025b40abSAlexander Gordeev 	/* Clear PPS state variables */
3465cc953b8SThomas Gleixner 	pps_clear(ntpdata);
347b0ee7556SRoman Zippel }
348b0ee7556SRoman Zippel 
34968f66f97SThomas Gleixner /**
35068f66f97SThomas Gleixner  * ntp_clear - Clears the NTP state variables
35168f66f97SThomas Gleixner  */
ntp_clear(void)35268f66f97SThomas Gleixner void ntp_clear(void)
35368f66f97SThomas Gleixner {
35468f66f97SThomas Gleixner 	__ntp_clear(&tk_ntp_data);
35568f66f97SThomas Gleixner }
35668f66f97SThomas Gleixner 
357ea7cf49aSJohn Stultz 
ntp_tick_length(void)358ea7cf49aSJohn Stultz u64 ntp_tick_length(void)
359ea7cf49aSJohn Stultz {
360ec93ec22SThomas Gleixner 	return tk_ntp_data.tick_length;
361ea7cf49aSJohn Stultz }
362ea7cf49aSJohn Stultz 
363833f32d7SJohn Stultz /**
364833f32d7SJohn Stultz  * ntp_get_next_leap - Returns the next leapsecond in CLOCK_REALTIME ktime_t
365833f32d7SJohn Stultz  *
366833f32d7SJohn Stultz  * Provides the time of the next leapsecond against CLOCK_REALTIME in
367833f32d7SJohn Stultz  * a ktime_t format. Returns KTIME_MAX if no leapsecond is pending.
368833f32d7SJohn Stultz  */
ntp_get_next_leap(void)369833f32d7SJohn Stultz ktime_t ntp_get_next_leap(void)
370833f32d7SJohn Stultz {
371bee18a23SThomas Gleixner 	struct ntp_data *ntpdata = &tk_ntp_data;
372833f32d7SJohn Stultz 	ktime_t ret;
373833f32d7SJohn Stultz 
374bee18a23SThomas Gleixner 	if ((ntpdata->time_state == TIME_INS) && (ntpdata->time_status & STA_INS))
37575d956b9SThomas Gleixner 		return ktime_set(ntpdata->ntp_next_leap_sec, 0);
3762456e855SThomas Gleixner 	ret = KTIME_MAX;
377833f32d7SJohn Stultz 	return ret;
378833f32d7SJohn Stultz }
379ea7cf49aSJohn Stultz 
3804c7ee8deSjohn stultz /*
381a0581cdbSThomas Gleixner  * This routine handles the overflow of the microsecond field
3824c7ee8deSjohn stultz  *
3834c7ee8deSjohn stultz  * The tricky bits of code to handle the accurate clock support
3844c7ee8deSjohn stultz  * were provided by Dave Mills ([email protected]) of NTP fame.
3854c7ee8deSjohn stultz  * They were originally developed for SUN and DEC kernels.
3864c7ee8deSjohn stultz  * All the kudos should go to Dave for this stuff.
3876b43ae8aSJohn Stultz  *
3886b43ae8aSJohn Stultz  * Also handles leap second processing, and returns leap offset
3894c7ee8deSjohn stultz  */
second_overflow(time64_t secs)390c7963487SDengChao int second_overflow(time64_t secs)
3914c7ee8deSjohn stultz {
392ec93ec22SThomas Gleixner 	struct ntp_data *ntpdata = &tk_ntp_data;
39339854fe8SIngo Molnar 	s64 delta;
3946b43ae8aSJohn Stultz 	int leap = 0;
395c7963487SDengChao 	s32 rem;
3964c7ee8deSjohn stultz 
3976b43ae8aSJohn Stultz 	/*
3986b43ae8aSJohn Stultz 	 * Leap second processing. If in leap-insert state at the end of the
3996b43ae8aSJohn Stultz 	 * day, the system clock is set back one second; if in leap-delete
4006b43ae8aSJohn Stultz 	 * state, the system clock is set ahead one second.
4016b43ae8aSJohn Stultz 	 */
402bee18a23SThomas Gleixner 	switch (ntpdata->time_state) {
4036b43ae8aSJohn Stultz 	case TIME_OK:
404bee18a23SThomas Gleixner 		if (ntpdata->time_status & STA_INS) {
405bee18a23SThomas Gleixner 			ntpdata->time_state = TIME_INS;
406c7963487SDengChao 			div_s64_rem(secs, SECS_PER_DAY, &rem);
40775d956b9SThomas Gleixner 			ntpdata->ntp_next_leap_sec = secs + SECS_PER_DAY - rem;
408bee18a23SThomas Gleixner 		} else if (ntpdata->time_status & STA_DEL) {
409bee18a23SThomas Gleixner 			ntpdata->time_state = TIME_DEL;
410c7963487SDengChao 			div_s64_rem(secs + 1, SECS_PER_DAY, &rem);
41175d956b9SThomas Gleixner 			ntpdata->ntp_next_leap_sec = secs + SECS_PER_DAY - rem;
412833f32d7SJohn Stultz 		}
4136b43ae8aSJohn Stultz 		break;
4146b43ae8aSJohn Stultz 	case TIME_INS:
415bee18a23SThomas Gleixner 		if (!(ntpdata->time_status & STA_INS)) {
41675d956b9SThomas Gleixner 			ntpdata->ntp_next_leap_sec = TIME64_MAX;
417bee18a23SThomas Gleixner 			ntpdata->time_state = TIME_OK;
41875d956b9SThomas Gleixner 		} else if (secs == ntpdata->ntp_next_leap_sec) {
4196b43ae8aSJohn Stultz 			leap = -1;
420bee18a23SThomas Gleixner 			ntpdata->time_state = TIME_OOP;
42138007dc0SAnna-Maria Behnsen 			pr_notice("Clock: inserting leap second 23:59:60 UTC\n");
4226b43ae8aSJohn Stultz 		}
4236b43ae8aSJohn Stultz 		break;
4246b43ae8aSJohn Stultz 	case TIME_DEL:
425bee18a23SThomas Gleixner 		if (!(ntpdata->time_status & STA_DEL)) {
42675d956b9SThomas Gleixner 			ntpdata->ntp_next_leap_sec = TIME64_MAX;
427bee18a23SThomas Gleixner 			ntpdata->time_state = TIME_OK;
42875d956b9SThomas Gleixner 		} else if (secs == ntpdata->ntp_next_leap_sec) {
4296b43ae8aSJohn Stultz 			leap = 1;
43075d956b9SThomas Gleixner 			ntpdata->ntp_next_leap_sec = TIME64_MAX;
431bee18a23SThomas Gleixner 			ntpdata->time_state = TIME_WAIT;
43238007dc0SAnna-Maria Behnsen 			pr_notice("Clock: deleting leap second 23:59:59 UTC\n");
4336b43ae8aSJohn Stultz 		}
4346b43ae8aSJohn Stultz 		break;
4356b43ae8aSJohn Stultz 	case TIME_OOP:
43675d956b9SThomas Gleixner 		ntpdata->ntp_next_leap_sec = TIME64_MAX;
437bee18a23SThomas Gleixner 		ntpdata->time_state = TIME_WAIT;
4386b43ae8aSJohn Stultz 		break;
4396b43ae8aSJohn Stultz 	case TIME_WAIT:
440bee18a23SThomas Gleixner 		if (!(ntpdata->time_status & (STA_INS | STA_DEL)))
441bee18a23SThomas Gleixner 			ntpdata->time_state = TIME_OK;
4426b43ae8aSJohn Stultz 		break;
4436b43ae8aSJohn Stultz 	}
4446b43ae8aSJohn Stultz 
4454c7ee8deSjohn stultz 	/* Bump the maxerror field */
4467891cf29SThomas Gleixner 	ntpdata->time_maxerror += MAXFREQ / NSEC_PER_USEC;
4477891cf29SThomas Gleixner 	if (ntpdata->time_maxerror > NTP_PHASE_LIMIT) {
4487891cf29SThomas Gleixner 		ntpdata->time_maxerror = NTP_PHASE_LIMIT;
449bee18a23SThomas Gleixner 		ntpdata->time_status |= STA_UNSYNC;
4504c7ee8deSjohn stultz 	}
4514c7ee8deSjohn stultz 
452025b40abSAlexander Gordeev 	/* Compute the phase adjustment for the next second */
453ec93ec22SThomas Gleixner 	ntpdata->tick_length	 = ntpdata->tick_length_base;
45439854fe8SIngo Molnar 
455d5143554SThomas Gleixner 	delta			 = ntp_offset_chunk(ntpdata, ntpdata->time_offset);
456d5143554SThomas Gleixner 	ntpdata->time_offset	-= delta;
457ec93ec22SThomas Gleixner 	ntpdata->tick_length	+= delta;
4588f807f8dSRoman Zippel 
459025b40abSAlexander Gordeev 	/* Check PPS signal */
460bee18a23SThomas Gleixner 	pps_dec_valid(ntpdata);
461025b40abSAlexander Gordeev 
462bb6400a2SThomas Gleixner 	if (!ntpdata->time_adjust)
463bd331268SJohn Stultz 		goto out;
4643c972c24SIngo Molnar 
465bb6400a2SThomas Gleixner 	if (ntpdata->time_adjust > MAX_TICKADJ) {
466bb6400a2SThomas Gleixner 		ntpdata->time_adjust -= MAX_TICKADJ;
467ec93ec22SThomas Gleixner 		ntpdata->tick_length += MAX_TICKADJ_SCALED;
468bd331268SJohn Stultz 		goto out;
4693c972c24SIngo Molnar 	}
4703c972c24SIngo Molnar 
471bb6400a2SThomas Gleixner 	if (ntpdata->time_adjust < -MAX_TICKADJ) {
472bb6400a2SThomas Gleixner 		ntpdata->time_adjust += MAX_TICKADJ;
473ec93ec22SThomas Gleixner 		ntpdata->tick_length -= MAX_TICKADJ_SCALED;
474bd331268SJohn Stultz 		goto out;
4753c972c24SIngo Molnar 	}
4763c972c24SIngo Molnar 
477bb6400a2SThomas Gleixner 	ntpdata->tick_length += (s64)(ntpdata->time_adjust * NSEC_PER_USEC / NTP_INTERVAL_FREQ)
4783c972c24SIngo Molnar 				<< NTP_SCALE_SHIFT;
479bb6400a2SThomas Gleixner 	ntpdata->time_adjust = 0;
4806b43ae8aSJohn Stultz 
481bd331268SJohn Stultz out:
4826b43ae8aSJohn Stultz 	return leap;
4834c7ee8deSjohn stultz }
4844c7ee8deSjohn stultz 
485c9e6189fSThomas Gleixner #if defined(CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC)
4860f295b06SJason Gunthorpe static void sync_hw_clock(struct work_struct *work);
487c9e6189fSThomas Gleixner static DECLARE_WORK(sync_work, sync_hw_clock);
488c9e6189fSThomas Gleixner static struct hrtimer sync_hrtimer;
489e3fab2f3SGeert Uytterhoeven #define SYNC_PERIOD_NS (11ULL * 60 * NSEC_PER_SEC)
4900f295b06SJason Gunthorpe 
sync_timer_callback(struct hrtimer * timer)491c9e6189fSThomas Gleixner static enum hrtimer_restart sync_timer_callback(struct hrtimer *timer)
4920f295b06SJason Gunthorpe {
49324c242ecSGeert Uytterhoeven 	queue_work(system_freezable_power_efficient_wq, &sync_work);
4940f295b06SJason Gunthorpe 
495c9e6189fSThomas Gleixner 	return HRTIMER_NORESTART;
4960f295b06SJason Gunthorpe }
4970f295b06SJason Gunthorpe 
sched_sync_hw_clock(unsigned long offset_nsec,bool retry)498c9e6189fSThomas Gleixner static void sched_sync_hw_clock(unsigned long offset_nsec, bool retry)
499c9e6189fSThomas Gleixner {
500c9e6189fSThomas Gleixner 	ktime_t exp = ktime_set(ktime_get_real_seconds(), 0);
5010f295b06SJason Gunthorpe 
502c9e6189fSThomas Gleixner 	if (retry)
503e3fab2f3SGeert Uytterhoeven 		exp = ktime_add_ns(exp, 2ULL * NSEC_PER_SEC - offset_nsec);
504c9e6189fSThomas Gleixner 	else
505c9e6189fSThomas Gleixner 		exp = ktime_add_ns(exp, SYNC_PERIOD_NS - offset_nsec);
506c9e6189fSThomas Gleixner 
507c9e6189fSThomas Gleixner 	hrtimer_start(&sync_hrtimer, exp, HRTIMER_MODE_ABS);
5080f295b06SJason Gunthorpe }
5090f295b06SJason Gunthorpe 
51033e62e83SThomas Gleixner /*
51169eca258SThomas Gleixner  * Check whether @now is correct versus the required time to update the RTC
51269eca258SThomas Gleixner  * and calculate the value which needs to be written to the RTC so that the
51369eca258SThomas Gleixner  * next seconds increment of the RTC after the write is aligned with the next
51469eca258SThomas Gleixner  * seconds increment of clock REALTIME.
51533e62e83SThomas Gleixner  *
51669eca258SThomas Gleixner  * tsched     t1 write(t2.tv_sec - 1sec))	t2 RTC increments seconds
51733e62e83SThomas Gleixner  *
51869eca258SThomas Gleixner  * t2.tv_nsec == 0
51969eca258SThomas Gleixner  * tsched = t2 - set_offset_nsec
52069eca258SThomas Gleixner  * newval = t2 - NSEC_PER_SEC
52169eca258SThomas Gleixner  *
52269eca258SThomas Gleixner  * ==> neval = tsched + set_offset_nsec - NSEC_PER_SEC
52369eca258SThomas Gleixner  *
52469eca258SThomas Gleixner  * As the execution of this code is not guaranteed to happen exactly at
52569eca258SThomas Gleixner  * tsched this allows it to happen within a fuzzy region:
52669eca258SThomas Gleixner  *
52769eca258SThomas Gleixner  *	abs(now - tsched) < FUZZ
52869eca258SThomas Gleixner  *
52969eca258SThomas Gleixner  * If @now is not inside the allowed window the function returns false.
53033e62e83SThomas Gleixner  */
rtc_tv_nsec_ok(unsigned long set_offset_nsec,struct timespec64 * to_set,const struct timespec64 * now)53169eca258SThomas Gleixner static inline bool rtc_tv_nsec_ok(unsigned long set_offset_nsec,
53233e62e83SThomas Gleixner 				  struct timespec64 *to_set,
53333e62e83SThomas Gleixner 				  const struct timespec64 *now)
53433e62e83SThomas Gleixner {
5354bf07f65SIngo Molnar 	/* Allowed error in tv_nsec, arbitrarily set to 5 jiffies in ns. */
53633e62e83SThomas Gleixner 	const unsigned long TIME_SET_NSEC_FUZZ = TICK_NSEC * 5;
53769eca258SThomas Gleixner 	struct timespec64 delay = {.tv_sec = -1,
53833e62e83SThomas Gleixner 				   .tv_nsec = set_offset_nsec};
53933e62e83SThomas Gleixner 
54033e62e83SThomas Gleixner 	*to_set = timespec64_add(*now, delay);
54133e62e83SThomas Gleixner 
54233e62e83SThomas Gleixner 	if (to_set->tv_nsec < TIME_SET_NSEC_FUZZ) {
54333e62e83SThomas Gleixner 		to_set->tv_nsec = 0;
54433e62e83SThomas Gleixner 		return true;
54533e62e83SThomas Gleixner 	}
54633e62e83SThomas Gleixner 
54733e62e83SThomas Gleixner 	if (to_set->tv_nsec > NSEC_PER_SEC - TIME_SET_NSEC_FUZZ) {
54833e62e83SThomas Gleixner 		to_set->tv_sec++;
54933e62e83SThomas Gleixner 		to_set->tv_nsec = 0;
55033e62e83SThomas Gleixner 		return true;
55133e62e83SThomas Gleixner 	}
55233e62e83SThomas Gleixner 	return false;
55333e62e83SThomas Gleixner }
55433e62e83SThomas Gleixner 
5553c00a1feSXunlei Pang #ifdef CONFIG_GENERIC_CMOS_UPDATE
update_persistent_clock64(struct timespec64 now64)5563c00a1feSXunlei Pang int __weak update_persistent_clock64(struct timespec64 now64)
5573c00a1feSXunlei Pang {
55892661788SArnd Bergmann 	return -ENODEV;
5593c00a1feSXunlei Pang }
56076e87d96SThomas Gleixner #else
update_persistent_clock64(struct timespec64 now64)56176e87d96SThomas Gleixner static inline int update_persistent_clock64(struct timespec64 now64)
56276e87d96SThomas Gleixner {
56376e87d96SThomas Gleixner 	return -ENODEV;
56476e87d96SThomas Gleixner }
5653c00a1feSXunlei Pang #endif
5663c00a1feSXunlei Pang 
56776e87d96SThomas Gleixner #ifdef CONFIG_RTC_SYSTOHC
56876e87d96SThomas Gleixner /* Save NTP synchronized time to the RTC */
update_rtc(struct timespec64 * to_set,unsigned long * offset_nsec)56976e87d96SThomas Gleixner static int update_rtc(struct timespec64 *to_set, unsigned long *offset_nsec)
5704c7ee8deSjohn stultz {
57176e87d96SThomas Gleixner 	struct rtc_device *rtc;
57276e87d96SThomas Gleixner 	struct rtc_time tm;
57376e87d96SThomas Gleixner 	int err = -ENODEV;
5740f295b06SJason Gunthorpe 
57576e87d96SThomas Gleixner 	rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE);
57676e87d96SThomas Gleixner 	if (!rtc)
57776e87d96SThomas Gleixner 		return -ENODEV;
5780f295b06SJason Gunthorpe 
57976e87d96SThomas Gleixner 	if (!rtc->ops || !rtc->ops->set_time)
58076e87d96SThomas Gleixner 		goto out_close;
58182644459SThomas Gleixner 
58276e87d96SThomas Gleixner 	/* First call might not have the correct offset */
58376e87d96SThomas Gleixner 	if (*offset_nsec == rtc->set_offset_nsec) {
58476e87d96SThomas Gleixner 		rtc_time64_to_tm(to_set->tv_sec, &tm);
58576e87d96SThomas Gleixner 		err = rtc_set_time(rtc, &tm);
58676e87d96SThomas Gleixner 	} else {
58776e87d96SThomas Gleixner 		/* Store the update offset and let the caller try again */
58876e87d96SThomas Gleixner 		*offset_nsec = rtc->set_offset_nsec;
58976e87d96SThomas Gleixner 		err = -EAGAIN;
5900f295b06SJason Gunthorpe 	}
59176e87d96SThomas Gleixner out_close:
59276e87d96SThomas Gleixner 	rtc_class_close(rtc);
59376e87d96SThomas Gleixner 	return err;
594023f333aSJason Gunthorpe }
59576e87d96SThomas Gleixner #else
update_rtc(struct timespec64 * to_set,unsigned long * offset_nsec)59676e87d96SThomas Gleixner static inline int update_rtc(struct timespec64 *to_set, unsigned long *offset_nsec)
59776e87d96SThomas Gleixner {
59876e87d96SThomas Gleixner 	return -ENODEV;
5994c7ee8deSjohn stultz }
60076e87d96SThomas Gleixner #endif
6010f295b06SJason Gunthorpe 
60248c3c65fSThomas Gleixner /**
60348c3c65fSThomas Gleixner  * ntp_synced - Tells whether the NTP status is not UNSYNC
60448c3c65fSThomas Gleixner  * Returns:	true if not UNSYNC, false otherwise
60548c3c65fSThomas Gleixner  */
ntp_synced(void)60648c3c65fSThomas Gleixner static inline bool ntp_synced(void)
60748c3c65fSThomas Gleixner {
608bee18a23SThomas Gleixner 	return !(tk_ntp_data.time_status & STA_UNSYNC);
60948c3c65fSThomas Gleixner }
61048c3c65fSThomas Gleixner 
6110f295b06SJason Gunthorpe /*
6120f295b06SJason Gunthorpe  * If we have an externally synchronized Linux clock, then update RTC clock
6130f295b06SJason Gunthorpe  * accordingly every ~11 minutes. Generally RTCs can only store second
6140f295b06SJason Gunthorpe  * precision, but many RTCs will adjust the phase of their second tick to
6150f295b06SJason Gunthorpe  * match the moment of update. This infrastructure arranges to call to the RTC
6160f295b06SJason Gunthorpe  * set at the correct moment to phase synchronize the RTC second tick over
6170f295b06SJason Gunthorpe  * with the kernel clock.
6180f295b06SJason Gunthorpe  */
sync_hw_clock(struct work_struct * work)6190f295b06SJason Gunthorpe static void sync_hw_clock(struct work_struct *work)
6200f295b06SJason Gunthorpe {
621c9e6189fSThomas Gleixner 	/*
62276e87d96SThomas Gleixner 	 * The default synchronization offset is 500ms for the deprecated
62376e87d96SThomas Gleixner 	 * update_persistent_clock64() under the assumption that it uses
62476e87d96SThomas Gleixner 	 * the infamous CMOS clock (MC146818).
62576e87d96SThomas Gleixner 	 */
62676e87d96SThomas Gleixner 	static unsigned long offset_nsec = NSEC_PER_SEC / 2;
62776e87d96SThomas Gleixner 	struct timespec64 now, to_set;
62876e87d96SThomas Gleixner 	int res = -EAGAIN;
62976e87d96SThomas Gleixner 
63076e87d96SThomas Gleixner 	/*
631c9e6189fSThomas Gleixner 	 * Don't update if STA_UNSYNC is set and if ntp_notify_cmos_timer()
632c9e6189fSThomas Gleixner 	 * managed to schedule the work between the timer firing and the
633c9e6189fSThomas Gleixner 	 * work being able to rearm the timer. Wait for the timer to expire.
634c9e6189fSThomas Gleixner 	 */
635c9e6189fSThomas Gleixner 	if (!ntp_synced() || hrtimer_is_queued(&sync_hrtimer))
6360f295b06SJason Gunthorpe 		return;
6370f295b06SJason Gunthorpe 
63876e87d96SThomas Gleixner 	ktime_get_real_ts64(&now);
63976e87d96SThomas Gleixner 	/* If @now is not in the allowed window, try again */
64076e87d96SThomas Gleixner 	if (!rtc_tv_nsec_ok(offset_nsec, &to_set, &now))
64176e87d96SThomas Gleixner 		goto rearm;
6420f295b06SJason Gunthorpe 
64376e87d96SThomas Gleixner 	/* Take timezone adjusted RTCs into account */
64476e87d96SThomas Gleixner 	if (persistent_clock_is_local)
64576e87d96SThomas Gleixner 		to_set.tv_sec -= (sys_tz.tz_minuteswest * 60);
64676e87d96SThomas Gleixner 
64776e87d96SThomas Gleixner 	/* Try the legacy RTC first. */
64876e87d96SThomas Gleixner 	res = update_persistent_clock64(to_set);
64976e87d96SThomas Gleixner 	if (res != -ENODEV)
65076e87d96SThomas Gleixner 		goto rearm;
65176e87d96SThomas Gleixner 
65276e87d96SThomas Gleixner 	/* Try the RTC class */
65376e87d96SThomas Gleixner 	res = update_rtc(&to_set, &offset_nsec);
65476e87d96SThomas Gleixner 	if (res == -ENODEV)
65576e87d96SThomas Gleixner 		return;
65676e87d96SThomas Gleixner rearm:
65776e87d96SThomas Gleixner 	sched_sync_hw_clock(offset_nsec, res != 0);
65882644459SThomas Gleixner }
65982644459SThomas Gleixner 
ntp_notify_cmos_timer(bool offset_set)66035b603f8SBenjamin ROBIN void ntp_notify_cmos_timer(bool offset_set)
66182644459SThomas Gleixner {
662c9e6189fSThomas Gleixner 	/*
66335b603f8SBenjamin ROBIN 	 * If the time jumped (using ADJ_SETOFFSET) cancels sync timer,
66435b603f8SBenjamin ROBIN 	 * which may have been running if the time was synchronized
66535b603f8SBenjamin ROBIN 	 * prior to the ADJ_SETOFFSET call.
66635b603f8SBenjamin ROBIN 	 */
66735b603f8SBenjamin ROBIN 	if (offset_set)
66835b603f8SBenjamin ROBIN 		hrtimer_cancel(&sync_hrtimer);
66935b603f8SBenjamin ROBIN 
67035b603f8SBenjamin ROBIN 	/*
671c9e6189fSThomas Gleixner 	 * When the work is currently executed but has not yet the timer
672c9e6189fSThomas Gleixner 	 * rearmed this queues the work immediately again. No big issue,
673c9e6189fSThomas Gleixner 	 * just a pointless work scheduled.
674c9e6189fSThomas Gleixner 	 */
675c9e6189fSThomas Gleixner 	if (ntp_synced() && !hrtimer_is_queued(&sync_hrtimer))
67624c242ecSGeert Uytterhoeven 		queue_work(system_freezable_power_efficient_wq, &sync_work);
67782644459SThomas Gleixner }
67882644459SThomas Gleixner 
ntp_init_cmos_sync(void)679c9e6189fSThomas Gleixner static void __init ntp_init_cmos_sync(void)
680c9e6189fSThomas Gleixner {
681*f66b0acfSNam Cao 	hrtimer_setup(&sync_hrtimer, sync_timer_callback, CLOCK_REALTIME, HRTIMER_MODE_ABS);
682c9e6189fSThomas Gleixner }
683c9e6189fSThomas Gleixner #else /* CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC) */
ntp_init_cmos_sync(void)684c9e6189fSThomas Gleixner static inline void __init ntp_init_cmos_sync(void) { }
685c9e6189fSThomas Gleixner #endif /* !CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC) */
686c9e6189fSThomas Gleixner 
68780f22571SIngo Molnar /*
68880f22571SIngo Molnar  * Propagate a new txc->status value into the NTP state:
68980f22571SIngo Molnar  */
process_adj_status(struct ntp_data * ntpdata,const struct __kernel_timex * txc)690bee18a23SThomas Gleixner static inline void process_adj_status(struct ntp_data *ntpdata, const struct __kernel_timex *txc)
69180f22571SIngo Molnar {
692bee18a23SThomas Gleixner 	if ((ntpdata->time_status & STA_PLL) && !(txc->status & STA_PLL)) {
693bee18a23SThomas Gleixner 		ntpdata->time_state = TIME_OK;
694bee18a23SThomas Gleixner 		ntpdata->time_status = STA_UNSYNC;
69575d956b9SThomas Gleixner 		ntpdata->ntp_next_leap_sec = TIME64_MAX;
696a0581cdbSThomas Gleixner 		/* Restart PPS frequency calibration */
697b1c89a76SThomas Gleixner 		pps_reset_freq_interval(ntpdata);
69880f22571SIngo Molnar 	}
69980f22571SIngo Molnar 
70080f22571SIngo Molnar 	/*
70180f22571SIngo Molnar 	 * If we turn on PLL adjustments then reset the
70280f22571SIngo Molnar 	 * reference time to current time.
70380f22571SIngo Molnar 	 */
704bee18a23SThomas Gleixner 	if (!(ntpdata->time_status & STA_PLL) && (txc->status & STA_PLL))
705161b8ec2SThomas Gleixner 		ntpdata->time_reftime = __ktime_get_real_seconds();
70680f22571SIngo Molnar 
707bee18a23SThomas Gleixner 	/* only set allowed bits */
708bee18a23SThomas Gleixner 	ntpdata->time_status &= STA_RONLY;
709bee18a23SThomas Gleixner 	ntpdata->time_status |= txc->status & ~STA_RONLY;
71080f22571SIngo Molnar }
711cd5398beSRichard Cochran 
process_adjtimex_modes(struct ntp_data * ntpdata,const struct __kernel_timex * txc,s32 * time_tai)71268f66f97SThomas Gleixner static inline void process_adjtimex_modes(struct ntp_data *ntpdata, const struct __kernel_timex *txc,
713ead25417SDeepa Dinamani 					  s32 *time_tai)
71480f22571SIngo Molnar {
71580f22571SIngo Molnar 	if (txc->modes & ADJ_STATUS)
716bee18a23SThomas Gleixner 		process_adj_status(ntpdata, txc);
71780f22571SIngo Molnar 
71880f22571SIngo Molnar 	if (txc->modes & ADJ_NANO)
719bee18a23SThomas Gleixner 		ntpdata->time_status |= STA_NANO;
720e9629165SIngo Molnar 
72180f22571SIngo Molnar 	if (txc->modes & ADJ_MICRO)
722bee18a23SThomas Gleixner 		ntpdata->time_status &= ~STA_NANO;
72380f22571SIngo Molnar 
72480f22571SIngo Molnar 	if (txc->modes & ADJ_FREQUENCY) {
725161b8ec2SThomas Gleixner 		ntpdata->time_freq = txc->freq * PPM_SCALE;
726161b8ec2SThomas Gleixner 		ntpdata->time_freq = min(ntpdata->time_freq, MAXFREQ_SCALED);
727161b8ec2SThomas Gleixner 		ntpdata->time_freq = max(ntpdata->time_freq, -MAXFREQ_SCALED);
728a0581cdbSThomas Gleixner 		/* Update pps_freq */
72912850b46SThomas Gleixner 		pps_set_freq(ntpdata);
73080f22571SIngo Molnar 	}
73180f22571SIngo Molnar 
73280f22571SIngo Molnar 	if (txc->modes & ADJ_MAXERROR)
7337891cf29SThomas Gleixner 		ntpdata->time_maxerror = clamp(txc->maxerror, 0, NTP_PHASE_LIMIT);
734e9629165SIngo Molnar 
73580f22571SIngo Molnar 	if (txc->modes & ADJ_ESTERROR)
7367891cf29SThomas Gleixner 		ntpdata->time_esterror = clamp(txc->esterror, 0, NTP_PHASE_LIMIT);
73780f22571SIngo Molnar 
73880f22571SIngo Molnar 	if (txc->modes & ADJ_TIMECONST) {
739d5143554SThomas Gleixner 		ntpdata->time_constant = clamp(txc->constant, 0, MAXTC);
740bee18a23SThomas Gleixner 		if (!(ntpdata->time_status & STA_NANO))
741d5143554SThomas Gleixner 			ntpdata->time_constant += 4;
742d5143554SThomas Gleixner 		ntpdata->time_constant = clamp(ntpdata->time_constant, 0, MAXTC);
74380f22571SIngo Molnar 	}
74480f22571SIngo Molnar 
745bee18a23SThomas Gleixner 	if (txc->modes & ADJ_TAI && txc->constant >= 0 && txc->constant <= MAX_TAI_OFFSET)
746cc244ddaSJohn Stultz 		*time_tai = txc->constant;
74780f22571SIngo Molnar 
74880f22571SIngo Molnar 	if (txc->modes & ADJ_OFFSET)
749bee18a23SThomas Gleixner 		ntp_update_offset(ntpdata, txc->offset);
750e9629165SIngo Molnar 
75180f22571SIngo Molnar 	if (txc->modes & ADJ_TICK)
75268f66f97SThomas Gleixner 		ntpdata->tick_usec = txc->tick;
75380f22571SIngo Molnar 
75480f22571SIngo Molnar 	if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET))
75568f66f97SThomas Gleixner 		ntp_update_frequency(ntpdata);
75680f22571SIngo Molnar }
75780f22571SIngo Molnar 
758ad460967SJohn Stultz /*
759a0581cdbSThomas Gleixner  * adjtimex() mainly allows reading (and writing, if superuser) of
760ad460967SJohn Stultz  * kernel time-keeping variables. used by xntpd.
761ad460967SJohn Stultz  */
__do_adjtimex(struct __kernel_timex * txc,const struct timespec64 * ts,s32 * time_tai,struct audit_ntp_data * ad)762ead25417SDeepa Dinamani int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts,
7637e8eda73SOndrej Mosnacek 		  s32 *time_tai, struct audit_ntp_data *ad)
764ad460967SJohn Stultz {
76568f66f97SThomas Gleixner 	struct ntp_data *ntpdata = &tk_ntp_data;
766ad460967SJohn Stultz 	int result;
767ad460967SJohn Stultz 
768916c7a85SRoman Zippel 	if (txc->modes & ADJ_ADJTIME) {
769bb6400a2SThomas Gleixner 		long save_adjust = ntpdata->time_adjust;
770916c7a85SRoman Zippel 
771916c7a85SRoman Zippel 		if (!(txc->modes & ADJ_OFFSET_READONLY)) {
772916c7a85SRoman Zippel 			/* adjtime() is independent from ntp_adjtime() */
773bb6400a2SThomas Gleixner 			ntpdata->time_adjust = txc->offset;
77468f66f97SThomas Gleixner 			ntp_update_frequency(ntpdata);
7757e8eda73SOndrej Mosnacek 
7767e8eda73SOndrej Mosnacek 			audit_ntp_set_old(ad, AUDIT_NTP_ADJUST,	save_adjust);
777bb6400a2SThomas Gleixner 			audit_ntp_set_new(ad, AUDIT_NTP_ADJUST,	ntpdata->time_adjust);
778916c7a85SRoman Zippel 		}
779916c7a85SRoman Zippel 		txc->offset = save_adjust;
780e9629165SIngo Molnar 	} else {
78180f22571SIngo Molnar 		/* If there are input parameters, then process them: */
7827e8eda73SOndrej Mosnacek 		if (txc->modes) {
783d5143554SThomas Gleixner 			audit_ntp_set_old(ad, AUDIT_NTP_OFFSET,	ntpdata->time_offset);
784161b8ec2SThomas Gleixner 			audit_ntp_set_old(ad, AUDIT_NTP_FREQ,	ntpdata->time_freq);
785bee18a23SThomas Gleixner 			audit_ntp_set_old(ad, AUDIT_NTP_STATUS,	ntpdata->time_status);
7867e8eda73SOndrej Mosnacek 			audit_ntp_set_old(ad, AUDIT_NTP_TAI,	*time_tai);
78768f66f97SThomas Gleixner 			audit_ntp_set_old(ad, AUDIT_NTP_TICK,	ntpdata->tick_usec);
7887e8eda73SOndrej Mosnacek 
78968f66f97SThomas Gleixner 			process_adjtimex_modes(ntpdata, txc, time_tai);
790eea83d89SRoman Zippel 
791d5143554SThomas Gleixner 			audit_ntp_set_new(ad, AUDIT_NTP_OFFSET,	ntpdata->time_offset);
792161b8ec2SThomas Gleixner 			audit_ntp_set_new(ad, AUDIT_NTP_FREQ,	ntpdata->time_freq);
793bee18a23SThomas Gleixner 			audit_ntp_set_new(ad, AUDIT_NTP_STATUS,	ntpdata->time_status);
7947e8eda73SOndrej Mosnacek 			audit_ntp_set_new(ad, AUDIT_NTP_TAI,	*time_tai);
79568f66f97SThomas Gleixner 			audit_ntp_set_new(ad, AUDIT_NTP_TICK,	ntpdata->tick_usec);
7967e8eda73SOndrej Mosnacek 		}
7977e8eda73SOndrej Mosnacek 
798d5143554SThomas Gleixner 		txc->offset = shift_right(ntpdata->time_offset * NTP_INTERVAL_FREQ, NTP_SCALE_SHIFT);
799bee18a23SThomas Gleixner 		if (!(ntpdata->time_status & STA_NANO))
800f5807b06SMarcelo Dalmas 			txc->offset = div_s64(txc->offset, NSEC_PER_USEC);
801e9629165SIngo Molnar 	}
802916c7a85SRoman Zippel 
803bee18a23SThomas Gleixner 	result = ntpdata->time_state;
804bee18a23SThomas Gleixner 	if (is_error_status(ntpdata->time_status))
805916c7a85SRoman Zippel 		result = TIME_ERROR;
806916c7a85SRoman Zippel 
807161b8ec2SThomas Gleixner 	txc->freq	   = shift_right((ntpdata->time_freq >> PPM_SCALE_INV_SHIFT) *
8082b9d1496SIngo Molnar 					 PPM_SCALE_INV, NTP_SCALE_SHIFT);
8097891cf29SThomas Gleixner 	txc->maxerror	   = ntpdata->time_maxerror;
8107891cf29SThomas Gleixner 	txc->esterror	   = ntpdata->time_esterror;
811bee18a23SThomas Gleixner 	txc->status	   = ntpdata->time_status;
812d5143554SThomas Gleixner 	txc->constant	   = ntpdata->time_constant;
81370bc42f9SAdrian Bunk 	txc->precision	   = 1;
814074b3b87SRoman Zippel 	txc->tolerance	   = MAXFREQ_SCALED / PPM_SCALE;
81568f66f97SThomas Gleixner 	txc->tick	   = ntpdata->tick_usec;
81687ace39bSJohn Stultz 	txc->tai	   = *time_tai;
8174c7ee8deSjohn stultz 
818a0581cdbSThomas Gleixner 	/* Fill PPS status fields */
819bee18a23SThomas Gleixner 	pps_fill_timex(ntpdata, txc);
820e9629165SIngo Molnar 
8212f584134SArnd Bergmann 	txc->time.tv_sec = ts->tv_sec;
82287ace39bSJohn Stultz 	txc->time.tv_usec = ts->tv_nsec;
823bee18a23SThomas Gleixner 	if (!(ntpdata->time_status & STA_NANO))
824ead25417SDeepa Dinamani 		txc->time.tv_usec = ts->tv_nsec / NSEC_PER_USEC;
825ee9851b2SRoman Zippel 
82696efdcf2SJohn Stultz 	/* Handle leapsec adjustments */
82775d956b9SThomas Gleixner 	if (unlikely(ts->tv_sec >= ntpdata->ntp_next_leap_sec)) {
828bee18a23SThomas Gleixner 		if ((ntpdata->time_state == TIME_INS) && (ntpdata->time_status & STA_INS)) {
82996efdcf2SJohn Stultz 			result = TIME_OOP;
83096efdcf2SJohn Stultz 			txc->tai++;
83196efdcf2SJohn Stultz 			txc->time.tv_sec--;
83296efdcf2SJohn Stultz 		}
833bee18a23SThomas Gleixner 		if ((ntpdata->time_state == TIME_DEL) && (ntpdata->time_status & STA_DEL)) {
83496efdcf2SJohn Stultz 			result = TIME_WAIT;
83596efdcf2SJohn Stultz 			txc->tai--;
83696efdcf2SJohn Stultz 			txc->time.tv_sec++;
83796efdcf2SJohn Stultz 		}
83875d956b9SThomas Gleixner 		if ((ntpdata->time_state == TIME_OOP) && (ts->tv_sec == ntpdata->ntp_next_leap_sec))
83996efdcf2SJohn Stultz 			result = TIME_WAIT;
84096efdcf2SJohn Stultz 	}
84196efdcf2SJohn Stultz 
842ee9851b2SRoman Zippel 	return result;
8434c7ee8deSjohn stultz }
84410a398d0SRoman Zippel 
845025b40abSAlexander Gordeev #ifdef	CONFIG_NTP_PPS
846025b40abSAlexander Gordeev 
847a0581cdbSThomas Gleixner /*
848a0581cdbSThomas Gleixner  * struct pps_normtime is basically a struct timespec, but it is
849025b40abSAlexander Gordeev  * semantically different (and it is the reason why it was invented):
850025b40abSAlexander Gordeev  * pps_normtime.nsec has a range of ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ]
851a0581cdbSThomas Gleixner  * while timespec.tv_nsec has a range of [0, NSEC_PER_SEC)
852a0581cdbSThomas Gleixner  */
853025b40abSAlexander Gordeev struct pps_normtime {
8547ec88e4bSArnd Bergmann 	s64		sec;	/* seconds */
855025b40abSAlexander Gordeev 	long		nsec;	/* nanoseconds */
856025b40abSAlexander Gordeev };
857025b40abSAlexander Gordeev 
858a0581cdbSThomas Gleixner /*
859a0581cdbSThomas Gleixner  * Normalize the timestamp so that nsec is in the
860a0581cdbSThomas Gleixner  * [ -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] interval
861a0581cdbSThomas Gleixner  */
pps_normalize_ts(struct timespec64 ts)8627ec88e4bSArnd Bergmann static inline struct pps_normtime pps_normalize_ts(struct timespec64 ts)
863025b40abSAlexander Gordeev {
864025b40abSAlexander Gordeev 	struct pps_normtime norm = {
865025b40abSAlexander Gordeev 		.sec = ts.tv_sec,
866025b40abSAlexander Gordeev 		.nsec = ts.tv_nsec
867025b40abSAlexander Gordeev 	};
868025b40abSAlexander Gordeev 
869025b40abSAlexander Gordeev 	if (norm.nsec > (NSEC_PER_SEC >> 1)) {
870025b40abSAlexander Gordeev 		norm.nsec -= NSEC_PER_SEC;
871025b40abSAlexander Gordeev 		norm.sec++;
872025b40abSAlexander Gordeev 	}
873025b40abSAlexander Gordeev 
874025b40abSAlexander Gordeev 	return norm;
875025b40abSAlexander Gordeev }
876025b40abSAlexander Gordeev 
877a0581cdbSThomas Gleixner /* Get current phase correction and jitter */
pps_phase_filter_get(struct ntp_data * ntpdata,long * jitter)8785cc953b8SThomas Gleixner static inline long pps_phase_filter_get(struct ntp_data *ntpdata, long *jitter)
879025b40abSAlexander Gordeev {
8805cc953b8SThomas Gleixner 	*jitter = ntpdata->pps_tf[0] - ntpdata->pps_tf[1];
881025b40abSAlexander Gordeev 	if (*jitter < 0)
882025b40abSAlexander Gordeev 		*jitter = -*jitter;
883025b40abSAlexander Gordeev 
884025b40abSAlexander Gordeev 	/* TODO: test various filters */
8855cc953b8SThomas Gleixner 	return ntpdata->pps_tf[0];
886025b40abSAlexander Gordeev }
887025b40abSAlexander Gordeev 
888a0581cdbSThomas Gleixner /* Add the sample to the phase filter */
pps_phase_filter_add(struct ntp_data * ntpdata,long err)8895cc953b8SThomas Gleixner static inline void pps_phase_filter_add(struct ntp_data *ntpdata, long err)
890025b40abSAlexander Gordeev {
8915cc953b8SThomas Gleixner 	ntpdata->pps_tf[2] = ntpdata->pps_tf[1];
8925cc953b8SThomas Gleixner 	ntpdata->pps_tf[1] = ntpdata->pps_tf[0];
8935cc953b8SThomas Gleixner 	ntpdata->pps_tf[0] = err;
894025b40abSAlexander Gordeev }
895025b40abSAlexander Gordeev 
896a0581cdbSThomas Gleixner /*
897a0581cdbSThomas Gleixner  * Decrease frequency calibration interval length. It is halved after four
898a0581cdbSThomas Gleixner  * consecutive unstable intervals.
899025b40abSAlexander Gordeev  */
pps_dec_freq_interval(struct ntp_data * ntpdata)900b1c89a76SThomas Gleixner static inline void pps_dec_freq_interval(struct ntp_data *ntpdata)
901025b40abSAlexander Gordeev {
902b1c89a76SThomas Gleixner 	if (--ntpdata->pps_intcnt <= -PPS_INTCOUNT) {
903b1c89a76SThomas Gleixner 		ntpdata->pps_intcnt = -PPS_INTCOUNT;
904b1c89a76SThomas Gleixner 		if (ntpdata->pps_shift > PPS_INTMIN) {
905b1c89a76SThomas Gleixner 			ntpdata->pps_shift--;
906b1c89a76SThomas Gleixner 			ntpdata->pps_intcnt = 0;
907025b40abSAlexander Gordeev 		}
908025b40abSAlexander Gordeev 	}
909025b40abSAlexander Gordeev }
910025b40abSAlexander Gordeev 
911a0581cdbSThomas Gleixner /*
912a0581cdbSThomas Gleixner  * Increase frequency calibration interval length. It is doubled after
913a0581cdbSThomas Gleixner  * four consecutive stable intervals.
914025b40abSAlexander Gordeev  */
pps_inc_freq_interval(struct ntp_data * ntpdata)915b1c89a76SThomas Gleixner static inline void pps_inc_freq_interval(struct ntp_data *ntpdata)
916025b40abSAlexander Gordeev {
917b1c89a76SThomas Gleixner 	if (++ntpdata->pps_intcnt >= PPS_INTCOUNT) {
918b1c89a76SThomas Gleixner 		ntpdata->pps_intcnt = PPS_INTCOUNT;
919b1c89a76SThomas Gleixner 		if (ntpdata->pps_shift < PPS_INTMAX) {
920b1c89a76SThomas Gleixner 			ntpdata->pps_shift++;
921b1c89a76SThomas Gleixner 			ntpdata->pps_intcnt = 0;
922025b40abSAlexander Gordeev 		}
923025b40abSAlexander Gordeev 	}
924025b40abSAlexander Gordeev }
925025b40abSAlexander Gordeev 
926a0581cdbSThomas Gleixner /*
927a0581cdbSThomas Gleixner  * Update clock frequency based on MONOTONIC_RAW clock PPS signal
928025b40abSAlexander Gordeev  * timestamps
929025b40abSAlexander Gordeev  *
930025b40abSAlexander Gordeev  * At the end of the calibration interval the difference between the
931025b40abSAlexander Gordeev  * first and last MONOTONIC_RAW clock timestamps divided by the length
932025b40abSAlexander Gordeev  * of the interval becomes the frequency update. If the interval was
933025b40abSAlexander Gordeev  * too long, the data are discarded.
934025b40abSAlexander Gordeev  * Returns the difference between old and new frequency values.
935025b40abSAlexander Gordeev  */
hardpps_update_freq(struct ntp_data * ntpdata,struct pps_normtime freq_norm)93668f66f97SThomas Gleixner static long hardpps_update_freq(struct ntp_data *ntpdata, struct pps_normtime freq_norm)
937025b40abSAlexander Gordeev {
938025b40abSAlexander Gordeev 	long delta, delta_mod;
939025b40abSAlexander Gordeev 	s64 ftemp;
940025b40abSAlexander Gordeev 
941a0581cdbSThomas Gleixner 	/* Check if the frequency interval was too long */
942b1c89a76SThomas Gleixner 	if (freq_norm.sec > (2 << ntpdata->pps_shift)) {
943bee18a23SThomas Gleixner 		ntpdata->time_status |= STA_PPSERROR;
9446fadb4a6SThomas Gleixner 		ntpdata->pps_errcnt++;
945b1c89a76SThomas Gleixner 		pps_dec_freq_interval(ntpdata);
94638007dc0SAnna-Maria Behnsen 		printk_deferred(KERN_ERR "hardpps: PPSERROR: interval too long - %lld s\n",
947025b40abSAlexander Gordeev 				freq_norm.sec);
948025b40abSAlexander Gordeev 		return 0;
949025b40abSAlexander Gordeev 	}
950025b40abSAlexander Gordeev 
951a0581cdbSThomas Gleixner 	/*
952a0581cdbSThomas Gleixner 	 * Here the raw frequency offset and wander (stability) is
953a0581cdbSThomas Gleixner 	 * calculated. If the wander is less than the wander threshold the
954a0581cdbSThomas Gleixner 	 * interval is increased; otherwise it is decreased.
955025b40abSAlexander Gordeev 	 */
956025b40abSAlexander Gordeev 	ftemp = div_s64(((s64)(-freq_norm.nsec)) << NTP_SCALE_SHIFT,
957025b40abSAlexander Gordeev 			freq_norm.sec);
95812850b46SThomas Gleixner 	delta = shift_right(ftemp - ntpdata->pps_freq, NTP_SCALE_SHIFT);
95912850b46SThomas Gleixner 	ntpdata->pps_freq = ftemp;
960025b40abSAlexander Gordeev 	if (delta > PPS_MAXWANDER || delta < -PPS_MAXWANDER) {
96138007dc0SAnna-Maria Behnsen 		printk_deferred(KERN_WARNING "hardpps: PPSWANDER: change=%ld\n", delta);
962bee18a23SThomas Gleixner 		ntpdata->time_status |= STA_PPSWANDER;
9636fadb4a6SThomas Gleixner 		ntpdata->pps_stbcnt++;
964b1c89a76SThomas Gleixner 		pps_dec_freq_interval(ntpdata);
965a0581cdbSThomas Gleixner 	} else {
966a0581cdbSThomas Gleixner 		/* Good sample */
967b1c89a76SThomas Gleixner 		pps_inc_freq_interval(ntpdata);
968025b40abSAlexander Gordeev 	}
969025b40abSAlexander Gordeev 
970a0581cdbSThomas Gleixner 	/*
971a0581cdbSThomas Gleixner 	 * The stability metric is calculated as the average of recent
972a0581cdbSThomas Gleixner 	 * frequency changes, but is used only for performance monitoring
973025b40abSAlexander Gordeev 	 */
974025b40abSAlexander Gordeev 	delta_mod = delta;
975025b40abSAlexander Gordeev 	if (delta_mod < 0)
976025b40abSAlexander Gordeev 		delta_mod = -delta_mod;
97712850b46SThomas Gleixner 	ntpdata->pps_stabil += (div_s64(((s64)delta_mod) << (NTP_SCALE_SHIFT - SHIFT_USEC),
97812850b46SThomas Gleixner 				     NSEC_PER_USEC) - ntpdata->pps_stabil) >> PPS_INTMIN;
979025b40abSAlexander Gordeev 
980a0581cdbSThomas Gleixner 	/* If enabled, the system clock frequency is updated */
981bee18a23SThomas Gleixner 	if ((ntpdata->time_status & STA_PPSFREQ) && !(ntpdata->time_status & STA_FREQHOLD)) {
98212850b46SThomas Gleixner 		ntpdata->time_freq = ntpdata->pps_freq;
98368f66f97SThomas Gleixner 		ntp_update_frequency(ntpdata);
984025b40abSAlexander Gordeev 	}
985025b40abSAlexander Gordeev 
986025b40abSAlexander Gordeev 	return delta;
987025b40abSAlexander Gordeev }
988025b40abSAlexander Gordeev 
989a0581cdbSThomas Gleixner /* Correct REALTIME clock phase error against PPS signal */
hardpps_update_phase(struct ntp_data * ntpdata,long error)990bee18a23SThomas Gleixner static void hardpps_update_phase(struct ntp_data *ntpdata, long error)
991025b40abSAlexander Gordeev {
992025b40abSAlexander Gordeev 	long correction = -error;
993025b40abSAlexander Gordeev 	long jitter;
994025b40abSAlexander Gordeev 
995a0581cdbSThomas Gleixner 	/* Add the sample to the median filter */
9965cc953b8SThomas Gleixner 	pps_phase_filter_add(ntpdata, correction);
9975cc953b8SThomas Gleixner 	correction = pps_phase_filter_get(ntpdata, &jitter);
998025b40abSAlexander Gordeev 
999a0581cdbSThomas Gleixner 	/*
1000a0581cdbSThomas Gleixner 	 * Nominal jitter is due to PPS signal noise. If it exceeds the
1001025b40abSAlexander Gordeev 	 * threshold, the sample is discarded; otherwise, if so enabled,
1002025b40abSAlexander Gordeev 	 * the time offset is updated.
1003025b40abSAlexander Gordeev 	 */
10049d7130dfSThomas Gleixner 	if (jitter > (ntpdata->pps_jitter << PPS_POPCORN)) {
100538007dc0SAnna-Maria Behnsen 		printk_deferred(KERN_WARNING "hardpps: PPSJITTER: jitter=%ld, limit=%ld\n",
10069d7130dfSThomas Gleixner 				jitter, (ntpdata->pps_jitter << PPS_POPCORN));
1007bee18a23SThomas Gleixner 		ntpdata->time_status |= STA_PPSJITTER;
10086fadb4a6SThomas Gleixner 		ntpdata->pps_jitcnt++;
1009bee18a23SThomas Gleixner 	} else if (ntpdata->time_status & STA_PPSTIME) {
1010a0581cdbSThomas Gleixner 		/* Correct the time using the phase offset */
1011d5143554SThomas Gleixner 		ntpdata->time_offset = div_s64(((s64)correction) << NTP_SCALE_SHIFT,
1012d5143554SThomas Gleixner 					       NTP_INTERVAL_FREQ);
1013a0581cdbSThomas Gleixner 		/* Cancel running adjtime() */
1014bb6400a2SThomas Gleixner 		ntpdata->time_adjust = 0;
1015025b40abSAlexander Gordeev 	}
1016a0581cdbSThomas Gleixner 	/* Update jitter */
10179d7130dfSThomas Gleixner 	ntpdata->pps_jitter += (jitter - ntpdata->pps_jitter) >> PPS_INTMIN;
1018025b40abSAlexander Gordeev }
1019025b40abSAlexander Gordeev 
1020025b40abSAlexander Gordeev /*
1021aa6f9c59SJohn Stultz  * __hardpps() - discipline CPU clock oscillator to external PPS signal
1022025b40abSAlexander Gordeev  *
1023025b40abSAlexander Gordeev  * This routine is called at each PPS signal arrival in order to
1024025b40abSAlexander Gordeev  * discipline the CPU clock oscillator to the PPS signal. It takes two
1025025b40abSAlexander Gordeev  * parameters: REALTIME and MONOTONIC_RAW clock timestamps. The former
1026025b40abSAlexander Gordeev  * is used to correct clock phase error and the latter is used to
1027025b40abSAlexander Gordeev  * correct the frequency.
1028025b40abSAlexander Gordeev  *
1029025b40abSAlexander Gordeev  * This code is based on David Mills's reference nanokernel
1030025b40abSAlexander Gordeev  * implementation. It was mostly rewritten but keeps the same idea.
1031025b40abSAlexander Gordeev  */
__hardpps(const struct timespec64 * phase_ts,const struct timespec64 * raw_ts)10327ec88e4bSArnd Bergmann void __hardpps(const struct timespec64 *phase_ts, const struct timespec64 *raw_ts)
1033025b40abSAlexander Gordeev {
1034025b40abSAlexander Gordeev 	struct pps_normtime pts_norm, freq_norm;
103568f66f97SThomas Gleixner 	struct ntp_data *ntpdata = &tk_ntp_data;
1036025b40abSAlexander Gordeev 
1037025b40abSAlexander Gordeev 	pts_norm = pps_normalize_ts(*phase_ts);
1038025b40abSAlexander Gordeev 
1039a0581cdbSThomas Gleixner 	/* Clear the error bits, they will be set again if needed */
1040bee18a23SThomas Gleixner 	ntpdata->time_status &= ~(STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR);
1041025b40abSAlexander Gordeev 
1042bee18a23SThomas Gleixner 	/* indicate signal presence */
1043bee18a23SThomas Gleixner 	ntpdata->time_status |= STA_PPSSIGNAL;
1044931a177fSThomas Gleixner 	ntpdata->pps_valid = PPS_VALID;
1045025b40abSAlexander Gordeev 
1046a0581cdbSThomas Gleixner 	/*
1047a0581cdbSThomas Gleixner 	 * When called for the first time, just start the frequency
1048a0581cdbSThomas Gleixner 	 * interval
1049a0581cdbSThomas Gleixner 	 */
1050db45e9bcSThomas Gleixner 	if (unlikely(ntpdata->pps_fbase.tv_sec == 0)) {
1051db45e9bcSThomas Gleixner 		ntpdata->pps_fbase = *raw_ts;
1052025b40abSAlexander Gordeev 		return;
1053025b40abSAlexander Gordeev 	}
1054025b40abSAlexander Gordeev 
1055a0581cdbSThomas Gleixner 	/* Ok, now we have a base for frequency calculation */
1056db45e9bcSThomas Gleixner 	freq_norm = pps_normalize_ts(timespec64_sub(*raw_ts, ntpdata->pps_fbase));
1057025b40abSAlexander Gordeev 
1058a0581cdbSThomas Gleixner 	/*
1059a0581cdbSThomas Gleixner 	 * Check that the signal is in the range
1060a0581cdbSThomas Gleixner 	 * [1s - MAXFREQ us, 1s + MAXFREQ us], otherwise reject it
1061a0581cdbSThomas Gleixner 	 */
106238007dc0SAnna-Maria Behnsen 	if ((freq_norm.sec == 0) || (freq_norm.nsec > MAXFREQ * freq_norm.sec) ||
1063025b40abSAlexander Gordeev 	    (freq_norm.nsec < -MAXFREQ * freq_norm.sec)) {
1064bee18a23SThomas Gleixner 		ntpdata->time_status |= STA_PPSJITTER;
1065a0581cdbSThomas Gleixner 		/* Restart the frequency calibration interval */
1066db45e9bcSThomas Gleixner 		ntpdata->pps_fbase = *raw_ts;
10676d9bcb62SJohn Stultz 		printk_deferred(KERN_ERR "hardpps: PPSJITTER: bad pulse\n");
1068025b40abSAlexander Gordeev 		return;
1069025b40abSAlexander Gordeev 	}
1070025b40abSAlexander Gordeev 
1071a0581cdbSThomas Gleixner 	/* Signal is ok. Check if the current frequency interval is finished */
1072b1c89a76SThomas Gleixner 	if (freq_norm.sec >= (1 << ntpdata->pps_shift)) {
10736fadb4a6SThomas Gleixner 		ntpdata->pps_calcnt++;
1074a0581cdbSThomas Gleixner 		/* Restart the frequency calibration interval */
1075db45e9bcSThomas Gleixner 		ntpdata->pps_fbase = *raw_ts;
107668f66f97SThomas Gleixner 		hardpps_update_freq(ntpdata, freq_norm);
1077025b40abSAlexander Gordeev 	}
1078025b40abSAlexander Gordeev 
1079bee18a23SThomas Gleixner 	hardpps_update_phase(ntpdata, pts_norm.nsec);
1080025b40abSAlexander Gordeev 
1081025b40abSAlexander Gordeev }
1082025b40abSAlexander Gordeev #endif	/* CONFIG_NTP_PPS */
1083025b40abSAlexander Gordeev 
ntp_tick_adj_setup(char * str)108410a398d0SRoman Zippel static int __init ntp_tick_adj_setup(char *str)
108510a398d0SRoman Zippel {
1086bb6400a2SThomas Gleixner 	int rc = kstrtos64(str, 0, &tk_ntp_data.ntp_tick_adj);
1087cdafb93fSFabian Frederick 	if (rc)
1088cdafb93fSFabian Frederick 		return rc;
1089069569e0SIngo Molnar 
1090bb6400a2SThomas Gleixner 	tk_ntp_data.ntp_tick_adj <<= NTP_SCALE_SHIFT;
109110a398d0SRoman Zippel 	return 1;
109210a398d0SRoman Zippel }
109310a398d0SRoman Zippel 
109410a398d0SRoman Zippel __setup("ntp_tick_adj=", ntp_tick_adj_setup);
10957dffa3c6SRoman Zippel 
ntp_init(void)10967dffa3c6SRoman Zippel void __init ntp_init(void)
10977dffa3c6SRoman Zippel {
10987dffa3c6SRoman Zippel 	ntp_clear();
1099c9e6189fSThomas Gleixner 	ntp_init_cmos_sync();
11007dffa3c6SRoman Zippel }
1101