aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/rtc/class.c3
-rw-r--r--drivers/rtc/systohc.c53
-rw-r--r--include/linux/rtc.h43
-rw-r--r--kernel/time/ntp.c166
4 files changed, 196 insertions, 69 deletions
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 2ed970d61da1..722d683e0b0f 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -161,6 +161,9 @@ static struct rtc_device *rtc_allocate_device(void)
161 161
162 device_initialize(&rtc->dev); 162 device_initialize(&rtc->dev);
163 163
164 /* Drivers can revise this default after allocating the device. */
165 rtc->set_offset_nsec = NSEC_PER_SEC / 2;
166
164 rtc->irq_freq = 1; 167 rtc->irq_freq = 1;
165 rtc->max_user_freq = 64; 168 rtc->max_user_freq = 64;
166 rtc->dev.class = rtc_class; 169 rtc->dev.class = rtc_class;
diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c
index b4a68ffcd06b..0c177647ea6c 100644
--- a/drivers/rtc/systohc.c
+++ b/drivers/rtc/systohc.c
@@ -10,6 +10,7 @@
10/** 10/**
11 * rtc_set_ntp_time - Save NTP synchronized time to the RTC 11 * rtc_set_ntp_time - Save NTP synchronized time to the RTC
12 * @now: Current time of day 12 * @now: Current time of day
13 * @target_nsec: pointer for desired now->tv_nsec value
13 * 14 *
14 * Replacement for the NTP platform function update_persistent_clock64 15 * Replacement for the NTP platform function update_persistent_clock64
15 * that stores time for later retrieval by rtc_hctosys. 16 * that stores time for later retrieval by rtc_hctosys.
@@ -18,30 +19,52 @@
18 * possible at all, and various other -errno for specific temporary failure 19 * possible at all, and various other -errno for specific temporary failure
19 * cases. 20 * cases.
20 * 21 *
22 * -EPROTO is returned if now.tv_nsec is not close enough to *target_nsec.
23 (
21 * If temporary failure is indicated the caller should try again 'soon' 24 * If temporary failure is indicated the caller should try again 'soon'
22 */ 25 */
23int rtc_set_ntp_time(struct timespec64 now) 26int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec)
24{ 27{
25 struct rtc_device *rtc; 28 struct rtc_device *rtc;
26 struct rtc_time tm; 29 struct rtc_time tm;
30 struct timespec64 to_set;
27 int err = -ENODEV; 31 int err = -ENODEV;
28 32 bool ok;
29 if (now.tv_nsec < (NSEC_PER_SEC >> 1))
30 rtc_time64_to_tm(now.tv_sec, &tm);
31 else
32 rtc_time64_to_tm(now.tv_sec + 1, &tm);
33 33
34 rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE); 34 rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE);
35 if (rtc) { 35 if (!rtc)
36 /* rtc_hctosys exclusively uses UTC, so we call set_time here, 36 goto out_err;
37 * not set_mmss. */ 37
38 if (rtc->ops && 38 if (!rtc->ops || (!rtc->ops->set_time && !rtc->ops->set_mmss64 &&
39 (rtc->ops->set_time || 39 !rtc->ops->set_mmss))
40 rtc->ops->set_mmss64 || 40 goto out_close;
41 rtc->ops->set_mmss)) 41
42 err = rtc_set_time(rtc, &tm); 42 /* Compute the value of tv_nsec we require the caller to supply in
43 rtc_class_close(rtc); 43 * now.tv_nsec. This is the value such that (now +
44 * set_offset_nsec).tv_nsec == 0.
45 */
46 set_normalized_timespec64(&to_set, 0, -rtc->set_offset_nsec);
47 *target_nsec = to_set.tv_nsec;
48
49 /* The ntp code must call this with the correct value in tv_nsec, if
50 * it does not we update target_nsec and return EPROTO to make the ntp
51 * code try again later.
52 */
53 ok = rtc_tv_nsec_ok(rtc->set_offset_nsec, &to_set, &now);
54 if (!ok) {
55 err = -EPROTO;
56 goto out_close;
44 } 57 }
45 58
59 rtc_time64_to_tm(to_set.tv_sec, &tm);
60
61 /* rtc_hctosys exclusively uses UTC, so we call set_time here, not
62 * set_mmss.
63 */
64 err = rtc_set_time(rtc, &tm);
65
66out_close:
67 rtc_class_close(rtc);
68out_err:
46 return err; 69 return err;
47} 70}
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index e6d0f9c1cafd..5b13fa029fd6 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -135,6 +135,14 @@ struct rtc_device {
135 /* Some hardware can't support UIE mode */ 135 /* Some hardware can't support UIE mode */
136 int uie_unsupported; 136 int uie_unsupported;
137 137
138 /* Number of nsec it takes to set the RTC clock. This influences when
139 * the set ops are called. An offset:
140 * - of 0.5 s will call RTC set for wall clock time 10.0 s at 9.5 s
141 * - of 1.5 s will call RTC set for wall clock time 10.0 s at 8.5 s
142 * - of -0.5 s will call RTC set for wall clock time 10.0 s at 10.5 s
143 */
144 long set_offset_nsec;
145
138 bool registered; 146 bool registered;
139 147
140 struct nvmem_config *nvmem_config; 148 struct nvmem_config *nvmem_config;
@@ -172,7 +180,7 @@ extern void devm_rtc_device_unregister(struct device *dev,
172 180
173extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm); 181extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
174extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm); 182extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
175extern int rtc_set_ntp_time(struct timespec64 now); 183extern int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec);
176int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm); 184int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm);
177extern int rtc_read_alarm(struct rtc_device *rtc, 185extern int rtc_read_alarm(struct rtc_device *rtc,
178 struct rtc_wkalrm *alrm); 186 struct rtc_wkalrm *alrm);
@@ -221,6 +229,39 @@ static inline bool is_leap_year(unsigned int year)
221 return (!(year % 4) && (year % 100)) || !(year % 400); 229 return (!(year % 4) && (year % 100)) || !(year % 400);
222} 230}
223 231
232/* Determine if we can call to driver to set the time. Drivers can only be
233 * called to set a second aligned time value, and the field set_offset_nsec
234 * specifies how far away from the second aligned time to call the driver.
235 *
236 * This also computes 'to_set' which is the time we are trying to set, and has
237 * a zero in tv_nsecs, such that:
238 * to_set - set_delay_nsec == now +/- FUZZ
239 *
240 */
241static inline bool rtc_tv_nsec_ok(s64 set_offset_nsec,
242 struct timespec64 *to_set,
243 const struct timespec64 *now)
244{
245 /* Allowed error in tv_nsec, arbitarily set to 5 jiffies in ns. */
246 const unsigned long TIME_SET_NSEC_FUZZ = TICK_NSEC * 5;
247 struct timespec64 delay = {.tv_sec = 0,
248 .tv_nsec = set_offset_nsec};
249
250 *to_set = timespec64_add(*now, delay);
251
252 if (to_set->tv_nsec < TIME_SET_NSEC_FUZZ) {
253 to_set->tv_nsec = 0;
254 return true;
255 }
256
257 if (to_set->tv_nsec > NSEC_PER_SEC - TIME_SET_NSEC_FUZZ) {
258 to_set->tv_sec++;
259 to_set->tv_nsec = 0;
260 return true;
261 }
262 return false;
263}
264
224#define rtc_register_device(device) \ 265#define rtc_register_device(device) \
225 __rtc_register_device(THIS_MODULE, device) 266 __rtc_register_device(THIS_MODULE, device)
226 267
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index edf19cc53140..bc19de1a0683 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -492,6 +492,67 @@ out:
492 return leap; 492 return leap;
493} 493}
494 494
495static void sync_hw_clock(struct work_struct *work);
496static DECLARE_DELAYED_WORK(sync_work, sync_hw_clock);
497
498static void sched_sync_hw_clock(struct timespec64 now,
499 unsigned long target_nsec, bool fail)
500
501{
502 struct timespec64 next;
503
504 getnstimeofday64(&next);
505 if (!fail)
506 next.tv_sec = 659;
507 else {
508 /*
509 * Try again as soon as possible. Delaying long periods
510 * decreases the accuracy of the work queue timer. Due to this
511 * the algorithm is very likely to require a short-sleep retry
512 * after the above long sleep to synchronize ts_nsec.
513 */
514 next.tv_sec = 0;
515 }
516
517 /* Compute the needed delay that will get to tv_nsec == target_nsec */
518 next.tv_nsec = target_nsec - next.tv_nsec;
519 if (next.tv_nsec <= 0)
520 next.tv_nsec += NSEC_PER_SEC;
521 if (next.tv_nsec >= NSEC_PER_SEC) {
522 next.tv_sec++;
523 next.tv_nsec -= NSEC_PER_SEC;
524 }
525
526 queue_delayed_work(system_power_efficient_wq, &sync_work,
527 timespec64_to_jiffies(&next));
528}
529
530static void sync_rtc_clock(void)
531{
532 unsigned long target_nsec;
533 struct timespec64 adjust, now;
534 int rc;
535
536 if (!IS_ENABLED(CONFIG_RTC_SYSTOHC))
537 return;
538
539 getnstimeofday64(&now);
540
541 adjust = now;
542 if (persistent_clock_is_local)
543 adjust.tv_sec -= (sys_tz.tz_minuteswest * 60);
544
545 /*
546 * The current RTC in use will provide the target_nsec it wants to be
547 * called at, and does rtc_tv_nsec_ok internally.
548 */
549 rc = rtc_set_ntp_time(adjust, &target_nsec);
550 if (rc == -ENODEV)
551 return;
552
553 sched_sync_hw_clock(now, target_nsec, rc);
554}
555
495#ifdef CONFIG_GENERIC_CMOS_UPDATE 556#ifdef CONFIG_GENERIC_CMOS_UPDATE
496int __weak update_persistent_clock(struct timespec now) 557int __weak update_persistent_clock(struct timespec now)
497{ 558{
@@ -507,76 +568,75 @@ int __weak update_persistent_clock64(struct timespec64 now64)
507} 568}
508#endif 569#endif
509 570
510#if defined(CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC) 571static bool sync_cmos_clock(void)
511static void sync_cmos_clock(struct work_struct *work);
512
513static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock);
514
515static void sync_cmos_clock(struct work_struct *work)
516{ 572{
573 static bool no_cmos;
517 struct timespec64 now; 574 struct timespec64 now;
518 struct timespec64 next; 575 struct timespec64 adjust;
519 int fail = 1; 576 int rc = -EPROTO;
577 long target_nsec = NSEC_PER_SEC / 2;
578
579 if (!IS_ENABLED(CONFIG_GENERIC_CMOS_UPDATE))
580 return false;
581
582 if (no_cmos)
583 return false;
520 584
521 /* 585 /*
522 * If we have an externally synchronized Linux clock, then update 586 * Historically update_persistent_clock64() has followed x86
523 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be 587 * semantics, which match the MC146818A/etc RTC. This RTC will store
524 * called as close as possible to 500 ms before the new second starts. 588 * 'adjust' and then in .5s it will advance once second.
525 * This code is run on a timer. If the clock is set, that timer 589 *
526 * may not expire at the correct time. Thus, we adjust... 590 * Architectures are strongly encouraged to use rtclib and not
527 * We want the clock to be within a couple of ticks from the target. 591 * implement this legacy API.
528 */ 592 */
529 if (!ntp_synced()) {
530 /*
531 * Not synced, exit, do not restart a timer (if one is
532 * running, let it run out).
533 */
534 return;
535 }
536
537 getnstimeofday64(&now); 593 getnstimeofday64(&now);
538 if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec * 5) { 594 if (rtc_tv_nsec_ok(-1 * target_nsec, &adjust, &now)) {
539 struct timespec64 adjust = now;
540
541 fail = -ENODEV;
542 if (persistent_clock_is_local) 595 if (persistent_clock_is_local)
543 adjust.tv_sec -= (sys_tz.tz_minuteswest * 60); 596 adjust.tv_sec -= (sys_tz.tz_minuteswest * 60);
544#ifdef CONFIG_GENERIC_CMOS_UPDATE 597 rc = update_persistent_clock64(adjust);
545 fail = update_persistent_clock64(adjust); 598 /*
546#endif 599 * The machine does not support update_persistent_clock64 even
547 600 * though it defines CONFIG_GENERIC_CMOS_UPDATE.
548#ifdef CONFIG_RTC_SYSTOHC 601 */
549 if (fail == -ENODEV) 602 if (rc == -ENODEV) {
550 fail = rtc_set_ntp_time(adjust); 603 no_cmos = true;
551#endif 604 return false;
605 }
552 } 606 }
553 607
554 next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2); 608 sched_sync_hw_clock(now, target_nsec, rc);
555 if (next.tv_nsec <= 0) 609 return true;
556 next.tv_nsec += NSEC_PER_SEC; 610}
557 611
558 if (!fail || fail == -ENODEV) 612/*
559 next.tv_sec = 659; 613 * If we have an externally synchronized Linux clock, then update RTC clock
560 else 614 * accordingly every ~11 minutes. Generally RTCs can only store second
561 next.tv_sec = 0; 615 * precision, but many RTCs will adjust the phase of their second tick to
616 * match the moment of update. This infrastructure arranges to call to the RTC
617 * set at the correct moment to phase synchronize the RTC second tick over
618 * with the kernel clock.
619 */
620static void sync_hw_clock(struct work_struct *work)
621{
622 if (!ntp_synced())
623 return;
562 624
563 if (next.tv_nsec >= NSEC_PER_SEC) { 625 if (sync_cmos_clock())
564 next.tv_sec++; 626 return;
565 next.tv_nsec -= NSEC_PER_SEC; 627
566 } 628 sync_rtc_clock();
567 queue_delayed_work(system_power_efficient_wq,
568 &sync_cmos_work, timespec64_to_jiffies(&next));
569} 629}
570 630
571void ntp_notify_cmos_timer(void) 631void ntp_notify_cmos_timer(void)
572{ 632{
573 queue_delayed_work(system_power_efficient_wq, &sync_cmos_work, 0); 633 if (!ntp_synced())
574} 634 return;
575
576#else
577void ntp_notify_cmos_timer(void) { }
578#endif
579 635
636 if (IS_ENABLED(CONFIG_GENERIC_CMOS_UPDATE) ||
637 IS_ENABLED(CONFIG_RTC_SYSTOHC))
638 queue_delayed_work(system_power_efficient_wq, &sync_work, 0);
639}
580 640
581/* 641/*
582 * Propagate a new txc->status value into the NTP state: 642 * Propagate a new txc->status value into the NTP state: