ntp, rtc: Move rtc_set_ntp_time() to ntp code
authorThomas Gleixner <tglx@linutronix.de>
Sun, 6 Dec 2020 21:46:19 +0000 (22:46 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 11 Dec 2020 09:40:52 +0000 (10:40 +0100)
rtc_set_ntp_time() is not really RTC functionality as the code is just a
user of RTC. Move it into the NTP code which allows further cleanups.

Requested-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/20201206220542.166871172@linutronix.de
drivers/rtc/Makefile
drivers/rtc/systohc.c [deleted file]
include/linux/rtc.h
kernel/time/ntp.c

index bfb5746..bb8f319 100644 (file)
@@ -6,7 +6,6 @@
 ccflags-$(CONFIG_RTC_DEBUG)    := -DDEBUG
 
 obj-$(CONFIG_RTC_LIB)          += lib.o
-obj-$(CONFIG_RTC_SYSTOHC)      += systohc.o
 obj-$(CONFIG_RTC_CLASS)                += rtc-core.o
 obj-$(CONFIG_RTC_MC146818_LIB) += rtc-mc146818-lib.o
 rtc-core-y                     := class.o interface.o
diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c
deleted file mode 100644 (file)
index 8b70f05..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/rtc.h>
-#include <linux/time.h>
-
-/**
- * rtc_set_ntp_time - Save NTP synchronized time to the RTC
- * @now: Current time of day
- * @target_nsec: pointer for desired now->tv_nsec value
- *
- * Replacement for the NTP platform function update_persistent_clock64
- * that stores time for later retrieval by rtc_hctosys.
- *
- * Returns 0 on successful RTC update, -ENODEV if a RTC update is not
- * possible at all, and various other -errno for specific temporary failure
- * cases.
- *
- * -EPROTO is returned if now.tv_nsec is not close enough to *target_nsec.
- *
- * If temporary failure is indicated the caller should try again 'soon'
- */
-int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec)
-{
-       struct rtc_device *rtc;
-       struct rtc_time tm;
-       struct timespec64 to_set;
-       int err = -ENODEV;
-       bool ok;
-
-       rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE);
-       if (!rtc)
-               goto out_err;
-
-       if (!rtc->ops || !rtc->ops->set_time)
-               goto out_close;
-
-       /* Compute the value of tv_nsec we require the caller to supply in
-        * now.tv_nsec.  This is the value such that (now +
-        * set_offset_nsec).tv_nsec == 0.
-        */
-       set_normalized_timespec64(&to_set, 0, -rtc->set_offset_nsec);
-       *target_nsec = to_set.tv_nsec;
-
-       /* The ntp code must call this with the correct value in tv_nsec, if
-        * it does not we update target_nsec and return EPROTO to make the ntp
-        * code try again later.
-        */
-       ok = rtc_tv_nsec_ok(rtc->set_offset_nsec, &to_set, &now);
-       if (!ok) {
-               err = -EPROTO;
-               goto out_close;
-       }
-
-       rtc_time64_to_tm(to_set.tv_sec, &tm);
-
-       err = rtc_set_time(rtc, &tm);
-
-out_close:
-       rtc_class_close(rtc);
-out_err:
-       return err;
-}
index 22d1575..ff62680 100644 (file)
@@ -165,7 +165,6 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc);
 
 extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
 extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
-extern int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec);
 int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm);
 extern int rtc_read_alarm(struct rtc_device *rtc,
                        struct rtc_wkalrm *alrm);
@@ -205,39 +204,6 @@ static inline bool is_leap_year(unsigned int year)
        return (!(year % 4) && (year % 100)) || !(year % 400);
 }
 
-/* Determine if we can call to driver to set the time. Drivers can only be
- * called to set a second aligned time value, and the field set_offset_nsec
- * specifies how far away from the second aligned time to call the driver.
- *
- * This also computes 'to_set' which is the time we are trying to set, and has
- * a zero in tv_nsecs, such that:
- *    to_set - set_delay_nsec == now +/- FUZZ
- *
- */
-static inline bool rtc_tv_nsec_ok(s64 set_offset_nsec,
-                                 struct timespec64 *to_set,
-                                 const struct timespec64 *now)
-{
-       /* Allowed error in tv_nsec, arbitarily set to 5 jiffies in ns. */
-       const unsigned long TIME_SET_NSEC_FUZZ = TICK_NSEC * 5;
-       struct timespec64 delay = {.tv_sec = 0,
-                                  .tv_nsec = set_offset_nsec};
-
-       *to_set = timespec64_add(*now, delay);
-
-       if (to_set->tv_nsec < TIME_SET_NSEC_FUZZ) {
-               to_set->tv_nsec = 0;
-               return true;
-       }
-
-       if (to_set->tv_nsec > NSEC_PER_SEC - TIME_SET_NSEC_FUZZ) {
-               to_set->tv_sec++;
-               to_set->tv_nsec = 0;
-               return true;
-       }
-       return false;
-}
-
 #define rtc_register_device(device) \
        __rtc_register_device(THIS_MODULE, device)
 
index ff1a7b8..84a5546 100644 (file)
@@ -519,15 +519,94 @@ static void sched_sync_hw_clock(unsigned long offset_nsec, bool retry)
        hrtimer_start(&sync_hrtimer, exp, HRTIMER_MODE_ABS);
 }
 
+/*
+ * Determine if we can call to driver to set the time. Drivers can only be
+ * called to set a second aligned time value, and the field set_offset_nsec
+ * specifies how far away from the second aligned time to call the driver.
+ *
+ * This also computes 'to_set' which is the time we are trying to set, and has
+ * a zero in tv_nsecs, such that:
+ *    to_set - set_delay_nsec == now +/- FUZZ
+ *
+ */
+static inline bool rtc_tv_nsec_ok(long set_offset_nsec,
+                                 struct timespec64 *to_set,
+                                 const struct timespec64 *now)
+{
+       /* Allowed error in tv_nsec, arbitarily set to 5 jiffies in ns. */
+       const unsigned long TIME_SET_NSEC_FUZZ = TICK_NSEC * 5;
+       struct timespec64 delay = {.tv_sec = 0,
+                                  .tv_nsec = set_offset_nsec};
+
+       *to_set = timespec64_add(*now, delay);
+
+       if (to_set->tv_nsec < TIME_SET_NSEC_FUZZ) {
+               to_set->tv_nsec = 0;
+               return true;
+       }
+
+       if (to_set->tv_nsec > NSEC_PER_SEC - TIME_SET_NSEC_FUZZ) {
+               to_set->tv_sec++;
+               to_set->tv_nsec = 0;
+               return true;
+       }
+       return false;
+}
+
+#ifdef CONFIG_RTC_SYSTOHC
+/*
+ * rtc_set_ntp_time - Save NTP synchronized time to the RTC
+ */
+static int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec)
+{
+       struct rtc_device *rtc;
+       struct rtc_time tm;
+       struct timespec64 to_set;
+       int err = -ENODEV;
+       bool ok;
+
+       rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE);
+       if (!rtc)
+               goto out_err;
+
+       if (!rtc->ops || !rtc->ops->set_time)
+               goto out_close;
+
+       /*
+        * Compute the value of tv_nsec we require the caller to supply in
+        * now.tv_nsec.  This is the value such that (now +
+        * set_offset_nsec).tv_nsec == 0.
+        */
+       set_normalized_timespec64(&to_set, 0, -rtc->set_offset_nsec);
+       *target_nsec = to_set.tv_nsec;
+
+       /*
+        * The ntp code must call this with the correct value in tv_nsec, if
+        * it does not we update target_nsec and return EPROTO to make the ntp
+        * code try again later.
+        */
+       ok = rtc_tv_nsec_ok(rtc->set_offset_nsec, &to_set, &now);
+       if (!ok) {
+               err = -EPROTO;
+               goto out_close;
+       }
+
+       rtc_time64_to_tm(to_set.tv_sec, &tm);
+
+       err = rtc_set_time(rtc, &tm);
+
+out_close:
+       rtc_class_close(rtc);
+out_err:
+       return err;
+}
+
 static void sync_rtc_clock(void)
 {
        unsigned long offset_nsec;
        struct timespec64 adjust;
        int rc;
 
-       if (!IS_ENABLED(CONFIG_RTC_SYSTOHC))
-               return;
-
        ktime_get_real_ts64(&adjust);
 
        if (persistent_clock_is_local)
@@ -544,6 +623,9 @@ static void sync_rtc_clock(void)
 
        sched_sync_hw_clock(offset_nsec, rc != 0);
 }
+#else
+static inline void sync_rtc_clock(void) { }
+#endif
 
 #ifdef CONFIG_GENERIC_CMOS_UPDATE
 int __weak update_persistent_clock64(struct timespec64 now64)