[PATCH v2] PCI: rzg3s-host: Fix NVMe resume errors after s2idle
From: Ovidiu Panait
Date: Thu Oct 29 2026 - 13:29:03 EST
On the Renesas RZ/V2H platform, when ASPM is enabled, resuming from s2idle
with an NVMe SSD connected fails with:
nvme nvme0: I/O tag 27 (001b) opcode 0x9 (Admin Cmd) QID 0 timeout, reset controller
nvme nvme0: Disabling device after reset failure: -19
This happens because during s2idle, when ASPM is enabled, nvme_suspend()
does not shut the drive down. It leaves it in D0, puts it in its lowest
NVMe power state, so that resume only has to restore the previous power
state instead of a full reinitialization. This assumes the drive keeps
its context over the suspend.
However, rzg3s_pcie_suspend_noirq() doesn't take this into account and
it always powers down the controller and asserts the controller resets,
including PERST#. That resets the drive, and the command the NVMe driver
sends on resume never completes.
To fix this, similar to the dwc driver, use
pci_host_common_d3cold_possible() to check if the controller should be
powered down and keep the controller running otherwise. To keep the
controller running, also call device_set_awake_path(), so that the PM
domain does not turn off the controller clocks.
Do this only for s2idle. In s2ram the SoC could be powered off, and
neither the PM domain nor the driver would restore the controller
clocks and resets on resume. In hibernation, the controller must be
reinitialized on restore.
Fixes: 7ef502fb35b2 ("PCI: Add Renesas RZ/G3S host controller driver")
Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@xxxxxxxxxxx>
---
v2 changes:
- Replaced pm_suspend_via_firmware() check with a pm_suspend_target_state
check.
- Updated the commit message to mention why device_set_awake_path() is
needed.
Note: This fix depends on this series:
https://lore.kernel.org/all/20261019065025.2146539-1-claudiu.beznea@xxxxxxxxxx/
drivers/pci/controller/pcie-rzg3s-host.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
index f6823c9bc414..996a51f2ba96 100644
--- a/drivers/pci/controller/pcie-rzg3s-host.c
+++ b/drivers/pci/controller/pcie-rzg3s-host.c
@@ -2450,6 +2450,14 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
static int rzg3s_pcie_suspend_noirq(struct device *dev)
{
struct rzg3s_pcie_host *host = dev_get_drvdata(dev);
+ struct pci_host_bridge *bridge = pci_host_bridge_from_priv(host);
+ bool pme_capable;
+
+ if (pm_suspend_target_state == PM_SUSPEND_TO_IDLE &&
+ !pci_host_common_d3cold_possible(bridge, &pme_capable)) {
+ device_set_awake_path(dev);
+ return 0;
+ }
return rzg3s_pcie_host_stop(host);
}
--
2.34.1