Add scoped versions of fwnode child node iterators that automatically
handle reference counting cleanup using the __free() attribute:
- fwnode_for_each_child_node_scoped()
- fwnode_for_each_named_child_node_scoped()
- fwnode_for_each_available_child_node_scoped()
These macros follow the same pattern as existing scoped iterators in the
kernel, ensuring fwnode references are automatically released when the
iterator variable goes out of scope. This prevents resource leaks and
eliminates the need for manual cleanup in error paths.
The implementation mirrors the non-scoped variants but uses
__free(fwnode_handle) for automatic resource management, providing a
safer and more convenient interface for drivers iterating over firmware
node children.
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
---
Notes:
checkpatch reports false positives that are intentionally ignored:
COMPLEX_MACRO, MACRO_ARG_REUSE, MACRO_ARG_PRECEDENCE
This is a standard iterator pattern following kernel conventions.
include/linux/property.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/include/linux/property.h b/include/linux/property.h
index 82f0cb3ab..279c244db 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -176,6 +176,20 @@ struct fwnode_handle *fwnode_get_next_available_child_node(
for (child = fwnode_get_next_available_child_node(fwnode, NULL); child;\
child = fwnode_get_next_available_child_node(fwnode, child))
+#define fwnode_for_each_child_node_scoped(fwnode, child) \
+ for (struct fwnode_handle *child __free(fwnode_handle) = \
+ fwnode_get_next_child_node(fwnode, NULL); \
+ child; child = fwnode_get_next_child_node(fwnode, child))
+
+#define fwnode_for_each_named_child_node_scoped(fwnode, child, name) \
+ fwnode_for_each_child_node_scoped(fwnode, child) \
+ for_each_if(fwnode_name_eq(child, name))
+
+#define fwnode_for_each_available_child_node_scoped(fwnode, child) \
+ for (struct fwnode_handle *child __free(fwnode_handle) = \
+ fwnode_get_next_available_child_node(fwnode, NULL); \
+ child; child = fwnode_get_next_available_child_node(fwnode, child))
+
struct fwnode_handle *device_get_next_child_node(const struct device *dev,
struct fwnode_handle *child);
--
2.43.0
On 9/1/25 6:36 PM, Jean-François Lessard wrote: > Add scoped versions of fwnode child node iterators that automatically > handle reference counting cleanup using the __free() attribute: > > - fwnode_for_each_child_node_scoped() > - fwnode_for_each_named_child_node_scoped() > - fwnode_for_each_available_child_node_scoped() > > These macros follow the same pattern as existing scoped iterators in the > kernel, ensuring fwnode references are automatically released when the > iterator variable goes out of scope. This prevents resource leaks and > eliminates the need for manual cleanup in error paths. > > The implementation mirrors the non-scoped variants but uses > __free(fwnode_handle) for automatic resource management, providing a > safer and more convenient interface for drivers iterating over firmware > node children. > > Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com> Thanks for adding a user and splitting it up (Andy was a bit faster than me :). > diff --git a/include/linux/property.h b/include/linux/property.h > index 82f0cb3ab..279c244db 100644 > --- a/include/linux/property.h > +++ b/include/linux/property.h > @@ -176,6 +176,20 @@ struct fwnode_handle *fwnode_get_next_available_child_node( > for (child = fwnode_get_next_available_child_node(fwnode, NULL); child;\ > child = fwnode_get_next_available_child_node(fwnode, child)) > > +#define fwnode_for_each_child_node_scoped(fwnode, child) \ > + for (struct fwnode_handle *child __free(fwnode_handle) = \ > + fwnode_get_next_child_node(fwnode, NULL); \ > + child; child = fwnode_get_next_child_node(fwnode, child)) > + > +#define fwnode_for_each_named_child_node_scoped(fwnode, child, name) \ > + fwnode_for_each_child_node_scoped(fwnode, child) \ > + for_each_if(fwnode_name_eq(child, name)) IIRC, your first patch mentioned that your driver series would only use fwnode_for_each_available_child_node_scoped(). And this series adds a user for fwnode_for_each_child_node_scoped(); do you also have a user for fwnode_for_each_named_child_node_scoped()?
Le 1 septembre 2025 13 h 48 min 14 s HAE, Danilo Krummrich <dakr@kernel.org> a écrit : >On 9/1/25 6:36 PM, Jean-François Lessard wrote: >> Add scoped versions of fwnode child node iterators that automatically >> handle reference counting cleanup using the __free() attribute: >> >> - fwnode_for_each_child_node_scoped() >> - fwnode_for_each_named_child_node_scoped() >> - fwnode_for_each_available_child_node_scoped() >> >> These macros follow the same pattern as existing scoped iterators in the >> kernel, ensuring fwnode references are automatically released when the >> iterator variable goes out of scope. This prevents resource leaks and >> eliminates the need for manual cleanup in error paths. >> >> The implementation mirrors the non-scoped variants but uses >> __free(fwnode_handle) for automatic resource management, providing a >> safer and more convenient interface for drivers iterating over firmware >> node children. >> >> Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com> > >Thanks for adding a user and splitting it up (Andy was a bit faster than me :). > Very welcome! Thanks for reviewing. >> diff --git a/include/linux/property.h b/include/linux/property.h >> index 82f0cb3ab..279c244db 100644 >> --- a/include/linux/property.h >> +++ b/include/linux/property.h >> @@ -176,6 +176,20 @@ struct fwnode_handle *fwnode_get_next_available_child_node( >> for (child = fwnode_get_next_available_child_node(fwnode, NULL); child;\ >> child = fwnode_get_next_available_child_node(fwnode, child)) >> +#define fwnode_for_each_child_node_scoped(fwnode, child) \ >> + for (struct fwnode_handle *child __free(fwnode_handle) = \ >> + fwnode_get_next_child_node(fwnode, NULL); \ >> + child; child = fwnode_get_next_child_node(fwnode, child)) >> + >> +#define fwnode_for_each_named_child_node_scoped(fwnode, child, name) \ >> + fwnode_for_each_child_node_scoped(fwnode, child) \ >> + for_each_if(fwnode_name_eq(child, name)) > >IIRC, your first patch mentioned that your driver series would only use >fwnode_for_each_available_child_node_scoped(). You are correct. Next version of TM16XX driver patch series will use fwnode_for_each_available_child_node_scoped() > >And this series adds a user for fwnode_for_each_child_node_scoped(); do you also have a user for fwnode_for_each_named_child_node_scoped()? No, I haven't found an existing user that requires the scoped version. The only usage I found of the non-scoped fwnode_for_each_named_child_node() is in drivers/base/property.c in fwnode_get_named_child_node_count(), which doesn't need to put the fwnode. I included it for consistency since the header defines all three non-scoped variants, but I understand the "no dead code" policy concern. Would you prefer I drop the fwnode_for_each_named_child_node_scoped() variant and submit a v4 with only the two variants that have real users? Regards, Jean-François Lessard
On Mon, Sep 01, 2025 at 02:16:35PM -0400, Jean-François Lessard wrote: > Le 1 septembre 2025 13 h 48 min 14 s HAE, Danilo Krummrich <dakr@kernel.org> a écrit : > >On 9/1/25 6:36 PM, Jean-François Lessard wrote: > >> Add scoped versions of fwnode child node iterators that automatically > >> handle reference counting cleanup using the __free() attribute: > >> > >> - fwnode_for_each_child_node_scoped() > >> - fwnode_for_each_named_child_node_scoped() > >> - fwnode_for_each_available_child_node_scoped() > >> > >> These macros follow the same pattern as existing scoped iterators in the > >> kernel, ensuring fwnode references are automatically released when the > >> iterator variable goes out of scope. This prevents resource leaks and > >> eliminates the need for manual cleanup in error paths. > >> > >> The implementation mirrors the non-scoped variants but uses > >> __free(fwnode_handle) for automatic resource management, providing a > >> safer and more convenient interface for drivers iterating over firmware > >> node children. > >> > >> Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com> > > > >Thanks for adding a user and splitting it up (Andy was a bit faster than me :). > > > > Very welcome! Thanks for reviewing. > > >> diff --git a/include/linux/property.h b/include/linux/property.h > >> index 82f0cb3ab..279c244db 100644 > >> --- a/include/linux/property.h > >> +++ b/include/linux/property.h > >> @@ -176,6 +176,20 @@ struct fwnode_handle *fwnode_get_next_available_child_node( > >> for (child = fwnode_get_next_available_child_node(fwnode, NULL); child;\ > >> child = fwnode_get_next_available_child_node(fwnode, child)) > >> +#define fwnode_for_each_child_node_scoped(fwnode, child) \ > >> + for (struct fwnode_handle *child __free(fwnode_handle) = \ > >> + fwnode_get_next_child_node(fwnode, NULL); \ > >> + child; child = fwnode_get_next_child_node(fwnode, child)) > >> + > >> +#define fwnode_for_each_named_child_node_scoped(fwnode, child, name) \ > >> + fwnode_for_each_child_node_scoped(fwnode, child) \ > >> + for_each_if(fwnode_name_eq(child, name)) > > > >IIRC, your first patch mentioned that your driver series would only use > >fwnode_for_each_available_child_node_scoped(). > > You are correct. Next version of TM16XX driver patch series will use > fwnode_for_each_available_child_node_scoped() > > > > >And this series adds a user for fwnode_for_each_child_node_scoped(); do you also have a user for fwnode_for_each_named_child_node_scoped()? > > No, I haven't found an existing user that requires the scoped version. The only > usage I found of the non-scoped fwnode_for_each_named_child_node() is in > drivers/base/property.c in fwnode_get_named_child_node_count(), which doesn't > need to put the fwnode. > > I included it for consistency since the header defines all three non-scoped > variants, but I understand the "no dead code" policy concern. > > Would you prefer I drop the fwnode_for_each_named_child_node_scoped() > variant and submit a v4 with only the two variants that have real users? Yes please.
Le 2 septembre 2025 00 h 50 min 08 s HAE, Greg Kroah-Hartman <gregkh@linuxfoundation.org> a écrit : >On Mon, Sep 01, 2025 at 02:16:35PM -0400, Jean-François Lessard wrote: >> Le 1 septembre 2025 13 h 48 min 14 s HAE, Danilo Krummrich <dakr@kernel.org> a écrit : >> >On 9/1/25 6:36 PM, Jean-François Lessard wrote: >> >> Add scoped versions of fwnode child node iterators that automatically >> >> handle reference counting cleanup using the __free() attribute: >> >> >> >> - fwnode_for_each_child_node_scoped() >> >> - fwnode_for_each_named_child_node_scoped() >> >> - fwnode_for_each_available_child_node_scoped() >> >> >> >> These macros follow the same pattern as existing scoped iterators in the >> >> kernel, ensuring fwnode references are automatically released when the >> >> iterator variable goes out of scope. This prevents resource leaks and >> >> eliminates the need for manual cleanup in error paths. >> >> >> >> The implementation mirrors the non-scoped variants but uses >> >> __free(fwnode_handle) for automatic resource management, providing a >> >> safer and more convenient interface for drivers iterating over firmware >> >> node children. >> >> >> >> Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com> >> > >> >Thanks for adding a user and splitting it up (Andy was a bit faster than me :). >> > >> >> Very welcome! Thanks for reviewing. >> >> >> diff --git a/include/linux/property.h b/include/linux/property.h >> >> index 82f0cb3ab..279c244db 100644 >> >> --- a/include/linux/property.h >> >> +++ b/include/linux/property.h >> >> @@ -176,6 +176,20 @@ struct fwnode_handle *fwnode_get_next_available_child_node( >> >> for (child = fwnode_get_next_available_child_node(fwnode, NULL); child;\ >> >> child = fwnode_get_next_available_child_node(fwnode, child)) >> >> +#define fwnode_for_each_child_node_scoped(fwnode, child) \ >> >> + for (struct fwnode_handle *child __free(fwnode_handle) = \ >> >> + fwnode_get_next_child_node(fwnode, NULL); \ >> >> + child; child = fwnode_get_next_child_node(fwnode, child)) >> >> + >> >> +#define fwnode_for_each_named_child_node_scoped(fwnode, child, name) \ >> >> + fwnode_for_each_child_node_scoped(fwnode, child) \ >> >> + for_each_if(fwnode_name_eq(child, name)) >> > >> >IIRC, your first patch mentioned that your driver series would only use >> >fwnode_for_each_available_child_node_scoped(). >> >> You are correct. Next version of TM16XX driver patch series will use >> fwnode_for_each_available_child_node_scoped() >> >> > >> >And this series adds a user for fwnode_for_each_child_node_scoped(); do you also have a user for fwnode_for_each_named_child_node_scoped()? >> >> No, I haven't found an existing user that requires the scoped version. The only >> usage I found of the non-scoped fwnode_for_each_named_child_node() is in >> drivers/base/property.c in fwnode_get_named_child_node_count(), which doesn't >> need to put the fwnode. >> >> I included it for consistency since the header defines all three non-scoped >> variants, but I understand the "no dead code" policy concern. >> >> Would you prefer I drop the fwnode_for_each_named_child_node_scoped() >> variant and submit a v4 with only the two variants that have real users? > >Yes please. Understood. I will do so.
© 2016 - 2025 Red Hat, Inc.