From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936764Ab2C3XF1 (ORCPT ); Fri, 30 Mar 2012 19:05:27 -0400 Received: from mail-pb0-f46.google.com ([209.85.160.46]:33001 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934802Ab2C3VFF (ORCPT ); Fri, 30 Mar 2012 17:05:05 -0400 Message-Id: <20120330195727.684990792@linuxfoundation.org> User-Agent: quilt/0.60-19.1 Date: Fri, 30 Mar 2012 12:58:01 -0700 From: Greg KH To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, John Stultz , Rabin Vincent Subject: [ 039/108] rtc: Disable the alarm in the hardware (v2) In-Reply-To: <20120330195812.GA31833@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.0-stable review patch. If anyone has any objections, please let me know. ------------------ From: Rabin Vincent commit 41c7f7424259ff11009449f87c95656f69f9b186 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. The original version of this patch was reverted. This version disables the irq directly instead of setting a disabled timer in the future. Cc: John Stultz Signed-off-by: Rabin Vincent [Merged in the second revision from Rabin] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/interface.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -762,6 +762,14 @@ static int rtc_timer_enqueue(struct rtc_ 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 @@ -783,8 +791,10 @@ static void rtc_timer_remove(struct rtc_ 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); @@ -846,7 +856,8 @@ again: err = __rtc_set_alarm(rtc, &alarm); if (err == -ETIME) goto again; - } + } else + rtc_alarm_disable(rtc); mutex_unlock(&rtc->ops_lock); }