Commit 8682df25 authored by Thomas Gleixner's avatar Thomas Gleixner

Merge branch 'fortglx/3.4/rtc' of git://git.linaro.org/people/jstultz/linux into timers/core

parents 9b612fa6 41c7f742
...@@ -73,6 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) ...@@ -73,6 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
err = -EINVAL; err = -EINVAL;
mutex_unlock(&rtc->ops_lock); mutex_unlock(&rtc->ops_lock);
/* A timer might have just expired */
schedule_work(&rtc->irqwork);
return err; return err;
} }
EXPORT_SYMBOL_GPL(rtc_set_time); EXPORT_SYMBOL_GPL(rtc_set_time);
...@@ -112,6 +114,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) ...@@ -112,6 +114,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
err = -EINVAL; err = -EINVAL;
mutex_unlock(&rtc->ops_lock); mutex_unlock(&rtc->ops_lock);
/* A timer might have just expired */
schedule_work(&rtc->irqwork);
return err; return err;
} }
...@@ -380,18 +384,27 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm); ...@@ -380,18 +384,27 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm);
int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{ {
int err; int err;
struct rtc_time now;
err = rtc_valid_tm(&alarm->time); err = rtc_valid_tm(&alarm->time);
if (err != 0) if (err != 0)
return err; return err;
err = rtc_read_time(rtc, &now);
if (err)
return err;
err = mutex_lock_interruptible(&rtc->ops_lock); err = mutex_lock_interruptible(&rtc->ops_lock);
if (err) if (err)
return err; return err;
rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
rtc->aie_timer.period = ktime_set(0, 0); rtc->aie_timer.period = ktime_set(0, 0);
if (alarm->enabled) {
/* Alarm has to be enabled & in the futrure for us to enqueue it */
if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 <
rtc->aie_timer.node.expires.tv64)) {
rtc->aie_timer.enabled = 1; rtc->aie_timer.enabled = 1;
timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node);
} }
...@@ -763,6 +776,14 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) ...@@ -763,6 +776,14 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
return 0; return 0;
} }
static void rtc_alarm_disable(struct rtc_device *rtc)
{
if (!rtc->ops || !rtc->ops->alarm_irq_enable)
return;
rtc->ops->alarm_irq_enable(rtc->dev.parent, false);
}
/** /**
* rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue
* @rtc rtc device * @rtc rtc device
...@@ -784,8 +805,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) ...@@ -784,8 +805,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
struct rtc_wkalrm alarm; struct rtc_wkalrm alarm;
int err; int err;
next = timerqueue_getnext(&rtc->timerqueue); next = timerqueue_getnext(&rtc->timerqueue);
if (!next) if (!next) {
rtc_alarm_disable(rtc);
return; return;
}
alarm.time = rtc_ktime_to_tm(next->expires); alarm.time = rtc_ktime_to_tm(next->expires);
alarm.enabled = 1; alarm.enabled = 1;
err = __rtc_set_alarm(rtc, &alarm); err = __rtc_set_alarm(rtc, &alarm);
...@@ -847,7 +870,8 @@ void rtc_timer_do_work(struct work_struct *work) ...@@ -847,7 +870,8 @@ void rtc_timer_do_work(struct work_struct *work)
err = __rtc_set_alarm(rtc, &alarm); err = __rtc_set_alarm(rtc, &alarm);
if (err == -ETIME) if (err == -ETIME)
goto again; goto again;
} } else
rtc_alarm_disable(rtc);
mutex_unlock(&rtc->ops_lock); mutex_unlock(&rtc->ops_lock);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment