Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Intel Rapid Start support for systemd
From 3c48ec58d20a33d9514b76a36b7c53226ee69815 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Sun, 13 Oct 2013 21:32:01 +0200
Subject: [PATCH] Add support for Intel Rapid Start
Instead of using the kernel's hybrid sleep, use the firmware for
laptops that support Intel Rapid Start, as explained in:
http://mjg59.dreamwidth.org/26022.html
and implemented in:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/log/drivers/platform/x86/intel-rst.c
---
src/shared/sleep-config.c | 38 +++++++++++++++++++++++++++++++++++++-
src/shared/sleep-config.h | 1 +
src/sleep/sleep.c | 3 +++
3 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
index d068bfc..65ed9b3 100644
--- a/src/shared/sleep-config.c
+++ b/src/shared/sleep-config.c
@@ -250,6 +250,38 @@ static bool enough_memory_for_hibernation(void) {
return r;
}
+/* Check whether Intel Rapid Start Technology is supported:
+ * http://mjg59.dreamwidth.org/26022.html
+ * and enable it if so */
+bool has_rapid_start(void) {
+ int r;
+ char **matches = NULL;
+ _cleanup_free_ char *p = NULL;
+
+ /* If /sys is read-only we cannot enable Rapid Start */
+ if (access("/sys/power/state", W_OK) < 0)
+ return false;
+
+ r = glob_extend(&matches, "/sys/bus/acpi/drivers/intel_rapid_start/*/wakeup_events");
+ if (r < 0)
+ return false;
+
+ /* We want to make sure to enable both flags:
+ * 1: Wake to enter hibernation when the wakeup timer expires
+ * 2: Wake to enter hibernation when the battery reaches a
+ * critical level
+ * as some firmwares might not allow changing the setting
+ * in their UIs. */
+ r = write_string_file(matches[0], "3");
+ if (r < 0) {
+ log_debug ("Failed to write '%s' to %s: %s",
+ "3", matches[0], strerror(-r));
+ return false;
+ }
+
+ return true;
+}
+
int can_sleep(const char *verb) {
_cleanup_strv_free_ char **modes = NULL, **states = NULL;
int r;
@@ -265,5 +297,9 @@ int can_sleep(const char *verb) {
if (!can_sleep_state(states) || !can_sleep_disk(modes))
return false;
- return streq(verb, "suspend") || enough_memory_for_hibernation();
+ if (streq(verb, "suspend"))
+ return true;
+ if (streq (verb, "hybrid-sleep"))
+ return enough_memory_for_hibernation() || has_rapid_start();
+ return enough_memory_for_hibernation();
}
diff --git a/src/shared/sleep-config.h b/src/shared/sleep-config.h
index 51d2dec..4fb418f 100644
--- a/src/shared/sleep-config.h
+++ b/src/shared/sleep-config.h
@@ -24,3 +24,4 @@ int parse_sleep_config(const char *verb, char ***modes, char ***states);
int can_sleep(const char *verb);
int can_sleep_disk(char **types);
int can_sleep_state(char **types);
+bool has_rapid_start(void);
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
index a56ab89..264f2c4 100644
--- a/src/sleep/sleep.c
+++ b/src/sleep/sleep.c
@@ -211,6 +211,9 @@ int main(int argc, char *argv[]) {
if (r <= 0)
goto finish;
+ if (has_rapid_start () && streq(arg_verb, "hybrid-sleep"))
+ arg_verb = "suspend";
+
r = parse_sleep_config(arg_verb, &modes, &states);
if (r < 0)
goto finish;
--
1.8.3.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.