diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-12-05 19:53:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-12-05 19:53:43 -0500 |
commit | 40c043b077c6e377c8440d71563c055d0c4f0f0a (patch) | |
tree | e0c1d672a1156d7840d3ef650ba1aa963c68e13a /drivers/rtc/interface.c | |
parent | f14aa871c7e1e58a01bf33a562ac314fae64517c (diff) | |
parent | de28f25e8244c7353abed8de0c7792f5f883588c (diff) |
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
clockevents: Set noop handler in clockevents_exchange_device()
tick-broadcast: Stop active broadcast device when replacing it
clocksource: Fix bug with max_deferment margin calculation
rtc: Fix some bugs that allowed accumulating time drift in suspend/resume
rtc: Disable the alarm in the hardware
Diffstat (limited to 'drivers/rtc/interface.c')
-rw-r--r-- | drivers/rtc/interface.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 8e286259a007..fa4d9f324189 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -319,6 +319,20 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
319 | } | 319 | } |
320 | EXPORT_SYMBOL_GPL(rtc_read_alarm); | 320 | EXPORT_SYMBOL_GPL(rtc_read_alarm); |
321 | 321 | ||
322 | static int ___rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | ||
323 | { | ||
324 | int err; | ||
325 | |||
326 | if (!rtc->ops) | ||
327 | err = -ENODEV; | ||
328 | else if (!rtc->ops->set_alarm) | ||
329 | err = -EINVAL; | ||
330 | else | ||
331 | err = rtc->ops->set_alarm(rtc->dev.parent, alarm); | ||
332 | |||
333 | return err; | ||
334 | } | ||
335 | |||
322 | static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | 336 | static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
323 | { | 337 | { |
324 | struct rtc_time tm; | 338 | struct rtc_time tm; |
@@ -342,14 +356,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
342 | * over right here, before we set the alarm. | 356 | * over right here, before we set the alarm. |
343 | */ | 357 | */ |
344 | 358 | ||
345 | if (!rtc->ops) | 359 | 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 | } | 360 | } |
354 | 361 | ||
355 | int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | 362 | int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
@@ -763,6 +770,20 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) | |||
763 | return 0; | 770 | return 0; |
764 | } | 771 | } |
765 | 772 | ||
773 | static void rtc_alarm_disable(struct rtc_device *rtc) | ||
774 | { | ||
775 | struct rtc_wkalrm alarm; | ||
776 | struct rtc_time tm; | ||
777 | |||
778 | __rtc_read_time(rtc, &tm); | ||
779 | |||
780 | alarm.time = rtc_ktime_to_tm(ktime_add(rtc_tm_to_ktime(tm), | ||
781 | ktime_set(300, 0))); | ||
782 | alarm.enabled = 0; | ||
783 | |||
784 | ___rtc_set_alarm(rtc, &alarm); | ||
785 | } | ||
786 | |||
766 | /** | 787 | /** |
767 | * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue | 788 | * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue |
768 | * @rtc rtc device | 789 | * @rtc rtc device |
@@ -784,8 +805,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) | |||
784 | struct rtc_wkalrm alarm; | 805 | struct rtc_wkalrm alarm; |
785 | int err; | 806 | int err; |
786 | next = timerqueue_getnext(&rtc->timerqueue); | 807 | next = timerqueue_getnext(&rtc->timerqueue); |
787 | if (!next) | 808 | if (!next) { |
809 | rtc_alarm_disable(rtc); | ||
788 | return; | 810 | return; |
811 | } | ||
789 | alarm.time = rtc_ktime_to_tm(next->expires); | 812 | alarm.time = rtc_ktime_to_tm(next->expires); |
790 | alarm.enabled = 1; | 813 | alarm.enabled = 1; |
791 | err = __rtc_set_alarm(rtc, &alarm); | 814 | err = __rtc_set_alarm(rtc, &alarm); |
@@ -847,7 +870,8 @@ again: | |||
847 | err = __rtc_set_alarm(rtc, &alarm); | 870 | err = __rtc_set_alarm(rtc, &alarm); |
848 | if (err == -ETIME) | 871 | if (err == -ETIME) |
849 | goto again; | 872 | goto again; |
850 | } | 873 | } else |
874 | rtc_alarm_disable(rtc); | ||
851 | 875 | ||
852 | mutex_unlock(&rtc->ops_lock); | 876 | mutex_unlock(&rtc->ops_lock); |
853 | } | 877 | } |