[PATCH v3 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]>
If .pre_init() succeeds but subsequent initialization 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.

Reviewed-by: Koichiro Den <[email protected]>
Tested-by: Koichiro Den <[email protected]>
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
V3: - Update commit message slightly
    - Add RB/TB from Den-san
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.