PCI: dwc: Add dw_pcie_ops.host_deinit() callback
authorSerge Semin <Sergey.Semin@baikalelectronics.ru>
Fri, 24 Jun 2022 14:39:40 +0000 (17:39 +0300)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 1 Aug 2022 20:07:34 +0000 (15:07 -0500)
dw_pcie_host_init() calls the dw_pcie_ops.host_init() callback to do
platform-specific host initialization.

Add a dw_pcie_ops.host_deinit() callback to perform the corresponding
cleanups in dw_pcie_host_deinit() and in dw_pcie_host_init() failure paths.

Link: https://lore.kernel.org/r/20220624143947.8991-9-Sergey.Semin@baikalelectronics.ru
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
drivers/pci/controller/dwc/pcie-designware-host.c
drivers/pci/controller/dwc/pcie-designware.h

index 479ab6c..9127b1a 100644 (file)
@@ -354,13 +354,14 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
                        pp->num_vectors = MSI_DEF_NUM_VECTORS;
                } else if (pp->num_vectors > MAX_MSI_IRQS) {
                        dev_err(dev, "Invalid number of vectors\n");
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto err_deinit_host;
                }
 
                if (pp->ops->msi_host_init) {
                        ret = pp->ops->msi_host_init(pp);
                        if (ret < 0)
-                               return ret;
+                               goto err_deinit_host;
                } else if (pp->has_msi_ctrl) {
                        u32 ctrl, num_ctrls;
 
@@ -372,8 +373,10 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
                                pp->msi_irq = platform_get_irq_byname_optional(pdev, "msi");
                                if (pp->msi_irq < 0) {
                                        pp->msi_irq = platform_get_irq(pdev, 0);
-                                       if (pp->msi_irq < 0)
-                                               return pp->msi_irq;
+                                       if (pp->msi_irq < 0) {
+                                               ret = pp->msi_irq;
+                                               goto err_deinit_host;
+                                       }
                                }
                        }
 
@@ -381,7 +384,7 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
 
                        ret = dw_pcie_allocate_domains(pp);
                        if (ret)
-                               return ret;
+                               goto err_deinit_host;
 
                        if (pp->msi_irq > 0)
                                irq_set_chained_handler_and_data(pp->msi_irq,
@@ -434,6 +437,11 @@ err_stop_link:
 err_free_msi:
        if (pp->has_msi_ctrl)
                dw_pcie_free_msi(pp);
+
+err_deinit_host:
+       if (pp->ops->host_deinit)
+               pp->ops->host_deinit(pp);
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(dw_pcie_host_init);
@@ -449,6 +457,9 @@ void dw_pcie_host_deinit(struct dw_pcie_rp *pp)
 
        if (pp->has_msi_ctrl)
                dw_pcie_free_msi(pp);
+
+       if (pp->ops->host_deinit)
+               pp->ops->host_deinit(pp);
 }
 EXPORT_SYMBOL_GPL(dw_pcie_host_deinit);
 
index d247f22..7f1c00f 100644 (file)
@@ -200,6 +200,7 @@ enum dw_pcie_device_mode {
 
 struct dw_pcie_host_ops {
        int (*host_init)(struct dw_pcie_rp *pp);
+       void (*host_deinit)(struct dw_pcie_rp *pp);
        int (*msi_host_init)(struct dw_pcie_rp *pp);
 };