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: Thu Jun 11 2026 - 04:07:54 EST


I'm sending this patch from Gmail, I hope it was parsed correctly and
is what you had in mind.

I am second guessing who to report to. *Something* is interrupting
this gpio pin and I am only sure that the event is being consumed by
Nvidia. So I decided to boot with no ignore_wake and all nouveau and
nvidia drivers blacklisted
(module_blacklist=nvidia,nvidia_drm,nvidia_modeset,nvidia_uvm,nouveau,nova_core)
and I was still able to reproduce the sleep issue again. This makes me
think it might be a platform bug, or atleast is is not caused by their
driver (or it could still be caused by the absence of the "corrected"
driver I guess). Sleep works fine on Windows though so maybe it's a
configuration or firmware issue.

Signed-off-by: Lenart Kos <koslenart@xxxxxxxxx>
---
Documentation/arch/x86/amd-debugging.rst | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

diff --git a/Documentation/arch/x86/amd-debugging.rst
b/Documentation/arch/x86/amd-debugging.rst
--- a/Documentation/arch/x86/amd-debugging.rst
+++ b/Documentation/arch/x86/amd-debugging.rst
@@ -133,6 +133,26 @@
The ``amd_s2idle.py`` script will capture most of these artifacts for you.
+Disabling a spurious GPIO wakeup
+================================
+
+The identification method above is not specific to *s2idle*; ``GPIO N
is active``
+is reported on resume from *S3* as well, and the ``GpioInt`` /
``_EVT`` lookup is
+the same.
+
+Identifying the notified device is often not enough to stop the wakeup, because
+the firmware may legitimately route a runtime ACPI event through a
+wakeup-capable GPIO. Such a pin can be kept as a runtime event while its wake
+capability is removed, using the ``gpiolib_acpi.ignore_wake=`` command line
+parameter. The format is ``<controller>@<pin>``, where the controller is the
+ACPI device instance of the GPIO chip (``AMDI0030:00`` for the AMD GPIO
+controller) and the pin is the line number: ::
+
+ gpiolib_acpi.ignore_wake=AMDI0030:00@2,AMDI0030:00@4
+
+This skips ``enable_irq_wake()`` for those pins, so they no longer wake the
+system while their ``_EVT`` notification still runs at runtime.
+
s2idle PM debug messages
========================

--
2.54.0




On Thu, Jun 11, 2026 at 6:34 AM Mario Limonciello
<mario.limonciello@xxxxxxx> wrote:
>
>
>
> On 6/10/26 17:13, Lenart Kos wrote:
> > While debugging with /dev/gpiochip I found out there is actually an
> > acpi event attached to both #2 and #4 so the report about there being
> > no _AEI resources was wrong...
> >
> > The _EVT handler shows what pin 4 is:
> > * Case (0x04): Notify(_SB.PCI0.GPP0.PEGP, 0x81) // "Information
> > Change" -> dGPU (NVIDIA)
> > * Case (0x0A): Notify(_SB.UBTC, 0x80) // USB Type-C status change
> >
> > Testing with cmdline
> > gpiolib_acpi.ignore_wake=AMDI0030:00@2,AMDI0030:00@4 it fixed the
> > issue as well. Maybe this can be added to gpiolib_acpi_quirks or
> > should this be fixed in Nvidia drivers? If you could kindly direct me
> > in the correct direction since this does not look like an AMD problem
> > anymore.
>
> This should not be quirked, there is something wrong with the NVIDIA
> software stack if it's asserting this GPIO over suspend.
>
> I would suggest you contact NVIDIA for a solution.
>
> But you at least have a workaround now.
>
> FWIW I do think that this debugging sequence you went through to
> determine the root cause and how to implement and discover this
> workaround is useful to add a paragraph to
> https://docs.kernel.org/arch/x86/amd-debugging.html.
>
> If you're willing to write up a patch to the documentation, I'm happy to
> review it.
>
> >
> >
> > On Wed, Jun 10, 2026 at 11:30 PM Mario Limonciello
> > <mario.limonciello@xxxxxxx> wrote:
> >>
> >> On 6/10/26 16:20, Lenart Kos wrote:
> >>> I have checked all the bios settings and the closest to modifying
> >>> sleep behaviour was a setting that enables opening the lid turning on
> >>> the laptop which was already disabled, so no, there are no sleep
> >>> settings.
> >>
> >> OK - then the LLM statement that this is a modern standby system sounds
> >> categorically wrong.
> >>
> >> It sounds like this is actually a system that only support S3.
> >>
> >>>
> >>> Regarding the HDMI port, it is connected to the Nvidia card. Only the
> >>> built-in screen is connected to the AMD card with eDP. I have not
> >>> reported this anywhere else yet, only here and the before mentioned
> >>> forum post. If this is an Nvidia issue I can report it to them as
> >>> well.
> >>
> >> As the behavior only happens with something connected to the HDMI port,
> >> I think you should discuss this with NVIDIA before we make any quirk
> >> decisions in the kernel.
> >>
> >> This really sounds like a driver bug to me if it's tied to that behavior.
> >>
> >> I personally would not be against more debugging infrastructure, but I
> >> would think that /dev/gpiochipX is enough for users to debug with.
> >>
> >> You can work with an LLM to try to come up with a solution that uses
> >> /dev/gpiochipX.
> >>
> >> I would certainly welcome a new section in
> >> https://docs.kernel.org/arch/x86/amd-debugging.html to explain how you
> >> used it if it's effective for debugging this problem.
> >>
> >>>
> >>> The HPD theory is pure guesswork done by LLM. What I can be certain of
> >>> is that disabling those specific pins
> >>> (https://github.com/Lenart12/legion-nowake/blob/6b599aad7afd1431e81048273106c5526561764b/legion_nowake.c#L59-L62)
> >>> did solve the problem, as to why and in what way, I would not bet on.
> >>> So the statements about HPD and your questions about them are maybe in
> >>> vain. What would be the best way to figure out if HPD is actually
> >>> attached to those pins?
> >>
> >> You can add some debugging statements specifically for when those GPIOs
> >> are firing interrupts. Unplug/plug and see if/when those GPIOs change.
> >>
> >> Maybe they're monitor presence lines? Maybe NVIDIA can tell you.
> >>
> >>>
> >>> FWIW I think that it is in fact not HPD as I have checked the GPIO
> >>> states when the monitor cable is connected or not and it seems to be
> >>> gpio #131 not #2 or #4. I have asked Claude to expand on what it knows
> >>> and what it assumes, this may be of help to you:
> >>> ---
> >>> What I have measured (facts):
> >>> * The resume is triggered by the AMD GPIO controller:
> >>> /sys/power/pm_wakeup_irq = 7 (pinctrl_amd), and the post‑resume log
> >>> shows GPIO 4 is active: 0x30057c00 with the wake‑status bit latched
> >>> and the S3 wake‑enable bit (bit 14) set.
> >>> * In /sys/kernel/debug/gpio, pins #2 and #4 are the only pins with
> >>> S0i3/S3 wake‑enable bits set and an interrupt enabled. (Pin #89 has an
> >>> interrupt but no wake bits — not a wake source.)
> >>> * These wake bits have no ACPI owner: decompiling the DSDT and all 16
> >>> SSDTs yields zero GpioInt / GpioIo / _AEI resources. Nothing in ACPI
> >>> references these pins.
> >>
> >> At least for AMD this is specifically more common in systems that
> >> support S3 (no _AEI resources).
> >>
> >>> * Empirically: suspend instant‑wakes only when an external display is
> >>> connected (reproduced over both HDMI and USB‑C/DP); with no display,
> >>> suspend holds. In the HDMI case, pin #4 is the one that latches the
> >>> wake.
> >>> * Clearing the S‑state wake‑enable bits (13/14/15) on pins #2 and #4
> >>> fixes it (verified across multiple suspends). Interrupt‑enable bits
> >>> left intact; no other wake source touched.
> >>> * GPIO #131 is the actual monitor‑presence line — its level cleanly
> >>> tracks plug/unplug (active‑low: LOW when a monitor is attached, HIGH
> >>> when not, confirmed across plug→unplug→replug). But #131 has no
> >>> interrupt and no wake bits — it does not wake the system.
> >>> * Pins #2 and #4 do not change level when the monitor is
> >>> plugged/unplugged (both steady while awake).
> >>>
> >>> What I am inferring (not proven):
> >>> * Because #4's level is steady while awake yet the wake only occurs
> >>> with a display connected, my working model is that #4 transitions
> >>> during the dGPU's suspend power‑down sequence, and that transition
> >>> only happens when the dGPU was actively driving an external display.
> >>> This is a plausible explanation of the display correlation, not a
> >>> verified one.
> >>> * The precise electrical function of pins #2/#4 is unknown without
> >>> schematics or a scope. They are not the monitor‑presence/HPD line
> >>> (that is the unarmed #131). I previously guessed "HPD"; the #131 data
> >>> contradicts that, so I'm withdrawing it.
> >>>
> >>> Unknown: what #2/#4 physically are, and why the firmware arms them as
> >>> sleep wake sources with no ACPI description.
> >>>
> >>> Net: a bare, firmware‑armed pinctrl-amd wake pin with no ACPI
> >>> description, which no existing in‑tree mechanism can disarm
> >>> (gpiolib_acpi.ignore_wake= needs an ACPI event; power/wakeup needs a
> >>> device owner; /dev/mem is blocked by IO_STRICT_DEVMEM).
> >>> ---
> >>>
> >>> I have not filed a bugzilla report yet.
> >>>
> >>> I hope I addressed your questions.
> >>>
> >>> On Wed, Jun 10, 2026 at 10:23 PM Mario Limonciello
> >>> <mario.limonciello@xxxxxxx> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 6/10/26 15:18, Lenart Kos wrote:
> >>>>> 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.
> >>>>
> >>>> Can you please check in Lenovo's BIOS setup if there is a sleep mode for
> >>>> this platform? If there isn't that's fine, I want to confirm what
> >>>> Lenovo actually presented before making further assumptions.
> >>>>
> >>>> If there is such a setting, what options does it offer? If you change
> >>>> it does the behavior change?
> >>>>
> >>>> Furthermore if this issue is only happening when connected to the HDMI
> >>>> port, that's the one connected to NVIDIA, right? Have you started a
> >>>> conversation with them? Assuming the HPD theory that has been presented
> >>>> is correct their driver should be in control of HPD behavior.
> >>>>
> >>>>>
> >>>>> 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.
> >>>>
> >>>> No worries; as long as I'm talking to a human about a problem not an
> >>>> LLM, I'm fine to work with you to see what we can come up with for a
> >>>> solution.
> >>>>
> >>>> I've got various inline comments/questions below. Can you please
> >>>> address them?
> >>>>
> >>>>>
> >>>>> 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