Blob Blame History Raw
From: Jan Kiszka <jan.kiszka@siemens.com>
Date: Tue, 15 May 2018 11:07:05 +0200
Subject: PCI: Rework of_pci_get_host_bridge_resources() to
 devm_of_pci_get_host_bridge_resources()

Git-commit: 5bd51b35c7cbbc98786282ada940429a33b52e17
Patch-mainline: v4.18-rc1
References: fate#326572

of_pci_get_host_bridge_resources() allocates the resource structures it
fills dynamically, but none of its callers care to release them so far.
Rather than requiring everyone to do this explicitly, convert the existing
function to a managed version.

Tested-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Acked-by: Joao Pinto <jpinto@synopsys.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
CC: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
---
 drivers/pci/dwc/pcie-designware-host.c |    2 +-
 drivers/pci/host/pci-aardvark.c        |    2 +-
 drivers/pci/host/pci-ftpci100.c        |    2 +-
 drivers/pci/host/pci-versatile.c       |    2 +-
 drivers/pci/host/pci-xgene.c           |    2 +-
 drivers/pci/host/pcie-altera.c         |    2 +-
 drivers/pci/host/pcie-iproc-platform.c |    2 +-
 drivers/pci/host/pcie-rcar.c           |    2 +-
 drivers/pci/host/pcie-rockchip.c       |    2 +-
 drivers/pci/host/pcie-xilinx-nwl.c     |    2 +-
 drivers/pci/host/pcie-xilinx.c         |    2 +-
 drivers/pci/of.c                       |   30 ++++++++++++------------------
 include/linux/of_pci.h                 |    4 ++--
 13 files changed, 25 insertions(+), 31 deletions(-)

--- a/drivers/pci/dwc/pcie-designware-host.c
+++ b/drivers/pci/dwc/pcie-designware-host.c
@@ -308,7 +308,7 @@ int dw_pcie_host_init(struct pcie_port *
 	if (!bridge)
 		return -ENOMEM;
 
-	ret = of_pci_get_host_bridge_resources(dev, 0, 0xff,
+	ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
 					&bridge->windows, &pp->io_base);
 	if (ret)
 		return ret;
--- a/drivers/pci/host/pci-aardvark.c
+++ b/drivers/pci/host/pci-aardvark.c
@@ -830,7 +830,7 @@ static int advk_pcie_parse_request_of_pc
 
 	INIT_LIST_HEAD(&pcie->resources);
 
-	err = of_pci_get_host_bridge_resources(dev, 0, 0xff,
+	err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
 						    &pcie->resources, &iobase);
 	if (err)
 		return err;
--- a/drivers/pci/host/pci-ftpci100.c
+++ b/drivers/pci/host/pci-ftpci100.c
@@ -467,7 +467,7 @@ static int faraday_pci_probe(struct plat
 	if (IS_ERR(p->base))
 		return PTR_ERR(p->base);
 
-	ret = of_pci_get_host_bridge_resources(dev, 0, 0xff,
+	ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
 						    &res, &io_base);
 	if (ret)
 		return ret;
--- a/drivers/pci/host/pci-versatile.c
+++ b/drivers/pci/host/pci-versatile.c
@@ -75,7 +75,7 @@ static int versatile_pci_parse_request_o
 	resource_size_t iobase;
 	struct resource_entry *win, *tmp;
 
-	err = of_pci_get_host_bridge_resources(dev, 0, 0xff, res, &iobase);
+	err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, res, &iobase);
 	if (err)
 		return err;
 
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -661,7 +661,7 @@ static int xgene_pcie_probe_bridge(struc
 	if (ret)
 		return ret;
 
-	ret = of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
+	ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
 						    &iobase);
 	if (ret)
 		return ret;
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -501,7 +501,7 @@ static int altera_pcie_parse_request_of_
 	struct device *dev = &pcie->pdev->dev;
 	struct resource_entry *win;
 
-	err = of_pci_get_host_bridge_resources(dev, 0, 0xff,
+	err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
 						    &pcie->resources, NULL);
 	if (err)
 		return err;
--- a/drivers/pci/host/pcie-iproc-platform.c
+++ b/drivers/pci/host/pcie-iproc-platform.c
@@ -107,7 +107,7 @@ static int iproc_pcie_pltfm_probe(struct
 		pcie->phy = NULL;
 	}
 
-	ret = of_pci_get_host_bridge_resources(dev, 0, 0xff, &resources,
+	ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &resources,
 						    &iobase);
 	if (ret) {
 		dev_err(dev, "unable to get PCI host bridge resources\n");
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -1091,7 +1091,7 @@ static int rcar_pcie_parse_request_of_pc
 	resource_size_t iobase;
 	struct resource_entry *win, *tmp;
 
-	err = of_pci_get_host_bridge_resources(dev, 0, 0xff,
+	err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
 						    &pci->resources, &iobase);
 	if (err)
 		return err;
--- a/drivers/pci/host/pcie-rockchip.c
+++ b/drivers/pci/host/pcie-rockchip.c
@@ -1399,7 +1399,7 @@ static int rockchip_pcie_probe(struct pl
 	if (err < 0)
 		goto err_vpcie;
 
-	err = of_pci_get_host_bridge_resources(dev, 0, 0xff,
+	err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
 						    &res, &io_base);
 	if (err)
 		goto err_vpcie;
--- a/drivers/pci/host/pcie-xilinx-nwl.c
+++ b/drivers/pci/host/pcie-xilinx-nwl.c
@@ -815,7 +815,7 @@ static int nwl_pcie_probe(struct platfor
 		return err;
 	}
 
-	err = of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
+	err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
 						    &iobase);
 	if (err) {
 		dev_err(dev, "Getting bridge resources failed\n");
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
@@ -664,7 +664,7 @@ static int xilinx_pcie_probe(struct plat
 		return err;
 	}
 
-	err = of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
+	err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
 						    &iobase);
 	if (err) {
 		dev_err(dev, "Getting bridge resources failed\n");
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -101,7 +101,7 @@ int pci_parse_request_of_pci_ranges(stru
 	struct resource_entry *win, *tmp;
 
 	INIT_LIST_HEAD(resources);
-	err = of_pci_get_host_bridge_resources(dev, 0, 0xff, resources,
+	err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, resources,
 						    &iobase);
 	if (err)
 		return err;
@@ -299,7 +299,8 @@ EXPORT_SYMBOL_GPL(of_pci_check_probe_onl
 
 #if defined(CONFIG_OF_ADDRESS)
 /**
- * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
+ * devm_of_pci_get_host_bridge_resources() - Resource-managed parsing of PCI
+ *                                           host bridge resources from DT
  * @dev: host bridge device
  * @busno: bus number associated with the bridge root bus
  * @bus_max: maximum number of buses for this bridge
@@ -308,8 +309,6 @@ EXPORT_SYMBOL_GPL(of_pci_check_probe_onl
  * address for the start of the I/O range. Can be NULL if the caller doesn't
  * expect I/O ranges to be present in the device tree.
  *
- * It is the caller's job to free the @resources list.
- *
  * This function will parse the "ranges" property of a PCI host bridge device
  * node and setup the resource mapping based on its content. It is expected
  * that the property conforms with the Power ePAPR document.
@@ -317,12 +316,11 @@ EXPORT_SYMBOL_GPL(of_pci_check_probe_onl
  * It returns zero if the range parsing has been successful or a standard error
  * value if it failed.
  */
-int of_pci_get_host_bridge_resources(struct device *dev,
+int devm_of_pci_get_host_bridge_resources(struct device *dev,
 			unsigned char busno, unsigned char bus_max,
 			struct list_head *resources, resource_size_t *io_base)
 {
 	struct device_node *dev_node = dev->of_node;
-	struct resource_entry *window;
 	struct resource *res;
 	struct resource *bus_range;
 	struct of_pci_range range;
@@ -333,7 +331,7 @@ int of_pci_get_host_bridge_resources(str
 	if (io_base)
 		*io_base = (resource_size_t)OF_BAD_ADDR;
 
-	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
+	bus_range = devm_kzalloc(dev, sizeof(*bus_range), GFP_KERNEL);
 	if (!bus_range)
 		return -ENOMEM;
 
@@ -355,7 +353,7 @@ int of_pci_get_host_bridge_resources(str
 	/* Check for ranges property */
 	err = of_pci_range_parser_init(&parser, dev_node);
 	if (err)
-		goto parse_failed;
+		goto failed;
 
 	dev_dbg(dev, "Parsing ranges property...\n");
 	for_each_of_pci_range(&parser, &range) {
@@ -377,15 +375,15 @@ int of_pci_get_host_bridge_resources(str
 		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
 			continue;
 
-		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+		res = devm_kzalloc(dev, sizeof(struct resource), GFP_KERNEL);
 		if (!res) {
 			err = -ENOMEM;
-			goto parse_failed;
+			goto failed;
 		}
 
 		err = of_pci_range_to_resource(&range, dev_node, res);
 		if (err) {
-			kfree(res);
+			devm_kfree(dev, res);
 			continue;
 		}
 
@@ -394,7 +392,7 @@ int of_pci_get_host_bridge_resources(str
 				dev_err(dev, "I/O range found for %pOF. Please provide an io_base pointer to save CPU base address\n",
 					dev_node);
 				err = -EINVAL;
-				goto conversion_failed;
+				goto failed;
 			}
 			if (*io_base != (resource_size_t)OF_BAD_ADDR)
 				dev_warn(dev, "More than one I/O resource converted for %pOF. CPU base address for old range lost!\n",
@@ -407,15 +405,11 @@ int of_pci_get_host_bridge_resources(str
 
 	return 0;
 
-conversion_failed:
-	kfree(res);
-parse_failed:
-	resource_list_for_each_entry(window, resources)
-		kfree(window->res);
+failed:
 	pci_free_resource_list(resources);
 	return err;
 }
-EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
+EXPORT_SYMBOL_GPL(devm_of_pci_get_host_bridge_resources);
 #endif /* CONFIG_OF_ADDRESS */
 
 /**
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -76,11 +76,11 @@ of_irq_parse_and_map_pci(const struct pc
 #endif
 
 #if defined(CONFIG_OF_ADDRESS)
-int of_pci_get_host_bridge_resources(struct device *dev,
+int devm_of_pci_get_host_bridge_resources(struct device *dev,
 			unsigned char busno, unsigned char bus_max,
 			struct list_head *resources, resource_size_t *io_base);
 #else
-static inline int of_pci_get_host_bridge_resources(struct device *dev,
+static inline int devm_of_pci_get_host_bridge_resources(struct device *dev,
 			unsigned char busno, unsigned char bus_max,
 			struct list_head *resources, resource_size_t *io_base)
 {