Skip to content

Commit fe31fca

Browse files
committed
Merge tag 'fortglx-3.20-time' of https://git.linaro.org/people/john.stultz/linux into timers/core
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
2 parents 9bc7491 + 9a4a445 commit fe31fca

File tree

10 files changed

+63
-46
lines changed

10 files changed

+63
-46
lines changed

drivers/rtc/hctosys.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ static int __init rtc_hctosys(void)
2626
{
2727
int err = -ENODEV;
2828
struct rtc_time tm;
29-
struct timespec tv = {
29+
struct timespec64 tv64 = {
3030
.tv_nsec = NSEC_PER_SEC >> 1,
3131
};
3232
struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
@@ -45,25 +45,17 @@ static int __init rtc_hctosys(void)
4545

4646
}
4747

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);
5649

57-
err = do_settimeofday(&tv);
50+
err = do_settimeofday64(&tv64);
5851

5952
dev_info(rtc->dev.parent,
6053
"setting system clock to "
61-
"%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
54+
"%d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n",
6255
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
6356
tm.tm_hour, tm.tm_min, tm.tm_sec,
64-
(unsigned int) tv.tv_sec);
57+
(long long) tv64.tv_sec);
6558

66-
err_invalid:
6759
err_read:
6860
rtc_class_close(rtc);
6961

drivers/rtc/interface.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
7373
else if (rtc->ops->set_time)
7474
err = rtc->ops->set_time(rtc->dev.parent, tm);
7575
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);
8078
} else
8179
err = -EINVAL;
8280

@@ -105,7 +103,7 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
105103

106104
err = rtc->ops->read_time(rtc->dev.parent, &old);
107105
if (err == 0) {
108-
rtc_time_to_tm(secs, &new);
106+
rtc_time64_to_tm(secs, &new);
109107

110108
/*
111109
* 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)
157155
int err;
158156
struct rtc_time before, now;
159157
int first_time = 1;
160-
unsigned long t_now, t_alm;
158+
time64_t t_now, t_alm;
161159
enum { none, day, month, year } missing = none;
162160
unsigned days;
163161

@@ -258,8 +256,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
258256
}
259257

260258
/* 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);
263261
if (t_now < t_alm)
264262
goto done;
265263

@@ -273,7 +271,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
273271
case day:
274272
dev_dbg(&rtc->dev, "alarm rollover: %s\n", "day");
275273
t_alm += 24 * 60 * 60;
276-
rtc_time_to_tm(t_alm, &alarm->time);
274+
rtc_time64_to_tm(t_alm, &alarm->time);
277275
break;
278276

279277
/* Month rollover ... if it's the 31th, an alarm on the 3rd will
@@ -346,19 +344,19 @@ EXPORT_SYMBOL_GPL(rtc_read_alarm);
346344
static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
347345
{
348346
struct rtc_time tm;
349-
long now, scheduled;
347+
time64_t now, scheduled;
350348
int err;
351349

352350
err = rtc_valid_tm(&alarm->time);
353351
if (err)
354352
return err;
355-
rtc_tm_to_time(&alarm->time, &scheduled);
353+
scheduled = rtc_tm_to_time64(&alarm->time);
356354

357355
/* Make sure we're not setting alarms in the past */
358356
err = __rtc_read_time(rtc, &tm);
359357
if (err)
360358
return err;
361-
rtc_tm_to_time(&tm, &now);
359+
now = rtc_tm_to_time64(&tm);
362360
if (scheduled <= now)
363361
return -ETIME;
364362
/*

drivers/rtc/rtc-dev.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,24 +304,24 @@ static long rtc_dev_ioctl(struct file *file,
304304
* Not supported here.
305305
*/
306306
{
307-
unsigned long now, then;
307+
time64_t now, then;
308308

309309
err = rtc_read_time(rtc, &tm);
310310
if (err < 0)
311311
return err;
312-
rtc_tm_to_time(&tm, &now);
312+
now = rtc_tm_to_time64(&tm);
313313

314314
alarm.time.tm_mday = tm.tm_mday;
315315
alarm.time.tm_mon = tm.tm_mon;
316316
alarm.time.tm_year = tm.tm_year;
317317
err = rtc_valid_tm(&alarm.time);
318318
if (err < 0)
319319
return err;
320-
rtc_tm_to_time(&alarm.time, &then);
320+
then = rtc_tm_to_time64(&alarm.time);
321321

322322
/* alarm may need to wrap into tomorrow */
323323
if (then < now) {
324-
rtc_time_to_tm(now + 24 * 60 * 60, &tm);
324+
rtc_time64_to_tm(now + 24 * 60 * 60, &tm);
325325
alarm.time.tm_mday = tm.tm_mday;
326326
alarm.time.tm_mon = tm.tm_mon;
327327
alarm.time.tm_year = tm.tm_year;

drivers/rtc/systohc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@
2020
*
2121
* If temporary failure is indicated the caller should try again 'soon'
2222
*/
23-
int rtc_set_ntp_time(struct timespec now)
23+
int rtc_set_ntp_time(struct timespec64 now)
2424
{
2525
struct rtc_device *rtc;
2626
struct rtc_time tm;
2727
int err = -ENODEV;
2828

2929
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);
3131
else
32-
rtc_time_to_tm(now.tv_sec + 1, &tm);
32+
rtc_time64_to_tm(now.tv_sec + 1, &tm);
3333

3434
rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
3535
if (rtc) {

include/linux/ktime.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,17 @@ static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2)
166166
}
167167

168168
#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+
}
170180
#else /* BITS_PER_LONG < 64 */
171181
# define ktime_divns(kt, div) (u64)((kt).tv64 / (div))
172182
#endif

include/linux/rtc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ extern void devm_rtc_device_unregister(struct device *dev,
161161
extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
162162
extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
163163
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);
165165
int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm);
166166
extern int rtc_read_alarm(struct rtc_device *rtc,
167167
struct rtc_wkalrm *alrm);

include/linux/timekeeping.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extern time64_t ktime_get_real_seconds(void);
3333

3434
extern int __getnstimeofday64(struct timespec64 *tv);
3535
extern void getnstimeofday64(struct timespec64 *tv);
36+
extern void getboottime64(struct timespec64 *ts);
3637

3738
#if BITS_PER_LONG == 64
3839
/**
@@ -72,6 +73,11 @@ static inline struct timespec get_monotonic_coarse(void)
7273
{
7374
return get_monotonic_coarse64();
7475
}
76+
77+
static inline void getboottime(struct timespec *ts)
78+
{
79+
return getboottime64(ts);
80+
}
7581
#else
7682
/**
7783
* Deprecated. Use do_settimeofday64().
@@ -129,9 +135,15 @@ static inline struct timespec get_monotonic_coarse(void)
129135
{
130136
return timespec64_to_timespec(get_monotonic_coarse64());
131137
}
132-
#endif
133138

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
135147

136148
#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts)
137149
#define ktime_get_real_ts64(ts) getnstimeofday64(ts)
@@ -217,6 +229,11 @@ static inline void get_monotonic_boottime(struct timespec *ts)
217229
*ts = ktime_to_timespec(ktime_get_boottime());
218230
}
219231

232+
static inline void get_monotonic_boottime64(struct timespec64 *ts)
233+
{
234+
*ts = ktime_to_timespec64(ktime_get_boottime());
235+
}
236+
220237
static inline void timekeeping_clocktai(struct timespec *ts)
221238
{
222239
*ts = ktime_to_timespec(ktime_get_clocktai());

kernel/time/hrtimer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
266266
/*
267267
* Divide a ktime value by a nanosecond value
268268
*/
269-
u64 ktime_divns(const ktime_t kt, s64 div)
269+
u64 __ktime_divns(const ktime_t kt, s64 div)
270270
{
271271
u64 dclc;
272272
int sft = 0;
@@ -282,7 +282,7 @@ u64 ktime_divns(const ktime_t kt, s64 div)
282282

283283
return dclc;
284284
}
285-
EXPORT_SYMBOL_GPL(ktime_divns);
285+
EXPORT_SYMBOL_GPL(__ktime_divns);
286286
#endif /* BITS_PER_LONG >= 64 */
287287

288288
/*

kernel/time/ntp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,13 +488,13 @@ static void sync_cmos_clock(struct work_struct *work)
488488

489489
getnstimeofday64(&now);
490490
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;
492492

493493
fail = -ENODEV;
494494
if (persistent_clock_is_local)
495495
adjust.tv_sec -= (sys_tz.tz_minuteswest * 60);
496496
#ifdef CONFIG_GENERIC_CMOS_UPDATE
497-
fail = update_persistent_clock(adjust);
497+
fail = update_persistent_clock(timespec64_to_timespec(adjust));
498498
#endif
499499
#ifdef CONFIG_RTC_SYSTOHC
500500
if (fail == -ENODEV)

kernel/time/timekeeping.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,24 +1659,24 @@ void update_wall_time(void)
16591659
}
16601660

16611661
/**
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
16641664
*
1665-
* Returns the wall-time of boot in a timespec.
1665+
* Returns the wall-time of boot in a timespec64.
16661666
*
16671667
* This is based on the wall_to_monotonic offset and the total suspend
16681668
* time. Calls to settimeofday will affect the value returned (which
16691669
* basically means that however wrong your real time clock is at boot time,
16701670
* you get the right time here).
16711671
*/
1672-
void getboottime(struct timespec *ts)
1672+
void getboottime64(struct timespec64 *ts)
16731673
{
16741674
struct timekeeper *tk = &tk_core.timekeeper;
16751675
ktime_t t = ktime_sub(tk->offs_real, tk->offs_boot);
16761676

1677-
*ts = ktime_to_timespec(t);
1677+
*ts = ktime_to_timespec64(t);
16781678
}
1679-
EXPORT_SYMBOL_GPL(getboottime);
1679+
EXPORT_SYMBOL_GPL(getboottime64);
16801680

16811681
unsigned long get_seconds(void)
16821682
{

0 commit comments

Comments
 (0)