device property: Introduce device_for_each_child_node_scoped()
authorJonathan Cameron <Jonathan.Cameron@huawei.com>
Sat, 17 Feb 2024 16:42:38 +0000 (16:42 +0000)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Mon, 25 Mar 2024 19:50:09 +0000 (19:50 +0000)
Similar to recently propose for_each_child_of_node_scoped() this
new version of the loop macro instantiates a new local
struct fwnode_handle * that uses the __free(fwnode_handle) auto
cleanup handling so that if a reference to a node is held on early
exit from the loop the reference will be released. If the loop
runs to completion, the child pointer will be NULL and no action will
be taken.

The reason this is useful is that it removes the need for
fwnode_handle_put() on early loop exits.  If there is a need
to retain the reference, then return_ptr(child) or no_free_ptr(child)
may be used to safely disable the auto cleanup.

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Link: https://lore.kernel.org/r/20240217164249.921878-5-jic23@kernel.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
include/linux/property.h

index 1322f0cce77a02acc9006cb63bfc697c8a693f31..61fc20e5f81f8da992aa021996ddf68ef3eff0ed 100644 (file)
@@ -175,6 +175,11 @@ struct fwnode_handle *device_get_next_child_node(const struct device *dev,
        for (child = device_get_next_child_node(dev, NULL); child;      \
             child = device_get_next_child_node(dev, child))
 
+#define device_for_each_child_node_scoped(dev, child)                  \
+       for (struct fwnode_handle *child __free(fwnode_handle) =        \
+               device_get_next_child_node(dev, NULL);                  \
+            child; child = device_get_next_child_node(dev, child))
+
 struct fwnode_handle *fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
                                                  const char *childname);
 struct fwnode_handle *device_get_named_child_node(const struct device *dev,