ntp/pps: use timespec64 for hardpps()
There is only one user of the hardpps function in the kernel, so it makes sense to atomically change it over to using 64-bit timestamps for y2038 safety. In the hardpps implementation, we also need to change the pps_normtime structure, which is similar to struct timespec and also requires a 64-bit seconds portion. This introduces two temporary variables in pps_kc_event() to do the conversion, they will be removed again in the next step, which seemed preferable to having a larger patch changing it all at the same time. Acked-by: Richard Cochran <richardcochran@gmail.com> Acked-by: David S. Miller <davem@davemloft.net> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: John Stultz <john.stultz@linaro.org>
This commit is contained in:
parent
9ffecb1028
commit
7ec88e4be4
|
@ -113,10 +113,12 @@ void pps_kc_event(struct pps_device *pps, struct pps_event_time *ts,
|
||||||
int event)
|
int event)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
struct timespec64 real = timespec_to_timespec64(ts->ts_real);
|
||||||
|
struct timespec64 raw = timespec_to_timespec64(ts->ts_raw);
|
||||||
|
|
||||||
/* Pass some events to kernel consumer if activated */
|
/* Pass some events to kernel consumer if activated */
|
||||||
spin_lock_irqsave(&pps_kc_hardpps_lock, flags);
|
spin_lock_irqsave(&pps_kc_hardpps_lock, flags);
|
||||||
if (pps == pps_kc_hardpps_dev && event & pps_kc_hardpps_mode)
|
if (pps == pps_kc_hardpps_dev && event & pps_kc_hardpps_mode)
|
||||||
hardpps(&ts->ts_real, &ts->ts_raw);
|
hardpps(&real, &raw);
|
||||||
spin_unlock_irqrestore(&pps_kc_hardpps_lock, flags);
|
spin_unlock_irqrestore(&pps_kc_hardpps_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,7 @@ extern unsigned long tick_nsec; /* SHIFTED_HZ period (nsec) */
|
||||||
#define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ)
|
#define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ)
|
||||||
|
|
||||||
extern int do_adjtimex(struct timex *);
|
extern int do_adjtimex(struct timex *);
|
||||||
extern void hardpps(const struct timespec *, const struct timespec *);
|
extern void hardpps(const struct timespec64 *, const struct timespec64 *);
|
||||||
|
|
||||||
int read_current_timer(unsigned long *timer_val);
|
int read_current_timer(unsigned long *timer_val);
|
||||||
void ntp_notify_cmos_timer(void);
|
void ntp_notify_cmos_timer(void);
|
||||||
|
|
|
@ -99,7 +99,7 @@ static time64_t ntp_next_leap_sec = TIME64_MAX;
|
||||||
static int pps_valid; /* signal watchdog counter */
|
static int pps_valid; /* signal watchdog counter */
|
||||||
static long pps_tf[3]; /* phase median filter */
|
static long pps_tf[3]; /* phase median filter */
|
||||||
static long pps_jitter; /* current jitter (ns) */
|
static long pps_jitter; /* current jitter (ns) */
|
||||||
static struct timespec pps_fbase; /* beginning of the last freq interval */
|
static struct timespec64 pps_fbase; /* beginning of the last freq interval */
|
||||||
static int pps_shift; /* current interval duration (s) (shift) */
|
static int pps_shift; /* current interval duration (s) (shift) */
|
||||||
static int pps_intcnt; /* interval counter */
|
static int pps_intcnt; /* interval counter */
|
||||||
static s64 pps_freq; /* frequency offset (scaled ns/s) */
|
static s64 pps_freq; /* frequency offset (scaled ns/s) */
|
||||||
|
@ -773,13 +773,13 @@ int __do_adjtimex(struct timex *txc, struct timespec64 *ts, s32 *time_tai)
|
||||||
* pps_normtime.nsec has a range of ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ]
|
* pps_normtime.nsec has a range of ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ]
|
||||||
* while timespec.tv_nsec has a range of [0, NSEC_PER_SEC) */
|
* while timespec.tv_nsec has a range of [0, NSEC_PER_SEC) */
|
||||||
struct pps_normtime {
|
struct pps_normtime {
|
||||||
__kernel_time_t sec; /* seconds */
|
s64 sec; /* seconds */
|
||||||
long nsec; /* nanoseconds */
|
long nsec; /* nanoseconds */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* normalize the timestamp so that nsec is in the
|
/* normalize the timestamp so that nsec is in the
|
||||||
( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] interval */
|
( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] interval */
|
||||||
static inline struct pps_normtime pps_normalize_ts(struct timespec ts)
|
static inline struct pps_normtime pps_normalize_ts(struct timespec64 ts)
|
||||||
{
|
{
|
||||||
struct pps_normtime norm = {
|
struct pps_normtime norm = {
|
||||||
.sec = ts.tv_sec,
|
.sec = ts.tv_sec,
|
||||||
|
@ -861,7 +861,7 @@ static long hardpps_update_freq(struct pps_normtime freq_norm)
|
||||||
pps_errcnt++;
|
pps_errcnt++;
|
||||||
pps_dec_freq_interval();
|
pps_dec_freq_interval();
|
||||||
printk_deferred(KERN_ERR
|
printk_deferred(KERN_ERR
|
||||||
"hardpps: PPSERROR: interval too long - %ld s\n",
|
"hardpps: PPSERROR: interval too long - %lld s\n",
|
||||||
freq_norm.sec);
|
freq_norm.sec);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -948,7 +948,7 @@ static void hardpps_update_phase(long error)
|
||||||
* This code is based on David Mills's reference nanokernel
|
* This code is based on David Mills's reference nanokernel
|
||||||
* implementation. It was mostly rewritten but keeps the same idea.
|
* implementation. It was mostly rewritten but keeps the same idea.
|
||||||
*/
|
*/
|
||||||
void __hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
|
void __hardpps(const struct timespec64 *phase_ts, const struct timespec64 *raw_ts)
|
||||||
{
|
{
|
||||||
struct pps_normtime pts_norm, freq_norm;
|
struct pps_normtime pts_norm, freq_norm;
|
||||||
|
|
||||||
|
@ -969,7 +969,7 @@ void __hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ok, now we have a base for frequency calculation */
|
/* ok, now we have a base for frequency calculation */
|
||||||
freq_norm = pps_normalize_ts(timespec_sub(*raw_ts, pps_fbase));
|
freq_norm = pps_normalize_ts(timespec64_sub(*raw_ts, pps_fbase));
|
||||||
|
|
||||||
/* check that the signal is in the range
|
/* check that the signal is in the range
|
||||||
* [1s - MAXFREQ us, 1s + MAXFREQ us], otherwise reject it */
|
* [1s - MAXFREQ us, 1s + MAXFREQ us], otherwise reject it */
|
||||||
|
|
|
@ -9,5 +9,5 @@ extern ktime_t ntp_get_next_leap(void);
|
||||||
extern int second_overflow(unsigned long secs);
|
extern int second_overflow(unsigned long secs);
|
||||||
extern int ntp_validate_timex(struct timex *);
|
extern int ntp_validate_timex(struct timex *);
|
||||||
extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *);
|
extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *);
|
||||||
extern void __hardpps(const struct timespec *, const struct timespec *);
|
extern void __hardpps(const struct timespec64 *, const struct timespec64 *);
|
||||||
#endif /* _LINUX_NTP_INTERNAL_H */
|
#endif /* _LINUX_NTP_INTERNAL_H */
|
||||||
|
|
|
@ -2025,7 +2025,7 @@ int do_adjtimex(struct timex *txc)
|
||||||
/**
|
/**
|
||||||
* hardpps() - Accessor function to NTP __hardpps function
|
* hardpps() - Accessor function to NTP __hardpps function
|
||||||
*/
|
*/
|
||||||
void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
|
void hardpps(const struct timespec64 *phase_ts, const struct timespec64 *raw_ts)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue