Enabling S3 suspend-to-ram for Linux on an HP Pavilion Aero 13

Since a few weeks I own an HP Pavilion Aero 13 which I want to use as travel laptop. This little thing has less than a kilogram and is powered by a beefy AMD Ryzen 5 5600U. Unfortunately, S3 suspend does not work on linux. It’s not because the device does not support it. It is because some stupid HP engineers decided not to expose this feature to the operating system.

Fortunately, linux allows to patch the ACPI table at boot, unveiling otherwise unavailable features to the operating system. After an hour of reserach, I found the required pieces in a reply at https://bbs.archlinux.org/viewtopic.php?pid=1975083#p1975083. In this post I document everything needed to activate S3 on linux on this device.

To see whether s3 is available, check the output of dmesg:

#> sudo dmesg | grep - "ACPI: PM: (supports"
[ 0.376849] ACPI: PM: (supports S0 S4 S5)

If S3 is missing, suspend is only possible with „s2idle“, not with the better „deep“ sleep mode:

#> cat /sys/power/mem_sleep

To get this fixed, the ACPI table needs to be dumped, modified and compiled. The compiled table can then be loaded by the kernel.

Install acpica and cpio. On archlinux it is done with the following command (on debien, the package is acpica-tools):

sudo pacman -S acpica cpio

Now the ACPI table can be dumped and decompiled into a folder:

mkdir /tmp/acpi
cd /tmp/acpi
acpidump -b
iasl -e *.dat -d dsdt.dat
iasl -d facp.dat

This creates a lot of files. The last 2 steps creates dsdt.dsl and facp.dsl which are readable versions of the tables.

In facp.dsl, only the „Oem Revision“ must be increased. I changed it from 01072009 to 01072010. Here is a patch:

#> diff -u facp.dsl.orig facp.dsl
--- facp.dsl.org	2023-01-21 19:18:29.977306514 +0100
+++ facp.dsl	2023-01-21 19:18:32.090610166 +0100
@@ -16,7 +16,7 @@
 [009h 0009 001h]                    Checksum : 50
 [00Ah 0010 006h]                      Oem ID : "HPQOEM"
 [010h 0016 008h]                Oem Table ID : "SLIC-MPC"
-[018h 0024 004h]                Oem Revision : 01072009
+[018h 0024 004h]                Oem Revision : 01072010
 [01Ch 0028 004h]             Asl Compiler ID : "HP  "
 [020h 0032 004h]       Asl Compiler Revision : 00010013

In dsdt.dsl, I also changed this revision to 01072010. Then I added the missing definition block for the S3 sleep mode. Way below, around line 9250 is a dupplicate block in a switch statement that fails during compilation. I just removed it. Here is the patch for this file:

#> diff -u dsdt.dsl.orig dsdt.dsl 
--- dsdt.dsl.orig	2023-01-21 19:13:51.847853395 +0100
+++ dsdt.dsl	2023-01-21 19:23:15.456611450 +0100
@@ -18,7 +18,7 @@
  *     Compiler ID      "ACPI"
  *     Compiler Version 0x20190509 (538510601)
-DefinitionBlock ("", "DSDT", 2, "HPQOEM", "8916    ", 0x01072009)
+DefinitionBlock ("", "DSDT", 2, "HPQOEM", "8916    ", 0x01072010)
     External (_GPE, DeviceObj)
     External (_PR_.P000, UnknownObj)
@@ -3016,6 +3016,13 @@
+    Name (_S3, Package (0x04)
+    {
+        0x03, 
+        0x03, 
+        Zero, 
+        Zero
+    })
     Name (_S4, Package (0x04)  // _S4_: S4 System State
@@ -9221,24 +9228,6 @@
                 Case (0x03)
-                    DerefOf (Local0 [0x02]) [One] = Zero
-                    DerefOf (Local0 [0x02]) [0x02] = Zero
-                    DerefOf (Local0 [0x02]) [0x03] = Zero
-                    DerefOf (Local0 [0x02]) [0x04] = Zero
-                    DerefOf (Local0 [0x02]) [0x05] = Zero
-                    DerefOf (Local0 [0x02]) [0x06] = Zero
-                    DerefOf (Local0 [0x02]) [0x07] = Zero
-                    DerefOf (Local0 [0x02]) [0x08] = Zero
-                    DerefOf (Local0 [0x02]) [0x09] = Zero
-                    DerefOf (Local0 [0x02]) [0x0A] = Zero
-                    DerefOf (Local0 [0x02]) [0x0B] = Zero
-                    DerefOf (Local0 [0x02]) [0x0C] = Zero
-                    DerefOf (Local0 [0x02]) [0x0D] = Zero
-                    DerefOf (Local0 [0x02]) [0x0E] = Zero
-                    DerefOf (Local0 [0x02]) [0x0F] = Zero
-                }
-                Case (0x03)
-                {
                     DerefOf (Local0 [0x02]) [One] = Zero
                     DerefOf (Local0 [0x02]) [0x02] = Zero
                     DerefOf (Local0 [0x02]) [0x03] = Zero

Now, both files can be compiled:

#> iasl -ve -tc dsdt.dsl
#> iasl -ve -tc facp.dsl

The result are dsdt.aml and facp.dsl. These files must be packet and can then be used as a initrd.

#> mkdir -p kernel/firmware/acpi
#> cp *.aml kernel/firmware/acpi
#> find kernel | cpio -H newc --create > acpi_override.cpio.img
#> sudo cp acpi_override.cpio.img /boot/

Now the initrd needs to be added to grub config. Ihis can be done by adding a line to /etc/default/grub. Also and option should be added to the linux command line that enforces to use deep sleep as default.

GRUB_CMDLINE_LINUX="... mem_sleep_default=deep"

Re-create the grub config:

sudo sh -c "grub-mkconfig > /boot/grub/grub.cfg"

After a reboot, S3 and suspend-to ram should be available and enabled:

#> sudo dmesg | grep - "ACPI: PM: (supports"
[ 0.376849] ACPI: PM: (supports S0 S3 S4 S5)

#> cat /sys/power/mem_sleep 
s2idle [deep]


Veröffentlicht unter Linux

2 Gedanken zu „Enabling S3 suspend-to-ram for Linux on an HP Pavilion Aero 13

  1. Thanks for the clear instructions, I managed to get S3 working on my Aero 13 as well! This solves my biggest gripe with the machine, apart from its abysmal battery life. I somewhat mitigated that by using the ‚conservative‘ CPU scaling governor. But if you have any suggestions to improve power use, I would greatly appreciate that.

    1. Hello,

      I’m running alpine on it with no special settings and battery is good enough for my use (I use it only for couch-surfing and abroad). A bit annoying is that the battery life is always reported way shorter that it actually is. I think the consumption reporting is broken – but it’s also on windows, so it seems to be another ACPI issue.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert