File tree Expand file tree Collapse file tree 5 files changed +101
-0
lines changed
Expand file tree Collapse file tree 5 files changed +101
-0
lines changed Original file line number Diff line number Diff line change @@ -104,6 +104,9 @@ does not apply to macros which take cell names as arguments.
104104For-each macros
105105===============
106106
107+ The :c:macro: `DT_FOREACH_CHILD ` macro allows iterating over the ancestor node
108+ of a devicetree node.
109+
107110There is currently only one "generic" for-each macro,
108111:c:func: `DT_FOREACH_CHILD `, which allows iterating over the children of a
109112devicetree node.
Original file line number Diff line number Diff line change 29612961 */
29622962#define DT_FOREACH_STATUS_OKAY_NODE_VARGS (fn , ...) DT_FOREACH_OKAY_VARGS_HELPER(fn, __VA_ARGS__)
29632963
2964+ /**
2965+ * @brief Invokes @p fn for each ancestor of @p node_id
2966+ *
2967+ * The macro @p fn must take one parameter, which will be the identifier
2968+ * of a child node of @p node_id to enable traversal of all ancestor nodes.
2969+ *
2970+ * The ancestor will be iterated over in the same order as they
2971+ * appear in the final devicetree.
2972+ *
2973+ * Example devicetree fragment:
2974+ *
2975+ * @code{.dts}
2976+ * n: node1 {
2977+ * foobar = "foo1";
2978+ *
2979+ * n_2: node2 {
2980+ * foobar = "foo2";
2981+ *
2982+ * n_3: node3 {
2983+ * foobar = "foo3";
2984+ * };
2985+ * };
2986+ * };
2987+ * @endcode
2988+ *
2989+ * Example usage:
2990+ *
2991+ * @code{.c}
2992+ * #define GET_PROP(n) DT_PROP(n, foobar),
2993+ *
2994+ * const char *ancestor_names[] = {
2995+ * DT_FOREACH_ANCESTOR(DT_NODELABEL(n_3), GET_PROP)
2996+ * };
2997+ * @endcode
2998+ *
2999+ * This expands to:
3000+ *
3001+ * @code{.c}
3002+ * const char *ancestor_names[] = {
3003+ * "foo2", "foo1",
3004+ * };
3005+ * @endcode
3006+ *
3007+ * @param node_id node identifier
3008+ * @param fn macro to invoke
3009+ */
3010+ #define DT_FOREACH_ANCESTOR (node_id , fn ) \
3011+ DT_CAT(node_id, _FOREACH_ANCESTOR)(fn)
3012+
29643013/**
29653014 * @brief Invokes @p fn for each child of @p node_id
29663015 *
Original file line number Diff line number Diff line change @@ -97,6 +97,7 @@ def main():
9797 out_dt_define (f"{ node .z_path_id } _FOREACH_NODELABEL_VARGS(fn, ...)" ,
9898 " " .join (f"fn({ nodelabel } , __VA_ARGS__)" for nodelabel in node .labels ))
9999
100+ write_parent (node )
100101 write_children (node )
101102 write_dep_info (node )
102103 write_idents_and_existence (node )
@@ -457,6 +458,17 @@ def write_compatibles(node: edtlib.Node) -> None:
457458 out_dt_define (f"{ node .z_path_id } _COMPAT_MODEL_IDX_{ i } " ,
458459 quote_str (node .edt .compat2model [compat ]))
459460
461+ def write_parent (node : edtlib .Node ) -> None :
462+ # Visit all parent nodes.
463+ def _visit_parent_node (node : edtlib .Node ):
464+ while node is not None :
465+ yield node .parent
466+ node = node .parent
467+
468+ # Writes helper macros for dealing with node's parent.
469+ out_dt_define (f"{ node .z_path_id } _FOREACH_ANCESTOR(fn)" ,
470+ " " .join (f"fn(DT_{ parent .z_path_id } )" for parent in
471+ _visit_parent_node (node ) if parent is not None ))
460472
461473def write_children (node : edtlib .Node ) -> None :
462474 # Writes helper macros for dealing with node's children.
Original file line number Diff line number Diff line change 570570 phys = <&test_transceiver1>;
571571 };
572572
573+ test_parent: test-parent {
574+ compatible = "vnd,parent-bindings";
575+
576+ test_parent_a: parent-a {
577+ val = <0>;
578+
579+ test_parent_b: parent-b {
580+ val = <0>;
581+ };
582+ };
583+ };
584+
573585 /* there should only be one of these */
574586 test_children: test-children {
575587 compatible = "vnd,child-bindings";
Original file line number Diff line number Diff line change @@ -2225,6 +2225,31 @@ ZTEST(devicetree_api, test_parent)
22252225 TEST_SPI_BUS_0 ), "" );
22262226}
22272227
2228+ #undef DT_DRV_COMPAT
2229+ #define DT_DRV_COMPAT vnd_parent_bindings
2230+ ZTEST (devicetree_api , test_parent_nodes_list )
2231+ {
2232+ /* When traversing upwards, there are no fixed attributes and labels */
2233+ #define TEST_FUNC (parent ) { /* No operation */ }
2234+ #define TEST_FUNC_AND_COMMA (parent ) TEST_FUNC(parent),
2235+
2236+ struct vnd_parent_binding {
2237+ int val ;
2238+ };
2239+
2240+ struct vnd_parent_binding vals_a [] = {
2241+ DT_FOREACH_ANCESTOR (DT_NODELABEL (test_parent_a ), TEST_FUNC_AND_COMMA )};
2242+
2243+ struct vnd_parent_binding vals_b [] = {
2244+ DT_FOREACH_ANCESTOR (DT_NODELABEL (test_parent_b ), TEST_FUNC_AND_COMMA )};
2245+
2246+ zassert_equal (ARRAY_SIZE (vals_a ), 3 , "" );
2247+ zassert_equal (ARRAY_SIZE (vals_b ), 4 , "" );
2248+
2249+ #undef TEST_FUNC_AND_COMMA
2250+ #undef TEST_FUNC
2251+ }
2252+
22282253#undef DT_DRV_COMPAT
22292254#define DT_DRV_COMPAT vnd_i2c_mux_controller
22302255ZTEST (devicetree_api , test_gparent )
You can’t perform that action at this time.
0 commit comments