[PATCH v4 06/10] PCI: wire CXL reset prepare/cleanup

smadhavan
2026-01-20T22:27:10Z

From: Srirangan Madhavan <smadhavan@nvidia.com>

Wire CXL reset preparation and cleanup into the PCI CXL reset path.
The flow now validates/offlines regions, performs teardown and cache
flushes, then releases the lock on completion or error. This keeps the
common reset_prepare flow intact while adding cxl_reset-specific quiesce logic.

Signed-off-by: Srirangan Madhavan <smadhavan@nvidia.com>
---
drivers/pci/pci.c | 19 ++++++++++++++++++-
include/linux/pci.h | 11 +++++++++++
2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e2d5ff25ab67..18047c893b0c 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4989,10 +4989,27 @@ static int cxl_reset(struct pci_dev *dev, bool probe)
if (probe)
return 0;

+ /*
+ * CXL-reset-specific preparation: validate memory offline,
+ * tear down regions, flush device caches.
+ */
+ rc = cxl_reset_prepare_device(dev);
+ if (rc)
+ return rc;
+
if (!pci_wait_for_pending_transaction(dev))
pci_err(dev, "timed out waiting for pending transaction; performing function level reset anyway\n");

- return cxl_reset_init(dev, dvsec);
+ rc = cxl_reset_init(dev, dvsec);
+ if (rc)
+ goto out_cleanup;
+
+ cxl_reset_cleanup_device(dev);
+ return 0;
+
+out_cleanup:
+ cxl_reset_cleanup_device(dev);
+ return rc;
}

static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 4a8c4767db6e..c074c2040b28 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1466,11 +1466,22 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags);
bool pci_device_is_present(struct pci_dev *pdev);
#ifdef CONFIG_CXL_PCI
bool cxl_is_type2_device(struct pci_dev *dev);
+int cxl_reset_prepare_device(struct pci_dev *pdev);
+void cxl_reset_cleanup_device(struct pci_dev *pdev);
#else
static inline bool cxl_is_type2_device(struct pci_dev *dev)
{
return false;
}
+
+static inline int cxl_reset_prepare_device(struct pci_dev *pdev)
+{
+ return 0;
+}
+
+static inline void cxl_reset_cleanup_device(struct pci_dev *pdev)
+{
+}
#endif
void pci_ignore_hotplug(struct pci_dev *dev);
struct pci_dev *pci_real_dma_dev(struct pci_dev *dev);
--
2.34.1