From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161372AbcFAPkg (ORCPT ); Wed, 1 Jun 2016 11:40:36 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:35641 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755371AbcFAPke (ORCPT ); Wed, 1 Jun 2016 11:40:34 -0400 From: Gabriele Mazzotta To: a.zummo@towertech.it, alexandre.belloni@free-electrons.com Cc: rtc-linux@googlegroups.com, linux-kernel@vger.kernel.org, matthew.garrett@nebula.com, Gabriele Mazzotta Subject: [PATCH 1/2] rtc-cmos: Clear expired alarm after resume Date: Wed, 1 Jun 2016 17:40:14 +0200 Message-Id: <1464795615-7748-1-git-send-email-gabriele.mzt@gmail.com> X-Mailer: git-send-email 2.8.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If the system wakes up because of a wake alarm, the internal state of the alarm is not updated. As consequence, the state no longer reflects the actual state of the hardware and setting a new alarm is not possible until the expired alarm is cleared. Signed-off-by: Gabriele Mazzotta --- drivers/rtc/rtc-cmos.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index fbe9c72..fd121e3 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -900,11 +900,33 @@ static inline int cmos_poweroff(struct device *dev) #ifdef CONFIG_PM_SLEEP +static void cmos_check_alarm(struct device *dev) +{ + struct cmos_rtc *cmos = dev_get_drvdata(dev); + struct rtc_wkalrm alarm; + struct rtc_time now; + time64_t t_now; + time64_t t_expires; + + cmos_read_time(dev, &now); + rtc_read_alarm(cmos->rtc, &alarm); + t_now = rtc_tm_to_time64(&now); + t_expires = rtc_tm_to_time64(&alarm.time); + + if (t_expires <= t_now && alarm.enabled) { + alarm.enabled = 0; + cmos->suspend_ctrl &= ~RTC_AIE; + rtc_set_alarm(cmos->rtc, &alarm); + } +} + static int cmos_resume(struct device *dev) { struct cmos_rtc *cmos = dev_get_drvdata(dev); unsigned char tmp; + cmos_check_alarm(dev); + if (cmos->enabled_wake) { if (cmos->wake_off) cmos->wake_off(dev); -- 2.8.1