[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