[PATCH v2 1/2] PCI: dwc: Add .post_deinit counterpart to endpoint .pre_init callback

From: Marek Vasut

Date: Thu Aug 20 2026 - 00:00:13 EST


In case the .pre_init() callback fails, it is mandatory to correctly
undo the hardware configuration which the .pre_init() callback did.
Intrododuce .post_deinit() callback to do exactly that, undo what
the .pre_init() callback did. Usually, that means stop the clock,
assert reset, and possibly program some registers to quiescense the
hardware. Invoke the .post_deinit() callback in dw_pcie_ep_deinit()
to retain functional symmetry.

Signed-off-by: Marek Vasut <marek.vasut+renesas@xxxxxxxxxxx>
---
Cc: "Krzysztof Wilczyński" <kwilczynski@xxxxxxxxxx>
Cc: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
Cc: Geert Uytterhoeven <geert+renesas@xxxxxxxxx>
Cc: Koichiro Den <den@xxxxxxxxxxxxx>
Cc: Lorenzo Pieralisi <lpieralisi@xxxxxxxxxx>
Cc: Magnus Damm <magnus.damm@xxxxxxxxx>
Cc: Manivannan Sadhasivam <mani@xxxxxxxxxx>
Cc: Rob Herring <robh@xxxxxxxxxx>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@xxxxxxxxxxx>
Cc: linux-kernel@xxxxxxxxxxxxxxx
Cc: linux-pci@xxxxxxxxxxxxxxx
Cc: linux-renesas-soc@xxxxxxxxxxxxxxx
---
V2: New patch
---
drivers/pci/controller/dwc/pcie-designware-ep.c | 8 +++++++-
drivers/pci/controller/dwc/pcie-designware.h | 1 +
2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index de8ee3db43601..1a3491b5003ec 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -1194,6 +1194,9 @@ void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
epc->mem->window.page_size);

pci_epc_mem_exit(epc);
+
+ if (ep->ops->post_deinit)
+ ep->ops->post_deinit(ep);
}
EXPORT_SYMBOL_GPL(dw_pcie_ep_deinit);

@@ -1553,7 +1556,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
ep->page_size);
if (ret < 0) {
dev_err(dev, "Failed to initialize address space\n");
- return ret;
+ goto err_deinit;
}

ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
@@ -1568,6 +1571,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)

err_exit_epc_mem:
pci_epc_mem_exit(epc);
+err_deinit:
+ if (ep->ops->post_deinit)
+ ep->ops->post_deinit(ep);

return ret;
}
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 0735ae9409240..a53ac27cd2447 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -475,6 +475,7 @@ struct dw_pcie_rp {

struct dw_pcie_ep_ops {
int (*pre_init)(struct dw_pcie_ep *ep);
+ void (*post_deinit)(struct dw_pcie_ep *ep);
int (*init)(struct dw_pcie_ep *ep);
int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no,
unsigned int type, u16 interrupt_num);
--
2.53.0