From: Mario Limonciello <mario.limonciello@amd.com>
To: Lenart Kos <koslenart@gmail.com>,
Basavaraj Natikar <Basavaraj.Natikar@amd.com>,
Shyam Sundar S K <Shyam-sundar.S-k@amd.com>,
Linus Walleij <linusw@kernel.org>
Cc: linux-gpio@vger.kernel.org, linux-pm@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: pinctrl: amd: spurious immediate resume from S3/s2idle via BIOS-armed wake GPIO with no ACPI owner (Lenovo Legion Pro 5 16ARX8)
Date: Wed, 10 Jun 2026 14:59:04 -0500 [thread overview]
Message-ID: <c982caf3-f855-41ad-80cd-3ce9598913ab@amd.com> (raw)
In-Reply-To: <CAFdvZNt+mRTE9Q+utn=T8GzU7s_09ULhUtzTMMa9dgGCsE+r9A@mail.gmail.com>
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?
next prev parent reply other threads:[~2026-06-10 19:59 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-10 19:32 Lenart Kos
2026-06-10 19:59 ` Mario Limonciello [this message]
2026-06-10 20:18 ` Lenart Kos
2026-06-10 20:23 ` Mario Limonciello
2026-06-10 21:20 ` Lenart Kos
2026-06-10 21:30 ` Mario Limonciello
2026-06-10 22:13 ` Lenart Kos
2026-06-11 4:34 ` Mario Limonciello
2026-06-11 8:07 ` Lenart Kos
2026-06-11 21:19 ` Mario Limonciello
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c982caf3-f855-41ad-80cd-3ce9598913ab@amd.com \
--to=mario.limonciello@amd.com \
--cc=Basavaraj.Natikar@amd.com \
--cc=Shyam-sundar.S-k@amd.com \
--cc=koslenart@gmail.com \
--cc=linusw@kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®