mirror of https://gitee.com/openkylin/linux.git
Merge branch 'fortglx/3.4/rtc' of git://git.linaro.org/people/jstultz/linux into timers/core
This commit is contained in:
commit
8682df25ca
|
@ -73,6 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
|
|||
err = -EINVAL;
|
||||
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
/* A timer might have just expired */
|
||||
schedule_work(&rtc->irqwork);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtc_set_time);
|
||||
|
@ -112,6 +114,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
|
|||
err = -EINVAL;
|
||||
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
/* A timer might have just expired */
|
||||
schedule_work(&rtc->irqwork);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -380,18 +384,27 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm);
|
|||
int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
||||
{
|
||||
int err;
|
||||
struct rtc_time now;
|
||||
|
||||
err = rtc_valid_tm(&alarm->time);
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
err = rtc_read_time(rtc, &now);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mutex_lock_interruptible(&rtc->ops_lock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
|
||||
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;
|
||||
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)
|
|||
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 rtc device
|
||||
|
@ -784,8 +805,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
|
|||
struct rtc_wkalrm alarm;
|
||||
int err;
|
||||
next = timerqueue_getnext(&rtc->timerqueue);
|
||||
if (!next)
|
||||
if (!next) {
|
||||
rtc_alarm_disable(rtc);
|
||||
return;
|
||||
}
|
||||
alarm.time = rtc_ktime_to_tm(next->expires);
|
||||
alarm.enabled = 1;
|
||||
err = __rtc_set_alarm(rtc, &alarm);
|
||||
|
@ -847,7 +870,8 @@ void rtc_timer_do_work(struct work_struct *work)
|
|||
err = __rtc_set_alarm(rtc, &alarm);
|
||||
if (err == -ETIME)
|
||||
goto again;
|
||||
}
|
||||
} else
|
||||
rtc_alarm_disable(rtc);
|
||||
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue