aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2015-09-28 16:21:31 -0400
committerJohn Stultz <john.stultz@linaro.org>2015-10-01 12:59:16 -0400
commitade1bdffe90e59cd257cb9bd4f5abe4de5f14911 (patch)
tree5ad7a6da9470e70915ea5d1640a5bd665ef2957b
parent5fd96c421ff2c76ec441aa4139c3b87dfea93e3a (diff)
ntp/pps: use y2038 safe types in pps_event_time
The pps_event_time uses two 'timespec' structures internally, which suffer from the y2038 problem. The uses of this structure are fairly self-contained in the pps code, so this replaces them all at once. Unfortunately, this includes the sfc ethernet driver aside from the pps subsystem, so we change that one as well. Both touch the same data structure, and there probably is no good way to split the patch into smaller units. 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/net/ethernet/sfc/ptp.c16
-rw-r--r--drivers/pps/kapi.c4
-rw-r--r--drivers/pps/kc.c4
-rw-r--r--include/linux/pps_kernel.h21
4 files changed, 19 insertions, 26 deletions
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index ad62615a93dc..fe849dbf9f80 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -646,28 +646,28 @@ static void efx_ptp_send_times(struct efx_nic *efx,
646 struct pps_event_time *last_time) 646 struct pps_event_time *last_time)
647{ 647{
648 struct pps_event_time now; 648 struct pps_event_time now;
649 struct timespec limit; 649 struct timespec64 limit;
650 struct efx_ptp_data *ptp = efx->ptp_data; 650 struct efx_ptp_data *ptp = efx->ptp_data;
651 struct timespec start; 651 struct timespec64 start;
652 int *mc_running = ptp->start.addr; 652 int *mc_running = ptp->start.addr;
653 653
654 pps_get_ts(&now); 654 pps_get_ts(&now);
655 start = now.ts_real; 655 start = now.ts_real;
656 limit = now.ts_real; 656 limit = now.ts_real;
657 timespec_add_ns(&limit, SYNCHRONISE_PERIOD_NS); 657 timespec64_add_ns(&limit, SYNCHRONISE_PERIOD_NS);
658 658
659 /* Write host time for specified period or until MC is done */ 659 /* Write host time for specified period or until MC is done */
660 while ((timespec_compare(&now.ts_real, &limit) < 0) && 660 while ((timespec64_compare(&now.ts_real, &limit) < 0) &&
661 ACCESS_ONCE(*mc_running)) { 661 ACCESS_ONCE(*mc_running)) {
662 struct timespec update_time; 662 struct timespec64 update_time;
663 unsigned int host_time; 663 unsigned int host_time;
664 664
665 /* Don't update continuously to avoid saturating the PCIe bus */ 665 /* Don't update continuously to avoid saturating the PCIe bus */
666 update_time = now.ts_real; 666 update_time = now.ts_real;
667 timespec_add_ns(&update_time, SYNCHRONISATION_GRANULARITY_NS); 667 timespec64_add_ns(&update_time, SYNCHRONISATION_GRANULARITY_NS);
668 do { 668 do {
669 pps_get_ts(&now); 669 pps_get_ts(&now);
670 } while ((timespec_compare(&now.ts_real, &update_time) < 0) && 670 } while ((timespec64_compare(&now.ts_real, &update_time) < 0) &&
671 ACCESS_ONCE(*mc_running)); 671 ACCESS_ONCE(*mc_running));
672 672
673 /* Synchronise NIC with single word of time only */ 673 /* Synchronise NIC with single word of time only */
@@ -723,7 +723,7 @@ efx_ptp_process_times(struct efx_nic *efx, MCDI_DECLARE_STRUCT_PTR(synch_buf),
723 struct efx_ptp_data *ptp = efx->ptp_data; 723 struct efx_ptp_data *ptp = efx->ptp_data;
724 u32 last_sec; 724 u32 last_sec;
725 u32 start_sec; 725 u32 start_sec;
726 struct timespec delta; 726 struct timespec64 delta;
727 ktime_t mc_time; 727 ktime_t mc_time;
728 728
729 if (number_readings == 0) 729 if (number_readings == 0)
diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c
index cdad4d95b20e..805c749ac1ad 100644
--- a/drivers/pps/kapi.c
+++ b/drivers/pps/kapi.c
@@ -179,8 +179,8 @@ void pps_event(struct pps_device *pps, struct pps_event_time *ts, int event,
179 /* check event type */ 179 /* check event type */
180 BUG_ON((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0); 180 BUG_ON((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0);
181 181
182 dev_dbg(pps->dev, "PPS event at %ld.%09ld\n", 182 dev_dbg(pps->dev, "PPS event at %lld.%09ld\n",
183 ts->ts_real.tv_sec, ts->ts_real.tv_nsec); 183 (s64)ts->ts_real.tv_sec, ts->ts_real.tv_nsec);
184 184
185 timespec_to_pps_ktime(&ts_real, ts->ts_real); 185 timespec_to_pps_ktime(&ts_real, ts->ts_real);
186 186
diff --git a/drivers/pps/kc.c b/drivers/pps/kc.c
index a16cea2ba980..e219db1f1c84 100644
--- a/drivers/pps/kc.c
+++ b/drivers/pps/kc.c
@@ -113,12 +113,10 @@ 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);
118 116
119 /* Pass some events to kernel consumer if activated */ 117 /* Pass some events to kernel consumer if activated */
120 spin_lock_irqsave(&pps_kc_hardpps_lock, flags); 118 spin_lock_irqsave(&pps_kc_hardpps_lock, flags);
121 if (pps == pps_kc_hardpps_dev && event & pps_kc_hardpps_mode) 119 if (pps == pps_kc_hardpps_dev && event & pps_kc_hardpps_mode)
122 hardpps(&real, &raw); 120 hardpps(&ts->ts_real, &ts->ts_raw);
123 spin_unlock_irqrestore(&pps_kc_hardpps_lock, flags); 121 spin_unlock_irqrestore(&pps_kc_hardpps_lock, flags);
124} 122}
diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h
index b2fbd62ab18d..54bf1484d41f 100644
--- a/include/linux/pps_kernel.h
+++ b/include/linux/pps_kernel.h
@@ -48,9 +48,9 @@ struct pps_source_info {
48 48
49struct pps_event_time { 49struct pps_event_time {
50#ifdef CONFIG_NTP_PPS 50#ifdef CONFIG_NTP_PPS
51 struct timespec ts_raw; 51 struct timespec64 ts_raw;
52#endif /* CONFIG_NTP_PPS */ 52#endif /* CONFIG_NTP_PPS */
53 struct timespec ts_real; 53 struct timespec64 ts_real;
54}; 54};
55 55
56/* The main struct */ 56/* The main struct */
@@ -105,7 +105,7 @@ extern void pps_event(struct pps_device *pps,
105struct pps_device *pps_lookup_dev(void const *cookie); 105struct pps_device *pps_lookup_dev(void const *cookie);
106 106
107static inline void timespec_to_pps_ktime(struct pps_ktime *kt, 107static inline void timespec_to_pps_ktime(struct pps_ktime *kt,
108 struct timespec ts) 108 struct timespec64 ts)
109{ 109{
110 kt->sec = ts.tv_sec; 110 kt->sec = ts.tv_sec;
111 kt->nsec = ts.tv_nsec; 111 kt->nsec = ts.tv_nsec;
@@ -115,29 +115,24 @@ static inline void timespec_to_pps_ktime(struct pps_ktime *kt,
115 115
116static inline void pps_get_ts(struct pps_event_time *ts) 116static inline void pps_get_ts(struct pps_event_time *ts)
117{ 117{
118 struct timespec64 raw, real; 118 ktime_get_raw_and_real_ts64(&ts->ts_raw, &ts->ts_real);
119
120 ktime_get_raw_and_real_ts64(&raw, &real);
121
122 ts->ts_raw = timespec64_to_timespec(raw);
123 ts->ts_real = timespec64_to_timespec(real);
124} 119}
125 120
126#else /* CONFIG_NTP_PPS */ 121#else /* CONFIG_NTP_PPS */
127 122
128static inline void pps_get_ts(struct pps_event_time *ts) 123static inline void pps_get_ts(struct pps_event_time *ts)
129{ 124{
130 getnstimeofday(&ts->ts_real); 125 ktime_get_real_ts64(&ts->ts_real);
131} 126}
132 127
133#endif /* CONFIG_NTP_PPS */ 128#endif /* CONFIG_NTP_PPS */
134 129
135/* Subtract known time delay from PPS event time(s) */ 130/* Subtract known time delay from PPS event time(s) */
136static inline void pps_sub_ts(struct pps_event_time *ts, struct timespec delta) 131static inline void pps_sub_ts(struct pps_event_time *ts, struct timespec64 delta)
137{ 132{
138 ts->ts_real = timespec_sub(ts->ts_real, delta); 133 ts->ts_real = timespec64_sub(ts->ts_real, delta);
139#ifdef CONFIG_NTP_PPS 134#ifdef CONFIG_NTP_PPS
140 ts->ts_raw = timespec_sub(ts->ts_raw, delta); 135 ts->ts_raw = timespec64_sub(ts->ts_raw, delta);
141#endif 136#endif
142} 137}
143 138