aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2015-09-28 16:21:28 -0400
committerJohn Stultz <john.stultz@linaro.org>2015-10-01 12:57:59 -0400
commit7ec88e4be461590b5a3817460c34603f76d9b3ae (patch)
tree00bcd8cf85a86a36c91e3e1d4c039a9ae491f770
parent9ffecb10283508260936b96022d4ee43a7798b4c (diff)
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>
-rw-r--r--drivers/pps/kc.c4
-rw-r--r--include/linux/timex.h2
-rw-r--r--kernel/time/ntp.c12
-rw-r--r--kernel/time/ntp_internal.h2
-rw-r--r--kernel/time/timekeeping.c2
5 files changed, 12 insertions, 10 deletions
diff --git a/drivers/pps/kc.c b/drivers/pps/kc.c
index e219db1f1c84..a16cea2ba980 100644
--- a/drivers/pps/kc.c
+++ b/drivers/pps/kc.c
@@ -113,10 +113,12 @@ void pps_kc_event(struct pps_device *pps, struct pps_event_time *ts,
113 int event) 113 int event)
114{ 114{
115 unsigned long flags; 115 unsigned long flags;
116 struct timespec64 real = timespec_to_timespec64(ts->ts_real);
117 struct timespec64 raw = timespec_to_timespec64(ts->ts_raw);
116 118
117 /* Pass some events to kernel consumer if activated */ 119 /* Pass some events to kernel consumer if activated */
118 spin_lock_irqsave(&pps_kc_hardpps_lock, flags); 120 spin_lock_irqsave(&pps_kc_hardpps_lock, flags);
119 if (pps == pps_kc_hardpps_dev && event & pps_kc_hardpps_mode) 121 if (pps == pps_kc_hardpps_dev && event & pps_kc_hardpps_mode)
120 hardpps(&ts->ts_real, &ts->ts_raw); 122 hardpps(&real, &raw);
121 spin_unlock_irqrestore(&pps_kc_hardpps_lock, flags); 123 spin_unlock_irqrestore(&pps_kc_hardpps_lock, flags);
122} 124}
diff --git a/include/linux/timex.h b/include/linux/timex.h
index 9d3f1a5b6178..39c25dbebfe8 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -152,7 +152,7 @@ extern unsigned long tick_nsec; /* SHIFTED_HZ period (nsec) */
152#define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ) 152#define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ)
153 153
154extern int do_adjtimex(struct timex *); 154extern int do_adjtimex(struct timex *);
155extern void hardpps(const struct timespec *, const struct timespec *); 155extern void hardpps(const struct timespec64 *, const struct timespec64 *);
156 156
157int read_current_timer(unsigned long *timer_val); 157int read_current_timer(unsigned long *timer_val);
158void ntp_notify_cmos_timer(void); 158void ntp_notify_cmos_timer(void);
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index df68cb875248..bd4fa6271262 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -99,7 +99,7 @@ static time64_t ntp_next_leap_sec = TIME64_MAX;
99static int pps_valid; /* signal watchdog counter */ 99static int pps_valid; /* signal watchdog counter */
100static long pps_tf[3]; /* phase median filter */ 100static long pps_tf[3]; /* phase median filter */
101static long pps_jitter; /* current jitter (ns) */ 101static long pps_jitter; /* current jitter (ns) */
102static struct timespec pps_fbase; /* beginning of the last freq interval */ 102static struct timespec64 pps_fbase; /* beginning of the last freq interval */
103static int pps_shift; /* current interval duration (s) (shift) */ 103static int pps_shift; /* current interval duration (s) (shift) */
104static int pps_intcnt; /* interval counter */ 104static int pps_intcnt; /* interval counter */
105static s64 pps_freq; /* frequency offset (scaled ns/s) */ 105static s64 pps_freq; /* frequency offset (scaled ns/s) */
@@ -773,13 +773,13 @@ int __do_adjtimex(struct timex *txc, struct timespec64 *ts, s32 *time_tai)
773 * pps_normtime.nsec has a range of ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] 773 * pps_normtime.nsec has a range of ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ]
774 * while timespec.tv_nsec has a range of [0, NSEC_PER_SEC) */ 774 * while timespec.tv_nsec has a range of [0, NSEC_PER_SEC) */
775struct pps_normtime { 775struct pps_normtime {
776 __kernel_time_t sec; /* seconds */ 776 s64 sec; /* seconds */
777 long nsec; /* nanoseconds */ 777 long nsec; /* nanoseconds */
778}; 778};
779 779
780/* normalize the timestamp so that nsec is in the 780/* normalize the timestamp so that nsec is in the
781 ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] interval */ 781 ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] interval */
782static inline struct pps_normtime pps_normalize_ts(struct timespec ts) 782static inline struct pps_normtime pps_normalize_ts(struct timespec64 ts)
783{ 783{
784 struct pps_normtime norm = { 784 struct pps_normtime norm = {
785 .sec = ts.tv_sec, 785 .sec = ts.tv_sec,
@@ -861,7 +861,7 @@ static long hardpps_update_freq(struct pps_normtime freq_norm)
861 pps_errcnt++; 861 pps_errcnt++;
862 pps_dec_freq_interval(); 862 pps_dec_freq_interval();
863 printk_deferred(KERN_ERR 863 printk_deferred(KERN_ERR
864 "hardpps: PPSERROR: interval too long - %ld s\n", 864 "hardpps: PPSERROR: interval too long - %lld s\n",
865 freq_norm.sec); 865 freq_norm.sec);
866 return 0; 866 return 0;
867 } 867 }
@@ -948,7 +948,7 @@ static void hardpps_update_phase(long error)
948 * This code is based on David Mills's reference nanokernel 948 * This code is based on David Mills's reference nanokernel
949 * implementation. It was mostly rewritten but keeps the same idea. 949 * implementation. It was mostly rewritten but keeps the same idea.
950 */ 950 */
951void __hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) 951void __hardpps(const struct timespec64 *phase_ts, const struct timespec64 *raw_ts)
952{ 952{
953 struct pps_normtime pts_norm, freq_norm; 953 struct pps_normtime pts_norm, freq_norm;
954 954
@@ -969,7 +969,7 @@ void __hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
969 } 969 }
970 970
971 /* ok, now we have a base for frequency calculation */ 971 /* ok, now we have a base for frequency calculation */
972 freq_norm = pps_normalize_ts(timespec_sub(*raw_ts, pps_fbase)); 972 freq_norm = pps_normalize_ts(timespec64_sub(*raw_ts, pps_fbase));
973 973
974 /* check that the signal is in the range 974 /* check that the signal is in the range
975 * [1s - MAXFREQ us, 1s + MAXFREQ us], otherwise reject it */ 975 * [1s - MAXFREQ us, 1s + MAXFREQ us], otherwise reject it */
diff --git a/kernel/time/ntp_internal.h b/kernel/time/ntp_internal.h
index 65430504ca26..af924470eac0 100644
--- a/kernel/time/ntp_internal.h
+++ b/kernel/time/ntp_internal.h
@@ -9,5 +9,5 @@ extern ktime_t ntp_get_next_leap(void);
9extern int second_overflow(unsigned long secs); 9extern int second_overflow(unsigned long secs);
10extern int ntp_validate_timex(struct timex *); 10extern int ntp_validate_timex(struct timex *);
11extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *); 11extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *);
12extern void __hardpps(const struct timespec *, const struct timespec *); 12extern void __hardpps(const struct timespec64 *, const struct timespec64 *);
13#endif /* _LINUX_NTP_INTERNAL_H */ 13#endif /* _LINUX_NTP_INTERNAL_H */
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 3739ac6aa473..177188b11a2e 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -2025,7 +2025,7 @@ int do_adjtimex(struct timex *txc)
2025/** 2025/**
2026 * hardpps() - Accessor function to NTP __hardpps function 2026 * hardpps() - Accessor function to NTP __hardpps function
2027 */ 2027 */
2028void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) 2028void hardpps(const struct timespec64 *phase_ts, const struct timespec64 *raw_ts)
2029{ 2029{
2030 unsigned long flags; 2030 unsigned long flags;
2031 2031