From b47f3ad598247071dcab661f94655bbe8074467a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 3 Jan 2012 17:32:13 -0800 Subject: Revert "rtc: Disable the alarm in the hardware" commit 157e8bf8b4823bfcdefa6c1548002374b61f61df upstream. This reverts commit c0afabd3d553c521e003779c127143ffde55a16f. It causes failures on Toshiba laptops - instead of disabling the alarm, it actually seems to enable it on the affected laptops, resulting in (for example) the laptop powering on automatically five minutes after shutdown. There's a patch for it that appears to work for at least some people, but it's too late to play around with this, so revert for now and try again in the next merge window. See for example http://bugs.debian.org/652869 Reported-and-bisected-by: Andreas Friedrich (Toshiba Tecra) Reported-by: Antonio-M. Corbi Bellot (Toshiba Portege R500) Reported-by: Marco Santos (Toshiba Portege Z830) Reported-by: Christophe Vu-Brugier (Toshiba Portege R830) Cc: Jonathan Nieder Requested-by: John Stultz Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/interface.c | 44 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) (limited to 'drivers/rtc/interface.c') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index bbb6f852c5ab..eb4c88316a15 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -318,20 +318,6 @@ 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; @@ -355,7 +341,14 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) * over right here, before we set the alarm. */ - return ___rtc_set_alarm(rtc, 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; } int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) @@ -769,20 +762,6 @@ 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 @@ -804,10 +783,8 @@ 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) { - rtc_alarm_disable(rtc); + if (!next) return; - } alarm.time = rtc_ktime_to_tm(next->expires); alarm.enabled = 1; err = __rtc_set_alarm(rtc, &alarm); @@ -869,8 +846,7 @@ again: err = __rtc_set_alarm(rtc, &alarm); if (err == -ETIME) goto again; - } else - rtc_alarm_disable(rtc); + } mutex_unlock(&rtc->ops_lock); } -- cgit v1.2.3 From 922d41ed4740408d2719a8c99d9f80138e562c03 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 10 Jan 2012 15:11:02 -0800 Subject: drivers/rtc/interface.c: fix alarm rollover when day or month is out-of-range commit e74a8f2edb92cb690b467cea0ab652c509e9f624 upstream. Commit f44f7f96a20a ("RTC: Initialize kernel state from RTC") introduced a potential infinite loop. If an alarm time contains a wildcard month and an invalid day (> 31), or a wildcard year and an invalid month (>= 12), the loop searching for the next matching date will never terminate. Treat the invalid values as wildcards. Fixes , Reported-by: leo weppelman Reported-by: "P. van Gaans" Signed-off-by: Ben Hutchings Signed-off-by: Jonathan Nieder Cc: Mark Brown Cc: Marcelo Roberto Jimenez Cc: Thomas Gleixner Cc: John Stultz Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/rtc/interface.c') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index eb4c88316a15..38d1dc74b2c0 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -227,11 +227,11 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) alarm->time.tm_hour = now.tm_hour; /* For simplicity, only support date rollover for now */ - if (alarm->time.tm_mday == -1) { + if (alarm->time.tm_mday < 1 || alarm->time.tm_mday > 31) { alarm->time.tm_mday = now.tm_mday; missing = day; } - if (alarm->time.tm_mon == -1) { + if ((unsigned)alarm->time.tm_mon >= 12) { alarm->time.tm_mon = now.tm_mon; if (missing == none) missing = month; -- cgit v1.2.3 From 220b62b4dae194046a0993d66c5a7651fcfed72e Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 22 Nov 2011 11:03:14 +0100 Subject: rtc: Disable the alarm in the hardware (v2) 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(-) (limited to 'drivers/rtc/interface.c') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 38d1dc74b2c0..636a2ec21810 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -762,6 +762,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 @@ -783,8 +791,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); @@ -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); } -- cgit v1.2.3