···2020config RTC_HCTOSYS2121 bool "Set system time from RTC on startup and resume"2222 default y2323+ depends on !ALWAYS_USE_PERSISTENT_CLOCK2324 help2425 If you say yes here, the system time (wall clock) will be set using2526 the value read from a specified RTC device. This is useful to avoid2627 unnecessary fsck runs at boot time, and to network better.27282929+config RTC_SYSTOHC3030+ bool "Set the RTC time based on NTP synchronization"3131+ default y3232+ depends on !ALWAYS_USE_PERSISTENT_CLOCK3333+ help3434+ If you say yes here, the system time (wall clock) will be stored3535+ in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 113636+ minutes if userspace reports synchronized NTP status.3737+2838config RTC_HCTOSYS_DEVICE2939 string "RTC used to set the system time"3030- depends on RTC_HCTOSYS = y4040+ depends on RTC_HCTOSYS = y || RTC_SYSTOHC = y3141 default "rtc0"3242 help3343 The RTC device that will be used to (re)initialize the system
···11+/*22+ * This program is free software; you can redistribute it and/or modify it33+ * under the terms of the GNU General Public License version 2 as published by44+ * the Free Software Foundation.55+ *66+ */77+#include <linux/rtc.h>88+#include <linux/time.h>99+1010+/**1111+ * rtc_set_ntp_time - Save NTP synchronized time to the RTC1212+ * @now: Current time of day1313+ *1414+ * Replacement for the NTP platform function update_persistent_clock1515+ * that stores time for later retrieval by rtc_hctosys.1616+ *1717+ * Returns 0 on successful RTC update, -ENODEV if a RTC update is not1818+ * possible at all, and various other -errno for specific temporary failure1919+ * cases.2020+ *2121+ * If temporary failure is indicated the caller should try again 'soon'2222+ */2323+int rtc_set_ntp_time(struct timespec 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))3030+ rtc_time_to_tm(now.tv_sec, &tm);3131+ else3232+ rtc_time_to_tm(now.tv_sec + 1, &tm);3333+3434+ rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);3535+ if (rtc) {3636+ /* rtc_hctosys exclusively uses UTC, so we call set_time here,3737+ * not set_mmss. */3838+ if (rtc->ops && (rtc->ops->set_time || rtc->ops->set_mmss))3939+ err = rtc_set_time(rtc, &tm);4040+ rtc_class_close(rtc);4141+ }4242+4343+ return err;4444+}
+7-3
fs/pstore/ram.c
···167167static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz)168168{169169 char *hdr;170170- struct timeval timestamp;170170+ struct timespec timestamp;171171 size_t len;172172173173- do_gettimeofday(×tamp);173173+ /* Report zeroed timestamp if called before timekeeping has resumed. */174174+ if (__getnstimeofday(×tamp)) {175175+ timestamp.tv_sec = 0;176176+ timestamp.tv_nsec = 0;177177+ }174178 hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu\n",175175- (long)timestamp.tv_sec, (long)timestamp.tv_usec);179179+ (long)timestamp.tv_sec, (long)(timestamp.tv_nsec / 1000));176180 WARN_ON_ONCE(!hdr);177181 len = hdr ? strlen(hdr) : 0;178182 persistent_ram_write(prz, hdr, len);
+1
include/linux/rtc.h
···138138extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);139139extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);140140extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs);141141+extern int rtc_set_ntp_time(struct timespec now);141142int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm);142143extern int rtc_read_alarm(struct rtc_device *rtc,143144 struct rtc_wkalrm *alrm);
···2929/* flag for if timekeeping is suspended */3030int __read_mostly timekeeping_suspended;31313232+/* Flag for if there is a persistent clock on this platform */3333+bool __read_mostly persistent_clock_exist = false;3434+3235static inline void tk_normalize_xtime(struct timekeeper *tk)3336{3437 while (tk->xtime_nsec >= ((u64)NSEC_PER_SEC << tk->shift)) {···267264}268265269266/**270270- * getnstimeofday - Returns the time of day in a timespec267267+ * __getnstimeofday - Returns the time of day in a timespec.271268 * @ts: pointer to the timespec to be set272269 *273273- * Returns the time of day in a timespec.270270+ * Updates the time of day in the timespec.271271+ * Returns 0 on success, or -ve when suspended (timespec will be undefined).274272 */275275-void getnstimeofday(struct timespec *ts)273273+int __getnstimeofday(struct timespec *ts)276274{277275 struct timekeeper *tk = &timekeeper;278276 unsigned long seq;279277 s64 nsecs = 0;280280-281281- WARN_ON(timekeeping_suspended);282278283279 do {284280 seq = read_seqbegin(&tk->lock);···289287290288 ts->tv_nsec = 0;291289 timespec_add_ns(ts, nsecs);290290+291291+ /*292292+ * Do not bail out early, in case there were callers still using293293+ * the value, even in the face of the WARN_ON.294294+ */295295+ if (unlikely(timekeeping_suspended))296296+ return -EAGAIN;297297+ return 0;298298+}299299+EXPORT_SYMBOL(__getnstimeofday);300300+301301+/**302302+ * getnstimeofday - Returns the time of day in a timespec.303303+ * @ts: pointer to the timespec to be set304304+ *305305+ * Returns the time of day in a timespec (WARN if suspended).306306+ */307307+void getnstimeofday(struct timespec *ts)308308+{309309+ WARN_ON(__getnstimeofday(ts));292310}293311EXPORT_SYMBOL(getnstimeofday);294312···662640 struct timespec now, boot, tmp;663641664642 read_persistent_clock(&now);643643+665644 if (!timespec_valid_strict(&now)) {666645 pr_warn("WARNING: Persistent clock returned invalid value!\n"667646 " Check your CMOS/BIOS settings.\n");668647 now.tv_sec = 0;669648 now.tv_nsec = 0;670670- }649649+ } else if (now.tv_sec || now.tv_nsec)650650+ persistent_clock_exist = true;671651672652 read_boot_clock(&boot);673653 if (!timespec_valid_strict(&boot)) {···742718{743719 struct timekeeper *tk = &timekeeper;744720 unsigned long flags;745745- struct timespec ts;746721747747- /* Make sure we don't set the clock twice */748748- read_persistent_clock(&ts);749749- if (!(ts.tv_sec == 0 && ts.tv_nsec == 0))722722+ /*723723+ * Make sure we don't set the clock twice, as timekeeping_resume()724724+ * already did it725725+ */726726+ if (has_persistent_clock())750727 return;751728752729 write_seqlock_irqsave(&tk->lock, flags);