aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig7
-rw-r--r--drivers/rtc/class.c23
2 files changed, 11 insertions, 19 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e1878877399c..42891726ea72 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -3,10 +3,10 @@
3# 3#
4 4
5config RTC_LIB 5config RTC_LIB
6 tristate 6 bool
7 7
8menuconfig RTC_CLASS 8menuconfig RTC_CLASS
9 tristate "Real Time Clock" 9 bool "Real Time Clock"
10 default n 10 default n
11 depends on !S390 11 depends on !S390
12 select RTC_LIB 12 select RTC_LIB
@@ -15,9 +15,6 @@ menuconfig RTC_CLASS
15 be allowed to plug one or more RTCs to your system. You will 15 be allowed to plug one or more RTCs to your system. You will
16 probably want to enable one or more of the interfaces below. 16 probably want to enable one or more of the interfaces below.
17 17
18 This driver can also be built as a module. If so, the module
19 will be called rtc-core.
20
21if RTC_CLASS 18if RTC_CLASS
22 19
23config RTC_HCTOSYS 20config RTC_HCTOSYS
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 39013867cbd6..4194e59e14cd 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -41,26 +41,21 @@ static void rtc_device_release(struct device *dev)
41 * system's wall clock; restore it on resume(). 41 * system's wall clock; restore it on resume().
42 */ 42 */
43 43
44static struct timespec delta;
45static time_t oldtime; 44static time_t oldtime;
45static struct timespec oldts;
46 46
47static int rtc_suspend(struct device *dev, pm_message_t mesg) 47static int rtc_suspend(struct device *dev, pm_message_t mesg)
48{ 48{
49 struct rtc_device *rtc = to_rtc_device(dev); 49 struct rtc_device *rtc = to_rtc_device(dev);
50 struct rtc_time tm; 50 struct rtc_time tm;
51 struct timespec ts = current_kernel_time();
52 51
53 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) 52 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
54 return 0; 53 return 0;
55 54
56 rtc_read_time(rtc, &tm); 55 rtc_read_time(rtc, &tm);
56 ktime_get_ts(&oldts);
57 rtc_tm_to_time(&tm, &oldtime); 57 rtc_tm_to_time(&tm, &oldtime);
58 58
59 /* RTC precision is 1 second; adjust delta for avg 1/2 sec err */
60 set_normalized_timespec(&delta,
61 ts.tv_sec - oldtime,
62 ts.tv_nsec - (NSEC_PER_SEC >> 1));
63
64 return 0; 59 return 0;
65} 60}
66 61
@@ -70,10 +65,12 @@ static int rtc_resume(struct device *dev)
70 struct rtc_time tm; 65 struct rtc_time tm;
71 time_t newtime; 66 time_t newtime;
72 struct timespec time; 67 struct timespec time;
68 struct timespec newts;
73 69
74 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) 70 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
75 return 0; 71 return 0;
76 72
73 ktime_get_ts(&newts);
77 rtc_read_time(rtc, &tm); 74 rtc_read_time(rtc, &tm);
78 if (rtc_valid_tm(&tm) != 0) { 75 if (rtc_valid_tm(&tm) != 0) {
79 pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev)); 76 pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev));
@@ -85,15 +82,13 @@ static int rtc_resume(struct device *dev)
85 pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); 82 pr_debug("%s: time travel!\n", dev_name(&rtc->dev));
86 return 0; 83 return 0;
87 } 84 }
85 /* calculate the RTC time delta */
86 set_normalized_timespec(&time, newtime - oldtime, 0);
88 87
89 /* restore wall clock using delta against this RTC; 88 /* subtract kernel time between rtc_suspend to rtc_resume */
90 * adjust again for avg 1/2 second RTC sampling error 89 time = timespec_sub(time, timespec_sub(newts, oldts));
91 */
92 set_normalized_timespec(&time,
93 newtime + delta.tv_sec,
94 (NSEC_PER_SEC >> 1) + delta.tv_nsec);
95 do_settimeofday(&time);
96 90
91 timekeeping_inject_sleeptime(&time);
97 return 0; 92 return 0;
98} 93}
99 94