[PATCH v2 1/2] PCI: dwc: Add .post_deinit counterpart to endpoint .pre_init callback
Marek Vasut <[email protected]>
| Newsgroups | org.kernel.vger.linux-renesas-soc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- Cc: "Krzysztof Wilczyński" <[email protected]> Cc: Bjorn Helgaas <[email protected]> Cc: Geert Uytterhoeven <[email protected]> Cc: Koichiro Den <[email protected]> Cc: Lorenzo Pieralisi <[email protected]> Cc: Magnus Damm <[email protected]> Cc: Manivannan Sadhasivam <[email protected]> Cc: Rob Herring <[email protected]> Cc: Yoshihiro Shimoda <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] --- 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