[PATCH] x86/PCI: Disable D3cold on Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10

Nika Krasnova posted 1 patch 2 days, 21 hours ago
arch/x86/pci/fixup.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
[PATCH] x86/PCI: Disable D3cold on Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10
Posted by Nika Krasnova 2 days, 21 hours ago
On the Lenovo IdeaPad Pro 5 14IAH10, the Intel BE200 Wi-Fi (8086:272b,
iwlwifi) fails to power back on from D3cold after a suspend-to-idle
(s2idle) cycle.  On resume the platform reports a successful ACPI D0
transition, but the device is left unpowered: config space reads back
as 0xffffffff, the firmware reset times out, and the wiphy fails to
resume:

  iwlwifi 0000:01:00.0: power state changed by ACPI to D0
  iwlwifi 0000:01:00.0: restore config 0x2c: 0xffffffff -> 0x00f48086
  ieee80211 phy0: PM: failed to resume async: error -110

The device stays unusable until a full power cycle; an iwlwifi module
reload and a PCI remove/rescan do not recover it, confirming the device
is genuinely unpowered rather than in a bad software state.

Setting the device's d3cold_allowed to 0 keeps it in D3hot across
suspend and resumes reliably, so the platform does not correctly restore
power to the M.2 Wi-Fi slot on the s2idle resume path.  This mirrors the
untested-vendor-transition pattern already handled for the Asus B1400
NVMe (see asus_disable_nvme_d3cold): the reference OS does not appear to
exercise the D3cold->D0 path, so it is left untested.

Add a DMI-matched fixup that forbids D3cold for the BE200 on this model.
Match on the product rather than the BIOS version so the workaround
survives BIOS updates that do not address the issue.

Signed-off-by: Nika Krasnova <nika@nikableh.moe>
Assisted-by: Claude:claude-opus-4-8
---

Not sure arch/x86/pci/fixup.c is the right home versus a PCI quirk in
drivers/pci/quirks.c; would be happy to move it.

The latest BIOS from Lenovo for this model (QLCN35WW, 2025-12-23) is
installed and the failure is still present, so there is currently no
firmware-level fix.

Tested on the affected machine: with this patch applied and my local
d3cold_allowed=0 udev workaround removed, the BE200 resumes from s2idle
across repeated suspend/resume cycles with no iwlwifi errors.

 arch/x86/pci/fixup.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index b301c6c8df75..3117f313930e 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -995,6 +995,39 @@ static void asus_disable_nvme_d3cold(struct pci_dev *pdev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x9a09, asus_disable_nvme_d3cold);
 
+/*
+ * Disable D3cold on the Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10
+ *
+ * On this platform the BE200 (8086:272b) fails to power back on from D3cold
+ * after an s2idle cycle: all config and CSR reads return 0xffffffff, the
+ * driver's firmware reset times out ("timeout waiting for FW reset ACK
+ * (inta_hw=0xffffffff)") and re-probe fails with -EIO.  A module reload and a
+ * PCI remove/rescan cannot revive the device; only a full platform power cycle
+ * does.  This looks like an untested transition by the vendor: the reference
+ * OS does not appear to exercise the D3cold->D0 path.
+ *
+ * Forbidding D3cold keeps the card in D3hot across suspend, which resumes
+ * reliably at the cost of a small amount of power while suspended.  Match on
+ * the product only (not the BIOS version) so the workaround survives BIOS
+ * updates that do not address the issue.
+ */
+static const struct dmi_system_id lenovo_be200_broken_d3cold_table[] = {
+	{
+		.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+				DMI_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Pro 5 14IAH10"),
+		},
+	},
+	{}
+};
+
+static void lenovo_disable_be200_d3cold(struct pci_dev *pdev)
+{
+	if (dmi_check_system(lenovo_be200_broken_d3cold_table) > 0)
+		pci_d3cold_disable(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x272b, lenovo_disable_be200_d3cold);
+
 #ifdef CONFIG_SUSPEND
 /*
  * Root Ports on some AMD SoCs advertise PME_Support for D3hot and D3cold, but
-- 
2.54.0