Commit a5737b21 authored by Rob Herring's avatar Rob Herring

of: Use scope based of_node_put() cleanups

Use the relatively new scope based of_node_put() cleanup to simplify
function exit handling. Doing so reduces the chances of forgetting an
of_node_put() and simplifies error paths by avoiding the need for goto
statements.
Reviewed-by: default avatarSaravana Kannan <saravanak@google.com>
Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Link: https://lore.kernel.org/r/20240409-dt-cleanup-free-v2-3-5b419a4af38d@kernel.orgSigned-off-by: default avatarRob Herring <robh@kernel.org>
parent 40b0f174
...@@ -486,34 +486,30 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, ...@@ -486,34 +486,30 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
* device that had registered logical PIO mapping, and the return code is * device that had registered logical PIO mapping, and the return code is
* relative to that node. * relative to that node.
*/ */
static u64 __of_translate_address(struct device_node *dev, static u64 __of_translate_address(struct device_node *node,
struct device_node *(*get_parent)(const struct device_node *), struct device_node *(*get_parent)(const struct device_node *),
const __be32 *in_addr, const char *rprop, const __be32 *in_addr, const char *rprop,
struct device_node **host) struct device_node **host)
{ {
struct device_node *parent = NULL; struct device_node *dev __free(device_node) = of_node_get(node);
struct device_node *parent __free(device_node) = get_parent(dev);
struct of_bus *bus, *pbus; struct of_bus *bus, *pbus;
__be32 addr[OF_MAX_ADDR_CELLS]; __be32 addr[OF_MAX_ADDR_CELLS];
int na, ns, pna, pns; int na, ns, pna, pns;
u64 result = OF_BAD_ADDR;
pr_debug("** translation for device %pOF **\n", dev); pr_debug("** translation for device %pOF **\n", dev);
/* Increase refcount at current level */
of_node_get(dev);
*host = NULL; *host = NULL;
/* Get parent & match bus type */
parent = get_parent(dev);
if (parent == NULL) if (parent == NULL)
goto bail; return OF_BAD_ADDR;
bus = of_match_bus(parent); bus = of_match_bus(parent);
/* Count address cells & copy address locally */ /* Count address cells & copy address locally */
bus->count_cells(dev, &na, &ns); bus->count_cells(dev, &na, &ns);
if (!OF_CHECK_COUNTS(na, ns)) { if (!OF_CHECK_COUNTS(na, ns)) {
pr_debug("Bad cell count for %pOF\n", dev); pr_debug("Bad cell count for %pOF\n", dev);
goto bail; return OF_BAD_ADDR;
} }
memcpy(addr, in_addr, na * 4); memcpy(addr, in_addr, na * 4);
...@@ -533,8 +529,7 @@ static u64 __of_translate_address(struct device_node *dev, ...@@ -533,8 +529,7 @@ static u64 __of_translate_address(struct device_node *dev,
/* If root, we have finished */ /* If root, we have finished */
if (parent == NULL) { if (parent == NULL) {
pr_debug("reached root node\n"); pr_debug("reached root node\n");
result = of_read_number(addr, na); return of_read_number(addr, na);
break;
} }
/* /*
...@@ -543,11 +538,11 @@ static u64 __of_translate_address(struct device_node *dev, ...@@ -543,11 +538,11 @@ static u64 __of_translate_address(struct device_node *dev,
*/ */
iorange = find_io_range_by_fwnode(&dev->fwnode); iorange = find_io_range_by_fwnode(&dev->fwnode);
if (iorange && (iorange->flags != LOGIC_PIO_CPU_MMIO)) { if (iorange && (iorange->flags != LOGIC_PIO_CPU_MMIO)) {
result = of_read_number(addr + 1, na - 1); u64 result = of_read_number(addr + 1, na - 1);
pr_debug("indirectIO matched(%pOF) 0x%llx\n", pr_debug("indirectIO matched(%pOF) 0x%llx\n",
dev, result); dev, result);
*host = of_node_get(dev); *host = no_free_ptr(dev);
break; return result;
} }
/* Get new parent bus and counts */ /* Get new parent bus and counts */
...@@ -555,7 +550,7 @@ static u64 __of_translate_address(struct device_node *dev, ...@@ -555,7 +550,7 @@ static u64 __of_translate_address(struct device_node *dev,
pbus->count_cells(dev, &pna, &pns); pbus->count_cells(dev, &pna, &pns);
if (!OF_CHECK_COUNTS(pna, pns)) { if (!OF_CHECK_COUNTS(pna, pns)) {
pr_err("Bad cell count for %pOF\n", dev); pr_err("Bad cell count for %pOF\n", dev);
break; return OF_BAD_ADDR;
} }
pr_debug("parent bus is %s (na=%d, ns=%d) on %pOF\n", pr_debug("parent bus is %s (na=%d, ns=%d) on %pOF\n",
...@@ -563,7 +558,7 @@ static u64 __of_translate_address(struct device_node *dev, ...@@ -563,7 +558,7 @@ static u64 __of_translate_address(struct device_node *dev,
/* Apply bus translation */ /* Apply bus translation */
if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
break; return OF_BAD_ADDR;
/* Complete the move up one level */ /* Complete the move up one level */
na = pna; na = pna;
...@@ -572,11 +567,8 @@ static u64 __of_translate_address(struct device_node *dev, ...@@ -572,11 +567,8 @@ static u64 __of_translate_address(struct device_node *dev,
of_dump_addr("one level translation:", addr, na); of_dump_addr("one level translation:", addr, na);
} }
bail:
of_node_put(parent);
of_node_put(dev);
return result; unreachable();
} }
u64 of_translate_address(struct device_node *dev, const __be32 *in_addr) u64 of_translate_address(struct device_node *dev, const __be32 *in_addr)
...@@ -654,19 +646,16 @@ EXPORT_SYMBOL(of_translate_dma_address); ...@@ -654,19 +646,16 @@ EXPORT_SYMBOL(of_translate_dma_address);
const __be32 *of_translate_dma_region(struct device_node *dev, const __be32 *prop, const __be32 *of_translate_dma_region(struct device_node *dev, const __be32 *prop,
phys_addr_t *start, size_t *length) phys_addr_t *start, size_t *length)
{ {
struct device_node *parent; struct device_node *parent __free(device_node) = __of_get_dma_parent(dev);
u64 address, size; u64 address, size;
int na, ns; int na, ns;
parent = __of_get_dma_parent(dev);
if (!parent) if (!parent)
return NULL; return NULL;
na = of_bus_n_addr_cells(parent); na = of_bus_n_addr_cells(parent);
ns = of_bus_n_size_cells(parent); ns = of_bus_n_size_cells(parent);
of_node_put(parent);
address = of_translate_dma_address(dev, prop); address = of_translate_dma_address(dev, prop);
if (address == OF_BAD_ADDR) if (address == OF_BAD_ADDR)
return NULL; return NULL;
...@@ -688,21 +677,19 @@ const __be32 *__of_get_address(struct device_node *dev, int index, int bar_no, ...@@ -688,21 +677,19 @@ const __be32 *__of_get_address(struct device_node *dev, int index, int bar_no,
{ {
const __be32 *prop; const __be32 *prop;
unsigned int psize; unsigned int psize;
struct device_node *parent; struct device_node *parent __free(device_node) = of_get_parent(dev);
struct of_bus *bus; struct of_bus *bus;
int onesize, i, na, ns; int onesize, i, na, ns;
/* Get parent & match bus type */
parent = of_get_parent(dev);
if (parent == NULL) if (parent == NULL)
return NULL; return NULL;
/* match the parent's bus type */
bus = of_match_bus(parent); bus = of_match_bus(parent);
if (strcmp(bus->name, "pci") && (bar_no >= 0)) { if (strcmp(bus->name, "pci") && (bar_no >= 0))
of_node_put(parent);
return NULL; return NULL;
}
bus->count_cells(dev, &na, &ns); bus->count_cells(dev, &na, &ns);
of_node_put(parent);
if (!OF_CHECK_ADDR_COUNT(na)) if (!OF_CHECK_ADDR_COUNT(na))
return NULL; return NULL;
...@@ -888,14 +875,13 @@ static u64 of_translate_ioport(struct device_node *dev, const __be32 *in_addr, ...@@ -888,14 +875,13 @@ static u64 of_translate_ioport(struct device_node *dev, const __be32 *in_addr,
*/ */
int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
{ {
struct device_node *node = of_node_get(np); struct device_node *node __free(device_node) = of_node_get(np);
const __be32 *ranges = NULL; const __be32 *ranges = NULL;
bool found_dma_ranges = false; bool found_dma_ranges = false;
struct of_range_parser parser; struct of_range_parser parser;
struct of_range range; struct of_range range;
struct bus_dma_region *r; struct bus_dma_region *r;
int len, num_ranges = 0; int len, num_ranges = 0;
int ret = 0;
while (node) { while (node) {
ranges = of_get_property(node, "dma-ranges", &len); ranges = of_get_property(node, "dma-ranges", &len);
...@@ -905,10 +891,9 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) ...@@ -905,10 +891,9 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
break; break;
/* Once we find 'dma-ranges', then a missing one is an error */ /* Once we find 'dma-ranges', then a missing one is an error */
if (found_dma_ranges && !ranges) { if (found_dma_ranges && !ranges)
ret = -ENODEV; return -ENODEV;
goto out;
}
found_dma_ranges = true; found_dma_ranges = true;
node = of_get_next_dma_parent(node); node = of_get_next_dma_parent(node);
...@@ -916,10 +901,8 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) ...@@ -916,10 +901,8 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
if (!node || !ranges) { if (!node || !ranges) {
pr_debug("no dma-ranges found for node(%pOF)\n", np); pr_debug("no dma-ranges found for node(%pOF)\n", np);
ret = -ENODEV; return -ENODEV;
goto out;
} }
of_dma_range_parser_init(&parser, node); of_dma_range_parser_init(&parser, node);
for_each_of_range(&parser, &range) { for_each_of_range(&parser, &range) {
if (range.cpu_addr == OF_BAD_ADDR) { if (range.cpu_addr == OF_BAD_ADDR) {
...@@ -930,16 +913,12 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) ...@@ -930,16 +913,12 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
num_ranges++; num_ranges++;
} }
if (!num_ranges) { if (!num_ranges)
ret = -EINVAL; return -EINVAL;
goto out;
}
r = kcalloc(num_ranges + 1, sizeof(*r), GFP_KERNEL); r = kcalloc(num_ranges + 1, sizeof(*r), GFP_KERNEL);
if (!r) { if (!r)
ret = -ENOMEM; return -ENOMEM;
goto out;
}
/* /*
* Record all info in the generic DMA ranges array for struct device, * Record all info in the generic DMA ranges array for struct device,
...@@ -957,9 +936,7 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) ...@@ -957,9 +936,7 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
r->size = range.size; r->size = range.size;
r++; r++;
} }
out: return 0;
of_node_put(node);
return ret;
} }
#endif /* CONFIG_HAS_DMA */ #endif /* CONFIG_HAS_DMA */
...@@ -1016,24 +993,18 @@ phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np) ...@@ -1016,24 +993,18 @@ phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np)
*/ */
bool of_dma_is_coherent(struct device_node *np) bool of_dma_is_coherent(struct device_node *np)
{ {
struct device_node *node; struct device_node *node __free(device_node) = of_node_get(np);
bool is_coherent = dma_default_coherent;
node = of_node_get(np);
while (node) { while (node) {
if (of_property_read_bool(node, "dma-coherent")) { if (of_property_read_bool(node, "dma-coherent"))
is_coherent = true; return true;
break;
} if (of_property_read_bool(node, "dma-noncoherent"))
if (of_property_read_bool(node, "dma-noncoherent")) { return false;
is_coherent = false;
break;
}
node = of_get_next_dma_parent(node); node = of_get_next_dma_parent(node);
} }
of_node_put(node); return dma_default_coherent;
return is_coherent;
} }
EXPORT_SYMBOL_GPL(of_dma_is_coherent); EXPORT_SYMBOL_GPL(of_dma_is_coherent);
...@@ -1049,20 +1020,14 @@ EXPORT_SYMBOL_GPL(of_dma_is_coherent); ...@@ -1049,20 +1020,14 @@ EXPORT_SYMBOL_GPL(of_dma_is_coherent);
*/ */
static bool of_mmio_is_nonposted(struct device_node *np) static bool of_mmio_is_nonposted(struct device_node *np)
{ {
struct device_node *parent;
bool nonposted;
if (!IS_ENABLED(CONFIG_ARCH_APPLE)) if (!IS_ENABLED(CONFIG_ARCH_APPLE))
return false; return false;
parent = of_get_parent(np); struct device_node *parent __free(device_node) = of_get_parent(np);
if (!parent) if (!parent)
return false; return false;
nonposted = of_property_read_bool(parent, "nonposted-mmio"); return of_property_read_bool(parent, "nonposted-mmio");
of_node_put(parent);
return nonposted;
} }
static int __of_address_to_resource(struct device_node *dev, int index, int bar_no, static int __of_address_to_resource(struct device_node *dev, int index, int bar_no,
......
...@@ -40,15 +40,12 @@ ...@@ -40,15 +40,12 @@
*/ */
bool of_graph_is_present(const struct device_node *node) bool of_graph_is_present(const struct device_node *node)
{ {
struct device_node *ports, *port; struct device_node *ports __free(device_node) = of_get_child_by_name(node, "ports");
ports = of_get_child_by_name(node, "ports");
if (ports) if (ports)
node = ports; node = ports;
port = of_get_child_by_name(node, "port"); struct device_node *port __free(device_node) = of_get_child_by_name(node, "port");
of_node_put(ports);
of_node_put(port);
return !!port; return !!port;
} }
...@@ -610,25 +607,22 @@ EXPORT_SYMBOL(of_graph_parse_endpoint); ...@@ -610,25 +607,22 @@ EXPORT_SYMBOL(of_graph_parse_endpoint);
*/ */
struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id) struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)
{ {
struct device_node *node, *port; struct device_node *node __free(device_node) = of_get_child_by_name(parent, "ports");
node = of_get_child_by_name(parent, "ports");
if (node) if (node)
parent = node; parent = node;
for_each_child_of_node(parent, port) { for_each_child_of_node_scoped(parent, port) {
u32 port_id = 0; u32 port_id = 0;
if (!of_node_name_eq(port, "port")) if (!of_node_name_eq(port, "port"))
continue; continue;
of_property_read_u32(port, "reg", &port_id); of_property_read_u32(port, "reg", &port_id);
if (id == port_id) if (id == port_id)
break; return_ptr(port);
} }
of_node_put(node); return NULL;
return port;
} }
EXPORT_SYMBOL(of_graph_get_port_by_id); EXPORT_SYMBOL(of_graph_get_port_by_id);
...@@ -655,15 +649,13 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, ...@@ -655,15 +649,13 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
* parent port node. * parent port node.
*/ */
if (!prev) { if (!prev) {
struct device_node *node; struct device_node *node __free(device_node) =
of_get_child_by_name(parent, "ports");
node = of_get_child_by_name(parent, "ports");
if (node) if (node)
parent = node; parent = node;
port = of_get_child_by_name(parent, "port"); port = of_get_child_by_name(parent, "port");
of_node_put(node);
if (!port) { if (!port) {
pr_debug("graph: no port node found in %pOF\n", parent); pr_debug("graph: no port node found in %pOF\n", parent);
return NULL; return NULL;
...@@ -1052,15 +1044,13 @@ static int of_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, ...@@ -1052,15 +1044,13 @@ static int of_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
struct fwnode_endpoint *endpoint) struct fwnode_endpoint *endpoint)
{ {
const struct device_node *node = to_of_node(fwnode); const struct device_node *node = to_of_node(fwnode);
struct device_node *port_node = of_get_parent(node); struct device_node *port_node __free(device_node) = of_get_parent(node);
endpoint->local_fwnode = fwnode; endpoint->local_fwnode = fwnode;
of_property_read_u32(port_node, "reg", &endpoint->port); of_property_read_u32(port_node, "reg", &endpoint->port);
of_property_read_u32(node, "reg", &endpoint->id); of_property_read_u32(node, "reg", &endpoint->id);
of_node_put(port_node);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment