All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] PCI: Disable spurious s2idle wake from the NVMe root port on ThinkPad P1 Gen 9
@ 2026-11-13  1:48 Kean Ren
  2026-11-13  2:12 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Kean Ren @ 2026-11-13  1:48 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-kernel

On Lenovo ThinkPad P1 Gen 9 (21UF, Panther Lake), firmware enables the
ACPI wake capability (_PRW) of PCIe root port 00:1c.4, which is the root
port of the primary NVMe SSD.  When the NVMe controller is put into D3
during system suspend, a spurious PME is raised on that root port, which
sets ACPI GPE 0x6F (SCI).  The SCI fires during the noirq suspend phase
and aborts s2idle before it reaches the low-power state: every suspend
is followed by a wake within ~2.5 seconds with practically zero s2idle
residency.

The downstream NVMe device is not a wake source (its own ACPI wake is
disabled), so the spurious event comes from the root port's wake/PME
path.  Disable the root port's wake capability as well.

No firmware with a fix is available: the issue reproduces with BIOS
N4SET31W (1.10) and N4SET32W (1.11), the latest version at the time of
writing.  Match the model only; if a fixed BIOS is released later, this
quirk can be removed or restricted to the affected BIOS versions.

Verified on 21UFZE0PCN:
 - gpe6F increments by one per suspend/resume on both BIOS versions;
 - masking gpe6F, or disabling RP05 wake via /proc/acpi/wakeup, makes
   s2idle stay asleep;
 - with this quirk, /proc/acpi/wakeup reports RP05 as disabled and
   gpe6F no longer increments across repeated suspends.

Signed-off-by: Kean Ren <rh_king@163.com>
---
 drivers/pci/quirks.c | 52 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 7f1f47ea2ee4..daccfbbec821 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -6595,3 +6595,55 @@ static void pci_mask_replay_timer_timeout(struct pci_dev *pdev)
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_GLI, 0x9750, pci_mask_replay_timer_timeout);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_GLI, 0x9755, pci_mask_replay_timer_timeout);
 #endif
+
+/*
+ * Lenovo ThinkPad P1 Gen 9 (21UF): the firmware enables the ACPI wake
+ * capability of PCIe root port 00:1c.4, which is the root port of the
+ * primary NVMe SSD.  When the NVMe controller is put into D3 during
+ * system suspend, a spurious PME is raised on that root port, which in
+ * turn fires ACPI GPE 0x6F (SCI) and aborts s2idle before the system
+ * reaches the low-power state.  The NVMe device itself is not a wake
+ * source (its own ACPI wake is disabled), so disable the root port's
+ * wake capability as well.
+ *
+ * No firmware with a fix is available: the issue reproduces with BIOS
+ * N4SET31W (1.10) and N4SET32W (1.11), the latest version at the time
+ * of writing.  Match the model only; if a fixed BIOS is released later,
+ * this quirk can be removed or restricted to the affected BIOS
+ * versions.
+ */
+static const struct dmi_system_id p1g9_rp05_wakeup_dmi[] __initconst = {
+	{
+		.ident = "Lenovo ThinkPad P1 Gen 9 (21UF)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "21UFZE0PCN"),
+		},
+	},
+	{ }
+};
+
+static int __init pci_fixup_p1g9_rp05_wakeup(void)
+{
+	struct pci_dev *rp;
+
+	if (!dmi_check_system(p1g9_rp05_wakeup_dmi))
+		return 0;
+
+	/* Root port of the primary NVMe SSD (05:00.0). */
+	rp = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0x1c, 4));
+	if (!rp)
+		return 0;
+
+	if (device_can_wakeup(&rp->dev)) {
+		device_set_wakeup_enable(&rp->dev, false);
+		pci_info(rp, "disabled spurious s2idle wake (BIOS %s)\n",
+			 dmi_get_system_info(DMI_BIOS_VERSION));
+	} else {
+		pci_warn(rp, "wakeup not enabled, cannot disable spurious s2idle wake\n");
+	}
+	pci_dev_put(rp);
+
+	return 0;
+}
+late_initcall(pci_fixup_p1g9_rp05_wakeup);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] PCI: Disable spurious s2idle wake from the NVMe root port on ThinkPad P1 Gen 9
  2026-11-13  1:48 [PATCH] PCI: Disable spurious s2idle wake from the NVMe root port on ThinkPad P1 Gen 9 Kean Ren
@ 2026-11-13  2:12 ` sashiko-bot
  0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-11-13  2:12 UTC (permalink / raw)
  To: Kean Ren; +Cc: linux-pci

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Medium] PCI: p1g9_rp05_wakeup_dmi matches single SKU 21UFZE0PCN
  instead of 21UF model
--

commit 75de6a519b5eeaae2e4b61c8891c8afd3aa3c727
Author: Kean Ren <rh_king@163.com>

PCI: Disable spurious s2idle wake from the NVMe root port on ThinkPad P1 Gen 9

This commit adds a DMI-based PCI quirk to disable ACPI wakeup on PCIe root
port 00:1c.4 on the Lenovo ThinkPad P1 Gen 9 (21UF) to prevent spurious
PMEs from aborting s2idle suspend.

> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index f7cd4149f8130..ead7a6c456986 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -6610,3 +6610,55 @@ static void pci_mask_replay_timer_timeout(struct pci_dev *pdev)
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_GLI, 0x9750, pci_mask_replay_timer_timeout);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_GLI, 0x9755, pci_mask_replay_timer_timeout);
>  #endif
> +
> +/*
> + * Lenovo ThinkPad P1 Gen 9 (21UF): the firmware enables the ACPI wake
> + * capability of PCIe root port 00:1c.4, which is the root port of the
> + * primary NVMe SSD.  When the NVMe controller is put into D3 during
> + * system suspend, a spurious PME is raised on that root port, which in
> + * turn fires ACPI GPE 0x6F (SCI) and aborts s2idle before the system
> + * reaches the low-power state.  The NVMe device itself is not a wake
> + * source (its own ACPI wake is disabled), so disable the root port's
> + * wake capability as well.
> + *
> + * No firmware with a fix is available: the issue reproduces with BIOS
> + * N4SET31W (1.10) and N4SET32W (1.11), the latest version at the time
> + * of writing.  Match the model only; if a fixed BIOS is released later,
> + * this quirk can be removed or restricted to the affected BIOS
> + * versions.
> + */
> +static const struct dmi_system_id p1g9_rp05_wakeup_dmi[] __initconst = {
> +	{
> +		.ident = "Lenovo ThinkPad P1 Gen 9 (21UF)",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "21UFZE0PCN"),
> +		},
> +	},
> +	{ }
> +};

[Severity: Medium]
Should p1g9_rp05_wakeup_dmi match "21UF" instead of "21UFZE0PCN"?

On Lenovo ThinkPads, DMI_PRODUCT_NAME holds the 10-character Machine Type
Model string, where the first four characters ("21UF") identify the model
and the remaining six ("ZE0PCN") identify a specific factory configuration
and regional SKU.  Matching the full "21UFZE0PCN" string leaves the quirk
inactive on all other 21UF configurations running the same BIOS, so s2idle
suspend will still abort on those machines.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261113014824.2396883-1-rh_king@163.com?part=1

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-11-13  2:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-13  1:48 [PATCH] PCI: Disable spurious s2idle wake from the NVMe root port on ThinkPad P1 Gen 9 Kean Ren
2026-11-13  2:12 ` sashiko-bot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.