Skip to content

Commit 91278bd

Browse files
pdgendtnashif
authored andcommitted
devicetree: Add DT_CHILD_BY_UNIT_ADDR_INT
Allow fetching child node identifiers by integer unit address. Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
1 parent da6cd1a commit 91278bd

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

doc/build/dts/macros.bnf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ node-macro =/ %s"DT_N" path-id %s"_P_" prop-id %s"_FOREACH_PROP_ELEM_SEP_VARGS"
7777
; These are used by DT_CHILD_NUM and DT_CHILD_NUM_STATUS_OKAY macros
7878
node-macro =/ %s"DT_N" path-id %s"_CHILD_NUM"
7979
node-macro =/ %s"DT_N" path-id %s"_CHILD_NUM_STATUS_OKAY"
80+
; This is used by DT_CHILD_BY_UNIT_ADDR_INT
81+
node-macro =/ %s"DT_N" path-id %s"_CHILD_UNIT_ADDR_INT_" DIGIT
8082
; These are used internally by DT_FOREACH_CHILD, which iterates over
8183
; each child node.
8284
node-macro =/ %s"DT_N" path-id %s"_FOREACH_CHILD"

include/zephyr/devicetree.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,41 @@
436436
*/
437437
#define DT_CHILD(node_id, child) UTIL_CAT(node_id, DT_S_PREFIX(child))
438438

439+
/**
440+
* @brief Get a node identifier for a child node with a matching unit address
441+
*
442+
* @note Only works for children with unique integer unit addresses.
443+
*
444+
* Example devicetree fragment:
445+
*
446+
* @code{.dts}
447+
* / {
448+
* soc-label: soc {
449+
* serial1: serial@40001000 {
450+
* status = "okay";
451+
* current-speed = <115200>;
452+
* ...
453+
* };
454+
* };
455+
* };
456+
* @endcode
457+
*
458+
* Example usage with DT_PROP() to get the status of the
459+
* `serial@40001000` node:
460+
*
461+
* @code{.c}
462+
* #define SOC_NODE DT_NODELABEL(soc_label)
463+
* DT_PROP(DT_CHILD_BY_UNIT_ADDR_INT(SOC_NODE, 1073745920), status) // "okay"
464+
* @endcode
465+
*
466+
* @param node_id node identifier
467+
* @param addr Integer unit address for the child node.
468+
*
469+
* @return node identifier for the child node with the specified unit address
470+
*/
471+
#define DT_CHILD_BY_UNIT_ADDR_INT(node_id, addr) \
472+
DT_CAT3(node_id, _CHILD_UNIT_ADDR_INT_, addr)
473+
439474
/**
440475
* @brief Get a node identifier for a status `okay` node with a compatible
441476
*
@@ -4079,6 +4114,21 @@
40794114
#define DT_INST_CHILD(inst, child) \
40804115
DT_CHILD(DT_DRV_INST(inst), child)
40814116

4117+
/**
4118+
* @brief Get a node identifier for a child node with a matching unit address of DT_DRV_INST(inst)
4119+
*
4120+
* @note Only works for children with unique integer unit addresses.
4121+
*
4122+
* @param inst instance number
4123+
* @param addr Integer unit address for the child node.
4124+
*
4125+
* @return node identifier for the child node with the specified unit address
4126+
*
4127+
* @see DT_CHILD_BY_UNIT_ADDR_INT
4128+
*/
4129+
#define DT_INST_CHILD_BY_UNIT_ADDR_INT(inst, addr) \
4130+
DT_CHILD_BY_UNIT_ADDR_INT(DT_DRV_INST(inst), addr)
4131+
40824132
/**
40834133
* @brief Get the number of child nodes of a given node
40844134
*

scripts/dts/gen_defines.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,19 @@ def write_children(node: edtlib.Node) -> None:
484484

485485
out_dt_define(f"{node.z_path_id}_CHILD_NUM_STATUS_OKAY", ok_nodes_num)
486486

487+
child_unit_addrs = {}
488+
for child in node.children.values():
489+
# Provide a way to query child nodes
490+
if (addr := child.unit_addr) is not None:
491+
child_unit_addrs.setdefault(addr, []).append(child)
492+
493+
for addr, children in child_unit_addrs.items():
494+
if len(children) != 1:
495+
# Duplicate unit addresses for different children, skip
496+
continue
497+
498+
out_dt_define(f"{node.z_path_id}_CHILD_UNIT_ADDR_INT_{addr}", f"DT_{children[0].z_path_id}")
499+
487500
out_dt_define(f"{node.z_path_id}_FOREACH_CHILD(fn)",
488501
" ".join(f"fn(DT_{child.z_path_id})" for child in
489502
node.children.values()))

0 commit comments

Comments
 (0)