From e6085c860614bbf385553d762443cd3e23fd3140 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam Date: Mon, 14 Nov 2022 10:48:53 +0530 Subject: [PATCH] NVIDIA: SAUCE: PCI: designware-host: Update resource cleanup BugLink: https://bugs.launchpad.net/bugs/2072591 Config space is mapped on every host init, however, its free'ed only when corresponding device is unbinded. During hotplug, host init is called multiple times causing mapping issues. So map config space only if its not mapped previously. Similarly during deinit, bridge resources are not freed, release the same. http://nvbugs/3868928 Signed-off-by: Nagarjuna Kristam Reviewed-by: Manikanta Maddireddy Reviewed-by: Bitan Biswas Tested-by: Abhilash G Reviewed-by: Abhilash G Reviewed-by: Laxman Dewangan Signed-off-by: Laxman Dewangan Acked-by: Jacob Martin Acked-by: Noah Wager Signed-off-by: Noah Wager --- .../pci/controller/dwc/pcie-designware-host.c | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 9c643d7abd1b..0ea4c26bccec 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -415,9 +415,11 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) pp->cfg0_size = resource_size(res); pp->cfg0_base = res->start; - pp->va_cfg0_base = devm_pci_remap_cfg_resource(dev, res); - if (IS_ERR(pp->va_cfg0_base)) - return PTR_ERR(pp->va_cfg0_base); + if (!pp->va_cfg0_base) { + pp->va_cfg0_base = devm_pci_remap_cfg_resource(dev, res); + if (IS_ERR(pp->va_cfg0_base)) + return PTR_ERR(pp->va_cfg0_base); + } } else { dev_err(dev, "Missing *config* reg space\n"); return -ENODEV; @@ -533,6 +535,8 @@ EXPORT_SYMBOL_GPL(dw_pcie_host_init); void dw_pcie_host_deinit(struct dw_pcie_rp *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct device *dev = pci->dev; + struct resource_entry *win, *tmp; pci_stop_root_bus(pp->bridge->bus); pci_remove_root_bus(pp->bridge->bus); @@ -546,6 +550,21 @@ void dw_pcie_host_deinit(struct dw_pcie_rp *pp) if (pp->ops->deinit) pp->ops->deinit(pp); + + resource_list_for_each_entry_safe(win, tmp, &pp->bridge->windows) { + switch (resource_type(win->res)) { + case IORESOURCE_IO: + pci_unmap_iospace(win->res); + devm_release_resource(dev, win->res); + break; + case IORESOURCE_MEM: + devm_release_resource(dev, win->res); + break; + default: + continue; + } + } + pci_free_host_bridge(pp->bridge); } EXPORT_SYMBOL_GPL(dw_pcie_host_deinit);