[systemd-devel] [PATCH] Add support for Intel Rapid Start
Zbigniew Jędrzejewski-Szmek
zbyszek at in.waw.pl
Sun Oct 13 13:40:29 PDT 2013
On Sun, Oct 13, 2013 at 09:50:59PM +0200, Bastien Nocera wrote:
>
> 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;
> +}
> +
This part looks ok.
> 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;
This disables sleep support for everyone who doesn't have rapid start...
> - 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();
Does this compile?
> @@ -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;
So, how exactly does this work? We request suspend from the kernel, and get
something functionally equivalent to hybrid-sleep instead? I think it would
be better to do something mjg suggested in the other mail: to configure this
explicitly by writting appropriate values when hybrid sleep has been requested.
> > + r = read_one_line_file("/sys/bus/acpi/devices/INT3392:00/wakeup_events", &p);
> /sys/bus/acpi/drivers/intel_rapid_start/*/wakeup_events would be better,
> if there's any way to use wildcards here.
There's a bunch of glob-related functions, like glob_exists or glob_extend
in util.h.
Zbyszek
More information about the systemd-devel
mailing list