aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/interface.c
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2010-09-23 18:07:34 -0400
committerJohn Stultz <john.stultz@linaro.org>2010-12-11 01:24:24 -0500
commit6610e0893b8bc6f59b14fed7f089c5997f035f88 (patch)
treeb13f4f516fe8fd31a6f6fbb68dd0c520c4c19df7 /drivers/rtc/interface.c
parentb007c389d3e09b823eccda1503390fa2a9adca0d (diff)
RTC: Rework RTC code to use timerqueue for events
This patch reworks a large portion of the generic RTC code to in-effect virtualize the rtc interrupt code. The current RTC interface is very much a raw hardware interface. Via the proc, /dev/, or sysfs interfaces, applciations can set the hardware to trigger interrupts in one of three modes: AIE: Alarm interrupt UIE: Update interrupt (ie: once per second) PIE: Periodic interrupt (sub-second irqs) The problem with this interface is that it limits the RTC hardware so it can only be used by one application at a time. The purpose of this patch is to extend the RTC code so that we can multiplex multiple applications event needs onto a single RTC device. This is done by utilizing the timerqueue infrastructure to manage a list of events, which cause the RTC hardware to be programmed to fire an interrupt for the next event in the list. In order to preserve the functionality of the exsting proc,/dev/ and sysfs interfaces, we emulate the different interrupt modes as follows: AIE: We create a rtc_timer dedicated to AIE mode interrupts. There is only one per device, so we don't change existing interface semantics. UIE: Again, a dedicated rtc_timer, set for periodic mode, is used to emulate UIE interrupts. Again, only one per device. PIE: Since PIE mode interrupts fire faster then the RTC's clock read granularity, we emulate PIE mode interrupts using a hrtimer. Again, one per device. With this patch, the rtctest.c application in Documentation/rtc.txt passes fine on x86 hardware. However, there may very well still be bugs, so greatly I'd appreciate any feedback or testing! Signed-off-by: John Stultz <john.stultz@linaro.org> LKML Reference: <1290136329-18291-4-git-send-email-john.stultz@linaro.org> Acked-by: Alessandro Zummo <a.zummo@towertech.it> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> CC: Alessandro Zummo <a.zummo@towertech.it> CC: Thomas Gleixner <tglx@linutronix.de> CC: Richard Cochran <richardcochran@gmail.com>
Diffstat (limited to 'drivers/rtc/interface.c')
-rw-r--r--drivers/rtc/interface.c574
1 files changed, 349 insertions, 225 deletions
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index a0c816238aa9..c81c50b497b7 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -14,15 +14,11 @@
14#include <linux/rtc.h> 14#include <linux/rtc.h>
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/log2.h> 16#include <linux/log2.h>
17#include <linux/workqueue.h>
17 18
18int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) 19static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
19{ 20{
20 int err; 21 int err;
21
22 err = mutex_lock_interruptible(&rtc->ops_lock);
23 if (err)
24 return err;
25
26 if (!rtc->ops) 22 if (!rtc->ops)
27 err = -ENODEV; 23 err = -ENODEV;
28 else if (!rtc->ops->read_time) 24 else if (!rtc->ops->read_time)
@@ -31,7 +27,18 @@ int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
31 memset(tm, 0, sizeof(struct rtc_time)); 27 memset(tm, 0, sizeof(struct rtc_time));
32 err = rtc->ops->read_time(rtc->dev.parent, tm); 28 err = rtc->ops->read_time(rtc->dev.parent, tm);
33 } 29 }
30 return err;
31}
32
33int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
34{
35 int err;
34 36
37 err = mutex_lock_interruptible(&rtc->ops_lock);
38 if (err)
39 return err;
40
41 err = __rtc_read_time(rtc, tm);
35 mutex_unlock(&rtc->ops_lock); 42 mutex_unlock(&rtc->ops_lock);
36 return err; 43 return err;
37} 44}
@@ -106,188 +113,54 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
106} 113}
107EXPORT_SYMBOL_GPL(rtc_set_mmss); 114EXPORT_SYMBOL_GPL(rtc_set_mmss);
108 115
109static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *alarm) 116int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
110{ 117{
111 int err; 118 int err;
112 119
113 err = mutex_lock_interruptible(&rtc->ops_lock); 120 err = mutex_lock_interruptible(&rtc->ops_lock);
114 if (err) 121 if (err)
115 return err; 122 return err;
116 123 alarm->enabled = rtc->aie_timer.enabled;
117 if (rtc->ops == NULL) 124 if (alarm->enabled)
118 err = -ENODEV; 125 alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires);
119 else if (!rtc->ops->read_alarm)
120 err = -EINVAL;
121 else {
122 memset(alarm, 0, sizeof(struct rtc_wkalrm));
123 err = rtc->ops->read_alarm(rtc->dev.parent, alarm);
124 }
125
126 mutex_unlock(&rtc->ops_lock); 126 mutex_unlock(&rtc->ops_lock);
127 return err; 127
128 return 0;
128} 129}
130EXPORT_SYMBOL_GPL(rtc_read_alarm);
129 131
130int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) 132int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
131{ 133{
134 struct rtc_time tm;
135 long now, scheduled;
132 int err; 136 int err;
133 struct rtc_time before, now;
134 int first_time = 1;
135 unsigned long t_now, t_alm;
136 enum { none, day, month, year } missing = none;
137 unsigned days;
138
139 /* The lower level RTC driver may return -1 in some fields,
140 * creating invalid alarm->time values, for reasons like:
141 *
142 * - The hardware may not be capable of filling them in;
143 * many alarms match only on time-of-day fields, not
144 * day/month/year calendar data.
145 *
146 * - Some hardware uses illegal values as "wildcard" match
147 * values, which non-Linux firmware (like a BIOS) may try
148 * to set up as e.g. "alarm 15 minutes after each hour".
149 * Linux uses only oneshot alarms.
150 *
151 * When we see that here, we deal with it by using values from
152 * a current RTC timestamp for any missing (-1) values. The
153 * RTC driver prevents "periodic alarm" modes.
154 *
155 * But this can be racey, because some fields of the RTC timestamp
156 * may have wrapped in the interval since we read the RTC alarm,
157 * which would lead to us inserting inconsistent values in place
158 * of the -1 fields.
159 *
160 * Reading the alarm and timestamp in the reverse sequence
161 * would have the same race condition, and not solve the issue.
162 *
163 * So, we must first read the RTC timestamp,
164 * then read the RTC alarm value,
165 * and then read a second RTC timestamp.
166 *
167 * If any fields of the second timestamp have changed
168 * when compared with the first timestamp, then we know
169 * our timestamp may be inconsistent with that used by
170 * the low-level rtc_read_alarm_internal() function.
171 *
172 * So, when the two timestamps disagree, we just loop and do
173 * the process again to get a fully consistent set of values.
174 *
175 * This could all instead be done in the lower level driver,
176 * but since more than one lower level RTC implementation needs it,
177 * then it's probably best best to do it here instead of there..
178 */
179 137
180 /* Get the "before" timestamp */ 138 err = rtc_valid_tm(&alarm->time);
181 err = rtc_read_time(rtc, &before); 139 if (err)
182 if (err < 0)
183 return err; 140 return err;
184 do { 141 rtc_tm_to_time(&alarm->time, &scheduled);
185 if (!first_time)
186 memcpy(&before, &now, sizeof(struct rtc_time));
187 first_time = 0;
188
189 /* get the RTC alarm values, which may be incomplete */
190 err = rtc_read_alarm_internal(rtc, alarm);
191 if (err)
192 return err;
193 if (!alarm->enabled)
194 return 0;
195
196 /* full-function RTCs won't have such missing fields */
197 if (rtc_valid_tm(&alarm->time) == 0)
198 return 0;
199
200 /* get the "after" timestamp, to detect wrapped fields */
201 err = rtc_read_time(rtc, &now);
202 if (err < 0)
203 return err;
204
205 /* note that tm_sec is a "don't care" value here: */
206 } while ( before.tm_min != now.tm_min
207 || before.tm_hour != now.tm_hour
208 || before.tm_mon != now.tm_mon
209 || before.tm_year != now.tm_year);
210
211 /* Fill in the missing alarm fields using the timestamp; we
212 * know there's at least one since alarm->time is invalid.
213 */
214 if (alarm->time.tm_sec == -1)
215 alarm->time.tm_sec = now.tm_sec;
216 if (alarm->time.tm_min == -1)
217 alarm->time.tm_min = now.tm_min;
218 if (alarm->time.tm_hour == -1)
219 alarm->time.tm_hour = now.tm_hour;
220
221 /* For simplicity, only support date rollover for now */
222 if (alarm->time.tm_mday == -1) {
223 alarm->time.tm_mday = now.tm_mday;
224 missing = day;
225 }
226 if (alarm->time.tm_mon == -1) {
227 alarm->time.tm_mon = now.tm_mon;
228 if (missing == none)
229 missing = month;
230 }
231 if (alarm->time.tm_year == -1) {
232 alarm->time.tm_year = now.tm_year;
233 if (missing == none)
234 missing = year;
235 }
236
237 /* with luck, no rollover is needed */
238 rtc_tm_to_time(&now, &t_now);
239 rtc_tm_to_time(&alarm->time, &t_alm);
240 if (t_now < t_alm)
241 goto done;
242
243 switch (missing) {
244 142
245 /* 24 hour rollover ... if it's now 10am Monday, an alarm that 143 /* Make sure we're not setting alarms in the past */
246 * that will trigger at 5am will do so at 5am Tuesday, which 144 err = __rtc_read_time(rtc, &tm);
247 * could also be in the next month or year. This is a common 145 rtc_tm_to_time(&tm, &now);
248 * case, especially for PCs. 146 if (scheduled <= now)
249 */ 147 return -ETIME;
250 case day: 148 /*
251 dev_dbg(&rtc->dev, "alarm rollover: %s\n", "day"); 149 * XXX - We just checked to make sure the alarm time is not
252 t_alm += 24 * 60 * 60; 150 * in the past, but there is still a race window where if
253 rtc_time_to_tm(t_alm, &alarm->time); 151 * the is alarm set for the next second and the second ticks
254 break; 152 * over right here, before we set the alarm.
255
256 /* Month rollover ... if it's the 31th, an alarm on the 3rd will
257 * be next month. An alarm matching on the 30th, 29th, or 28th
258 * may end up in the month after that! Many newer PCs support
259 * this type of alarm.
260 */ 153 */
261 case month:
262 dev_dbg(&rtc->dev, "alarm rollover: %s\n", "month");
263 do {
264 if (alarm->time.tm_mon < 11)
265 alarm->time.tm_mon++;
266 else {
267 alarm->time.tm_mon = 0;
268 alarm->time.tm_year++;
269 }
270 days = rtc_month_days(alarm->time.tm_mon,
271 alarm->time.tm_year);
272 } while (days < alarm->time.tm_mday);
273 break;
274
275 /* Year rollover ... easy except for leap years! */
276 case year:
277 dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year");
278 do {
279 alarm->time.tm_year++;
280 } while (rtc_valid_tm(&alarm->time) != 0);
281 break;
282
283 default:
284 dev_warn(&rtc->dev, "alarm rollover not handled\n");
285 }
286 154
287done: 155 if (!rtc->ops)
288 return 0; 156 err = -ENODEV;
157 else if (!rtc->ops->set_alarm)
158 err = -EINVAL;
159 else
160 err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
161
162 return err;
289} 163}
290EXPORT_SYMBOL_GPL(rtc_read_alarm);
291 164
292int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) 165int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
293{ 166{
@@ -300,16 +173,18 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
300 err = mutex_lock_interruptible(&rtc->ops_lock); 173 err = mutex_lock_interruptible(&rtc->ops_lock);
301 if (err) 174 if (err)
302 return err; 175 return err;
303 176 if (rtc->aie_timer.enabled) {
304 if (!rtc->ops) 177 rtctimer_remove(rtc, &rtc->aie_timer);
305 err = -ENODEV; 178 rtc->aie_timer.enabled = 0;
306 else if (!rtc->ops->set_alarm) 179 }
307 err = -EINVAL; 180 rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
308 else 181 rtc->aie_timer.period = ktime_set(0, 0);
309 err = rtc->ops->set_alarm(rtc->dev.parent, alarm); 182 if (alarm->enabled) {
310 183 rtc->aie_timer.enabled = 1;
184 rtctimer_enqueue(rtc, &rtc->aie_timer);
185 }
311 mutex_unlock(&rtc->ops_lock); 186 mutex_unlock(&rtc->ops_lock);
312 return err; 187 return 0;
313} 188}
314EXPORT_SYMBOL_GPL(rtc_set_alarm); 189EXPORT_SYMBOL_GPL(rtc_set_alarm);
315 190
@@ -319,6 +194,16 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled)
319 if (err) 194 if (err)
320 return err; 195 return err;
321 196
197 if (rtc->aie_timer.enabled != enabled) {
198 if (enabled) {
199 rtc->aie_timer.enabled = 1;
200 rtctimer_enqueue(rtc, &rtc->aie_timer);
201 } else {
202 rtctimer_remove(rtc, &rtc->aie_timer);
203 rtc->aie_timer.enabled = 0;
204 }
205 }
206
322 if (!rtc->ops) 207 if (!rtc->ops)
323 err = -ENODEV; 208 err = -ENODEV;
324 else if (!rtc->ops->alarm_irq_enable) 209 else if (!rtc->ops->alarm_irq_enable)
@@ -337,52 +222,53 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
337 if (err) 222 if (err)
338 return err; 223 return err;
339 224
340#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL 225 /* make sure we're changing state */
341 if (enabled == 0 && rtc->uie_irq_active) { 226 if (rtc->uie_rtctimer.enabled == enabled)
342 mutex_unlock(&rtc->ops_lock); 227 goto out;
343 return rtc_dev_update_irq_enable_emul(rtc, enabled); 228
229 if (enabled) {
230 struct rtc_time tm;
231 ktime_t now, onesec;
232
233 __rtc_read_time(rtc, &tm);
234 onesec = ktime_set(1, 0);
235 now = rtc_tm_to_ktime(tm);
236 rtc->uie_rtctimer.node.expires = ktime_add(now, onesec);
237 rtc->uie_rtctimer.period = ktime_set(1, 0);
238 rtc->uie_rtctimer.enabled = 1;
239 rtctimer_enqueue(rtc, &rtc->uie_rtctimer);
240 } else {
241 rtctimer_remove(rtc, &rtc->uie_rtctimer);
242 rtc->uie_rtctimer.enabled = 0;
344 } 243 }
345#endif
346
347 if (!rtc->ops)
348 err = -ENODEV;
349 else if (!rtc->ops->update_irq_enable)
350 err = -EINVAL;
351 else
352 err = rtc->ops->update_irq_enable(rtc->dev.parent, enabled);
353 244
245out:
354 mutex_unlock(&rtc->ops_lock); 246 mutex_unlock(&rtc->ops_lock);
355
356#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
357 /*
358 * Enable emulation if the driver did not provide
359 * the update_irq_enable function pointer or if returned
360 * -EINVAL to signal that it has been configured without
361 * interrupts or that are not available at the moment.
362 */
363 if (err == -EINVAL)
364 err = rtc_dev_update_irq_enable_emul(rtc, enabled);
365#endif
366 return err; 247 return err;
248
367} 249}
368EXPORT_SYMBOL_GPL(rtc_update_irq_enable); 250EXPORT_SYMBOL_GPL(rtc_update_irq_enable);
369 251
252
370/** 253/**
371 * rtc_update_irq - report RTC periodic, alarm, and/or update irqs 254 * rtc_handle_legacy_irq - AIE, UIE and PIE event hook
372 * @rtc: the rtc device 255 * @rtc: pointer to the rtc device
373 * @num: how many irqs are being reported (usually one) 256 *
374 * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF 257 * This function is called when an AIE, UIE or PIE mode interrupt
375 * Context: any 258 * has occured (or been emulated).
259 *
260 * Triggers the registered irq_task function callback.
376 */ 261 */
377void rtc_update_irq(struct rtc_device *rtc, 262static void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode)
378 unsigned long num, unsigned long events)
379{ 263{
380 unsigned long flags; 264 unsigned long flags;
381 265
266 /* mark one irq of the appropriate mode */
382 spin_lock_irqsave(&rtc->irq_lock, flags); 267 spin_lock_irqsave(&rtc->irq_lock, flags);
383 rtc->irq_data = (rtc->irq_data + (num << 8)) | events; 268 rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF|mode);
384 spin_unlock_irqrestore(&rtc->irq_lock, flags); 269 spin_unlock_irqrestore(&rtc->irq_lock, flags);
385 270
271 /* call the task func */
386 spin_lock_irqsave(&rtc->irq_task_lock, flags); 272 spin_lock_irqsave(&rtc->irq_task_lock, flags);
387 if (rtc->irq_task) 273 if (rtc->irq_task)
388 rtc->irq_task->func(rtc->irq_task->private_data); 274 rtc->irq_task->func(rtc->irq_task->private_data);
@@ -391,6 +277,69 @@ void rtc_update_irq(struct rtc_device *rtc,
391 wake_up_interruptible(&rtc->irq_queue); 277 wake_up_interruptible(&rtc->irq_queue);
392 kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); 278 kill_fasync(&rtc->async_queue, SIGIO, POLL_IN);
393} 279}
280
281
282/**
283 * rtc_aie_update_irq - AIE mode rtctimer hook
284 * @private: pointer to the rtc_device
285 *
286 * This functions is called when the aie_timer expires.
287 */
288void rtc_aie_update_irq(void *private)
289{
290 struct rtc_device *rtc = (struct rtc_device *)private;
291 rtc_handle_legacy_irq(rtc, 1, RTC_AF);
292}
293
294
295/**
296 * rtc_uie_update_irq - UIE mode rtctimer hook
297 * @private: pointer to the rtc_device
298 *
299 * This functions is called when the uie_timer expires.
300 */
301void rtc_uie_update_irq(void *private)
302{
303 struct rtc_device *rtc = (struct rtc_device *)private;
304 rtc_handle_legacy_irq(rtc, 1, RTC_UF);
305}
306
307
308/**
309 * rtc_pie_update_irq - PIE mode hrtimer hook
310 * @timer: pointer to the pie mode hrtimer
311 *
312 * This function is used to emulate PIE mode interrupts
313 * using an hrtimer. This function is called when the periodic
314 * hrtimer expires.
315 */
316enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer)
317{
318 struct rtc_device *rtc;
319 ktime_t period;
320 int count;
321 rtc = container_of(timer, struct rtc_device, pie_timer);
322
323 period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
324 count = hrtimer_forward_now(timer, period);
325
326 rtc_handle_legacy_irq(rtc, count, RTC_PF);
327
328 return HRTIMER_RESTART;
329}
330
331/**
332 * rtc_update_irq - Triggered when a RTC interrupt occurs.
333 * @rtc: the rtc device
334 * @num: how many irqs are being reported (usually one)
335 * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF
336 * Context: any
337 */
338void rtc_update_irq(struct rtc_device *rtc,
339 unsigned long num, unsigned long events)
340{
341 schedule_work(&rtc->irqwork);
342}
394EXPORT_SYMBOL_GPL(rtc_update_irq); 343EXPORT_SYMBOL_GPL(rtc_update_irq);
395 344
396static int __rtc_match(struct device *dev, void *data) 345static int __rtc_match(struct device *dev, void *data)
@@ -477,18 +426,20 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled
477 int err = 0; 426 int err = 0;
478 unsigned long flags; 427 unsigned long flags;
479 428
480 if (rtc->ops->irq_set_state == NULL)
481 return -ENXIO;
482
483 spin_lock_irqsave(&rtc->irq_task_lock, flags); 429 spin_lock_irqsave(&rtc->irq_task_lock, flags);
484 if (rtc->irq_task != NULL && task == NULL) 430 if (rtc->irq_task != NULL && task == NULL)
485 err = -EBUSY; 431 err = -EBUSY;
486 if (rtc->irq_task != task) 432 if (rtc->irq_task != task)
487 err = -EACCES; 433 err = -EACCES;
488 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
489 434
490 if (err == 0) 435 if (enabled) {
491 err = rtc->ops->irq_set_state(rtc->dev.parent, enabled); 436 ktime_t period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
437 hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL);
438 } else {
439 hrtimer_cancel(&rtc->pie_timer);
440 }
441 rtc->pie_enabled = enabled;
442 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
492 443
493 return err; 444 return err;
494} 445}
@@ -509,21 +460,194 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
509 int err = 0; 460 int err = 0;
510 unsigned long flags; 461 unsigned long flags;
511 462
512 if (rtc->ops->irq_set_freq == NULL)
513 return -ENXIO;
514
515 spin_lock_irqsave(&rtc->irq_task_lock, flags); 463 spin_lock_irqsave(&rtc->irq_task_lock, flags);
516 if (rtc->irq_task != NULL && task == NULL) 464 if (rtc->irq_task != NULL && task == NULL)
517 err = -EBUSY; 465 err = -EBUSY;
518 if (rtc->irq_task != task) 466 if (rtc->irq_task != task)
519 err = -EACCES; 467 err = -EACCES;
520 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
521
522 if (err == 0) { 468 if (err == 0) {
523 err = rtc->ops->irq_set_freq(rtc->dev.parent, freq); 469 rtc->irq_freq = freq;
524 if (err == 0) 470 if (rtc->pie_enabled) {
525 rtc->irq_freq = freq; 471 ktime_t period;
472 hrtimer_cancel(&rtc->pie_timer);
473 period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
474 hrtimer_start(&rtc->pie_timer, period,
475 HRTIMER_MODE_REL);
476 }
526 } 477 }
478 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
527 return err; 479 return err;
528} 480}
529EXPORT_SYMBOL_GPL(rtc_irq_set_freq); 481EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
482
483/**
484 * rtctimer_enqueue - Adds a rtc_timer to the rtc_device timerqueue
485 * @rtc rtc device
486 * @timer timer being added.
487 *
488 * Enqueues a timer onto the rtc devices timerqueue and sets
489 * the next alarm event appropriately.
490 *
491 * Must hold ops_lock for proper serialization of timerqueue
492 */
493void rtctimer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
494{
495 timerqueue_add(&rtc->timerqueue, &timer->node);
496 if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) {
497 struct rtc_wkalrm alarm;
498 int err;
499 alarm.time = rtc_ktime_to_tm(timer->node.expires);
500 alarm.enabled = 1;
501 err = __rtc_set_alarm(rtc, &alarm);
502 if (err == -ETIME)
503 schedule_work(&rtc->irqwork);
504 }
505}
506
507/**
508 * rtctimer_remove - Removes a rtc_timer from the rtc_device timerqueue
509 * @rtc rtc device
510 * @timer timer being removed.
511 *
512 * Removes a timer onto the rtc devices timerqueue and sets
513 * the next alarm event appropriately.
514 *
515 * Must hold ops_lock for proper serialization of timerqueue
516 */
517void rtctimer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
518{
519 struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue);
520 timerqueue_del(&rtc->timerqueue, &timer->node);
521
522 if (next == &timer->node) {
523 struct rtc_wkalrm alarm;
524 int err;
525 next = timerqueue_getnext(&rtc->timerqueue);
526 if (!next)
527 return;
528 alarm.time = rtc_ktime_to_tm(next->expires);
529 alarm.enabled = 1;
530 err = __rtc_set_alarm(rtc, &alarm);
531 if (err == -ETIME)
532 schedule_work(&rtc->irqwork);
533 }
534}
535
536/**
537 * rtctimer_do_work - Expires rtc timers
538 * @rtc rtc device
539 * @timer timer being removed.
540 *
541 * Expires rtc timers. Reprograms next alarm event if needed.
542 * Called via worktask.
543 *
544 * Serializes access to timerqueue via ops_lock mutex
545 */
546void rtctimer_do_work(struct work_struct *work)
547{
548 struct rtc_timer *timer;
549 struct timerqueue_node *next;
550 ktime_t now;
551 struct rtc_time tm;
552
553 struct rtc_device *rtc =
554 container_of(work, struct rtc_device, irqwork);
555
556 mutex_lock(&rtc->ops_lock);
557again:
558 __rtc_read_time(rtc, &tm);
559 now = rtc_tm_to_ktime(tm);
560 while ((next = timerqueue_getnext(&rtc->timerqueue))) {
561 if (next->expires.tv64 > now.tv64)
562 break;
563
564 /* expire timer */
565 timer = container_of(next, struct rtc_timer, node);
566 timerqueue_del(&rtc->timerqueue, &timer->node);
567 timer->enabled = 0;
568 if (timer->task.func)
569 timer->task.func(timer->task.private_data);
570
571 /* Re-add/fwd periodic timers */
572 if (ktime_to_ns(timer->period)) {
573 timer->node.expires = ktime_add(timer->node.expires,
574 timer->period);
575 timer->enabled = 1;
576 timerqueue_add(&rtc->timerqueue, &timer->node);
577 }
578 }
579
580 /* Set next alarm */
581 if (next) {
582 struct rtc_wkalrm alarm;
583 int err;
584 alarm.time = rtc_ktime_to_tm(next->expires);
585 alarm.enabled = 1;
586 err = __rtc_set_alarm(rtc, &alarm);
587 if (err == -ETIME)
588 goto again;
589 }
590
591 mutex_unlock(&rtc->ops_lock);
592}
593
594
595/* rtctimer_init - Initializes an rtc_timer
596 * @timer: timer to be intiialized
597 * @f: function pointer to be called when timer fires
598 * @data: private data passed to function pointer
599 *
600 * Kernel interface to initializing an rtc_timer.
601 */
602void rtctimer_init(struct rtc_timer *timer, void (*f)(void* p), void* data)
603{
604 timerqueue_init(&timer->node);
605 timer->enabled = 0;
606 timer->task.func = f;
607 timer->task.private_data = data;
608}
609
610/* rtctimer_start - Sets an rtc_timer to fire in the future
611 * @ rtc: rtc device to be used
612 * @ timer: timer being set
613 * @ expires: time at which to expire the timer
614 * @ period: period that the timer will recur
615 *
616 * Kernel interface to set an rtc_timer
617 */
618int rtctimer_start(struct rtc_device *rtc, struct rtc_timer* timer,
619 ktime_t expires, ktime_t period)
620{
621 int ret = 0;
622 mutex_lock(&rtc->ops_lock);
623 if (timer->enabled)
624 rtctimer_remove(rtc, timer);
625
626 timer->node.expires = expires;
627 timer->period = period;
628
629 timer->enabled = 1;
630 rtctimer_enqueue(rtc, timer);
631
632 mutex_unlock(&rtc->ops_lock);
633 return ret;
634}
635
636/* rtctimer_cancel - Stops an rtc_timer
637 * @ rtc: rtc device to be used
638 * @ timer: timer being set
639 *
640 * Kernel interface to cancel an rtc_timer
641 */
642int rtctimer_cancel(struct rtc_device *rtc, struct rtc_timer* timer)
643{
644 int ret = 0;
645 mutex_lock(&rtc->ops_lock);
646 if (timer->enabled)
647 rtctimer_remove(rtc, timer);
648 timer->enabled = 0;
649 mutex_unlock(&rtc->ops_lock);
650 return ret;
651}
652
653