From: Gabriele Mazzotta <gabriele.mzt@gmail.com>
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 <gabriele.mzt@gmail.com>
Subject: [rtc-linux] [PATCH v2 2/2] rtc-cmos: Restore alarm after resume
Date: Thu, 1 Sep 2016 00:59:00 +0200 [thread overview]
Message-ID: <20160831225900.20122-2-gabriele.mzt@gmail.com> (raw)
In-Reply-To: <20160831225900.20122-1-gabriele.mzt@gmail.com>
Some platform firmware may interfere with the RTC alarm over suspend,
resulting in the kernel and hardware having different ideas about system
state but also potentially causing problems with firmware that assumes the
OS will clean this case up. This patch restores the RTC alarm on resume
to ensure that kernel and hardware are in sync.
The case we've seen is Intel Rapid Start, which is a firmware-mediated
feature that automatically transitions systems from suspend-to-RAM to
suspend-to-disk without OS involvement. It does this by setting the RTC
alarm and a flag that indicates that on wake it should perform the
transition rather than re-starting the OS. However, if the OS has set a
wakeup alarm that would wake the machine earlier, it refuses to overwrite
it and allows the system to wake instead.
This fails in the following situation:
1) User configures Intel Rapid Start to transition after (say) 15
minutes
2) User suspends to RAM. Firmware sets the wakeup alarm for 15 minutes
in the future
3) User resumes after 5 minutes. Firmware does not reset the alarm, and
as such it is still set for 10 minutes in the future
4) User suspends after 5 minutes. Firmware notices that the alarm is set
for 5 minutes in the future, which is less than the 15 minute transition
threshold. It therefore assumes that the user wants the machine to wake
in 5 minutes
5) System resumes after 5 minutes
The worst case scenario here is that the user may have put the system in a
bag between (4) and (5), resulting in it running in a confined space and
potentially overheating. This seems reasonably important. The Rapid
Start support code got added in 3.11, but it can be configured in the
firmware regardless of kernel support.
Signed-off-by: Gabriele Mazzotta <gabriele.mzt@gmail.com>
---
drivers/rtc/rtc-cmos.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 62d5b33..4cdb335 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -62,6 +62,8 @@ struct cmos_rtc {
u8 day_alrm;
u8 mon_alrm;
u8 century;
+
+ struct rtc_wkalrm saved_wkalrm;
};
/* both platform and pnp busses use negative numbers for invalid irqs */
@@ -880,6 +882,8 @@ static int cmos_suspend(struct device *dev)
enable_irq_wake(cmos->irq);
}
+ cmos_read_alarm(dev, &cmos->saved_wkalrm);
+
dev_dbg(dev, "suspend%s, ctrl %02x\n",
(tmp & RTC_AIE) ? ", alarm may wake" : "",
tmp);
@@ -900,6 +904,22 @@ static inline int cmos_poweroff(struct device *dev)
#ifdef CONFIG_PM_SLEEP
+static void cmos_check_wkalrm(struct device *dev)
+{
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+ struct rtc_wkalrm current_alarm;
+ time64_t t_current_expires;
+ time64_t t_saved_expires;
+
+ cmos_read_alarm(dev, ¤t_alarm);
+ t_current_expires = rtc_tm_to_time64(¤t_alarm.time);
+ t_saved_expires = rtc_tm_to_time64(&cmos->saved_wkalrm.time);
+ if (t_current_expires != t_saved_expires ||
+ cmos->saved_wkalrm.enabled != current_alarm.enabled) {
+ cmos_set_alarm(dev, &cmos->saved_wkalrm);
+ }
+}
+
static bool cmos_is_wkalrm_expired(struct device *dev)
{
struct cmos_rtc *cmos = dev_get_drvdata(dev);
@@ -935,6 +955,9 @@ static int cmos_resume(struct device *dev)
cmos->enabled_wake = 0;
}
+ /* The BIOS might have changed the alarm, restore it */
+ cmos_check_wkalrm(dev);
+
is_wkalrm_expired = cmos_is_wkalrm_expired(dev);
spin_lock_irq(&rtc_lock);
--
2.9.3
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
next prev parent reply other threads:[~2016-08-31 22:59 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-31 22:58 [rtc-linux] [PATCH v2 1/2] rtc-cmos: Ensure no expired alarm is left enabled after resume Gabriele Mazzotta
2016-08-31 22:59 ` Gabriele Mazzotta [this message]
2016-09-02 19:43 ` [rtc-linux] " Gabriele Mazzotta
2016-09-05 22:26 ` Alexandre Belloni
2016-09-06 9:47 ` Gabriele Mazzotta
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160831225900.20122-2-gabriele.mzt@gmail.com \
--to=gabriele.mzt@gmail.com \
--cc=a.zummo@towertech.it \
--cc=alexandre.belloni@free-electrons.com \
--cc=linux-kernel@vger.kernel.org \
--cc=matthew.garrett@nebula.com \
--cc=rtc-linux@googlegroups.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox