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 | 28 ++++++++++++++++++++++++++-- src/shared/sleep-config.h | 1 + src/sleep/sleep.c | 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index d068bfc..c5551fc 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -250,6 +250,26 @@ static bool enough_memory_for_hibernation(void) { return r; } +/* Check whether Intel Rapid Start Technology is supported: + * http://mjg59.dreamwidth.org/26022.html */ +bool has_rapid_start(void) { + int r; + _cleanup_free_ char *p = NULL; + + r = read_one_line_file("/sys/bus/acpi/devices/INT3392:00/wakeup_events", &p); + if (r < 0) + return false; + + /* We only support rapid start if we have both values set: + * 1: Wake to enter hibernation when the wakeup timer expires + * 2: Wake to enter hibernation when the battery reaches a + * critical level */ + if (p[0] == '3' && p[1] == '\0') + return true; + + return false; +} + int can_sleep(const char *verb) { _cleanup_strv_free_ char **modes = NULL, **states = NULL; int r; @@ -262,8 +282,12 @@ int can_sleep(const char *verb) { if (r < 0) return false; - if (!can_sleep_state(states) || !can_sleep_disk(modes)) + if (!can_sleep_state(states) || !can_sleep_disk(modes) || !has_rapid_start()) 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 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel