PCI: Rework of_pci_get_host_bridge_resources() to devm_of_pci_get_host_bridge_resources()
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>
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 820fe05..d088c91 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -244,7 +244,8 @@
#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
@@ -253,8 +254,6 @@
* 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.
@@ -262,12 +261,11 @@
* 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;
@@ -278,7 +276,7 @@
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;
@@ -300,7 +298,7 @@
/* 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) {
@@ -322,15 +320,15 @@
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;
}
@@ -339,7 +337,7 @@
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",
@@ -352,15 +350,11 @@
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 */
/**
@@ -604,7 +598,7 @@
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;