Re: [PATCH] x86/PCI: Disable D3cold on Intel BE200 Wi-Fi on Lenovo IdeaPad Pro 5 14IAH10
From: Bjorn Helgaas
Date: Tue Jul 28 2026 - 16:10:16 EST
[+cc Emmanuel, Mark]
On Wed, Jul 22, 2026 at 04:13:15AM +0200, Nika Krasnova wrote:
> 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.
I guess this means "lspci -xs01:00.0" after resume shows all 0xff?
> 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@xxxxxxxxxxxx>
> 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
>