Skip to content

Commit

Permalink
rtc: Disable the alarm in the hardware
Browse files Browse the repository at this point in the history
commit c0afabd upstream.

Currently, the RTC code does not disable the alarm in the hardware.

This means that after a sequence such as the one below (the files are in the
RTC sysfs), the box will boot up after 2 minutes even though we've
asked for the alarm to be turned off.

	# echo $((`cat since_epoch`)+120) > wakealarm
	# echo 0 > wakealarm
	# poweroff

Fix this by disabling the alarm when there are no timers to run.

Cc: John Stultz <[email protected]>
Signed-off-by: Rabin Vincent <[email protected]>
Signed-off-by: John Stultz <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
vitkyrka authored and gregkh committed Dec 9, 2011
1 parent 4e3cd81 commit 4ebbdc2
Showing 1 changed file with 34 additions and 10 deletions.
44 changes: 34 additions & 10 deletions drivers/rtc/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,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;
Expand All @@ -341,14 +355,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)
Expand Down Expand Up @@ -762,6 +769,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
Expand All @@ -783,8 +804,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);
Expand Down Expand Up @@ -846,7 +869,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);
}
Expand Down

0 comments on commit 4ebbdc2

Please sign in to comment.