From 8dea5accee8089d7d5168c3040ae245c06e25aa1 Mon Sep 17 00:00:00 2001 From: Baikal Electronics Date: Fri, 24 Jun 2022 17:39:40 +0300 Subject: [PATCH] PCI: dwc: Add dw_pcie_ops.host_deinit() callback 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 Signed-off-by: Bjorn Helgaas Reviewed-by: Manivannan Sadhasivam --- .../pci/controller/dwc/pcie-designware-host.c | 21 ++++++++++++++----- drivers/pci/controller/dwc/pcie-designware.h | 1 + 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 479ab6cadbac5..9127b1a57bc14 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -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); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index d247f227464c1..7f1c00fa084d6 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -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); }; -- 2.39.5