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
This commit is contained in:
Linus Torvalds
2011-12-05 16:53:43 -08:00
5 changed files with 43 additions and 18 deletions

View File

@@ -319,6 +319,20 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
}
EXPORT_SYMBOL_GPL(rtc_read_alarm);
static int ___rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
int err;
if (!rtc->ops)
err = -ENODEV;
else if (!rtc->ops->set_alarm)
err = -EINVAL;
else
err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
return err;
}
static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
struct rtc_time tm;
@@ -342,14 +356,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
* over right here, before we set the alarm.
*/
if (!rtc->ops)
err = -ENODEV;
else if (!rtc->ops->set_alarm)
err = -EINVAL;
else
err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
return err;
return ___rtc_set_alarm(rtc, alarm);
}
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)
return 0;
}
static void rtc_alarm_disable(struct rtc_device *rtc)
{
struct rtc_wkalrm alarm;
struct rtc_time tm;
__rtc_read_time(rtc, &tm);
alarm.time = rtc_ktime_to_tm(ktime_add(rtc_tm_to_ktime(tm),
ktime_set(300, 0)));
alarm.enabled = 0;
___rtc_set_alarm(rtc, &alarm);
}
/**
* 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 @@ again:
err = __rtc_set_alarm(rtc, &alarm);
if (err == -ETIME)
goto again;
}
} else
rtc_alarm_disable(rtc);
mutex_unlock(&rtc->ops_lock);
}