Re: pinctrl: amd: spurious immediate resume from S3/s2idle via BIOS-armed wake GPIO with no ACPI owner (Lenovo Legion Pro 5 16ARX8)

From: Lenart Kos

Date: Wed Jun 10 2026 - 16:18:27 EST


Thanks for taking your time for this. To answer your questions:

S3 path:
AFAIK it was on [deep] since my system was installed and I strongly
remember being it as so, although it is possible that I misremembered
since I have been debugging this sleep issue since January. In any
case I have also tried setting sleep to [s2idle] before and it did not
fix the waking issue even if set in s2 sleep mode.
The firmware is not modified, everything is installed from Fedora
sources without modification.

Methodology:
Yes you are correct about LLMs, I have thrown every bit of my
knowledge and time that I have available for this without success and
Claude has finally solved this after a few months being irritated by
this. I had decided to forward most of the information I received from
LLM in the hopes it was useful to an expert in the area, but in
hindsight I can see this was a mistake without AI disclosure, I'm
sorry. So for your other questions regarding why this assumption was
made or why was something done a certain way - I don't know, but I am
willing to assist with testing. Apologies for this mess, it's my first
time filing a bug to the LKML.

On Wed, Jun 10, 2026 at 9:59 PM Mario Limonciello
<mario.limonciello@xxxxxxx> wrote:
>
> First off -
>
> How did you get into an S3 path? These systems that ship with only
> Modern Standby / s2idle normally shouldn't be able to get into S3.
>
> ╰─❯ cat /sys/power/mem_sleep
> [s2idle]
>
> Have you modified the firmware in some way to try to enable an
> unvalidated path?
>
> I have some more questions about your methodology below because when
> debugging a kernel issue an LLM can sometimes make WILD assumptions that
> are totally a house of cards.
>
> On 6/10/26 14:32, Lenart Kos wrote:
> > ## Summary
> >
> > On the Lenovo Legion Pro 5 16ARX8, suspending (S3 *or* s2idle) with an external
> > display connected resumes the machine after ~1 second. The wake is delivered by
> > the AMD GPIO controller (`pinctrl_amd`, IRQ 7) from GPIO pin **#4**
> > (and pin #2 for
> > the USB‑C/DP path), which the **BIOS has armed as an S0i3/S3 wake
> > source directly
> > in the FCH GPIO register**, with **no ACPI description**
> > (`_AEI`/`GpioInt`/`_PRW`)
> > anywhere in the DSDT or the 16 SSDTs. Because there is no ACPI owner,
> > none of the
> > existing override mechanisms (`gpiolib_acpi.ignore_wake=`, device
> > `power/wakeup`)
> > can reach it, and `IO_STRICT_DEVMEM` blocks any userspace register
> > write. The pin
> > is an external‑display HPD line, so the edge produced while the GPU
> > powers down on
> > the way into sleep immediately wakes the system.
> >
> > ## Affected system
> >
> > ```
> > DMI sys_vendor LENOVO
> > DMI product_name 82WM
> > DMI product_version Legion Pro 5 16ARX8
> > DMI board_name LNVNB161216
> > BIOS LPCN62WW (2025-06-17) # latest available; does NOT fix this
> > SoC AMD Ryzen 7 7745HX (Raphael), GPIO ctrl AMDI0030 @ 0xFED81500
> > GPU NVIDIA RTX 4060 Mobile (HDMI) + AMD Raphael iGPU (USB-C DP)
> > Kernel 6.17+ through 7.0.x (reproduced on Fedora 43/44)
> > ```
> >
> > ## Symptom / evidence
> >
> > Failed-suspend kernel log (verbose PM):
> > ```
> > PM: suspend entry (deep)
> > ...
> > amd_gpio AMDI0030:00: ... Clearing debounce for GPIO #2 during suspend.
> > amd_gpio AMDI0030:00: ... Clearing debounce for GPIO #4 during suspend.
> > amd_gpio AMDI0030:00: ... Disabling GPIO #89 interrupt for suspend. #
> > not a wake src
> > ACPI: PM: Preparing to enter system sleep state S3
> > Timekeeping suspended for 1.384 seconds
> > PM: Triggering wakeup from IRQ 7 # IRQ 7 = pinctrl_amd
> > ...
> > GPIO 4 is active: 0x30057c00 # bit 14 (WAKE_CNTRL_S3) + bit 29 (wake latched)
> > ```
> > `/sys/power/pm_wakeup_irq` = `7`.
> >
> > `/sys/kernel/debug/gpio` (relevant rows) shows pins #2 and #4 armed for S0i3+S3
> > wake with their interrupt enabled, while #89 has no wake bits:
> > ```
> > #2 😛| ↓ | edge |⏰|⏰| | | ... 0x147ae0
> > #4 😛| b | edge |⏰|⏰| | | ... 0x57ce0 <- both-edge HPD, S0i3+S3 wake set
>
> How did you determine this is an HPD line? Is that a pure guess? Or
> did you look at a schematic/trace etc?
>
> > #89 😛| ↓ | level| | | | | ... 0x151b00 <- no wake bits (red herring)
> > ```
> >
> > ## Root cause
> >
> > 1. The external‑display HPD lines are routed to SoC GPIO #2 (USB‑C/DP) and #4
> > (HDMI/dGPU).
>
> How do you know?
>
> > 2. The BIOS sets `WAKE_CNTRL_S0I3`/`WAKE_CNTRL_S3` (bits 13/14) on
> > those pins in the
> > FCH GPIO register block and **never describes them in ACPI** — decompiling the
> > DSDT and all 16 SSDTs yields **zero** `GpioInt`/`GpioIo`/`_AEI` resources.
> > 3. `pinctrl_amd` correctly preserves hardware-armed wake pins across
> > suspend, so the
> > HPD edge generated during the suspend transition wakes the system immediately.
> >
> > This is effectively an unvalidated firmware S3 path (the platform ships as
> > Modern-Standby-only); but note **both** the S0i3 and S3 wake bits are set, so
> > s2idle is affected too.
>
> So how did you get into S3?
>
> >
> > ## Why existing mechanisms don't help
> >
> > - `/proc/acpi/wakeup`, PCI/ACPI `power/wakeup` — wrong layer; this is
> > not a PCIe PME.
> > Disabling wakeup on the GPP bridges / GPU has no effect (verified).
> > - `gpiolib_acpi.ignore_wake=` / `ignore_interrupt=` — only match
> > **ACPI-declared**
> > GPIO events; this pin has no ACPI declaration, so they cannot target it.
> > - `/dev/mem` register write — blocked by `CONFIG_IO_STRICT_DEVMEM=y`
> > (the region is
> > claimed by pinctrl_amd).
> >
> > There is currently **no way, in-tree, to disarm a bare (non-ACPI) firmware-armed
> > pinctrl-amd wake pin.** That is the gap.
> >
> > ## Suggested fix (maintainers' choice)
> >
> > A working out-of-tree reference implementation (clears bits 13/14/15
> > on pins #2/#4
> > at probe and on `PM_SUSPEND_PREPARE`) is here:
> > **https://github.com/Lenart12/legion-nowake** — please feel free to reuse.
>
> Why not use /dev/gpiochipX devices to change GPIOs?
>
> >
> > Possible in-tree directions:
> > 1. **DMI-matched quirk in `pinctrl-amd`** that clears the S-state
> > wake-enable bits
> > for the affected pins at probe (smallest change; precedent exists for AMD GPIO
> > wake quirks).
> > 2. **A generic override** for bare pins, e.g. a
> > `pinctrl_amd.ignore_wake=<pin,...>`
> > module parameter, analogous to `gpiolib_acpi.ignore_wake=` but for
> > hardware-armed
> > pins without ACPI events. This would help the broader class of AMD laptops that
> > hit firmware-armed spurious wakes.
> >
> > ## Reproduction
> >
> > 1. AMD laptop where a display HPD is wired to a GPIO the BIOS arms for wake.
> > 2. Connect an external monitor, `systemctl suspend`.
> > 3. Observe resume after ~1s; `pm_wakeup_irq` = the `pinctrl_amd` IRQ;
> > the offending
> > pin shows `wake latched` in the post-resume `GPIO N is active` log.
>
> On the presumption that this is correct about being an HPD pin doesn't
> this actually point at a GPU driver bug?
>
> >
> > ## Public discussion / full diagnostics
> >
> > Fedora Discussion (complete diagnostic walkthrough, ACPI dumps, gpio table):
> > https://discussion.fedoraproject.org/t/immediate-wake-from-s3-sleep-when-hdmi-is-connected-irq-7-pinctrl-amd
> >
> > ## Attachments to include when filing
> >
> > - `acpidump` output (or note: DSDT + all SSDTs contain no GpioInt/_AEI).
> > - Full verbose-PM `dmesg` of one failed suspend (`pm_debug_messages=1`).
> > - `sudo cat /sys/kernel/debug/gpio`.
> > - `cat /sys/class/dmi/id/{sys_vendor,product_name,product_version,board_name,bios_version}`.
>
> Where is the kernel bugzilla that you attached all these artifacts?
>


--
Lep pozdrav,
Lenart Arvo Kos