From 3c0c03b9eb3f63f7058fb8363b552f8ccb55a113 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Wed, 2 Feb 2022 14:41:38 +0100 Subject: [PATCH] cmake: dts: Add dt_comp_path() cmake function Add a new cmake extension function: dt_comp_path( COMPATIBLE [INDEX ]) to get a list of paths for the nodes with the given . This is useful when we have to cycle through several nodes with the same compatible. Signed-off-by: Carlo Caione --- cmake/extensions.cmake | 54 ++++++++++++++++++++++++++++++++++++ scripts/dts/gen_dts_cmake.py | 15 ++++++++++ 2 files changed, 69 insertions(+) diff --git a/cmake/extensions.cmake b/cmake/extensions.cmake index 9746fb14506..5564d470324 100644 --- a/cmake/extensions.cmake +++ b/cmake/extensions.cmake @@ -2855,6 +2855,60 @@ function(dt_prop var) endif() endfunction() +# Usage: +# +# dt_comp_path( COMPATIBLE [INDEX ]) +# +# Get a list of paths for the nodes with the given compatible. The value will +# be returned in the parameter. +# will be undefined if no such compatible exists. +# +# For details and considerations about the format of and the returned +# parameter refer to dt_prop(). +# +# : Return variable where the property value will be stored +# COMPATIBLE : Compatible for which the list of paths should be +# returned, as it appears in the DTS source +# INDEX : Optional index when retrieving a value in an array property + +function(dt_comp_path var) + set(req_single_args "COMPATIBLE") + set(single_args "INDEX") + cmake_parse_arguments(DT_COMP "" "${req_single_args};${single_args}" "" ${ARGN}) + + if(${ARGV0} IN_LIST req_single_args) + message(FATAL_ERROR "dt_comp_path(${ARGV0} ...) missing return parameter.") + endif() + + foreach(arg ${req_single_args}) + if(NOT DEFINED DT_COMP_${arg}) + message(FATAL_ERROR "dt_comp_path(${ARGV0} ...) " + "missing required argument: ${arg}" + ) + endif() + endforeach() + + get_property(exists TARGET devicetree_target + PROPERTY "DT_COMP|${DT_COMP_COMPATIBLE}" + SET + ) + + if(NOT exists) + set(${var} PARENT_SCOPE) + return() + endif() + + get_target_property(val devicetree_target + "DT_COMP|${DT_COMP_COMPATIBLE}" + ) + + if(DEFINED DT_COMP_INDEX) + list(GET val ${DT_COMP_INDEX} element) + set(${var} "${element}" PARENT_SCOPE) + else() + set(${var} "${val}" PARENT_SCOPE) + endif() +endfunction() # Usage: # dt_num_regs( PATH ) diff --git a/scripts/dts/gen_dts_cmake.py b/scripts/dts/gen_dts_cmake.py index f86d2a875ea..8afc5987a8e 100755 --- a/scripts/dts/gen_dts_cmake.py +++ b/scripts/dts/gen_dts_cmake.py @@ -43,6 +43,7 @@ import argparse import os import pickle import sys +from collections import defaultdict sys.path.append(os.path.join(os.path.dirname(__file__), 'python-devicetree', 'src')) @@ -95,6 +96,7 @@ def main(): for alias in node.aliases: cmake_props.append(f'"DT_ALIAS|{alias}" "{path}"') + compatible2paths = defaultdict(list) for node in edt.nodes: cmake_props.append(f'"DT_NODE|{node.path}" TRUE') @@ -117,6 +119,11 @@ def main(): cmake_prop = f'DT_PROP|{node.path}|{item}' cmake_props.append(f'"{cmake_prop}" "{cmake_value}"') + if item == 'compatible': + # compatibles is always an array + for comp in node.props[item].val: + compatible2paths[comp].append(node.path) + if node.regs is not None: cmake_props.append(f'"DT_REG|{node.path}|NUM" "{len(node.regs)}"') cmake_addr = '' @@ -136,6 +143,14 @@ def main(): cmake_props.append(f'"DT_REG|{node.path}|ADDR" "{cmake_addr}"') cmake_props.append(f'"DT_REG|{node.path}|SIZE" "{cmake_size}"') + for comp in compatible2paths.keys(): + cmake_path = '' + for path in compatible2paths[comp]: + cmake_path = f'{cmake_path}{path};' + + cmake_comp = f'DT_COMP|{comp}' + cmake_props.append(f'"{cmake_comp}" "{cmake_path}"') + with open(args.cmake_out, "w", encoding="utf-8") as cmake_file: print('add_custom_target(devicetree_target)', file=cmake_file) print(file=cmake_file)