Skip to content

Commit 475eadc

Browse files
committed
devicetree: Add DT_CHILD_BY_UNIT_ADDR
Allow fetching child node identifiers by unit address. Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
1 parent 474d068 commit 475eadc

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

include/zephyr/devicetree.h

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

438+
/**
439+
* @brief Get a node identifier for a child node by a unit address
440+
*
441+
* Example devicetree fragment:
442+
*
443+
* @code{.dts}
444+
* / {
445+
* soc-label: soc {
446+
* serial1: serial@40001000 {
447+
* status = "okay";
448+
* current-speed = <115200>;
449+
* reg = <0x40001000 0x1000>;
450+
* ...
451+
* };
452+
* };
453+
* };
454+
* @endcode
455+
*
456+
* Example usage with DT_PROP() to get the status of the
457+
* `serial@40001000` node:
458+
*
459+
* @code{.c}
460+
* #define SOC_NODE DT_NODELABEL(soc_label)
461+
* DT_PROP(DT_CHILD_BY_UNIT_ADDR(SOC_NODE, 0x40001000), status) // "okay"
462+
* @endcode
463+
*
464+
*
465+
* @param node_id node identifier
466+
* @param addr Unit address for the child node. Can be hexadecimal (prefix with 0x) or decimal
467+
*
468+
* @return node identifier for the child node with the reg address at a specified index
469+
*/
470+
#define DT_CHILD_BY_UNIT_ADDR(node_id, addr) \
471+
DT_CAT3(node_id, _CHILD_UNIT_ADDR_, addr)
472+
438473
/**
439474
* @brief Get a node identifier for a status `okay` node with a compatible
440475
*
@@ -4066,6 +4101,19 @@
40664101
#define DT_INST_CHILD(inst, child) \
40674102
DT_CHILD(DT_DRV_INST(inst), child)
40684103

4104+
/**
4105+
* @brief Get a node identifier for a child node by a unit address of DT_DRV_INST(inst)
4106+
*
4107+
* @param inst instance number
4108+
* @param addr Unit address for the child node. Can be hexadecimal (prefix with 0x) or decimal
4109+
*
4110+
* @return node identifier for the child node with the reg address at a specified index
4111+
*
4112+
* @see DT_CHILD_BY_UNIT_ADDR
4113+
*/
4114+
#define DT_INST_CHILD_BY_UNIT_ADDR(inst, addr) \
4115+
DT_CHILD_BY_UNIT_ADDR(DT_DRV_INST(inst), addr)
4116+
40694117
/**
40704118
* @brief Get the number of child nodes of a given node
40714119
*

scripts/dts/gen_defines.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,23 @@ 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+
# Decimal and hexadecimal variants
499+
out_dt_define(f"{node.z_path_id}_CHILD_UNIT_ADDR_{addr}", f"DT_{children[0].z_path_id}")
500+
out_dt_define(
501+
f"{node.z_path_id}_CHILD_UNIT_ADDR_{hex(addr)}", f"DT_{children[0].z_path_id}"
502+
)
503+
487504
out_dt_define(f"{node.z_path_id}_FOREACH_CHILD(fn)",
488505
" ".join(f"fn(DT_{child.z_path_id})" for child in
489506
node.children.values()))

0 commit comments

Comments
 (0)