aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2013-02-04 05:03:03 -0500
committerThomas Gleixner <tglx@linutronix.de>2013-02-04 05:03:03 -0500
commit90889a635a9b5488624bccce3ff6b2eec68c007b (patch)
tree8ddde1e04060bd65ca2aafb09b38066cb7d69b4d
parenta9037430c6c784165a940a90bcd29f886834c8e7 (diff)
parent6f16eebe1ff82176339a0439c98ebec9768b0ee2 (diff)
Merge branch 'fortglx/3.9/time' of git://git.linaro.org/people/jstultz/linux into timers/core
Trivial conflict in arch/x86/Kconfig Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/powerpc/kernel/time.c2
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/kernel/tsc.c3
-rw-r--r--drivers/rtc/Kconfig12
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/class.c7
-rw-r--r--drivers/rtc/systohc.c44
-rw-r--r--fs/pstore/ram.c10
-rw-r--r--include/linux/rtc.h1
-rw-r--r--include/linux/time.h12
-rw-r--r--kernel/posix-timers.c2
-rw-r--r--kernel/time/Kconfig5
-rw-r--r--kernel/time/ntp.c16
-rw-r--r--kernel/time/timekeeping.c45
15 files changed, 141 insertions, 22 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 212c255b9347..f5bda78792d9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6598,7 +6598,7 @@ F: drivers/dma/dw_dmac_regs.h
6598F: drivers/dma/dw_dmac.c 6598F: drivers/dma/dw_dmac.c
6599 6599
6600TIMEKEEPING, NTP 6600TIMEKEEPING, NTP
6601M: John Stultz <johnstul@us.ibm.com> 6601M: John Stultz <john.stultz@linaro.org>
6602M: Thomas Gleixner <tglx@linutronix.de> 6602M: Thomas Gleixner <tglx@linutronix.de>
6603T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core 6603T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core
6604S: Supported 6604S: Supported
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 127361e093f4..aaba2e05a417 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -668,7 +668,7 @@ int update_persistent_clock(struct timespec now)
668 struct rtc_time tm; 668 struct rtc_time tm;
669 669
670 if (!ppc_md.set_rtc_time) 670 if (!ppc_md.set_rtc_time)
671 return 0; 671 return -ENODEV;
672 672
673 to_tm(now.tv_sec + 1 + timezone_offset, &tm); 673 to_tm(now.tv_sec + 1 + timezone_offset, &tm);
674 tm.tm_year -= 1900; 674 tm.tm_year -= 1900;
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 225543bf45a5..97b023f0cbe8 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -106,6 +106,7 @@ config X86
106 select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC) 106 select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)
107 select GENERIC_TIME_VSYSCALL if X86_64 107 select GENERIC_TIME_VSYSCALL if X86_64
108 select KTIME_SCALAR if X86_32 108 select KTIME_SCALAR if X86_32
109 select ALWAYS_USE_PERSISTENT_CLOCK
109 select GENERIC_STRNCPY_FROM_USER 110 select GENERIC_STRNCPY_FROM_USER
110 select GENERIC_STRNLEN_USER 111 select GENERIC_STRNLEN_USER
111 select HAVE_CONTEXT_TRACKING if X86_64 112 select HAVE_CONTEXT_TRACKING if X86_64
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 06ccb5073a3f..4b9ea101fe3b 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -623,7 +623,8 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu)
623 ns_now = __cycles_2_ns(tsc_now); 623 ns_now = __cycles_2_ns(tsc_now);
624 624
625 if (cpu_khz) { 625 if (cpu_khz) {
626 *scale = (NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR)/cpu_khz; 626 *scale = ((NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR) +
627 cpu_khz / 2) / cpu_khz;
627 *offset = ns_now - mult_frac(tsc_now, *scale, 628 *offset = ns_now - mult_frac(tsc_now, *scale,
628 (1UL << CYC2NS_SCALE_FACTOR)); 629 (1UL << CYC2NS_SCALE_FACTOR));
629 } 630 }
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 923a9da9c829..5e44eaabf457 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -20,14 +20,24 @@ if RTC_CLASS
20config RTC_HCTOSYS 20config RTC_HCTOSYS
21 bool "Set system time from RTC on startup and resume" 21 bool "Set system time from RTC on startup and resume"
22 default y 22 default y
23 depends on !ALWAYS_USE_PERSISTENT_CLOCK
23 help 24 help
24 If you say yes here, the system time (wall clock) will be set using 25 If you say yes here, the system time (wall clock) will be set using
25 the value read from a specified RTC device. This is useful to avoid 26 the value read from a specified RTC device. This is useful to avoid
26 unnecessary fsck runs at boot time, and to network better. 27 unnecessary fsck runs at boot time, and to network better.
27 28
29config RTC_SYSTOHC
30 bool "Set the RTC time based on NTP synchronization"
31 default y
32 depends on !ALWAYS_USE_PERSISTENT_CLOCK
33 help
34 If you say yes here, the system time (wall clock) will be stored
35 in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11
36 minutes if userspace reports synchronized NTP status.
37
28config RTC_HCTOSYS_DEVICE 38config RTC_HCTOSYS_DEVICE
29 string "RTC used to set the system time" 39 string "RTC used to set the system time"
30 depends on RTC_HCTOSYS = y 40 depends on RTC_HCTOSYS = y || RTC_SYSTOHC = y
31 default "rtc0" 41 default "rtc0"
32 help 42 help
33 The RTC device that will be used to (re)initialize the system 43 The RTC device that will be used to (re)initialize the system
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 4418ef3f9ecc..ec2988b00a44 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -6,6 +6,7 @@ ccflags-$(CONFIG_RTC_DEBUG) := -DDEBUG
6 6
7obj-$(CONFIG_RTC_LIB) += rtc-lib.o 7obj-$(CONFIG_RTC_LIB) += rtc-lib.o
8obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o 8obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o
9obj-$(CONFIG_RTC_SYSTOHC) += systohc.o
9obj-$(CONFIG_RTC_CLASS) += rtc-core.o 10obj-$(CONFIG_RTC_CLASS) += rtc-core.o
10rtc-core-y := class.o interface.o 11rtc-core-y := class.o interface.o
11 12
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 5143629dedbd..26388f182594 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -50,6 +50,10 @@ static int rtc_suspend(struct device *dev, pm_message_t mesg)
50 struct rtc_device *rtc = to_rtc_device(dev); 50 struct rtc_device *rtc = to_rtc_device(dev);
51 struct rtc_time tm; 51 struct rtc_time tm;
52 struct timespec delta, delta_delta; 52 struct timespec delta, delta_delta;
53
54 if (has_persistent_clock())
55 return 0;
56
53 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) 57 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
54 return 0; 58 return 0;
55 59
@@ -88,6 +92,9 @@ static int rtc_resume(struct device *dev)
88 struct timespec new_system, new_rtc; 92 struct timespec new_system, new_rtc;
89 struct timespec sleep_time; 93 struct timespec sleep_time;
90 94
95 if (has_persistent_clock())
96 return 0;
97
91 rtc_hctosys_ret = -ENODEV; 98 rtc_hctosys_ret = -ENODEV;
92 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) 99 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
93 return 0; 100 return 0;
diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c
new file mode 100644
index 000000000000..bf3e242ccc5c
--- /dev/null
+++ b/drivers/rtc/systohc.c
@@ -0,0 +1,44 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published by
4 * the Free Software Foundation.
5 *
6 */
7#include <linux/rtc.h>
8#include <linux/time.h>
9
10/**
11 * rtc_set_ntp_time - Save NTP synchronized time to the RTC
12 * @now: Current time of day
13 *
14 * Replacement for the NTP platform function update_persistent_clock
15 * that stores time for later retrieval by rtc_hctosys.
16 *
17 * Returns 0 on successful RTC update, -ENODEV if a RTC update is not
18 * possible at all, and various other -errno for specific temporary failure
19 * cases.
20 *
21 * If temporary failure is indicated the caller should try again 'soon'
22 */
23int rtc_set_ntp_time(struct timespec now)
24{
25 struct rtc_device *rtc;
26 struct rtc_time tm;
27 int err = -ENODEV;
28
29 if (now.tv_nsec < (NSEC_PER_SEC >> 1))
30 rtc_time_to_tm(now.tv_sec, &tm);
31 else
32 rtc_time_to_tm(now.tv_sec + 1, &tm);
33
34 rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
35 if (rtc) {
36 /* rtc_hctosys exclusively uses UTC, so we call set_time here,
37 * not set_mmss. */
38 if (rtc->ops && (rtc->ops->set_time || rtc->ops->set_mmss))
39 err = rtc_set_time(rtc, &tm);
40 rtc_class_close(rtc);
41 }
42
43 return err;
44}
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 7003e5266f25..288f068740f6 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -167,12 +167,16 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
167static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz) 167static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz)
168{ 168{
169 char *hdr; 169 char *hdr;
170 struct timeval timestamp; 170 struct timespec timestamp;
171 size_t len; 171 size_t len;
172 172
173 do_gettimeofday(&timestamp); 173 /* Report zeroed timestamp if called before timekeeping has resumed. */
174 if (__getnstimeofday(&timestamp)) {
175 timestamp.tv_sec = 0;
176 timestamp.tv_nsec = 0;
177 }
174 hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu\n", 178 hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu\n",
175 (long)timestamp.tv_sec, (long)timestamp.tv_usec); 179 (long)timestamp.tv_sec, (long)(timestamp.tv_nsec / 1000));
176 WARN_ON_ONCE(!hdr); 180 WARN_ON_ONCE(!hdr);
177 len = hdr ? strlen(hdr) : 0; 181 len = hdr ? strlen(hdr) : 0;
178 persistent_ram_write(prz, hdr, len); 182 persistent_ram_write(prz, hdr, len);
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 9531845c419f..11d05f9fe8b6 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -138,6 +138,7 @@ extern void rtc_device_unregister(struct rtc_device *rtc);
138extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm); 138extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
139extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm); 139extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
140extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs); 140extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs);
141extern int rtc_set_ntp_time(struct timespec now);
141int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm); 142int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm);
142extern int rtc_read_alarm(struct rtc_device *rtc, 143extern int rtc_read_alarm(struct rtc_device *rtc,
143 struct rtc_wkalrm *alrm); 144 struct rtc_wkalrm *alrm);
diff --git a/include/linux/time.h b/include/linux/time.h
index 4d358e9d10f1..476e1d7b2c37 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -115,6 +115,17 @@ static inline bool timespec_valid_strict(const struct timespec *ts)
115 return true; 115 return true;
116} 116}
117 117
118extern bool persistent_clock_exist;
119
120#ifdef ALWAYS_USE_PERSISTENT_CLOCK
121#define has_persistent_clock() true
122#else
123static inline bool has_persistent_clock(void)
124{
125 return persistent_clock_exist;
126}
127#endif
128
118extern void read_persistent_clock(struct timespec *ts); 129extern void read_persistent_clock(struct timespec *ts);
119extern void read_boot_clock(struct timespec *ts); 130extern void read_boot_clock(struct timespec *ts);
120extern int update_persistent_clock(struct timespec now); 131extern int update_persistent_clock(struct timespec now);
@@ -158,6 +169,7 @@ extern int do_setitimer(int which, struct itimerval *value,
158 struct itimerval *ovalue); 169 struct itimerval *ovalue);
159extern unsigned int alarm_setitimer(unsigned int seconds); 170extern unsigned int alarm_setitimer(unsigned int seconds);
160extern int do_getitimer(int which, struct itimerval *value); 171extern int do_getitimer(int which, struct itimerval *value);
172extern int __getnstimeofday(struct timespec *tv);
161extern void getnstimeofday(struct timespec *tv); 173extern void getnstimeofday(struct timespec *tv);
162extern void getrawmonotonic(struct timespec *ts); 174extern void getrawmonotonic(struct timespec *ts);
163extern void getnstime_raw_and_real(struct timespec *ts_raw, 175extern void getnstime_raw_and_real(struct timespec *ts_raw,
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 69185ae6b701..10349d5f2ec3 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -997,7 +997,7 @@ SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
997 997
998 err = kc->clock_adj(which_clock, &ktx); 998 err = kc->clock_adj(which_clock, &ktx);
999 999
1000 if (!err && copy_to_user(utx, &ktx, sizeof(ktx))) 1000 if (err >= 0 && copy_to_user(utx, &ktx, sizeof(ktx)))
1001 return -EFAULT; 1001 return -EFAULT;
1002 1002
1003 return err; 1003 return err;
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig
index b69692250af4..24510d84efd7 100644
--- a/kernel/time/Kconfig
+++ b/kernel/time/Kconfig
@@ -12,6 +12,11 @@ config CLOCKSOURCE_WATCHDOG
12config ARCH_CLOCKSOURCE_DATA 12config ARCH_CLOCKSOURCE_DATA
13 bool 13 bool
14 14
15# Platforms has a persistent clock
16config ALWAYS_USE_PERSISTENT_CLOCK
17 bool
18 default n
19
15# Timekeeping vsyscall support 20# Timekeeping vsyscall support
16config GENERIC_TIME_VSYSCALL 21config GENERIC_TIME_VSYSCALL
17 bool 22 bool
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 24174b4d669b..313b161504b7 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -15,6 +15,7 @@
15#include <linux/time.h> 15#include <linux/time.h>
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/rtc.h>
18 19
19#include "tick-internal.h" 20#include "tick-internal.h"
20 21
@@ -483,8 +484,7 @@ out:
483 return leap; 484 return leap;
484} 485}
485 486
486#ifdef CONFIG_GENERIC_CMOS_UPDATE 487#if defined(CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC)
487
488static void sync_cmos_clock(struct work_struct *work); 488static void sync_cmos_clock(struct work_struct *work);
489 489
490static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock); 490static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock);
@@ -510,14 +510,22 @@ static void sync_cmos_clock(struct work_struct *work)
510 } 510 }
511 511
512 getnstimeofday(&now); 512 getnstimeofday(&now);
513 if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) 513 if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) {
514 fail = -ENODEV;
515#ifdef CONFIG_GENERIC_CMOS_UPDATE
514 fail = update_persistent_clock(now); 516 fail = update_persistent_clock(now);
517#endif
518#ifdef CONFIG_RTC_SYSTOHC
519 if (fail == -ENODEV)
520 fail = rtc_set_ntp_time(now);
521#endif
522 }
515 523
516 next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2); 524 next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2);
517 if (next.tv_nsec <= 0) 525 if (next.tv_nsec <= 0)
518 next.tv_nsec += NSEC_PER_SEC; 526 next.tv_nsec += NSEC_PER_SEC;
519 527
520 if (!fail) 528 if (!fail || fail == -ENODEV)
521 next.tv_sec = 659; 529 next.tv_sec = 659;
522 else 530 else
523 next.tv_sec = 0; 531 next.tv_sec = 0;
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index cbc6acb0db3f..1e35515a875e 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -29,6 +29,9 @@ static struct timekeeper timekeeper;
29/* flag for if timekeeping is suspended */ 29/* flag for if timekeeping is suspended */
30int __read_mostly timekeeping_suspended; 30int __read_mostly timekeeping_suspended;
31 31
32/* Flag for if there is a persistent clock on this platform */
33bool __read_mostly persistent_clock_exist = false;
34
32static inline void tk_normalize_xtime(struct timekeeper *tk) 35static inline void tk_normalize_xtime(struct timekeeper *tk)
33{ 36{
34 while (tk->xtime_nsec >= ((u64)NSEC_PER_SEC << tk->shift)) { 37 while (tk->xtime_nsec >= ((u64)NSEC_PER_SEC << tk->shift)) {
@@ -264,19 +267,18 @@ static void timekeeping_forward_now(struct timekeeper *tk)
264} 267}
265 268
266/** 269/**
267 * getnstimeofday - Returns the time of day in a timespec 270 * __getnstimeofday - Returns the time of day in a timespec.
268 * @ts: pointer to the timespec to be set 271 * @ts: pointer to the timespec to be set
269 * 272 *
270 * Returns the time of day in a timespec. 273 * Updates the time of day in the timespec.
274 * Returns 0 on success, or -ve when suspended (timespec will be undefined).
271 */ 275 */
272void getnstimeofday(struct timespec *ts) 276int __getnstimeofday(struct timespec *ts)
273{ 277{
274 struct timekeeper *tk = &timekeeper; 278 struct timekeeper *tk = &timekeeper;
275 unsigned long seq; 279 unsigned long seq;
276 s64 nsecs = 0; 280 s64 nsecs = 0;
277 281
278 WARN_ON(timekeeping_suspended);
279
280 do { 282 do {
281 seq = read_seqbegin(&tk->lock); 283 seq = read_seqbegin(&tk->lock);
282 284
@@ -287,6 +289,26 @@ void getnstimeofday(struct timespec *ts)
287 289
288 ts->tv_nsec = 0; 290 ts->tv_nsec = 0;
289 timespec_add_ns(ts, nsecs); 291 timespec_add_ns(ts, nsecs);
292
293 /*
294 * Do not bail out early, in case there were callers still using
295 * the value, even in the face of the WARN_ON.
296 */
297 if (unlikely(timekeeping_suspended))
298 return -EAGAIN;
299 return 0;
300}
301EXPORT_SYMBOL(__getnstimeofday);
302
303/**
304 * getnstimeofday - Returns the time of day in a timespec.
305 * @ts: pointer to the timespec to be set
306 *
307 * Returns the time of day in a timespec (WARN if suspended).
308 */
309void getnstimeofday(struct timespec *ts)
310{
311 WARN_ON(__getnstimeofday(ts));
290} 312}
291EXPORT_SYMBOL(getnstimeofday); 313EXPORT_SYMBOL(getnstimeofday);
292 314
@@ -640,12 +662,14 @@ void __init timekeeping_init(void)
640 struct timespec now, boot, tmp; 662 struct timespec now, boot, tmp;
641 663
642 read_persistent_clock(&now); 664 read_persistent_clock(&now);
665
643 if (!timespec_valid_strict(&now)) { 666 if (!timespec_valid_strict(&now)) {
644 pr_warn("WARNING: Persistent clock returned invalid value!\n" 667 pr_warn("WARNING: Persistent clock returned invalid value!\n"
645 " Check your CMOS/BIOS settings.\n"); 668 " Check your CMOS/BIOS settings.\n");
646 now.tv_sec = 0; 669 now.tv_sec = 0;
647 now.tv_nsec = 0; 670 now.tv_nsec = 0;
648 } 671 } else if (now.tv_sec || now.tv_nsec)
672 persistent_clock_exist = true;
649 673
650 read_boot_clock(&boot); 674 read_boot_clock(&boot);
651 if (!timespec_valid_strict(&boot)) { 675 if (!timespec_valid_strict(&boot)) {
@@ -718,11 +742,12 @@ void timekeeping_inject_sleeptime(struct timespec *delta)
718{ 742{
719 struct timekeeper *tk = &timekeeper; 743 struct timekeeper *tk = &timekeeper;
720 unsigned long flags; 744 unsigned long flags;
721 struct timespec ts;
722 745
723 /* Make sure we don't set the clock twice */ 746 /*
724 read_persistent_clock(&ts); 747 * Make sure we don't set the clock twice, as timekeeping_resume()
725 if (!(ts.tv_sec == 0 && ts.tv_nsec == 0)) 748 * already did it
749 */
750 if (has_persistent_clock())
726 return; 751 return;
727 752
728 write_seqlock_irqsave(&tk->lock, flags); 753 write_seqlock_irqsave(&tk->lock, flags);