aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/interface.c')
-rw-r--r--drivers/rtc/interface.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 8e286259a007..3bcc7cfcaba7 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -73,6 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
73 err = -EINVAL; 73 err = -EINVAL;
74 74
75 mutex_unlock(&rtc->ops_lock); 75 mutex_unlock(&rtc->ops_lock);
76 /* A timer might have just expired */
77 schedule_work(&rtc->irqwork);
76 return err; 78 return err;
77} 79}
78EXPORT_SYMBOL_GPL(rtc_set_time); 80EXPORT_SYMBOL_GPL(rtc_set_time);
@@ -112,6 +114,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
112 err = -EINVAL; 114 err = -EINVAL;
113 115
114 mutex_unlock(&rtc->ops_lock); 116 mutex_unlock(&rtc->ops_lock);
117 /* A timer might have just expired */
118 schedule_work(&rtc->irqwork);
115 119
116 return err; 120 return err;
117} 121}
@@ -319,6 +323,20 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
319} 323}
320EXPORT_SYMBOL_GPL(rtc_read_alarm); 324EXPORT_SYMBOL_GPL(rtc_read_alarm);
321 325
326static int ___rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
327{
328 int err;
329
330 if (!rtc->ops)
331 err = -ENODEV;
332 else if (!rtc->ops->set_alarm)
333 err = -EINVAL;
334 else
335 err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
336
337 return err;
338}
339
322static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) 340static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
323{ 341{
324 struct rtc_time tm; 342 struct rtc_time tm;
@@ -342,14 +360,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
342 * over right here, before we set the alarm. 360 * over right here, before we set the alarm.
343 */ 361 */
344 362
345 if (!rtc->ops) 363 return ___rtc_set_alarm(rtc, alarm);
346 err = -ENODEV;
347 else if (!rtc->ops->set_alarm)
348 err = -EINVAL;
349 else
350 err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
351
352 return err;
353} 364}
354 365
355int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) 366int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
@@ -396,6 +407,8 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
396 timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); 407 timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node);
397 } 408 }
398 mutex_unlock(&rtc->ops_lock); 409 mutex_unlock(&rtc->ops_lock);
410 /* maybe that was in the past.*/
411 schedule_work(&rtc->irqwork);
399 return err; 412 return err;
400} 413}
401EXPORT_SYMBOL_GPL(rtc_initialize_alarm); 414EXPORT_SYMBOL_GPL(rtc_initialize_alarm);
@@ -763,6 +776,20 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
763 return 0; 776 return 0;
764} 777}
765 778
779static void rtc_alarm_disable(struct rtc_device *rtc)
780{
781 struct rtc_wkalrm alarm;
782 struct rtc_time tm;
783
784 __rtc_read_time(rtc, &tm);
785
786 alarm.time = rtc_ktime_to_tm(ktime_add(rtc_tm_to_ktime(tm),
787 ktime_set(300, 0)));
788 alarm.enabled = 0;
789
790 ___rtc_set_alarm(rtc, &alarm);
791}
792
766/** 793/**
767 * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue 794 * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue
768 * @rtc rtc device 795 * @rtc rtc device
@@ -784,8 +811,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
784 struct rtc_wkalrm alarm; 811 struct rtc_wkalrm alarm;
785 int err; 812 int err;
786 next = timerqueue_getnext(&rtc->timerqueue); 813 next = timerqueue_getnext(&rtc->timerqueue);
787 if (!next) 814 if (!next) {
815 rtc_alarm_disable(rtc);
788 return; 816 return;
817 }
789 alarm.time = rtc_ktime_to_tm(next->expires); 818 alarm.time = rtc_ktime_to_tm(next->expires);
790 alarm.enabled = 1; 819 alarm.enabled = 1;
791 err = __rtc_set_alarm(rtc, &alarm); 820 err = __rtc_set_alarm(rtc, &alarm);
@@ -847,7 +876,8 @@ again:
847 err = __rtc_set_alarm(rtc, &alarm); 876 err = __rtc_set_alarm(rtc, &alarm);
848 if (err == -ETIME) 877 if (err == -ETIME)
849 goto again; 878 goto again;
850 } 879 } else
880 rtc_alarm_disable(rtc);
851 881
852 mutex_unlock(&rtc->ops_lock); 882 mutex_unlock(&rtc->ops_lock);
853} 883}