aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2012-02-15 14:28:38 -0500
committerThomas Gleixner <tglx@linutronix.de>2012-02-15 14:28:38 -0500
commit8682df25ca9afd3aac30f2c72d00bd98de2118e8 (patch)
tree6c0f5c1e9797a5b908a1b57d21cdf16c69911154 /drivers
parent9b612fa627105af2738d9205554e2a6dc8d32228 (diff)
parent41c7f7424259ff11009449f87c95656f69f9b186 (diff)
Merge branch 'fortglx/3.4/rtc' of git://git.linaro.org/people/jstultz/linux into timers/core
Diffstat (limited to 'drivers')
-rw-r--r--drivers/rtc/interface.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 8a1c031391d6..dc87eda65814 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}
@@ -380,18 +384,27 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm);
380int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) 384int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
381{ 385{
382 int err; 386 int err;
387 struct rtc_time now;
383 388
384 err = rtc_valid_tm(&alarm->time); 389 err = rtc_valid_tm(&alarm->time);
385 if (err != 0) 390 if (err != 0)
386 return err; 391 return err;
387 392
393 err = rtc_read_time(rtc, &now);
394 if (err)
395 return err;
396
388 err = mutex_lock_interruptible(&rtc->ops_lock); 397 err = mutex_lock_interruptible(&rtc->ops_lock);
389 if (err) 398 if (err)
390 return err; 399 return err;
391 400
392 rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); 401 rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
393 rtc->aie_timer.period = ktime_set(0, 0); 402 rtc->aie_timer.period = ktime_set(0, 0);
394 if (alarm->enabled) { 403
404 /* Alarm has to be enabled & in the futrure for us to enqueue it */
405 if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 <
406 rtc->aie_timer.node.expires.tv64)) {
407
395 rtc->aie_timer.enabled = 1; 408 rtc->aie_timer.enabled = 1;
396 timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); 409 timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node);
397 } 410 }
@@ -763,6 +776,14 @@ 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 if (!rtc->ops || !rtc->ops->alarm_irq_enable)
782 return;
783
784 rtc->ops->alarm_irq_enable(rtc->dev.parent, false);
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}