aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorTina Ruchandani <ruchandani.tina@gmail.com>2016-03-19 14:21:14 -0400
committerDavid S. Miller <davem@davemloft.net>2016-03-20 16:47:13 -0400
commitebf918cf9922748b9d4d9bf6a2620530cdc5a1d0 (patch)
tree815830cb374a7c8d945af83d1ed00ff89930a269 /drivers/isdn
parent4320f21935534dad44e8d112fc085d13c29e7f66 (diff)
isdn: Use ktime_t instead of 'struct timeval'
'struct timeval' uses 32-bit representation for seconds which will overflow in year 2038 and beyond. mISDN/clock.c needs to compute and store elapsed time in intervals of 125 microseconds. This patch replaces the usage of 'struct timeval' with 64-bit ktime_t which is y2038 safe. The patch also replaces do_gettimeofday() (wall-clock time) with ktime_get() (monotonic time) since we only care about elapsed time here. Signed-off-by: Tina Ruchandani <ruchandani.tina@gmail.com> Suggested-by: Arnd Bergmnann <arnd@arndb.de> Suggested-by: David Miller <davem@davemloft.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/mISDN/clock.c69
1 files changed, 29 insertions, 40 deletions
diff --git a/drivers/isdn/mISDN/clock.c b/drivers/isdn/mISDN/clock.c
index 693fb7c9b59a..f8f659f1ce1b 100644
--- a/drivers/isdn/mISDN/clock.c
+++ b/drivers/isdn/mISDN/clock.c
@@ -37,6 +37,7 @@
37#include <linux/types.h> 37#include <linux/types.h>
38#include <linux/stddef.h> 38#include <linux/stddef.h>
39#include <linux/spinlock.h> 39#include <linux/spinlock.h>
40#include <linux/ktime.h>
40#include <linux/mISDNif.h> 41#include <linux/mISDNif.h>
41#include <linux/export.h> 42#include <linux/export.h>
42#include "core.h" 43#include "core.h"
@@ -45,15 +46,15 @@ static u_int *debug;
45static LIST_HEAD(iclock_list); 46static LIST_HEAD(iclock_list);
46static DEFINE_RWLOCK(iclock_lock); 47static DEFINE_RWLOCK(iclock_lock);
47static u16 iclock_count; /* counter of last clock */ 48static u16 iclock_count; /* counter of last clock */
48static struct timeval iclock_tv; /* time stamp of last clock */ 49static ktime_t iclock_timestamp; /* time stamp of last clock */
49static int iclock_tv_valid; /* already received one timestamp */ 50static int iclock_timestamp_valid; /* already received one timestamp */
50static struct mISDNclock *iclock_current; 51static struct mISDNclock *iclock_current;
51 52
52void 53void
53mISDN_init_clock(u_int *dp) 54mISDN_init_clock(u_int *dp)
54{ 55{
55 debug = dp; 56 debug = dp;
56 do_gettimeofday(&iclock_tv); 57 iclock_timestamp = ktime_get();
57} 58}
58 59
59static void 60static void
@@ -86,7 +87,7 @@ select_iclock(void)
86 } 87 }
87 if (bestclock != iclock_current) { 88 if (bestclock != iclock_current) {
88 /* no clock received yet */ 89 /* no clock received yet */
89 iclock_tv_valid = 0; 90 iclock_timestamp_valid = 0;
90 } 91 }
91 iclock_current = bestclock; 92 iclock_current = bestclock;
92} 93}
@@ -139,12 +140,11 @@ mISDN_unregister_clock(struct mISDNclock *iclock)
139EXPORT_SYMBOL(mISDN_unregister_clock); 140EXPORT_SYMBOL(mISDN_unregister_clock);
140 141
141void 142void
142mISDN_clock_update(struct mISDNclock *iclock, int samples, struct timeval *tv) 143mISDN_clock_update(struct mISDNclock *iclock, int samples, ktime_t *timestamp)
143{ 144{
144 u_long flags; 145 u_long flags;
145 struct timeval tv_now; 146 ktime_t timestamp_now;
146 time_t elapsed_sec; 147 u16 delta;
147 int elapsed_8000th;
148 148
149 write_lock_irqsave(&iclock_lock, flags); 149 write_lock_irqsave(&iclock_lock, flags);
150 if (iclock_current != iclock) { 150 if (iclock_current != iclock) {
@@ -156,33 +156,27 @@ mISDN_clock_update(struct mISDNclock *iclock, int samples, struct timeval *tv)
156 write_unlock_irqrestore(&iclock_lock, flags); 156 write_unlock_irqrestore(&iclock_lock, flags);
157 return; 157 return;
158 } 158 }
159 if (iclock_tv_valid) { 159 if (iclock_timestamp_valid) {
160 /* increment sample counter by given samples */ 160 /* increment sample counter by given samples */
161 iclock_count += samples; 161 iclock_count += samples;
162 if (tv) { /* tv must be set, if function call is delayed */ 162 if (timestamp) { /* timestamp must be set, if function call is delayed */
163 iclock_tv.tv_sec = tv->tv_sec; 163 iclock_timestamp = *timestamp;
164 iclock_tv.tv_usec = tv->tv_usec; 164 } else {
165 } else 165 iclock_timestamp = ktime_get();
166 do_gettimeofday(&iclock_tv); 166 }
167 } else { 167 } else {
168 /* calc elapsed time by system clock */ 168 /* calc elapsed time by system clock */
169 if (tv) { /* tv must be set, if function call is delayed */ 169 if (timestamp) { /* timestamp must be set, if function call is delayed */
170 tv_now.tv_sec = tv->tv_sec; 170 timestamp_now = *timestamp;
171 tv_now.tv_usec = tv->tv_usec; 171 } else {
172 } else 172 timestamp_now = ktime_get();
173 do_gettimeofday(&tv_now);
174 elapsed_sec = tv_now.tv_sec - iclock_tv.tv_sec;
175 elapsed_8000th = (tv_now.tv_usec / 125)
176 - (iclock_tv.tv_usec / 125);
177 if (elapsed_8000th < 0) {
178 elapsed_sec -= 1;
179 elapsed_8000th += 8000;
180 } 173 }
174 delta = ktime_divns(ktime_sub(timestamp_now, iclock_timestamp),
175 (NSEC_PER_SEC / 8000));
181 /* add elapsed time to counter and set new timestamp */ 176 /* add elapsed time to counter and set new timestamp */
182 iclock_count += elapsed_sec * 8000 + elapsed_8000th; 177 iclock_count += delta;
183 iclock_tv.tv_sec = tv_now.tv_sec; 178 iclock_timestamp = timestamp_now;
184 iclock_tv.tv_usec = tv_now.tv_usec; 179 iclock_timestamp_valid = 1;
185 iclock_tv_valid = 1;
186 if (*debug & DEBUG_CLOCK) 180 if (*debug & DEBUG_CLOCK)
187 printk("Received first clock from source '%s'.\n", 181 printk("Received first clock from source '%s'.\n",
188 iclock_current ? iclock_current->name : "nothing"); 182 iclock_current ? iclock_current->name : "nothing");
@@ -195,22 +189,17 @@ unsigned short
195mISDN_clock_get(void) 189mISDN_clock_get(void)
196{ 190{
197 u_long flags; 191 u_long flags;
198 struct timeval tv_now; 192 ktime_t timestamp_now;
199 time_t elapsed_sec; 193 u16 delta;
200 int elapsed_8000th;
201 u16 count; 194 u16 count;
202 195
203 read_lock_irqsave(&iclock_lock, flags); 196 read_lock_irqsave(&iclock_lock, flags);
204 /* calc elapsed time by system clock */ 197 /* calc elapsed time by system clock */
205 do_gettimeofday(&tv_now); 198 timestamp_now = ktime_get();
206 elapsed_sec = tv_now.tv_sec - iclock_tv.tv_sec; 199 delta = ktime_divns(ktime_sub(timestamp_now, iclock_timestamp),
207 elapsed_8000th = (tv_now.tv_usec / 125) - (iclock_tv.tv_usec / 125); 200 (NSEC_PER_SEC / 8000));
208 if (elapsed_8000th < 0) {
209 elapsed_sec -= 1;
210 elapsed_8000th += 8000;
211 }
212 /* add elapsed time to counter */ 201 /* add elapsed time to counter */
213 count = iclock_count + elapsed_sec * 8000 + elapsed_8000th; 202 count = iclock_count + delta;
214 read_unlock_irqrestore(&iclock_lock, flags); 203 read_unlock_irqrestore(&iclock_lock, flags);
215 return count; 204 return count;
216} 205}