aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/class.c')
-rw-r--r--drivers/rtc/class.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 565562ba6ac9..4194e59e14cd 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -16,6 +16,7 @@
16#include <linux/kdev_t.h> 16#include <linux/kdev_t.h>
17#include <linux/idr.h> 17#include <linux/idr.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/workqueue.h>
19 20
20#include "rtc-core.h" 21#include "rtc-core.h"
21 22
@@ -40,26 +41,21 @@ static void rtc_device_release(struct device *dev)
40 * system's wall clock; restore it on resume(). 41 * system's wall clock; restore it on resume().
41 */ 42 */
42 43
43static struct timespec delta;
44static time_t oldtime; 44static time_t oldtime;
45static struct timespec oldts;
45 46
46static int rtc_suspend(struct device *dev, pm_message_t mesg) 47static int rtc_suspend(struct device *dev, pm_message_t mesg)
47{ 48{
48 struct rtc_device *rtc = to_rtc_device(dev); 49 struct rtc_device *rtc = to_rtc_device(dev);
49 struct rtc_time tm; 50 struct rtc_time tm;
50 struct timespec ts = current_kernel_time();
51 51
52 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) 52 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
53 return 0; 53 return 0;
54 54
55 rtc_read_time(rtc, &tm); 55 rtc_read_time(rtc, &tm);
56 ktime_get_ts(&oldts);
56 rtc_tm_to_time(&tm, &oldtime); 57 rtc_tm_to_time(&tm, &oldtime);
57 58
58 /* RTC precision is 1 second; adjust delta for avg 1/2 sec err */
59 set_normalized_timespec(&delta,
60 ts.tv_sec - oldtime,
61 ts.tv_nsec - (NSEC_PER_SEC >> 1));
62
63 return 0; 59 return 0;
64} 60}
65 61
@@ -69,10 +65,12 @@ static int rtc_resume(struct device *dev)
69 struct rtc_time tm; 65 struct rtc_time tm;
70 time_t newtime; 66 time_t newtime;
71 struct timespec time; 67 struct timespec time;
68 struct timespec newts;
72 69
73 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) 70 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
74 return 0; 71 return 0;
75 72
73 ktime_get_ts(&newts);
76 rtc_read_time(rtc, &tm); 74 rtc_read_time(rtc, &tm);
77 if (rtc_valid_tm(&tm) != 0) { 75 if (rtc_valid_tm(&tm) != 0) {
78 pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev)); 76 pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev));
@@ -84,15 +82,13 @@ static int rtc_resume(struct device *dev)
84 pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); 82 pr_debug("%s: time travel!\n", dev_name(&rtc->dev));
85 return 0; 83 return 0;
86 } 84 }
85 /* calculate the RTC time delta */
86 set_normalized_timespec(&time, newtime - oldtime, 0);
87 87
88 /* restore wall clock using delta against this RTC; 88 /* subtract kernel time between rtc_suspend to rtc_resume */
89 * adjust again for avg 1/2 second RTC sampling error 89 time = timespec_sub(time, timespec_sub(newts, oldts));
90 */
91 set_normalized_timespec(&time,
92 newtime + delta.tv_sec,
93 (NSEC_PER_SEC >> 1) + delta.tv_nsec);
94 do_settimeofday(&time);
95 90
91 timekeeping_inject_sleeptime(&time);
96 return 0; 92 return 0;
97} 93}
98 94
@@ -116,6 +112,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
116 struct module *owner) 112 struct module *owner)
117{ 113{
118 struct rtc_device *rtc; 114 struct rtc_device *rtc;
115 struct rtc_wkalrm alrm;
119 int id, err; 116 int id, err;
120 117
121 if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) { 118 if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) {
@@ -142,6 +139,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
142 rtc->id = id; 139 rtc->id = id;
143 rtc->ops = ops; 140 rtc->ops = ops;
144 rtc->owner = owner; 141 rtc->owner = owner;
142 rtc->irq_freq = 1;
145 rtc->max_user_freq = 64; 143 rtc->max_user_freq = 64;
146 rtc->dev.parent = dev; 144 rtc->dev.parent = dev;
147 rtc->dev.class = rtc_class; 145 rtc->dev.class = rtc_class;
@@ -152,14 +150,34 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
152 spin_lock_init(&rtc->irq_task_lock); 150 spin_lock_init(&rtc->irq_task_lock);
153 init_waitqueue_head(&rtc->irq_queue); 151 init_waitqueue_head(&rtc->irq_queue);
154 152
153 /* Init timerqueue */
154 timerqueue_init_head(&rtc->timerqueue);
155 INIT_WORK(&rtc->irqwork, rtc_timer_do_work);
156 /* Init aie timer */
157 rtc_timer_init(&rtc->aie_timer, rtc_aie_update_irq, (void *)rtc);
158 /* Init uie timer */
159 rtc_timer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, (void *)rtc);
160 /* Init pie timer */
161 hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
162 rtc->pie_timer.function = rtc_pie_update_irq;
163 rtc->pie_enabled = 0;
164
165 /* Check to see if there is an ALARM already set in hw */
166 err = __rtc_read_alarm(rtc, &alrm);
167
168 if (!err && !rtc_valid_tm(&alrm.time))
169 rtc_initialize_alarm(rtc, &alrm);
170
155 strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); 171 strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
156 dev_set_name(&rtc->dev, "rtc%d", id); 172 dev_set_name(&rtc->dev, "rtc%d", id);
157 173
158 rtc_dev_prepare(rtc); 174 rtc_dev_prepare(rtc);
159 175
160 err = device_register(&rtc->dev); 176 err = device_register(&rtc->dev);
161 if (err) 177 if (err) {
178 put_device(&rtc->dev);
162 goto exit_kfree; 179 goto exit_kfree;
180 }
163 181
164 rtc_dev_add_device(rtc); 182 rtc_dev_add_device(rtc);
165 rtc_sysfs_add_device(rtc); 183 rtc_sysfs_add_device(rtc);