Skip to content

Commit d857aa7

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 d857aa7

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

include/zephyr/devicetree.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,42 @@
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 with a matching unit address
440+
*
441+
* @note Only works for children with unique unit addresses.
442+
*
443+
* Example devicetree fragment:
444+
*
445+
* @code{.dts}
446+
* / {
447+
* soc-label: soc {
448+
* serial1: serial@40001000 {
449+
* status = "okay";
450+
* current-speed = <115200>;
451+
* ...
452+
* };
453+
* };
454+
* };
455+
* @endcode
456+
*
457+
* Example usage with DT_PROP() to get the status of the
458+
* `serial@40001000` node:
459+
*
460+
* @code{.c}
461+
* #define SOC_NODE DT_NODELABEL(soc_label)
462+
* DT_PROP(DT_CHILD_BY_UNIT_ADDR(SOC_NODE, 0x40001000), status) // "okay"
463+
* @endcode
464+
*
465+
* @param node_id node identifier
466+
* @param addr Unit address for the child node. Can be decimal or
467+
* hexadecimal (lowercase and prefixed with 0x)
468+
*
469+
* @return node identifier for the child node with the specified unit address
470+
*/
471+
#define DT_CHILD_BY_UNIT_ADDR(node_id, addr) \
472+
DT_CAT3(node_id, _CHILD_UNIT_ADDR_, addr)
473+
438474
/**
439475
* @brief Get a node identifier for a status `okay` node with a compatible
440476
*
@@ -4066,6 +4102,19 @@
40664102
#define DT_INST_CHILD(inst, child) \
40674103
DT_CHILD(DT_DRV_INST(inst), child)
40684104

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

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)