Pull time updates from John Stultz for 3.20: * ktime division optimization * Expose a few more y2038-safe timekeeping interfaces * RTC core changes to address y2038
Unified · Split
| @@ -26,7 +26,7 @@ static int __init rtc_hctosys(void) · 25 unmodified lines | ||
| 26 | 26 | { |
| 27 | 27 | int err = -ENODEV; |
| 28 | 28 | struct rtc_time tm; |
| 29 | − struct timespec tv = { | |
| 29 | + struct timespec64 tv64 = { | |
| 30 | 30 | .tv_nsec = NSEC_PER_SEC >> 1, |
| 31 | 31 | }; |
| 32 | 32 | struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); |
| @@ -45,25 +45,17 @@ static int __init rtc_hctosys(void) · 12 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | − err = rtc_valid_tm(&tm); | |
| 49 | − if (err) { | |
| 50 | − dev_err(rtc->dev.parent, | |
| 51 | − "hctosys: invalid date/time\n"); | |
| 52 | − goto err_invalid; | |
| 53 | − } | |
| 54 | − | |
| 55 | − rtc_tm_to_time(&tm, &tv.tv_sec); | |
| 48 | + tv64.tv_sec = rtc_tm_to_time64(&tm); | |
| 56 | 49 | |
| 57 | − err = do_settimeofday(&tv); | |
| 50 | + err = do_settimeofday64(&tv64); | |
| 58 | 51 | |
| 59 | 52 | dev_info(rtc->dev.parent, |
| 60 | 53 | "setting system clock to " |
| 61 | − "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n", | |
| 54 | + "%d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n", | |
| 62 | 55 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, |
| 63 | 56 | tm.tm_hour, tm.tm_min, tm.tm_sec, |
| 64 | − (unsigned int) tv.tv_sec); | |
| 57 | + (long long) tv64.tv_sec); | |
| 65 | 58 | |
| 66 | −err_invalid: | |
| 67 | 59 | err_read: |
| 68 | 60 | rtc_class_close(rtc); |
| 69 | 61 | |
| @@ -73,10 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) · 72 unmodified lines | ||
| 73 | 73 | else if (rtc->ops->set_time) |
| 74 | 74 | err = rtc->ops->set_time(rtc->dev.parent, tm); |
| 75 | 75 | else if (rtc->ops->set_mmss) { |
| 76 | − unsigned long secs; | |
| 77 | − err = rtc_tm_to_time(tm, &secs); | |
| 78 | − if (err == 0) | |
| 79 | − err = rtc->ops->set_mmss(rtc->dev.parent, secs); | |
| 76 | + time64_t secs64 = rtc_tm_to_time64(tm); | |
| 77 | + err = rtc->ops->set_mmss(rtc->dev.parent, secs64); | |
| 80 | 78 | } else |
| 81 | 79 | err = -EINVAL; |
| 82 | 80 | |
| @@ -105,7 +103,7 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) · 22 unmodified lines | ||
| 105 | 103 | |
| 106 | 104 | err = rtc->ops->read_time(rtc->dev.parent, &old); |
| 107 | 105 | if (err == 0) { |
| 108 | − rtc_time_to_tm(secs, &new); | |
| 106 | + rtc_time64_to_tm(secs, &new); | |
| 109 | 107 | |
| 110 | 108 | /* |
| 111 | 109 | * avoid writing when we're going to change the day of |
| @@ -157,7 +155,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) · 45 unmodified lines | ||
| 157 | 155 | int err; |
| 158 | 156 | struct rtc_time before, now; |
| 159 | 157 | int first_time = 1; |
| 160 | − unsigned long t_now, t_alm; | |
| 158 | + time64_t t_now, t_alm; | |
| 161 | 159 | enum { none, day, month, year } missing = none; |
| 162 | 160 | unsigned days; |
| 163 | 161 | |
| @@ -258,8 +256,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) · 94 unmodified lines | ||
| 258 | 256 | } |
| 259 | 257 | |
| 260 | 258 | /* with luck, no rollover is needed */ |
| 261 | − rtc_tm_to_time(&now, &t_now); | |
| 262 | − rtc_tm_to_time(&alarm->time, &t_alm); | |
| 259 | + t_now = rtc_tm_to_time64(&now); | |
| 260 | + t_alm = rtc_tm_to_time64(&alarm->time); | |
| 263 | 261 | if (t_now < t_alm) |
| 264 | 262 | goto done; |
| 265 | 263 | |
| @@ -273,7 +271,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) · 7 unmodified lines | ||
| 273 | 271 | case day: |
| 274 | 272 | dev_dbg(&rtc->dev, "alarm rollover: %s\n", "day"); |
| 275 | 273 | t_alm += 24 * 60 * 60; |
| 276 | − rtc_time_to_tm(t_alm, &alarm->time); | |
| 274 | + rtc_time64_to_tm(t_alm, &alarm->time); | |
| 277 | 275 | break; |
| 278 | 276 | |
| 279 | 277 | /* Month rollover ... if it's the 31th, an alarm on the 3rd will |
| @@ -346,19 +344,19 @@ EXPORT_SYMBOL_GPL(rtc_read_alarm); · 66 unmodified lines | ||
| 346 | 344 | static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
| 347 | 345 | { |
| 348 | 346 | struct rtc_time tm; |
| 349 | − long now, scheduled; | |
| 347 | + time64_t now, scheduled; | |
| 350 | 348 | int err; |
| 351 | 349 | |
| 352 | 350 | err = rtc_valid_tm(&alarm->time); |
| 353 | 351 | if (err) |
| 354 | 352 | return err; |
| 355 | − rtc_tm_to_time(&alarm->time, &scheduled); | |
| 353 | + scheduled = rtc_tm_to_time64(&alarm->time); | |
| 356 | 354 | |
| 357 | 355 | /* Make sure we're not setting alarms in the past */ |
| 358 | 356 | err = __rtc_read_time(rtc, &tm); |
| 359 | 357 | if (err) |
| 360 | 358 | return err; |
| 361 | − rtc_tm_to_time(&tm, &now); | |
| 359 | + now = rtc_tm_to_time64(&tm); | |
| 362 | 360 | if (scheduled <= now) |
| 363 | 361 | return -ETIME; |
| 364 | 362 | /* |
| @@ -304,12 +304,12 @@ static long rtc_dev_ioctl(struct file *file, · 303 unmodified lines | ||
| 304 | 304 | * Not supported here. |
| 305 | 305 | */ |
| 306 | 306 | { |
| 307 | − unsigned long now, then; | |
| 307 | + time64_t now, then; | |
| 308 | 308 | |
| 309 | 309 | err = rtc_read_time(rtc, &tm); |
| 310 | 310 | if (err < 0) |
| 311 | 311 | return err; |
| 312 | − rtc_tm_to_time(&tm, &now); | |
| 312 | + now = rtc_tm_to_time64(&tm); | |
| 313 | 313 | |
| 314 | 314 | alarm.time.tm_mday = tm.tm_mday; |
| 315 | 315 | alarm.time.tm_mon = tm.tm_mon; |
| @@ -317,11 +317,11 @@ static long rtc_dev_ioctl(struct file *file, · 1 unmodified line | ||
| 317 | 317 | err = rtc_valid_tm(&alarm.time); |
| 318 | 318 | if (err < 0) |
| 319 | 319 | return err; |
| 320 | − rtc_tm_to_time(&alarm.time, &then); | |
| 320 | + then = rtc_tm_to_time64(&alarm.time); | |
| 321 | 321 | |
| 322 | 322 | /* alarm may need to wrap into tomorrow */ |
| 323 | 323 | if (then < now) { |
| 324 | − rtc_time_to_tm(now + 24 * 60 * 60, &tm); | |
| 324 | + rtc_time64_to_tm(now + 24 * 60 * 60, &tm); | |
| 325 | 325 | alarm.time.tm_mday = tm.tm_mday; |
| 326 | 326 | alarm.time.tm_mon = tm.tm_mon; |
| 327 | 327 | alarm.time.tm_year = tm.tm_year; |
| @@ -20,16 +20,16 @@ · 19 unmodified lines | ||
| 20 | 20 | * |
| 21 | 21 | * If temporary failure is indicated the caller should try again 'soon' |
| 22 | 22 | */ |
| 23 | −int rtc_set_ntp_time(struct timespec now) | |
| 23 | +int rtc_set_ntp_time(struct timespec64 now) | |
| 24 | 24 | { |
| 25 | 25 | struct rtc_device *rtc; |
| 26 | 26 | struct rtc_time tm; |
| 27 | 27 | int err = -ENODEV; |
| 28 | 28 | |
| 29 | 29 | if (now.tv_nsec < (NSEC_PER_SEC >> 1)) |
| 30 | − rtc_time_to_tm(now.tv_sec, &tm); | |
| 30 | + rtc_time64_to_tm(now.tv_sec, &tm); | |
| 31 | 31 | else |
| 32 | − rtc_time_to_tm(now.tv_sec + 1, &tm); | |
| 32 | + rtc_time64_to_tm(now.tv_sec + 1, &tm); | |
| 33 | 33 | |
| 34 | 34 | rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); |
| 35 | 35 | if (rtc) { |
| @@ -166,7 +166,17 @@ static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2) · 165 unmodified lines | ||
| 166 | 166 | } |
| 167 | 167 | |
| 168 | 168 | #if BITS_PER_LONG < 64 |
| 169 | −extern u64 ktime_divns(const ktime_t kt, s64 div); | |
| 169 | +extern u64 __ktime_divns(const ktime_t kt, s64 div); | |
| 170 | +static inline u64 ktime_divns(const ktime_t kt, s64 div) | |
| 171 | +{ | |
| 172 | + if (__builtin_constant_p(div) && !(div >> 32)) { | |
| 173 | + u64 ns = kt.tv64; | |
| 174 | + do_div(ns, div); | |
| 175 | + return ns; | |
| 176 | + } else { | |
| 177 | + return __ktime_divns(kt, div); | |
| 178 | + } | |
| 179 | +} | |
| 170 | 180 | #else /* BITS_PER_LONG < 64 */ |
| 171 | 181 | # define ktime_divns(kt, div) (u64)((kt).tv64 / (div)) |
| 172 | 182 | #endif |
| @@ -161,7 +161,7 @@ extern void devm_rtc_device_unregister(struct device *dev, · 160 unmodified lines | ||
| 161 | 161 | extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm); |
| 162 | 162 | extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm); |
| 163 | 163 | extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs); |
| 164 | −extern int rtc_set_ntp_time(struct timespec now); | |
| 164 | +extern int rtc_set_ntp_time(struct timespec64 now); | |
| 165 | 165 | int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm); |
| 166 | 166 | extern int rtc_read_alarm(struct rtc_device *rtc, |
| 167 | 167 | struct rtc_wkalrm *alrm); |
| @@ -33,6 +33,7 @@ extern time64_t ktime_get_real_seconds(void); · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | extern int __getnstimeofday64(struct timespec64 *tv); |
| 35 | 35 | extern void getnstimeofday64(struct timespec64 *tv); |
| 36 | +extern void getboottime64(struct timespec64 *ts); | |
| 36 | 37 | |
| 37 | 38 | #if BITS_PER_LONG == 64 |
| 38 | 39 | /** |
| @@ -72,6 +73,11 @@ static inline struct timespec get_monotonic_coarse(void) · 33 unmodified lines | ||
| 72 | 73 | { |
| 73 | 74 | return get_monotonic_coarse64(); |
| 74 | 75 | } |
| 76 | + | |
| 77 | +static inline void getboottime(struct timespec *ts) | |
| 78 | +{ | |
| 79 | + return getboottime64(ts); | |
| 80 | +} | |
| 75 | 81 | #else |
| 76 | 82 | /** |
| 77 | 83 | * Deprecated. Use do_settimeofday64(). |
| @@ -129,9 +135,15 @@ static inline struct timespec get_monotonic_coarse(void) · 51 unmodified lines | ||
| 129 | 135 | { |
| 130 | 136 | return timespec64_to_timespec(get_monotonic_coarse64()); |
| 131 | 137 | } |
| 132 | −#endif | |
| 133 | 138 | |
| 134 | −extern void getboottime(struct timespec *ts); | |
| 139 | +static inline void getboottime(struct timespec *ts) | |
| 140 | +{ | |
| 141 | + struct timespec64 ts64; | |
| 142 | + | |
| 143 | + getboottime64(&ts64); | |
| 144 | + *ts = timespec64_to_timespec(ts64); | |
| 145 | +} | |
| 146 | +#endif | |
| 135 | 147 | |
| 136 | 148 | #define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts) |
| 137 | 149 | #define ktime_get_real_ts64(ts) getnstimeofday64(ts) |
| @@ -217,6 +229,11 @@ static inline void get_monotonic_boottime(struct timespec *ts) · 79 unmodified lines | ||
| 217 | 229 | *ts = ktime_to_timespec(ktime_get_boottime()); |
| 218 | 230 | } |
| 219 | 231 | |
| 232 | +static inline void get_monotonic_boottime64(struct timespec64 *ts) | |
| 233 | +{ | |
| 234 | + *ts = ktime_to_timespec64(ktime_get_boottime()); | |
| 235 | +} | |
| 236 | + | |
| 220 | 237 | static inline void timekeeping_clocktai(struct timespec *ts) |
| 221 | 238 | { |
| 222 | 239 | *ts = ktime_to_timespec(ktime_get_clocktai()); |
| @@ -266,7 +266,7 @@ lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags) · 265 unmodified lines | ||
| 266 | 266 | /* |
| 267 | 267 | * Divide a ktime value by a nanosecond value |
| 268 | 268 | */ |
| 269 | −u64 ktime_divns(const ktime_t kt, s64 div) | |
| 269 | +u64 __ktime_divns(const ktime_t kt, s64 div) | |
| 270 | 270 | { |
| 271 | 271 | u64 dclc; |
| 272 | 272 | int sft = 0; |
| @@ -282,7 +282,7 @@ u64 ktime_divns(const ktime_t kt, s64 div) · 9 unmodified lines | ||
| 282 | 282 | |
| 283 | 283 | return dclc; |
| 284 | 284 | } |
| 285 | −EXPORT_SYMBOL_GPL(ktime_divns); | |
| 285 | +EXPORT_SYMBOL_GPL(__ktime_divns); | |
| 286 | 286 | #endif /* BITS_PER_LONG >= 64 */ |
| 287 | 287 | |
| 288 | 288 | /* |
| @@ -488,13 +488,13 @@ static void sync_cmos_clock(struct work_struct *work) · 487 unmodified lines | ||
| 488 | 488 | |
| 489 | 489 | getnstimeofday64(&now); |
| 490 | 490 | if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec * 5) { |
| 491 | − struct timespec adjust = timespec64_to_timespec(now); | |
| 491 | + struct timespec64 adjust = now; | |
| 492 | 492 | |
| 493 | 493 | fail = -ENODEV; |
| 494 | 494 | if (persistent_clock_is_local) |
| 495 | 495 | adjust.tv_sec -= (sys_tz.tz_minuteswest * 60); |
| 496 | 496 | #ifdef CONFIG_GENERIC_CMOS_UPDATE |
| 497 | − fail = update_persistent_clock(adjust); | |
| 497 | + fail = update_persistent_clock(timespec64_to_timespec(adjust)); | |
| 498 | 498 | #endif |
| 499 | 499 | #ifdef CONFIG_RTC_SYSTOHC |
| 500 | 500 | if (fail == -ENODEV) |
| @@ -1659,24 +1659,24 @@ out: · 1658 unmodified lines | ||
| 1659 | 1659 | } |
| 1660 | 1660 | |
| 1661 | 1661 | /** |
| 1662 | − * getboottime - Return the real time of system boot. | |
| 1663 | − * @ts: pointer to the timespec to be set | |
| 1662 | + * getboottime64 - Return the real time of system boot. | |
| 1663 | + * @ts: pointer to the timespec64 to be set | |
| 1664 | 1664 | * |
| 1665 | − * Returns the wall-time of boot in a timespec. | |
| 1665 | + * Returns the wall-time of boot in a timespec64. | |
| 1666 | 1666 | * |
| 1667 | 1667 | * This is based on the wall_to_monotonic offset and the total suspend |
| 1668 | 1668 | * time. Calls to settimeofday will affect the value returned (which |
| 1669 | 1669 | * basically means that however wrong your real time clock is at boot time, |
| 1670 | 1670 | * you get the right time here). |
| 1671 | 1671 | */ |
| 1672 | −void getboottime(struct timespec *ts) | |
| 1672 | +void getboottime64(struct timespec64 *ts) | |
| 1673 | 1673 | { |
| 1674 | 1674 | struct timekeeper *tk = &tk_core.timekeeper; |
| 1675 | 1675 | ktime_t t = ktime_sub(tk->offs_real, tk->offs_boot); |
| 1676 | 1676 | |
| 1677 | − *ts = ktime_to_timespec(t); | |
| 1677 | + *ts = ktime_to_timespec64(t); | |
| 1678 | 1678 | } |
| 1679 | −EXPORT_SYMBOL_GPL(getboottime); | |
| 1679 | +EXPORT_SYMBOL_GPL(getboottime64); | |
| 1680 | 1680 | |
| 1681 | 1681 | unsigned long get_seconds(void) |
| 1682 | 1682 | { |