LCOV - code coverage report
Current view: top level - zephyr - devicetree.h Hit Total Coverage
Test: new.info Lines: 234 235 99.6 %
Date: 2024-12-21 18:13:37

          Line data    Source code
       1           1 : /*
       2             :  * SPDX-License-Identifier: Apache-2.0
       3             :  * Copyright (c) 2020 Nordic Semiconductor
       4             :  * Copyright (c) 2020, Linaro Ltd.
       5             :  *
       6             :  * Not a generated file. Feel free to modify.
       7             :  */
       8             : 
       9             : /**
      10             :  * @file
      11             :  * @brief Devicetree main header
      12             :  *
      13             :  * API for accessing the current application's devicetree macros.
      14             :  */
      15             : 
      16             : #ifndef ZEPHYR_INCLUDE_DEVICETREE_H_
      17             : #define ZEPHYR_INCLUDE_DEVICETREE_H_
      18             : 
      19             : #include <zephyr/devicetree_generated.h>
      20             : #include <zephyr/irq_multilevel.h>
      21             : 
      22             : #if !defined(_LINKER) && !defined(_ASMLANGUAGE)
      23             : #include <stdint.h>
      24             : #endif
      25             : 
      26             : #include <zephyr/sys/util.h>
      27             : 
      28             : /**
      29             :  * @brief devicetree.h API
      30             :  * @defgroup devicetree Devicetree
      31             :  * @since 2.2
      32             :  * @version 1.2.0
      33             :  * @{
      34             :  * @}
      35             :  */
      36             : 
      37             : /*
      38             :  * Property suffixes
      39             :  * -----------------
      40             :  *
      41             :  * These are the optional parts that come after the _P_<property>
      42             :  * part in DT_N_<path-id>_P_<property-id> macros, or the "prop-suf"
      43             :  * nonterminal in the DT guide's macros.bnf file.
      44             :  *
      45             :  * Before adding new ones, check this list to avoid conflicts. If any
      46             :  * are missing from this list, please add them. It should be complete.
      47             :  *
      48             :  * _ENUM_IDX: property's value as an index into bindings enum
      49             :  * _ENUM_VAL_<val>_EXISTS property's value as a token exists
      50             :  * _EXISTS: property is defined
      51             :  * _FOREACH_PROP_ELEM: helper for "iterating" over values in the property
      52             :  * _FOREACH_PROP_ELEM_VARGS: foreach functions with variable number of arguments
      53             :  * _IDX_<i>: logical index into property
      54             :  * _IDX_<i>_EXISTS: logical index into property is defined
      55             :  * _IDX_<i>_PH: phandle array's phandle by index (or phandle, phandles)
      56             :  * _IDX_<i>_STRING_TOKEN: string array element value as a token
      57             :  * _IDX_<i>_STRING_UPPER_TOKEN: string array element value as a uppercased token
      58             :  * _IDX <i>_STRING_UNQUOTED: string array element value as a sequence of tokens, with no quotes
      59             :  * _IDX_<i>_VAL_<val>: phandle array's specifier value by index
      60             :  * _IDX_<i>_VAL_<val>_EXISTS: cell value exists, by index
      61             :  * _LEN: property logical length
      62             :  * _NAME_<name>_PH: phandle array's phandle by name
      63             :  * _NAME_<name>_VAL_<val>: phandle array's property specifier by name
      64             :  * _NAME_<name>_VAL_<val>_EXISTS: cell value exists, by name
      65             :  * _STRING_TOKEN: string property's value as a token
      66             :  * _STRING_UPPER_TOKEN: like _STRING_TOKEN, but uppercased
      67             :  * _STRING_UNQUOTED: string property's value as a sequence of tokens, with no quotes
      68             :  */
      69             : 
      70             : /**
      71             :  * @defgroup devicetree-generic-id Node identifiers and helpers
      72             :  * @ingroup devicetree
      73             :  * @{
      74             :  */
      75             : 
      76             : /**
      77             :  * @brief Name for an invalid node identifier
      78             :  *
      79             :  * This supports cases where factored macros can be invoked from paths where
      80             :  * devicetree data may or may not be available. It is a preprocessor identifier
      81             :  * that does not match any valid devicetree node identifier.
      82             :  */
      83           1 : #define DT_INVALID_NODE _
      84             : 
      85             : /**
      86             :  * @brief Node identifier for the root node in the devicetree
      87             :  */
      88           1 : #define DT_ROOT DT_N
      89             : 
      90             : /**
      91             :  * @brief Get a node identifier for a devicetree path
      92             :  *
      93             :  * @note This macro returns a node identifier from path components. To get
      94             :  *       a path string from a node identifier, use DT_NODE_PATH() instead.
      95             :  *
      96             :  * The arguments to this macro are the names of non-root nodes in the
      97             :  * tree required to reach the desired node, starting from the root.
      98             :  * Non-alphanumeric characters in each name must be converted to
      99             :  * underscores to form valid C tokens, and letters must be lowercased.
     100             :  *
     101             :  * Example devicetree fragment:
     102             :  *
     103             :  * @code{.dts}
     104             :  *     / {
     105             :  *             soc {
     106             :  *                     serial1: serial@40001000 {
     107             :  *                             status = "okay";
     108             :  *                             current-speed = <115200>;
     109             :  *                             ...
     110             :  *                     };
     111             :  *             };
     112             :  *     };
     113             :  * @endcode
     114             :  *
     115             :  * You can use `DT_PATH(soc, serial_40001000)` to get a node identifier
     116             :  * for the `serial@40001000` node. Node labels like `serial1` cannot be
     117             :  * used as DT_PATH() arguments; use DT_NODELABEL() for those instead.
     118             :  *
     119             :  * Example usage with DT_PROP() to get the `current-speed` property:
     120             :  *
     121             :  * @code{.c}
     122             :  *     DT_PROP(DT_PATH(soc, serial_40001000), current_speed) // 115200
     123             :  * @endcode
     124             :  *
     125             :  * (The `current-speed` property is also in `lowercase-and-underscores`
     126             :  * form when used with this API.)
     127             :  *
     128             :  * When determining arguments to DT_PATH():
     129             :  *
     130             :  * - the first argument corresponds to a child node of the root (`soc` above)
     131             :  * - a second argument corresponds to a child of the first argument
     132             :  *   (`serial_40001000` above, from the node name `serial@40001000`
     133             :  *   after lowercasing and changing `@` to `_`)
     134             :  * - and so on for deeper nodes in the desired node's path
     135             :  *
     136             :  * @param ... lowercase-and-underscores node names along the node's path,
     137             :  *            with each name given as a separate argument
     138             :  * @return node identifier for the node with that path
     139             :  */
     140           1 : #define DT_PATH(...) DT_PATH_INTERNAL(__VA_ARGS__)
     141             : 
     142             : /**
     143             :  * @brief Get a node identifier for a node label
     144             :  *
     145             :  * Convert non-alphanumeric characters in the node label to
     146             :  * underscores to form valid C tokens, and lowercase all letters. Note
     147             :  * that node labels are not the same thing as label properties.
     148             :  *
     149             :  * Example devicetree fragment:
     150             :  *
     151             :  * @code{.dts}
     152             :  *     serial1: serial@40001000 {
     153             :  *             label = "UART_0";
     154             :  *             status = "okay";
     155             :  *             current-speed = <115200>;
     156             :  *             ...
     157             :  *     };
     158             :  * @endcode
     159             :  *
     160             :  * The only node label in this example is `serial1`.
     161             :  *
     162             :  * The string `UART_0` is *not* a node label; it's the value of a
     163             :  * property named label.
     164             :  *
     165             :  * You can use `DT_NODELABEL(serial1)` to get a node identifier for the
     166             :  * `serial@40001000` node. Example usage with DT_PROP() to get the
     167             :  * current-speed property:
     168             :  *
     169             :  * @code{.c}
     170             :  *     DT_PROP(DT_NODELABEL(serial1), current_speed) // 115200
     171             :  * @endcode
     172             :  *
     173             :  * Another example devicetree fragment:
     174             :  *
     175             :  * @code{.dts}
     176             :  *     cpu@0 {
     177             :  *            L2_0: l2-cache {
     178             :  *                    cache-level = <2>;
     179             :  *                    ...
     180             :  *            };
     181             :  *     };
     182             :  * @endcode
     183             :  *
     184             :  * Example usage to get the cache-level property:
     185             :  *
     186             :  * @code{.c}
     187             :  *     DT_PROP(DT_NODELABEL(l2_0), cache_level) // 2
     188             :  * @endcode
     189             :  *
     190             :  * Notice how `L2_0` in the devicetree is lowercased to `l2_0` in the
     191             :  * DT_NODELABEL() argument.
     192             :  *
     193             :  * @param label lowercase-and-underscores node label name
     194             :  * @return node identifier for the node with that label
     195             :  */
     196           1 : #define DT_NODELABEL(label) DT_CAT(DT_N_NODELABEL_, label)
     197             : 
     198             : /**
     199             :  * @brief Get a node identifier from /aliases
     200             :  *
     201             :  * This macro's argument is a property of the `/aliases` node. It
     202             :  * returns a node identifier for the node which is aliased. Convert
     203             :  * non-alphanumeric characters in the alias property to underscores to
     204             :  * form valid C tokens, and lowercase all letters.
     205             :  *
     206             :  * Example devicetree fragment:
     207             :  *
     208             :  * @code{.dts}
     209             :  *     / {
     210             :  *             aliases {
     211             :  *                     my-serial = &serial1;
     212             :  *             };
     213             :  *
     214             :  *             soc {
     215             :  *                     serial1: serial@40001000 {
     216             :  *                             status = "okay";
     217             :  *                             current-speed = <115200>;
     218             :  *                             ...
     219             :  *                     };
     220             :  *             };
     221             :  *     };
     222             :  * @endcode
     223             :  *
     224             :  * You can use DT_ALIAS(my_serial) to get a node identifier for the
     225             :  * `serial@40001000` node. Notice how `my-serial` in the devicetree
     226             :  * becomes `my_serial` in the DT_ALIAS() argument. Example usage with
     227             :  * DT_PROP() to get the current-speed property:
     228             :  *
     229             :  * @code{.c}
     230             :  *     DT_PROP(DT_ALIAS(my_serial), current_speed) // 115200
     231             :  * @endcode
     232             :  *
     233             :  * @param alias lowercase-and-underscores alias name.
     234             :  * @return node identifier for the node with that alias
     235             :  */
     236           1 : #define DT_ALIAS(alias) DT_CAT(DT_N_ALIAS_, alias)
     237             : 
     238             : /**
     239             :  * @brief Test if the devicetree has a given alias
     240             :  * @param alias_name lowercase-and-underscores devicetree alias name
     241             :  * @return 1 if the alias exists and refers to a node, 0 otherwise
     242             :  */
     243           1 : #define DT_HAS_ALIAS(alias_name) DT_NODE_EXISTS(DT_ALIAS(alias_name))
     244             : 
     245             : /**
     246             :  * @brief Get a node identifier for an instance of a compatible
     247             :  *
     248             :  * All nodes with a particular compatible property value are assigned
     249             :  * instance numbers, which are zero-based indexes specific to that
     250             :  * compatible. You can get a node identifier for these nodes by
     251             :  * passing DT_INST() an instance number, @p inst, along with the
     252             :  * lowercase-and-underscores version of the compatible, @p compat.
     253             :  *
     254             :  * Instance numbers have the following properties:
     255             :  *
     256             :  * - for each compatible, instance numbers start at 0 and are contiguous
     257             :  * - exactly one instance number is assigned for each node with a compatible,
     258             :  *   **including disabled nodes**
     259             :  * - enabled nodes (status property is `okay` or missing) are assigned the
     260             :  *   instance numbers starting from 0, and disabled nodes have instance
     261             :  *   numbers which are greater than those of any enabled node
     262             :  *
     263             :  * No other guarantees are made. In particular:
     264             :  *
     265             :  * - instance numbers **in no way reflect** any numbering scheme that
     266             :  *   might exist in SoC documentation, node labels or unit addresses,
     267             :  *   or properties of the /aliases node (use DT_NODELABEL() or DT_ALIAS()
     268             :  *   for those)
     269             :  * - there **is no general guarantee** that the same node will have
     270             :  *   the same instance number between builds, even if you are building
     271             :  *   the same application again in the same build directory
     272             :  *
     273             :  * Example devicetree fragment:
     274             :  *
     275             :  * @code{.dts}
     276             :  *     serial1: serial@40001000 {
     277             :  *             compatible = "vnd,soc-serial";
     278             :  *             status = "disabled";
     279             :  *             current-speed = <9600>;
     280             :  *             ...
     281             :  *     };
     282             :  *
     283             :  *     serial2: serial@40002000 {
     284             :  *             compatible = "vnd,soc-serial";
     285             :  *             status = "okay";
     286             :  *             current-speed = <57600>;
     287             :  *             ...
     288             :  *     };
     289             :  *
     290             :  *     serial3: serial@40003000 {
     291             :  *             compatible = "vnd,soc-serial";
     292             :  *             current-speed = <115200>;
     293             :  *             ...
     294             :  *     };
     295             :  * @endcode
     296             :  *
     297             :  * Assuming no other nodes in the devicetree have compatible
     298             :  * `"vnd,soc-serial"`, that compatible has nodes with instance numbers
     299             :  * 0, 1, and 2.
     300             :  *
     301             :  * The nodes `serial@40002000` and `serial@40003000` are both enabled, so
     302             :  * their instance numbers are 0 and 1, but no guarantees are made
     303             :  * regarding which node has which instance number.
     304             :  *
     305             :  * Since `serial@40001000` is the only disabled node, it has instance
     306             :  * number 2, since disabled nodes are assigned the largest instance
     307             :  * numbers. Therefore:
     308             :  *
     309             :  * @code{.c}
     310             :  *     // Could be 57600 or 115200. There is no way to be sure:
     311             :  *     // either serial@40002000 or serial@40003000 could
     312             :  *     // have instance number 0, so this could be the current-speed
     313             :  *     // property of either of those nodes.
     314             :  *     DT_PROP(DT_INST(0, vnd_soc_serial), current_speed)
     315             :  *
     316             :  *     // Could be 57600 or 115200, for the same reason.
     317             :  *     // If the above expression expands to 57600, then
     318             :  *     // this expands to 115200, and vice-versa.
     319             :  *     DT_PROP(DT_INST(1, vnd_soc_serial), current_speed)
     320             :  *
     321             :  *     // 9600, because there is only one disabled node, and
     322             :  *     // disabled nodes are "at the end" of the instance
     323             :  *     // number "list".
     324             :  *     DT_PROP(DT_INST(2, vnd_soc_serial), current_speed)
     325             :  * @endcode
     326             :  *
     327             :  * Notice how `"vnd,soc-serial"` in the devicetree becomes `vnd_soc_serial`
     328             :  * (without quotes) in the DT_INST() arguments. (As usual, `current-speed`
     329             :  * in the devicetree becomes `current_speed` as well.)
     330             :  *
     331             :  * Nodes whose `compatible` property has multiple values are assigned
     332             :  * independent instance numbers for each compatible.
     333             :  *
     334             :  * @param inst instance number for compatible @p compat
     335             :  * @param compat lowercase-and-underscores compatible, without quotes
     336             :  * @return node identifier for the node with that instance number and
     337             :  *         compatible
     338             :  */
     339           1 : #define DT_INST(inst, compat) UTIL_CAT(DT_N_INST, DT_DASH(inst, compat))
     340             : 
     341             : /**
     342             :  * @brief Get a node identifier for a parent node
     343             :  *
     344             :  * Example devicetree fragment:
     345             :  *
     346             :  * @code{.dts}
     347             :  *     parent: parent-node {
     348             :  *             child: child-node {
     349             :  *                     ...
     350             :  *             };
     351             :  *     };
     352             :  * @endcode
     353             :  *
     354             :  * The following are equivalent ways to get the same node identifier:
     355             :  *
     356             :  * @code{.c}
     357             :  *     DT_NODELABEL(parent)
     358             :  *     DT_PARENT(DT_NODELABEL(child))
     359             :  * @endcode
     360             :  *
     361             :  * @param node_id node identifier
     362             :  * @return a node identifier for the node's parent
     363             :  */
     364           1 : #define DT_PARENT(node_id) DT_CAT(node_id, _PARENT)
     365             : 
     366             : /**
     367             :  * @brief Get a node identifier for a grandparent node
     368             :  *
     369             :  * Example devicetree fragment:
     370             :  *
     371             :  * @code{.dts}
     372             :  *     gparent: grandparent-node {
     373             :  *             parent: parent-node {
     374             :  *                     child: child-node { ... }
     375             :  *             };
     376             :  *     };
     377             :  * @endcode
     378             :  *
     379             :  * The following are equivalent ways to get the same node identifier:
     380             :  *
     381             :  * @code{.c}
     382             :  *     DT_GPARENT(DT_NODELABEL(child))
     383             :  *     DT_PARENT(DT_PARENT(DT_NODELABEL(child))
     384             :  * @endcode
     385             :  *
     386             :  * @param node_id node identifier
     387             :  * @return a node identifier for the node's parent's parent
     388             :  */
     389           1 : #define DT_GPARENT(node_id) DT_PARENT(DT_PARENT(node_id))
     390             : 
     391             : /**
     392             :  * @brief Get a node identifier for a child node
     393             :  *
     394             :  * Example devicetree fragment:
     395             :  *
     396             :  * @code{.dts}
     397             :  *     / {
     398             :  *             soc-label: soc {
     399             :  *                     serial1: serial@40001000 {
     400             :  *                             status = "okay";
     401             :  *                             current-speed = <115200>;
     402             :  *                             ...
     403             :  *                     };
     404             :  *             };
     405             :  *     };
     406             :  * @endcode
     407             :  *
     408             :  * Example usage with DT_PROP() to get the status of the
     409             :  * `serial@40001000` node:
     410             :  *
     411             :  * @code{.c}
     412             :  *     #define SOC_NODE DT_NODELABEL(soc_label)
     413             :  *     DT_PROP(DT_CHILD(SOC_NODE, serial_40001000), status) // "okay"
     414             :  * @endcode
     415             :  *
     416             :  * Node labels like `serial1` cannot be used as the @p child argument
     417             :  * to this macro. Use DT_NODELABEL() for that instead.
     418             :  *
     419             :  * You can also use DT_FOREACH_CHILD() to iterate over node
     420             :  * identifiers for all of a node's children.
     421             :  *
     422             :  * @param node_id node identifier
     423             :  * @param child lowercase-and-underscores child node name
     424             :  * @return node identifier for the node with the name referred to by 'child'
     425             :  */
     426           1 : #define DT_CHILD(node_id, child) UTIL_CAT(node_id, DT_S_PREFIX(child))
     427             : 
     428             : /**
     429             :  * @brief Get a node identifier for a status `okay` node with a compatible
     430             :  *
     431             :  * Use this if you want to get an arbitrary enabled node with a given
     432             :  * compatible, and you do not care which one you get. If any enabled
     433             :  * nodes with the given compatible exist, a node identifier for one
     434             :  * of them is returned. Otherwise, @ref DT_INVALID_NODE is returned.
     435             :  *
     436             :  * Example devicetree fragment:
     437             :  *
     438             :  * @code{.dts}
     439             :  *      node-a {
     440             :  *              compatible = "vnd,device";
     441             :  *              status = "okay";
     442             :  *      };
     443             :  *
     444             :  *      node-b {
     445             :  *              compatible = "vnd,device";
     446             :  *              status = "okay";
     447             :  *      };
     448             :  *
     449             :  *      node-c {
     450             :  *              compatible = "vnd,device";
     451             :  *              status = "disabled";
     452             :  *      };
     453             :  * @endcode
     454             :  *
     455             :  * Example usage:
     456             :  *
     457             :  * @code{.c}
     458             :  *     DT_COMPAT_GET_ANY_STATUS_OKAY(vnd_device)
     459             :  * @endcode
     460             :  *
     461             :  * This expands to a node identifier for either `node-a` or `node-b`.
     462             :  * It will not expand to a node identifier for `node-c`, because that
     463             :  * node does not have status `okay`.
     464             :  *
     465             :  * @param compat lowercase-and-underscores compatible, without quotes
     466             :  * @return node identifier for a node with that compatible, or
     467             :  *         @ref DT_INVALID_NODE
     468             :  */
     469           1 : #define DT_COMPAT_GET_ANY_STATUS_OKAY(compat)                   \
     470             :         COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat),  \
     471             :                     (DT_INST(0, compat)),               \
     472             :                     (DT_INVALID_NODE))
     473             : 
     474             : /**
     475             :  * @brief Get a devicetree node's full path as a string literal
     476             :  *
     477             :  * This returns the path to a node from a node identifier. To get a
     478             :  * node identifier from path components instead, use DT_PATH().
     479             :  *
     480             :  * Example devicetree fragment:
     481             :  *
     482             :  * @code{.dts}
     483             :  *     / {
     484             :  *             soc {
     485             :  *                     node: my-node@12345678 { ... };
     486             :  *             };
     487             :  *     };
     488             :  * @endcode
     489             :  *
     490             :  * Example usage:
     491             :  *
     492             :  * @code{.c}
     493             :  *    DT_NODE_PATH(DT_NODELABEL(node)) // "/soc/my-node@12345678"
     494             :  *    DT_NODE_PATH(DT_PATH(soc))       // "/soc"
     495             :  *    DT_NODE_PATH(DT_ROOT)            // "/"
     496             :  * @endcode
     497             :  *
     498             :  * @param node_id node identifier
     499             :  * @return the node's full path in the devicetree
     500             :  */
     501           1 : #define DT_NODE_PATH(node_id) DT_CAT(node_id, _PATH)
     502             : 
     503             : /**
     504             :  * @brief Get a devicetree node's name with unit-address as a string literal
     505             :  *
     506             :  * This returns the node name and unit-address from a node identifier.
     507             :  *
     508             :  * Example devicetree fragment:
     509             :  *
     510             :  * @code{.dts}
     511             :  *     / {
     512             :  *             soc {
     513             :  *                     node: my-node@12345678 { ... };
     514             :  *             };
     515             :  *     };
     516             :  * @endcode
     517             :  *
     518             :  * Example usage:
     519             :  *
     520             :  * @code{.c}
     521             :  *    DT_NODE_FULL_NAME(DT_NODELABEL(node)) // "my-node@12345678"
     522             :  * @endcode
     523             :  *
     524             :  * @param node_id node identifier
     525             :  * @return the node's name with unit-address as a string in the devicetree
     526             :  */
     527           1 : #define DT_NODE_FULL_NAME(node_id) DT_CAT(node_id, _FULL_NAME)
     528             : 
     529             : /**
     530             :  * @brief Get the node's full name, including the unit-address, as an unquoted
     531             :  *        sequence of tokens
     532             :  *
     533             :  * This macro returns removed "the quotes" from the node's full name.
     534             :  *
     535             :  * Example devicetree fragment:
     536             :  *
     537             :  * @code{.dts}
     538             :  *     / {
     539             :  *             soc {
     540             :  *                     node: my-node@12345678 { ... };
     541             :  *             };
     542             :  *     };
     543             :  * @endcode
     544             :  *
     545             :  * Example usage:
     546             :  *
     547             :  * @code{.c}
     548             :  *    DT_NODE_FULL_NAME_UNQUOTED(DT_NODELABEL(node)) // my-node@12345678
     549             :  * @endcode
     550             :  *
     551             :  * @param node_id node identifier
     552             :  * @return the node's full name with unit-address as a sequence of tokens,
     553             :  *         with no quotes
     554             :  */
     555           1 : #define DT_NODE_FULL_NAME_UNQUOTED(node_id) DT_CAT(node_id, _FULL_NAME_UNQUOTED)
     556             : 
     557             : /**
     558             :  * @brief Get the node's full name, including the unit-address, as a token.
     559             :  *
     560             :  * This macro returns removed "the quotes" from the node's full name and
     561             :  * converting any non-alphanumeric characters to underscores.
     562             :  *
     563             :  * Example devicetree fragment:
     564             :  *
     565             :  * @code{.dts}
     566             :  *     / {
     567             :  *             soc {
     568             :  *                     node: my-node@12345678 { ... };
     569             :  *             };
     570             :  *     };
     571             :  * @endcode
     572             :  *
     573             :  * Example usage:
     574             :  *
     575             :  * @code{.c}
     576             :  *    DT_NODE_FULL_NAME_TOKEN(DT_NODELABEL(node)) // my_node_12345678
     577             :  * @endcode
     578             :  *
     579             :  * @param node_id node identifier
     580             :  * @return the node's full name with unit-address as a token, i.e. without any quotes
     581             :  *         and with special characters converted to underscores
     582             :  */
     583           1 : #define DT_NODE_FULL_NAME_TOKEN(node_id) DT_CAT(node_id, _FULL_NAME_TOKEN)
     584             : 
     585             : /**
     586             :  * @brief Like DT_NODE_FULL_NAME_TOKEN(), but uppercased.
     587             :  *
     588             :  * This macro returns removed "the quotes" from the node's full name,
     589             :  * converting any non-alphanumeric characters to underscores, and
     590             :  * capitalizing the result.
     591             :  *
     592             :  * Example devicetree fragment:
     593             :  *
     594             :  * @code{.dts}
     595             :  *     / {
     596             :  *             soc {
     597             :  *                     node: my-node@12345678 { ... };
     598             :  *             };
     599             :  *     };
     600             :  * @endcode
     601             :  *
     602             :  * Example usage:
     603             :  *
     604             :  * @code{.c}
     605             :  *    DT_NODE_FULL_NAME_UPPER_TOKEN(DT_NODELABEL(node)) // MY_NODE_12345678
     606             :  * @endcode
     607             :  *
     608             :  * @param node_id node identifier
     609             :  * @return the node's full name with unit-address as an uppercased token,
     610             :  *         i.e. without any quotes and with special characters converted
     611             :  *         to underscores
     612             :  */
     613           1 : #define DT_NODE_FULL_NAME_UPPER_TOKEN(node_id) DT_CAT(node_id, _FULL_NAME_UPPER_TOKEN)
     614             : 
     615             : /**
     616             :  * @brief Get a devicetree node's index into its parent's list of children
     617             :  *
     618             :  * Indexes are zero-based.
     619             :  *
     620             :  * It is an error to use this macro with the root node.
     621             :  *
     622             :  * Example devicetree fragment:
     623             :  *
     624             :  * @code{.dts}
     625             :  *     parent {
     626             :  *             c1: child-1 {};
     627             :  *             c2: child-2 {};
     628             :  *     };
     629             :  * @endcode
     630             :  *
     631             :  * Example usage:
     632             :  *
     633             :  * @code{.c}
     634             :  *     DT_NODE_CHILD_IDX(DT_NODELABEL(c1)) // 0
     635             :  *     DT_NODE_CHILD_IDX(DT_NODELABEL(c2)) // 1
     636             :  * @endcode
     637             :  *
     638             :  * @param node_id node identifier
     639             :  * @return the node's index in its parent node's list of children
     640             :  */
     641           1 : #define DT_NODE_CHILD_IDX(node_id) DT_CAT(node_id, _CHILD_IDX)
     642             : 
     643             : /**
     644             :  * @brief Get the number of child nodes of a given node
     645             :  *
     646             :  * @param node_id a node identifier
     647             :  * @return Number of child nodes
     648             :  */
     649           1 : #define DT_CHILD_NUM(node_id) DT_CAT(node_id, _CHILD_NUM)
     650             : 
     651             : 
     652             : /**
     653             :  * @brief Get the number of child nodes of a given node
     654             :  *        which child nodes' status are okay
     655             :  *
     656             :  * @param node_id a node identifier
     657             :  * @return Number of child nodes which status are okay
     658             :  */
     659           1 : #define DT_CHILD_NUM_STATUS_OKAY(node_id) \
     660             :         DT_CAT(node_id, _CHILD_NUM_STATUS_OKAY)
     661             : 
     662             : /**
     663             :  * @brief Do @p node_id1 and @p node_id2 refer to the same node?
     664             :  *
     665             :  * Both @p node_id1 and @p node_id2 must be node identifiers for nodes
     666             :  * that exist in the devicetree (if unsure, you can check with
     667             :  * DT_NODE_EXISTS()).
     668             :  *
     669             :  * The expansion evaluates to 0 or 1, but may not be a literal integer
     670             :  * 0 or 1.
     671             :  *
     672             :  * @internal
     673             :  * Implementation note: distinct nodes have distinct node identifiers.
     674             :  * See include/zephyr/devicetree/ordinals.h.
     675             :  * @endinternal
     676             :  *
     677             :  * @param node_id1 first node identifier
     678             :  * @param node_id2 second node identifier
     679             :  * @return an expression that evaluates to 1 if the node identifiers
     680             :  *         refer to the same node, and evaluates to 0 otherwise
     681             :  */
     682           1 : #define DT_SAME_NODE(node_id1, node_id2) \
     683             :         (DT_DEP_ORD(node_id1) == (DT_DEP_ORD(node_id2)))
     684             : 
     685             : /**
     686             :  * @brief Get a devicetree node's node labels as an array of strings
     687             :  *
     688             :  * Example devicetree fragment:
     689             :  *
     690             :  * @code{.dts}
     691             :  *     foo: bar: node@deadbeef {};
     692             :  * @endcode
     693             :  *
     694             :  * Example usage:
     695             :  *
     696             :  * @code{.c}
     697             :  *     DT_NODELABEL_STRING_ARRAY(DT_NODELABEL(foo))
     698             :  * @endcode
     699             :  *
     700             :  * This expands to:
     701             :  *
     702             :  * @code{.c}
     703             :  *     { "foo", "bar", }
     704             :  * @endcode
     705             :  *
     706             :  * @param node_id node identifier
     707             :  * @return an array initializer for an array of the node's node labels as strings
     708             :  */
     709           1 : #define DT_NODELABEL_STRING_ARRAY(node_id) \
     710             :         { DT_FOREACH_NODELABEL(node_id, DT_NODELABEL_STRING_ARRAY_ENTRY_INTERNAL) }
     711             : 
     712             : /**
     713             :  * @}
     714             :  */
     715             : 
     716             : /**
     717             :  * @defgroup devicetree-generic-prop Property accessors
     718             :  * @ingroup devicetree
     719             :  * @{
     720             :  */
     721             : 
     722             : /**
     723             :  * @brief Get a devicetree property value
     724             :  *
     725             :  * For properties whose bindings have the following types, this macro
     726             :  * expands to:
     727             :  *
     728             :  * - string: a string literal
     729             :  * - boolean: `0` if the property is false, or `1` if it is true
     730             :  * - int: the property's value as an integer literal
     731             :  * - array, uint8-array, string-array: an initializer expression in braces,
     732             :  *   whose elements are integer or string literals (like `{0, 1, 2}`,
     733             :  *   `{"hello", "world"}`, etc.)
     734             :  * - phandle: a node identifier for the node with that phandle
     735             :  *
     736             :  * A property's type is usually defined by its binding. In some
     737             :  * special cases, it has an assumed type defined by the devicetree
     738             :  * specification even when no binding is available: `compatible` has
     739             :  * type string-array, `status` has type string, and
     740             :  * `interrupt-controller` has type boolean.
     741             :  *
     742             :  * For other properties or properties with unknown type due to a
     743             :  * missing binding, behavior is undefined.
     744             :  *
     745             :  * For usage examples, see DT_PATH(), DT_ALIAS(), DT_NODELABEL(),
     746             :  * and DT_INST() above.
     747             :  *
     748             :  * @param node_id node identifier
     749             :  * @param prop lowercase-and-underscores property name
     750             :  * @return a representation of the property's value
     751             :  */
     752           1 : #define DT_PROP(node_id, prop) DT_CAT3(node_id, _P_, prop)
     753             : 
     754             : /**
     755             :  * @brief Get a property's logical length
     756             :  *
     757             :  * Here, "length" is a number of elements, which may differ from the
     758             :  * property's size in bytes.
     759             :  *
     760             :  * The return value depends on the property's type:
     761             :  *
     762             :  * - for types array, string-array, and uint8-array, this expands
     763             :  *   to the number of elements in the array
     764             :  * - for type phandles, this expands to the number of phandles
     765             :  * - for type phandle-array, this expands to the number of
     766             :  *   phandle and specifier blocks in the property
     767             :  * - for type phandle, this expands to 1 (so that a phandle
     768             :  *   can be treated as a degenerate case of phandles with length 1)
     769             :  * - for type string, this expands to 1 (so that a string can be
     770             :  *   treated as a degenerate case of string-array with length 1)
     771             :  *
     772             :  * These properties are handled as special cases:
     773             :  *
     774             :  * - reg property: use `DT_NUM_REGS(node_id)` instead
     775             :  * - interrupts property: use `DT_NUM_IRQS(node_id)` instead
     776             :  *
     777             :  * It is an error to use this macro with the `ranges`, `dma-ranges`, `reg`
     778             :  * or `interrupts` properties.
     779             :  *
     780             :  * For other properties, behavior is undefined.
     781             :  *
     782             :  * @param node_id node identifier
     783             :  * @param prop a lowercase-and-underscores property with a logical length
     784             :  * @return the property's length
     785             :  */
     786           1 : #define DT_PROP_LEN(node_id, prop) DT_CAT4(node_id, _P_, prop, _LEN)
     787             : 
     788             : /**
     789             :  * @brief Like DT_PROP_LEN(), but with a fallback to @p default_value
     790             :  *
     791             :  * If the property is defined (as determined by DT_NODE_HAS_PROP()),
     792             :  * this expands to DT_PROP_LEN(node_id, prop). The @p default_value
     793             :  * parameter is not expanded in this case.
     794             :  *
     795             :  * Otherwise, this expands to @p default_value.
     796             :  *
     797             :  * @param node_id node identifier
     798             :  * @param prop a lowercase-and-underscores property with a logical length
     799             :  * @param default_value a fallback value to expand to
     800             :  * @return the property's length or the given default value
     801             :  */
     802           1 : #define DT_PROP_LEN_OR(node_id, prop, default_value) \
     803             :         COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
     804             :                     (DT_PROP_LEN(node_id, prop)), (default_value))
     805             : 
     806             : /**
     807             :  * @brief Is index @p idx valid for an array type property?
     808             :  *
     809             :  * If this returns 1, then DT_PROP_BY_IDX(node_id, prop, idx) or
     810             :  * DT_PHA_BY_IDX(node_id, prop, idx, ...) are valid at index @p idx.
     811             :  * If it returns 0, it is an error to use those macros with that index.
     812             :  *
     813             :  * These properties are handled as special cases:
     814             :  *
     815             :  * - `reg` property: use DT_REG_HAS_IDX(node_id, idx) instead
     816             :  * - `interrupts` property: use DT_IRQ_HAS_IDX(node_id, idx) instead
     817             :  *
     818             :  * It is an error to use this macro with the `reg` or `interrupts` properties.
     819             :  *
     820             :  * @param node_id node identifier
     821             :  * @param prop a lowercase-and-underscores property with a logical length
     822             :  * @param idx index to check
     823             :  * @return An expression which evaluates to 1 if @p idx is a valid index
     824             :  *         into the given property, and 0 otherwise.
     825             :  */
     826           1 : #define DT_PROP_HAS_IDX(node_id, prop, idx) \
     827             :         IS_ENABLED(DT_CAT6(node_id, _P_, prop, _IDX_, idx, _EXISTS))
     828             : 
     829             : /**
     830             :  * @brief Is name @p name available in a `foo-names` property?
     831             :  *
     832             :  * This property is handled as special case:
     833             :  *
     834             :  * - `interrupts` property: use DT_IRQ_HAS_NAME(node_id, idx) instead
     835             :  *
     836             :  * It is an error to use this macro with the `interrupts` property.
     837             :  *
     838             :  * Example devicetree fragment:
     839             :  *
     840             :  * @code{.dts}
     841             :  *      nx: node-x {
     842             :  *              foos = <&bar xx yy>, <&baz xx zz>;
     843             :  *              foo-names = "event", "error";
     844             :  *              status = "okay";
     845             :  *      };
     846             :  * @endcode
     847             :  *
     848             :  * Example usage:
     849             :  *
     850             :  * @code{.c}
     851             :  *     DT_PROP_HAS_NAME(DT_NODELABEL(nx), foos, event)    // 1
     852             :  *     DT_PROP_HAS_NAME(DT_NODELABEL(nx), foos, failure)  // 0
     853             :  * @endcode
     854             :  *
     855             :  * @param node_id node identifier
     856             :  * @param prop a lowercase-and-underscores `prop-names` type property
     857             :  * @param name a lowercase-and-underscores name to check
     858             :  * @return An expression which evaluates to 1 if "name" is an available
     859             :  *         name into the given property, and 0 otherwise.
     860             :  */
     861           1 : #define DT_PROP_HAS_NAME(node_id, prop, name) \
     862             :         IS_ENABLED(DT_CAT6(node_id, _P_, prop, _NAME_, name, _EXISTS))
     863             : 
     864             : /**
     865             :  * @brief Get the value at index @p idx in an array type property
     866             :  *
     867             :  * It might help to read the argument order as being similar to
     868             :  * `node->property[index]`.
     869             :  *
     870             :  * The return value depends on the property's type:
     871             :  *
     872             :  * - for types array, string-array, uint8-array, and phandles,
     873             :  *   this expands to the idx-th array element as an
     874             :  *   integer, string literal, integer, and node identifier
     875             :  *   respectively
     876             :  *
     877             :  * - for type phandle, idx must be 0 and the expansion is a node
     878             :  *   identifier (this treats phandle like a phandles of length 1)
     879             :  *
     880             :  * - for type string, idx must be 0 and the expansion is the
     881             :  *   entire string (this treats string like string-array of length 1)
     882             :  *
     883             :  * These properties are handled as special cases:
     884             :  *
     885             :  * - `reg`: use DT_REG_ADDR_BY_IDX() or DT_REG_SIZE_BY_IDX() instead
     886             :  * - `interrupts`: use DT_IRQ_BY_IDX()
     887             :  * - `ranges`: use DT_NUM_RANGES()
     888             :  * - `dma-ranges`: it is an error to use this property with
     889             :  *   DT_PROP_BY_IDX()
     890             :  *
     891             :  * For properties of other types, behavior is undefined.
     892             :  *
     893             :  * @param node_id node identifier
     894             :  * @param prop lowercase-and-underscores property name
     895             :  * @param idx the index to get
     896             :  * @return a representation of the idx-th element of the property
     897             :  */
     898           1 : #define DT_PROP_BY_IDX(node_id, prop, idx) \
     899             :         DT_CAT5(node_id, _P_, prop, _IDX_, idx)
     900             : 
     901             : /**
     902             :  * @brief Get the last element of an array type property
     903             :  *
     904             :  * @param node_id node identifier
     905             :  * @param prop lowercase-and-underscores property name
     906             :  *
     907             :  * @return a representation of the last element of the property
     908             :  */
     909           1 : #define DT_PROP_LAST(node_id, prop) \
     910             :         DT_PROP_BY_IDX(node_id, prop, UTIL_DEC(DT_PROP_LEN(node_id, prop)))
     911             : 
     912             : /**
     913             :  * @brief Like DT_PROP(), but with a fallback to @p default_value
     914             :  *
     915             :  * If the value exists, this expands to DT_PROP(node_id, prop).
     916             :  * The @p default_value parameter is not expanded in this case.
     917             :  *
     918             :  * Otherwise, this expands to @p default_value.
     919             :  *
     920             :  * @param node_id node identifier
     921             :  * @param prop lowercase-and-underscores property name
     922             :  * @param default_value a fallback value to expand to
     923             :  * @return the property's value or @p default_value
     924             :  */
     925           1 : #define DT_PROP_OR(node_id, prop, default_value) \
     926             :         COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
     927             :                     (DT_PROP(node_id, prop)), (default_value))
     928             : 
     929             : /**
     930             :  * @brief Get a property array value's index into its enumeration values
     931             :  *
     932             :  * The return values start at zero.
     933             :  *
     934             :  * Example devicetree fragment:
     935             :  *
     936             :  * @code{.dts}
     937             :  *     some_node: some-node {
     938             :  *         compat = "vend,enum-string-array";
     939             :  *         foos =
     940             :  *             <&phandle val1>,
     941             :  *             <&phandle val2>,
     942             :  *             <&phandle val3>;
     943             :  *         foo-names = "default", "option3", "option1";
     944             :  *     };
     945             :  * @endcode
     946             :  *
     947             :  * Example bindings fragment:
     948             :  *
     949             :  * @code{.yaml}
     950             :  * compatible: vend,enum-string-array
     951             :  * properties:
     952             :  *   foos:
     953             :  *     type: phandle-array
     954             :  *     description: |
     955             :  *       Explanation about what this phandle-array exactly is for.
     956             :  *
     957             :  *   foo-names:
     958             :  *     type: string-array
     959             :  *     description: |
     960             :  *       Some explanation about the available options
     961             :  *       default: explain default
     962             :  *       option1: explain option1
     963             :  *       option2: explain option2
     964             :  *       option3: explain option3
     965             :  *     enum:
     966             :  *       - default
     967             :  *       - option1
     968             :  *       - option2
     969             :  *       - option3
     970             :  * @endcode
     971             :  *
     972             :  * Example usage:
     973             :  *
     974             :  * @code{.c}
     975             :  *     DT_ENUM_IDX_BY_IDX(DT_NODELABEL(some_node), foo_names, 0) // 0
     976             :  *     DT_ENUM_IDX_BY_IDX(DT_NODELABEL(some_node), foo_names, 2) // 1
     977             :  * @endcode
     978             :  *
     979             :  * @param node_id node identifier
     980             :  * @param prop lowercase-and-underscores property name
     981             :  * @param idx the index to get
     982             :  * @return zero-based index of the property's value in its enum: list
     983             :  */
     984           1 : #define DT_ENUM_IDX_BY_IDX(node_id, prop, idx) \
     985             :         DT_CAT6(node_id, _P_, prop, _IDX_, idx, _ENUM_IDX)
     986             : 
     987             : /**
     988             :  * @brief Equivalent to @ref DT_ENUM_IDX_BY_IDX(node_id, prop, 0).
     989             :  * @param node_id node identifier
     990             :  * @param prop lowercase-and-underscores property name
     991             :  * @return zero-based index of the property's value in its enum: list
     992             :  */
     993           1 : #define DT_ENUM_IDX(node_id, prop) DT_ENUM_IDX_BY_IDX(node_id, prop, 0)
     994             : 
     995             : /**
     996             :  * @brief Like DT_ENUM_IDX_BY_IDX(), but with a fallback to a default enum index
     997             :  *
     998             :  * If the value exists, this expands to its zero based index value thanks to
     999             :  * DT_ENUM_IDX_BY_IDX(node_id, prop, idx).
    1000             :  *
    1001             :  * Otherwise, this expands to provided default index enum value.
    1002             :  *
    1003             :  * @param node_id node identifier
    1004             :  * @param prop lowercase-and-underscores property name
    1005             :  * @param idx the index to get
    1006             :  * @param default_idx_value a fallback index value to expand to
    1007             :  * @return zero-based index of the property's value in its enum if present,
    1008             :  *         default_idx_value otherwise
    1009             :  */
    1010           1 : #define DT_ENUM_IDX_BY_IDX_OR(node_id, prop, idx, default_idx_value) \
    1011             :         COND_CODE_1(DT_PROP_HAS_IDX(node_id, prop, idx), \
    1012             :                     (DT_ENUM_IDX_BY_IDX(node_id, prop, idx)), (default_idx_value))
    1013             : 
    1014             : /**
    1015             :  * @brief Equivalent to DT_ENUM_IDX_BY_IDX_OR(node_id, prop, 0, default_idx_value).
    1016             :  * @param node_id node identifier
    1017             :  * @param prop lowercase-and-underscores property name
    1018             :  * @param default_idx_value a fallback index value to expand to
    1019             :  * @return zero-based index of the property's value in its enum if present,
    1020             :  *         default_idx_value otherwise
    1021             :  */
    1022           1 : #define DT_ENUM_IDX_OR(node_id, prop, default_idx_value) \
    1023             :         DT_ENUM_IDX_BY_IDX_OR(node_id, prop, 0, default_idx_value)
    1024             : 
    1025             : /**
    1026             :  * @brief Does a node enumeration property array have a given value?
    1027             :  *
    1028             :  * @param node_id node identifier
    1029             :  * @param prop lowercase-and-underscores property name
    1030             :  * @param idx the index to get
    1031             :  * @param value lowercase-and-underscores enumeration value
    1032             :  * @return 1 if the node property has the value @a value, 0 otherwise.
    1033             :  */
    1034           1 : #define DT_ENUM_HAS_VALUE_BY_IDX(node_id, prop, idx, value) \
    1035             :         IS_ENABLED(DT_CAT8(node_id, _P_, prop, _IDX_, idx, _ENUM_VAL_, value, _EXISTS))
    1036             : 
    1037             : /**
    1038             :  * @brief Equivalent to DT_ENUM_HAS_VALUE_BY_IDX(node_id, prop, 0, value).
    1039             :  * @param node_id node identifier
    1040             :  * @param prop lowercase-and-underscores property name
    1041             :  * @param value lowercase-and-underscores enumeration value
    1042             :  * @return 1 if the node property has the value @a value, 0 otherwise.
    1043             :  */
    1044           1 : #define DT_ENUM_HAS_VALUE(node_id, prop, value) \
    1045             :         DT_ENUM_HAS_VALUE_BY_IDX(node_id, prop, 0, value)
    1046             : 
    1047             : /**
    1048             :  * @brief Get a string property's value as a token.
    1049             :  *
    1050             :  * This removes "the quotes" from a string property's value,
    1051             :  * converting any non-alphanumeric characters to underscores. This can
    1052             :  * be useful, for example, when programmatically using the value to
    1053             :  * form a C variable or code.
    1054             :  *
    1055             :  * DT_STRING_TOKEN() can only be used for properties with string type.
    1056             :  *
    1057             :  * It is an error to use DT_STRING_TOKEN() in other circumstances.
    1058             :  *
    1059             :  * Example devicetree fragment:
    1060             :  *
    1061             :  * @code{.dts}
    1062             :  *     n1: node-1 {
    1063             :  *             prop = "foo";
    1064             :  *     };
    1065             :  *     n2: node-2 {
    1066             :  *             prop = "FOO";
    1067             :  *     }
    1068             :  *     n3: node-3 {
    1069             :  *             prop = "123 foo";
    1070             :  *     };
    1071             :  * @endcode
    1072             :  *
    1073             :  * Example bindings fragment:
    1074             :  *
    1075             :  * @code{.yaml}
    1076             :  *     properties:
    1077             :  *       prop:
    1078             :  *         type: string
    1079             :  * @endcode
    1080             :  *
    1081             :  * Example usage:
    1082             :  *
    1083             :  * @code{.c}
    1084             :  *     DT_STRING_TOKEN(DT_NODELABEL(n1), prop) // foo
    1085             :  *     DT_STRING_TOKEN(DT_NODELABEL(n2), prop) // FOO
    1086             :  *     DT_STRING_TOKEN(DT_NODELABEL(n3), prop) // 123_foo
    1087             :  * @endcode
    1088             :  *
    1089             :  * Notice how:
    1090             :  *
    1091             :  * - Unlike C identifiers, the property values may begin with a
    1092             :  *   number. It's the user's responsibility not to use such values as
    1093             :  *   the name of a C identifier.
    1094             :  *
    1095             :  * - The uppercased `"FOO"` in the DTS remains `FOO` as a token. It is
    1096             :  *   *not* converted to `foo`.
    1097             :  *
    1098             :  * - The whitespace in the DTS `"123 foo"` string is converted to
    1099             :  *   `123_foo` as a token.
    1100             :  *
    1101             :  * @param node_id node identifier
    1102             :  * @param prop lowercase-and-underscores property name
    1103             :  * @return the value of @p prop as a token, i.e. without any quotes
    1104             :  *         and with special characters converted to underscores
    1105             :  */
    1106           1 : #define DT_STRING_TOKEN(node_id, prop) \
    1107             :         DT_CAT4(node_id, _P_, prop, _STRING_TOKEN)
    1108             : 
    1109             : /**
    1110             :  * @brief Like DT_STRING_TOKEN(), but with a fallback to @p default_value
    1111             :  *
    1112             :  * If the value exists, this expands to DT_STRING_TOKEN(node_id, prop).
    1113             :  * The @p default_value parameter is not expanded in this case.
    1114             :  *
    1115             :  * Otherwise, this expands to @p default_value.
    1116             :  *
    1117             :  * @param node_id node identifier
    1118             :  * @param prop lowercase-and-underscores property name
    1119             :  * @param default_value a fallback value to expand to
    1120             :  * @return the property's value as a token, or @p default_value
    1121             :  */
    1122           1 : #define DT_STRING_TOKEN_OR(node_id, prop, default_value) \
    1123             :         COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
    1124             :                 (DT_STRING_TOKEN(node_id, prop)), (default_value))
    1125             : 
    1126             : /**
    1127             :  * @brief Like DT_STRING_TOKEN(), but uppercased.
    1128             :  *
    1129             :  * This removes "the quotes" from a string property's value,
    1130             :  * converting any non-alphanumeric characters to underscores, and
    1131             :  * capitalizing the result. This can be useful, for example, when
    1132             :  * programmatically using the value to form a C variable or code.
    1133             :  *
    1134             :  * DT_STRING_UPPER_TOKEN() can only be used for properties with string type.
    1135             :  *
    1136             :  * It is an error to use DT_STRING_UPPER_TOKEN() in other circumstances.
    1137             :  *
    1138             :  * Example devicetree fragment:
    1139             :  *
    1140             :  * @code{.dts}
    1141             :  *     n1: node-1 {
    1142             :  *             prop = "foo";
    1143             :  *     };
    1144             :  *     n2: node-2 {
    1145             :  *             prop = "123 foo";
    1146             :  *     };
    1147             :  * @endcode
    1148             :  *
    1149             :  * Example bindings fragment:
    1150             :  *
    1151             :  * @code{.yaml}
    1152             :  *     properties:
    1153             :  *       prop:
    1154             :  *         type: string
    1155             :  *
    1156             :  * @endcode
    1157             :  *
    1158             :  * Example usage:
    1159             :  *
    1160             :  * @code{.c}
    1161             :  *     DT_STRING_UPPER_TOKEN(DT_NODELABEL(n1), prop) // FOO
    1162             :  *     DT_STRING_UPPER_TOKEN(DT_NODELABEL(n2), prop) // 123_FOO
    1163             :  * @endcode
    1164             :  *
    1165             :  * Notice how:
    1166             :  *
    1167             :  * - Unlike C identifiers, the property values may begin with a
    1168             :  *   number. It's the user's responsibility not to use such values as
    1169             :  *   the name of a C identifier.
    1170             :  *
    1171             :  * - The lowercased `"foo"` in the DTS becomes `FOO` as a token, i.e.
    1172             :  *   it is uppercased.
    1173             :  *
    1174             :  * - The whitespace in the DTS `"123 foo"` string is converted to
    1175             :  *   `123_FOO` as a token, i.e. it is uppercased and whitespace becomes
    1176             :  *   an underscore.
    1177             :  *
    1178             :  * @param node_id node identifier
    1179             :  * @param prop lowercase-and-underscores property name
    1180             :  * @return the value of @p prop as an uppercased token, i.e. without
    1181             :  *         any quotes and with special characters converted to underscores
    1182             :  */
    1183           1 : #define DT_STRING_UPPER_TOKEN(node_id, prop) \
    1184             :         DT_CAT4(node_id, _P_, prop, _STRING_UPPER_TOKEN)
    1185             : 
    1186             : /**
    1187             :  * @brief Like DT_STRING_UPPER_TOKEN(), but with a fallback to @p default_value
    1188             :  *
    1189             :  * If the value exists, this expands to DT_STRING_UPPER_TOKEN(node_id, prop).
    1190             :  * The @p default_value parameter is not expanded in this case.
    1191             :  *
    1192             :  * Otherwise, this expands to @p default_value.
    1193             :  *
    1194             :  * @param node_id node identifier
    1195             :  * @param prop lowercase-and-underscores property name
    1196             :  * @param default_value a fallback value to expand to
    1197             :  * @return the property's value as an uppercased token,
    1198             :  *         or @p default_value
    1199             :  */
    1200           1 : #define DT_STRING_UPPER_TOKEN_OR(node_id, prop, default_value) \
    1201             :         COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
    1202             :                 (DT_STRING_UPPER_TOKEN(node_id, prop)), (default_value))
    1203             : 
    1204             : /**
    1205             :  * @brief Get a string property's value as an unquoted sequence of tokens
    1206             :  *
    1207             :  * This removes "the quotes" from string-valued properties.
    1208             :  * That can be useful, for example,
    1209             :  * when defining floating point values as a string in devicetree
    1210             :  * that you would like to use to initialize a float or double variable in C.
    1211             :  *
    1212             :  * DT_STRING_UNQUOTED() can only be used for properties with string type.
    1213             :  *
    1214             :  * It is an error to use DT_STRING_UNQUOTED() in other circumstances.
    1215             :  *
    1216             :  * Example devicetree fragment:
    1217             :  *
    1218             :  *     n1: node-1 {
    1219             :  *             prop = "12.7";
    1220             :  *     };
    1221             :  *     n2: node-2 {
    1222             :  *             prop = "0.5";
    1223             :  *     }
    1224             :  *     n3: node-3 {
    1225             :  *             prop = "A B C";
    1226             :  *     };
    1227             :  *
    1228             :  * Example bindings fragment:
    1229             :  *
    1230             :  *     properties:
    1231             :  *       prop:
    1232             :  *         type: string
    1233             :  *
    1234             :  * Example usage:
    1235             :  *
    1236             :  *     DT_STRING_UNQUOTED(DT_NODELABEL(n1), prop) // 12.7
    1237             :  *     DT_STRING_UNQUOTED(DT_NODELABEL(n2), prop) // 0.5
    1238             :  *     DT_STRING_UNQUOTED(DT_NODELABEL(n3), prop) // A B C
    1239             :  *
    1240             :  * @param node_id node identifier
    1241             :  * @param prop lowercase-and-underscores property name
    1242             :  * @return the property's value as a sequence of tokens, with no quotes
    1243             :  */
    1244           1 : #define DT_STRING_UNQUOTED(node_id, prop) \
    1245             :         DT_CAT4(node_id, _P_, prop, _STRING_UNQUOTED)
    1246             : 
    1247             : /**
    1248             :  * @brief Like DT_STRING_UNQUOTED(), but with a fallback to @p default_value
    1249             :  *
    1250             :  * If the value exists, this expands to DT_STRING_UNQUOTED(node_id, prop).
    1251             :  * The @p default_value parameter is not expanded in this case.
    1252             :  *
    1253             :  * Otherwise, this expands to @p default_value.
    1254             :  *
    1255             :  * @param node_id node identifier
    1256             :  * @param prop lowercase-and-underscores property name
    1257             :  * @param default_value a fallback value to expand to
    1258             :  * @return the property's value as a sequence of tokens, with no quotes,
    1259             :  *         or @p default_value
    1260             :  */
    1261           1 : #define DT_STRING_UNQUOTED_OR(node_id, prop, default_value) \
    1262             :         COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
    1263             :                 (DT_STRING_UNQUOTED(node_id, prop)), (default_value))
    1264             : 
    1265             : /**
    1266             :  * @brief Get an element out of a string-array property as a token.
    1267             :  *
    1268             :  * This removes "the quotes" from an element in the array, and converts
    1269             :  * non-alphanumeric characters to underscores. That can be useful, for example,
    1270             :  * when programmatically using the value to form a C variable or code.
    1271             :  *
    1272             :  * DT_STRING_TOKEN_BY_IDX() can only be used for properties with
    1273             :  * string-array type.
    1274             :  *
    1275             :  * It is an error to use DT_STRING_TOKEN_BY_IDX() in other circumstances.
    1276             :  *
    1277             :  * Example devicetree fragment:
    1278             :  *
    1279             :  * @code{.dts}
    1280             :  *     n1: node-1 {
    1281             :  *             prop = "f1", "F2";
    1282             :  *     };
    1283             :  *     n2: node-2 {
    1284             :  *             prop = "123 foo", "456 FOO";
    1285             :  *     };
    1286             :  * @endcode
    1287             :  *
    1288             :  * Example bindings fragment:
    1289             :  *
    1290             :  * @code{.yaml}
    1291             :  *     properties:
    1292             :  *       prop:
    1293             :  *         type: string-array
    1294             :  * @endcode
    1295             :  *
    1296             :  * Example usage:
    1297             :  *
    1298             :  * @code{.c}
    1299             :  *     DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 0) // f1
    1300             :  *     DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 1) // F2
    1301             :  *     DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 0) // 123_foo
    1302             :  *     DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 1) // 456_FOO
    1303             :  * @endcode
    1304             :  *
    1305             :  * For more information, see @ref DT_STRING_TOKEN.
    1306             :  *
    1307             :  * @param node_id node identifier
    1308             :  * @param prop lowercase-and-underscores property name
    1309             :  * @param idx the index to get
    1310             :  * @return the element in @p prop at index @p idx as a token
    1311             :  */
    1312           1 : #define DT_STRING_TOKEN_BY_IDX(node_id, prop, idx) \
    1313             :         DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_TOKEN)
    1314             : 
    1315             : /**
    1316             :  * @brief Like DT_STRING_TOKEN_BY_IDX(), but uppercased.
    1317             :  *
    1318             :  * This removes "the quotes" and capitalizes an element in the array, and
    1319             :  * converts non-alphanumeric characters to underscores. That can be useful, for
    1320             :  * example, when programmatically using the value to form a C variable or code.
    1321             :  *
    1322             :  * DT_STRING_UPPER_TOKEN_BY_IDX() can only be used for properties with
    1323             :  * string-array type.
    1324             :  *
    1325             :  * It is an error to use DT_STRING_UPPER_TOKEN_BY_IDX() in other circumstances.
    1326             :  *
    1327             :  * Example devicetree fragment:
    1328             :  *
    1329             :  * @code{.dts}
    1330             :  *     n1: node-1 {
    1331             :  *             prop = "f1", "F2";
    1332             :  *     };
    1333             :  *     n2: node-2 {
    1334             :  *             prop = "123 foo", "456 FOO";
    1335             :  *     };
    1336             :  * @endcode
    1337             :  *
    1338             :  * Example bindings fragment:
    1339             :  *
    1340             :  * @code{.yaml}
    1341             :  *     properties:
    1342             :  *       prop:
    1343             :  *         type: string-array
    1344             :  * @endcode
    1345             :  *
    1346             :  * Example usage:
    1347             :  *
    1348             :  * @code{.c}
    1349             :  *     DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 0) // F1
    1350             :  *     DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 1) // F2
    1351             :  *     DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 0) // 123_FOO
    1352             :  *     DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 1) // 456_FOO
    1353             :  * @endcode
    1354             :  *
    1355             :  * For more information, see @ref DT_STRING_UPPER_TOKEN.
    1356             :  *
    1357             :  * @param node_id node identifier
    1358             :  * @param prop lowercase-and-underscores property name
    1359             :  * @param idx the index to get
    1360             :  * @return the element in @p prop at index @p idx as an uppercased token
    1361             :  */
    1362           1 : #define DT_STRING_UPPER_TOKEN_BY_IDX(node_id, prop, idx) \
    1363             :         DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_UPPER_TOKEN)
    1364             : 
    1365             : /**
    1366             :  * @brief Get a string array item value as an unquoted sequence of tokens.
    1367             :  *
    1368             :  * This removes "the quotes" from string-valued item.
    1369             :  * That can be useful, for example,
    1370             :  * when defining floating point values as a string in devicetree
    1371             :  * that you would like to use to initialize a float or double variable in C.
    1372             :  *
    1373             :  * DT_STRING_UNQUOTED_BY_IDX() can only be used for properties with
    1374             :  * string-array type.
    1375             :  *
    1376             :  * It is an error to use DT_STRING_UNQUOTED_BY_IDX() in other circumstances.
    1377             :  *
    1378             :  * Example devicetree fragment:
    1379             :  *
    1380             :  *     n1: node-1 {
    1381             :  *             prop = "12.7", "34.1";
    1382             :  *     };
    1383             :  *     n2: node-2 {
    1384             :  *             prop = "A B", "C D";
    1385             :  *     }
    1386             :  *
    1387             :  * Example bindings fragment:
    1388             :  *
    1389             :  *     properties:
    1390             :  *       prop:
    1391             :  *         type: string-array
    1392             :  *
    1393             :  * Example usage:
    1394             :  *
    1395             :  *     DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n1), prop, 0) // 12.7
    1396             :  *     DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n1), prop, 1) // 34.1
    1397             :  *     DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n2), prop, 0) // A B
    1398             :  *     DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n2), prop, 1) // C D
    1399             :  *
    1400             :  * @param node_id node identifier
    1401             :  * @param prop lowercase-and-underscores property name
    1402             :  * @param idx the index to get
    1403             :  * @return the property's value as a sequence of tokens, with no quotes
    1404             :  */
    1405           1 : #define DT_STRING_UNQUOTED_BY_IDX(node_id, prop, idx) \
    1406             :         DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_UNQUOTED)
    1407             : 
    1408             : /*
    1409             :  * phandle properties
    1410             :  *
    1411             :  * These are special-cased to manage the impedance mismatch between
    1412             :  * phandles, which are just uint32_t node properties that only make sense
    1413             :  * within the tree itself, and C values.
    1414             :  */
    1415             : 
    1416             : /**
    1417             :  * @brief Get a property value from a phandle in a property.
    1418             :  *
    1419             :  * This is a shorthand for:
    1420             :  *
    1421             :  * @code{.c}
    1422             :  *     DT_PROP(DT_PHANDLE_BY_IDX(node_id, phs, idx), prop)
    1423             :  * @endcode
    1424             :  *
    1425             :  * That is, @p prop is a property of the phandle's node, not a
    1426             :  * property of @p node_id.
    1427             :  *
    1428             :  * Example devicetree fragment:
    1429             :  *
    1430             :  * @code{.dts}
    1431             :  *     n1: node-1 {
    1432             :  *             foo = <&n2 &n3>;
    1433             :  *     };
    1434             :  *
    1435             :  *     n2: node-2 {
    1436             :  *             bar = <42>;
    1437             :  *     };
    1438             :  *
    1439             :  *     n3: node-3 {
    1440             :  *             baz = <43>;
    1441             :  *     };
    1442             :  * @endcode
    1443             :  *
    1444             :  * Example usage:
    1445             :  *
    1446             :  * @code{.c}
    1447             :  *     #define N1 DT_NODELABEL(n1)
    1448             :  *
    1449             :  *     DT_PROP_BY_PHANDLE_IDX(N1, foo, 0, bar) // 42
    1450             :  *     DT_PROP_BY_PHANDLE_IDX(N1, foo, 1, baz) // 43
    1451             :  * @endcode
    1452             :  *
    1453             :  * @param node_id node identifier
    1454             :  * @param phs lowercase-and-underscores property with type `phandle`,
    1455             :  *            `phandles`, or `phandle-array`
    1456             :  * @param idx logical index into @p phs, which must be zero if @p phs
    1457             :  *            has type `phandle`
    1458             :  * @param prop lowercase-and-underscores property of the phandle's node
    1459             :  * @return the property's value
    1460             :  */
    1461           1 : #define DT_PROP_BY_PHANDLE_IDX(node_id, phs, idx, prop) \
    1462             :         DT_PROP(DT_PHANDLE_BY_IDX(node_id, phs, idx), prop)
    1463             : 
    1464             : /**
    1465             :  * @brief Like DT_PROP_BY_PHANDLE_IDX(), but with a fallback to
    1466             :  * @p default_value.
    1467             :  *
    1468             :  * If the value exists, this expands to DT_PROP_BY_PHANDLE_IDX(node_id, phs,
    1469             :  * idx, prop). The @p default_value parameter is not expanded in this
    1470             :  * case.
    1471             :  *
    1472             :  * Otherwise, this expands to @p default_value.
    1473             :  *
    1474             :  * @param node_id node identifier
    1475             :  * @param phs lowercase-and-underscores property with type `phandle`,
    1476             :  *            `phandles`, or `phandle-array`
    1477             :  * @param idx logical index into @p phs, which must be zero if @p phs
    1478             :  *            has type `phandle`
    1479             :  * @param prop lowercase-and-underscores property of the phandle's node
    1480             :  * @param default_value a fallback value to expand to
    1481             :  * @return the property's value
    1482             :  */
    1483           1 : #define DT_PROP_BY_PHANDLE_IDX_OR(node_id, phs, idx, prop, default_value) \
    1484             :         DT_PROP_OR(DT_PHANDLE_BY_IDX(node_id, phs, idx), prop, default_value)
    1485             : 
    1486             : /**
    1487             :  * @brief Get a property value from a phandle's node
    1488             :  *
    1489             :  * This is equivalent to DT_PROP_BY_PHANDLE_IDX(node_id, ph, 0, prop).
    1490             :  *
    1491             :  * @param node_id node identifier
    1492             :  * @param ph lowercase-and-underscores property of @p node_id
    1493             :  *           with type `phandle`
    1494             :  * @param prop lowercase-and-underscores property of the phandle's node
    1495             :  * @return the property's value
    1496             :  */
    1497           1 : #define DT_PROP_BY_PHANDLE(node_id, ph, prop) \
    1498             :         DT_PROP_BY_PHANDLE_IDX(node_id, ph, 0, prop)
    1499             : 
    1500             : /**
    1501             :  * @brief Get a phandle-array specifier cell value at an index
    1502             :  *
    1503             :  * It might help to read the argument order as being similar to
    1504             :  * `node->phandle_array[index].cell`. That is, the cell value is in
    1505             :  * the @p pha property of @p node_id, inside the specifier at index
    1506             :  * @p idx.
    1507             :  *
    1508             :  * Example devicetree fragment:
    1509             :  *
    1510             :  * @code{.dts}
    1511             :  *     gpio0: gpio@abcd1234 {
    1512             :  *             #gpio-cells = <2>;
    1513             :  *     };
    1514             :  *
    1515             :  *     gpio1: gpio@1234abcd {
    1516             :  *             #gpio-cells = <2>;
    1517             :  *     };
    1518             :  *
    1519             :  *     led: led_0 {
    1520             :  *             gpios = <&gpio0 17 0x1>, <&gpio1 5 0x3>;
    1521             :  *     };
    1522             :  * @endcode
    1523             :  *
    1524             :  * Bindings fragment for the `gpio0` and `gpio1` nodes:
    1525             :  *
    1526             :  * @code{.yaml}
    1527             :  *     gpio-cells:
    1528             :  *       - pin
    1529             :  *       - flags
    1530             :  * @endcode
    1531             :  *
    1532             :  * Above, `gpios` has two elements:
    1533             :  *
    1534             :  * - index 0 has specifier <17 0x1>, so its `pin` cell is 17, and its
    1535             :  *   `flags` cell is 0x1
    1536             :  * - index 1 has specifier <5 0x3>, so `pin` is 5 and `flags` is 0x3
    1537             :  *
    1538             :  * Example usage:
    1539             :  *
    1540             :  * @code{.c}
    1541             :  *     #define LED DT_NODELABEL(led)
    1542             :  *
    1543             :  *     DT_PHA_BY_IDX(LED, gpios, 0, pin)   // 17
    1544             :  *     DT_PHA_BY_IDX(LED, gpios, 1, flags) // 0x3
    1545             :  * @endcode
    1546             :  *
    1547             :  * @param node_id node identifier
    1548             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    1549             :  * @param idx logical index into @p pha
    1550             :  * @param cell lowercase-and-underscores cell name within the specifier
    1551             :  *             at @p pha index @p idx
    1552             :  * @return the cell's value
    1553             :  */
    1554           1 : #define DT_PHA_BY_IDX(node_id, pha, idx, cell) \
    1555             :         DT_CAT7(node_id, _P_, pha, _IDX_, idx, _VAL_, cell)
    1556             : 
    1557             : /**
    1558             :  * @brief Like DT_PHA_BY_IDX(), but with a fallback to @p default_value.
    1559             :  *
    1560             :  * If the value exists, this expands to DT_PHA_BY_IDX(node_id, pha,
    1561             :  * idx, cell). The @p default_value parameter is not expanded in this
    1562             :  * case.
    1563             :  *
    1564             :  * Otherwise, this expands to @p default_value.
    1565             :  *
    1566             :  * @internal
    1567             :  * Implementation note: the _IDX_##idx##_VAL_##cell##_EXISTS macros are
    1568             :  * defined, so it's safe to use DT_PROP_OR() here, because that uses an
    1569             :  * IS_ENABLED() on the _EXISTS macro.
    1570             :  * @endinternal
    1571             :  *
    1572             :  * @param node_id node identifier
    1573             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    1574             :  * @param idx logical index into @p pha
    1575             :  * @param cell lowercase-and-underscores cell name within the specifier
    1576             :  *             at @p pha index @p idx
    1577             :  * @param default_value a fallback value to expand to
    1578             :  * @return the cell's value or @p default_value
    1579             :  */
    1580           1 : #define DT_PHA_BY_IDX_OR(node_id, pha, idx, cell, default_value) \
    1581             :         DT_PROP_OR(node_id, DT_CAT5(pha, _IDX_, idx, _VAL_, cell), default_value)
    1582             : 
    1583             : /**
    1584             :  * @brief Equivalent to DT_PHA_BY_IDX(node_id, pha, 0, cell)
    1585             :  * @param node_id node identifier
    1586             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    1587             :  * @param cell lowercase-and-underscores cell name
    1588             :  * @return the cell's value
    1589             :  */
    1590           1 : #define DT_PHA(node_id, pha, cell) DT_PHA_BY_IDX(node_id, pha, 0, cell)
    1591             : 
    1592             : /**
    1593             :  * @brief Like DT_PHA(), but with a fallback to @p default_value
    1594             :  *
    1595             :  * If the value exists, this expands to DT_PHA(node_id, pha, cell).
    1596             :  * The @p default_value parameter is not expanded in this case.
    1597             :  *
    1598             :  * Otherwise, this expands to @p default_value.
    1599             :  *
    1600             :  * @param node_id node identifier
    1601             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    1602             :  * @param cell lowercase-and-underscores cell name
    1603             :  * @param default_value a fallback value to expand to
    1604             :  * @return the cell's value or @p default_value
    1605             :  */
    1606           1 : #define DT_PHA_OR(node_id, pha, cell, default_value) \
    1607             :         DT_PHA_BY_IDX_OR(node_id, pha, 0, cell, default_value)
    1608             : 
    1609             : /**
    1610             :  * @brief Get a value within a phandle-array specifier by name
    1611             :  *
    1612             :  * This is like DT_PHA_BY_IDX(), except it treats @p pha as a structure
    1613             :  * where each array element has a name.
    1614             :  *
    1615             :  * It might help to read the argument order as being similar to
    1616             :  * `node->phandle_struct.name.cell`. That is, the cell value is in the
    1617             :  * @p pha property of @p node_id, treated as a data structure where
    1618             :  * each array element has a name.
    1619             :  *
    1620             :  * Example devicetree fragment:
    1621             :  *
    1622             :  * @code{.dts}
    1623             :  *     n: node {
    1624             :  *             io-channels = <&adc1 10>, <&adc2 20>;
    1625             :  *             io-channel-names = "SENSOR", "BANDGAP";
    1626             :  *     };
    1627             :  * @endcode
    1628             :  *
    1629             :  * Bindings fragment for the "adc1" and "adc2" nodes:
    1630             :  *
    1631             :  * @code{.yaml}
    1632             :  *     io-channel-cells:
    1633             :  *       - input
    1634             :  * @endcode
    1635             :  *
    1636             :  * Example usage:
    1637             :  *
    1638             :  * @code{.c}
    1639             :  *     DT_PHA_BY_NAME(DT_NODELABEL(n), io_channels, sensor, input)  // 10
    1640             :  *     DT_PHA_BY_NAME(DT_NODELABEL(n), io_channels, bandgap, input) // 20
    1641             :  * @endcode
    1642             :  *
    1643             :  * @param node_id node identifier
    1644             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    1645             :  * @param name lowercase-and-underscores name of a specifier in @p pha
    1646             :  * @param cell lowercase-and-underscores cell name in the named specifier
    1647             :  * @return the cell's value
    1648             :  */
    1649           1 : #define DT_PHA_BY_NAME(node_id, pha, name, cell) \
    1650             :         DT_CAT7(node_id, _P_, pha, _NAME_, name, _VAL_, cell)
    1651             : 
    1652             : /**
    1653             :  * @brief Like DT_PHA_BY_NAME(), but with a fallback to @p default_value
    1654             :  *
    1655             :  * If the value exists, this expands to DT_PHA_BY_NAME(node_id, pha,
    1656             :  * name, cell). The @p default_value parameter is not expanded in this case.
    1657             :  *
    1658             :  * Otherwise, this expands to @p default_value.
    1659             :  *
    1660             :  * @internal
    1661             :  * Implementation note: the `_NAME_##name##_VAL_##cell##_EXISTS` macros are
    1662             :  * defined, so it's safe to use DT_PROP_OR() here, because that uses an
    1663             :  * IS_ENABLED() on the `_EXISTS` macro.
    1664             :  * @endinternal
    1665             :  *
    1666             :  * @param node_id node identifier
    1667             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    1668             :  * @param name lowercase-and-underscores name of a specifier in @p pha
    1669             :  * @param cell lowercase-and-underscores cell name in the named specifier
    1670             :  * @param default_value a fallback value to expand to
    1671             :  * @return the cell's value or @p default_value
    1672             :  */
    1673           1 : #define DT_PHA_BY_NAME_OR(node_id, pha, name, cell, default_value) \
    1674             :         DT_PROP_OR(node_id, DT_CAT5(pha, _NAME_, name, _VAL_, cell), default_value)
    1675             : 
    1676             : /**
    1677             :  * @brief Get a phandle's node identifier from a phandle array by @p name
    1678             :  *
    1679             :  * It might help to read the argument order as being similar to
    1680             :  * `node->phandle_struct.name.phandle`. That is, the phandle array is
    1681             :  * treated as a structure with named elements. The return value is
    1682             :  * the node identifier for a phandle inside the structure.
    1683             :  *
    1684             :  * Example devicetree fragment:
    1685             :  *
    1686             :  * @code{.dts}
    1687             :  *     adc1: adc@abcd1234 {
    1688             :  *             foobar = "ADC_1";
    1689             :  *     };
    1690             :  *
    1691             :  *     adc2: adc@1234abcd {
    1692             :  *             foobar = "ADC_2";
    1693             :  *     };
    1694             :  *
    1695             :  *     n: node {
    1696             :  *             io-channels = <&adc1 10>, <&adc2 20>;
    1697             :  *             io-channel-names = "SENSOR", "BANDGAP";
    1698             :  *     };
    1699             :  * @endcode
    1700             :  *
    1701             :  * Above, "io-channels" has two elements:
    1702             :  *
    1703             :  * - the element named `"SENSOR"` has phandle `&adc1`
    1704             :  * - the element named `"BANDGAP"` has phandle `&adc2`
    1705             :  *
    1706             :  * Example usage:
    1707             :  *
    1708             :  * @code{.c}
    1709             :  *     #define NODE DT_NODELABEL(n)
    1710             :  *
    1711             :  *     DT_PROP(DT_PHANDLE_BY_NAME(NODE, io_channels, sensor), foobar)  // "ADC_1"
    1712             :  *     DT_PROP(DT_PHANDLE_BY_NAME(NODE, io_channels, bandgap), foobar) // "ADC_2"
    1713             :  * @endcode
    1714             :  *
    1715             :  * Notice how devicetree properties and names are lowercased, and
    1716             :  * non-alphanumeric characters are converted to underscores.
    1717             :  *
    1718             :  * @param node_id node identifier
    1719             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    1720             :  * @param name lowercase-and-underscores name of an element in @p pha
    1721             :  * @return a node identifier for the node with that phandle
    1722             :  */
    1723           1 : #define DT_PHANDLE_BY_NAME(node_id, pha, name) \
    1724             :         DT_CAT6(node_id, _P_, pha, _NAME_, name, _PH)
    1725             : 
    1726             : /**
    1727             :  * @brief Get a node identifier for a phandle in a property.
    1728             :  *
    1729             :  * When a node's value at a logical index contains a phandle, this
    1730             :  * macro returns a node identifier for the node with that phandle.
    1731             :  *
    1732             :  * Therefore, if @p prop has type `phandle`, @p idx must be zero. (A
    1733             :  * `phandle` type is treated as a `phandles` with a fixed length of
    1734             :  * 1).
    1735             :  *
    1736             :  * Example devicetree fragment:
    1737             :  *
    1738             :  * @code{.dts}
    1739             :  *     n1: node-1 {
    1740             :  *             foo = <&n2 &n3>;
    1741             :  *     };
    1742             :  *
    1743             :  *     n2: node-2 { ... };
    1744             :  *     n3: node-3 { ... };
    1745             :  * @endcode
    1746             :  *
    1747             :  * Above, `foo` has type phandles and has two elements:
    1748             :  *
    1749             :  * - index 0 has phandle `&n2`, which is `node-2`'s phandle
    1750             :  * - index 1 has phandle `&n3`, which is `node-3`'s phandle
    1751             :  *
    1752             :  * Example usage:
    1753             :  *
    1754             :  * @code{.c}
    1755             :  *     #define N1 DT_NODELABEL(n1)
    1756             :  *
    1757             :  *     DT_PHANDLE_BY_IDX(N1, foo, 0) // node identifier for node-2
    1758             :  *     DT_PHANDLE_BY_IDX(N1, foo, 1) // node identifier for node-3
    1759             :  * @endcode
    1760             :  *
    1761             :  * Behavior is analogous for phandle-arrays.
    1762             :  *
    1763             :  * @internal
    1764             :  * Implementation note: using DT_CAT6 above defers concatenation until
    1765             :  * after expansion of each parameter. This is important when 'idx' is
    1766             :  * expandable to a number, but it isn't one "yet".
    1767             :  * @endinternal
    1768             :  *
    1769             :  * @param node_id node identifier
    1770             :  * @param prop lowercase-and-underscores property name in @p node_id
    1771             :  *             with type `phandle`, `phandles` or `phandle-array`
    1772             :  * @param idx index into @p prop
    1773             :  * @return node identifier for the node with the phandle at that index
    1774             :  */
    1775           1 : #define DT_PHANDLE_BY_IDX(node_id, prop, idx) \
    1776             :         DT_CAT6(node_id, _P_, prop, _IDX_, idx, _PH)
    1777             : 
    1778             : /**
    1779             :  * @brief Get a node identifier for a phandle property's value
    1780             :  *
    1781             :  * This is equivalent to DT_PHANDLE_BY_IDX(node_id, prop, 0). Its primary
    1782             :  * benefit is readability when @p prop has type `phandle`.
    1783             :  *
    1784             :  * @param node_id node identifier
    1785             :  * @param prop lowercase-and-underscores property of @p node_id
    1786             :  *             with type `phandle`
    1787             :  * @return a node identifier for the node pointed to by "ph"
    1788             :  */
    1789           1 : #define DT_PHANDLE(node_id, prop) DT_PHANDLE_BY_IDX(node_id, prop, 0)
    1790             : 
    1791             : /**
    1792             :  * @}
    1793             :  */
    1794             : 
    1795             : /**
    1796             :  * @defgroup devicetree-ranges-prop ranges property
    1797             :  * @ingroup devicetree
    1798             :  * @{
    1799             :  */
    1800             : 
    1801             : /**
    1802             :  * @brief Get the number of range blocks in the ranges property
    1803             :  *
    1804             :  * Use this instead of DT_PROP_LEN(node_id, ranges).
    1805             :  *
    1806             :  * Example devicetree fragment:
    1807             :  *
    1808             :  * @code{.dts}
    1809             :  *     pcie0: pcie@0 {
    1810             :  *             compatible = "pcie-controller";
    1811             :  *             reg = <0 1>;
    1812             :  *             #address-cells = <3>;
    1813             :  *             #size-cells = <2>;
    1814             :  *
    1815             :  *             ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
    1816             :  *                      <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
    1817             :  *                      <0x3000000 0x80 0 0x80 0 0x80 0>;
    1818             :  *     };
    1819             :  *
    1820             :  *     other: other@1 {
    1821             :  *             reg = <1 1>;
    1822             :  *
    1823             :  *             ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
    1824             :  *                      <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
    1825             :  *     };
    1826             :  * @endcode
    1827             :  *
    1828             :  * Example usage:
    1829             :  *
    1830             :  * @code{.c}
    1831             :  *     DT_NUM_RANGES(DT_NODELABEL(pcie0)) // 3
    1832             :  *     DT_NUM_RANGES(DT_NODELABEL(other)) // 2
    1833             :  * @endcode
    1834             :  *
    1835             :  * @param node_id node identifier
    1836             :  */
    1837           1 : #define DT_NUM_RANGES(node_id) DT_CAT(node_id, _RANGES_NUM)
    1838             : 
    1839             : /**
    1840             :  * @brief Is @p idx a valid range block index?
    1841             :  *
    1842             :  * If this returns 1, then DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(node_id, idx),
    1843             :  * DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(node_id, idx) or
    1844             :  * DT_RANGES_LENGTH_BY_IDX(node_id, idx) are valid.
    1845             :  * For DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx) the return value
    1846             :  * of DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(node_id, idx) will indicate
    1847             :  * validity.
    1848             :  * If it returns 0, it is an error to use those macros with index @p idx,
    1849             :  * including DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx).
    1850             :  *
    1851             :  * Example devicetree fragment:
    1852             :  *
    1853             :  * @code{.dts}
    1854             :  *     pcie0: pcie@0 {
    1855             :  *             compatible = "pcie-controller";
    1856             :  *             reg = <0 1>;
    1857             :  *             #address-cells = <3>;
    1858             :  *             #size-cells = <2>;
    1859             :  *
    1860             :  *             ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
    1861             :  *                      <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
    1862             :  *                      <0x3000000 0x80 0 0x80 0 0x80 0>;
    1863             :  *     };
    1864             :  *
    1865             :  *     other: other@1 {
    1866             :  *             reg = <1 1>;
    1867             :  *
    1868             :  *             ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
    1869             :  *                      <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
    1870             :  *     };
    1871             :  * @endcode
    1872             :  *
    1873             :  * Example usage:
    1874             :  *
    1875             :  * @code{.c}
    1876             :  *     DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 0) // 1
    1877             :  *     DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 1) // 1
    1878             :  *     DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 2) // 1
    1879             :  *     DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 3) // 0
    1880             :  *     DT_RANGES_HAS_IDX(DT_NODELABEL(other), 0) // 1
    1881             :  *     DT_RANGES_HAS_IDX(DT_NODELABEL(other), 1) // 1
    1882             :  *     DT_RANGES_HAS_IDX(DT_NODELABEL(other), 2) // 0
    1883             :  *     DT_RANGES_HAS_IDX(DT_NODELABEL(other), 3) // 0
    1884             :  * @endcode
    1885             :  *
    1886             :  * @param node_id node identifier
    1887             :  * @param idx index to check
    1888             :  * @return 1 if @p idx is a valid register block index,
    1889             :  *         0 otherwise.
    1890             :  */
    1891           1 : #define DT_RANGES_HAS_IDX(node_id, idx) \
    1892             :         IS_ENABLED(DT_CAT4(node_id, _RANGES_IDX_, idx, _EXISTS))
    1893             : 
    1894             : /**
    1895             :  * @brief Does a ranges property have child bus flags at index?
    1896             :  *
    1897             :  * If this returns 1, then DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx) is valid.
    1898             :  * If it returns 0, it is an error to use this macro with index @p idx.
    1899             :  * This macro only returns 1 for PCIe buses (i.e. nodes whose bindings specify they
    1900             :  * are "pcie" bus nodes.)
    1901             :  *
    1902             :  * Example devicetree fragment:
    1903             :  *
    1904             :  * @code{.dts}
    1905             :  *     parent {
    1906             :  *             #address-cells = <2>;
    1907             :  *
    1908             :  *             pcie0: pcie@0 {
    1909             :  *                     compatible = "pcie-controller";
    1910             :  *                     reg = <0 0 1>;
    1911             :  *                     #address-cells = <3>;
    1912             :  *                     #size-cells = <2>;
    1913             :  *
    1914             :  *                     ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
    1915             :  *                              <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
    1916             :  *                              <0x3000000 0x80 0 0x80 0 0x80 0>;
    1917             :  *             };
    1918             :  *
    1919             :  *             other: other@1 {
    1920             :  *                     reg = <0 1 1>;
    1921             :  *
    1922             :  *                     ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
    1923             :  *                              <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
    1924             :  *             };
    1925             :  *     };
    1926             :  * @endcode
    1927             :  *
    1928             :  * Example usage:
    1929             :  *
    1930             :  * @code{.c}
    1931             :  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 0) // 1
    1932             :  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 1) // 1
    1933             :  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 2) // 1
    1934             :  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 3) // 0
    1935             :  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 0) // 0
    1936             :  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 1) // 0
    1937             :  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 2) // 0
    1938             :  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 3) // 0
    1939             :  * @endcode
    1940             :  *
    1941             :  * @param node_id node identifier
    1942             :  * @param idx logical index into the ranges array
    1943             :  * @return 1 if @p idx is a valid child bus flags index,
    1944             :  *         0 otherwise.
    1945             :  */
    1946           1 : #define DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(node_id, idx) \
    1947             :         IS_ENABLED(DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_CHILD_BUS_FLAGS_EXISTS))
    1948             : 
    1949             : /**
    1950             :  * @brief Get the ranges property child bus flags at index
    1951             :  *
    1952             :  * When the node is a PCIe bus, the Child Bus Address has an extra cell used to store some
    1953             :  * flags, thus this cell is extracted from the Child Bus Address as Child Bus Flags field.
    1954             :  *
    1955             :  * Example devicetree fragments:
    1956             :  *
    1957             :  * @code{.dts}
    1958             :  *     parent {
    1959             :  *             #address-cells = <2>;
    1960             :  *
    1961             :  *             pcie0: pcie@0 {
    1962             :  *                     compatible = "pcie-controller";
    1963             :  *                     reg = <0 0 1>;
    1964             :  *                     #address-cells = <3>;
    1965             :  *                     #size-cells = <2>;
    1966             :  *
    1967             :  *                     ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
    1968             :  *                              <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
    1969             :  *                              <0x3000000 0x80 0 0x80 0 0x80 0>;
    1970             :  *             };
    1971             :  *     };
    1972             :  * @endcode
    1973             :  *
    1974             :  * Example usage:
    1975             :  *
    1976             :  * @code{.c}
    1977             :  *     DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(DT_NODELABEL(pcie0), 0) // 0x1000000
    1978             :  *     DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x2000000
    1979             :  *     DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x3000000
    1980             :  * @endcode
    1981             :  *
    1982             :  * @param node_id node identifier
    1983             :  * @param idx logical index into the ranges array
    1984             :  * @returns range child bus flags field at idx
    1985             :  */
    1986           1 : #define DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx) \
    1987             :         DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_CHILD_BUS_FLAGS)
    1988             : 
    1989             : /**
    1990             :  * @brief Get the ranges property child bus address at index
    1991             :  *
    1992             :  * When the node is a PCIe bus, the Child Bus Address has an extra cell used to store some
    1993             :  * flags, thus this cell is removed from the Child Bus Address.
    1994             :  *
    1995             :  * Example devicetree fragments:
    1996             :  *
    1997             :  * @code{.dts}
    1998             :  *     parent {
    1999             :  *             #address-cells = <2>;
    2000             :  *
    2001             :  *             pcie0: pcie@0 {
    2002             :  *                     compatible = "pcie-controller";
    2003             :  *                     reg = <0 0 1>;
    2004             :  *                     #address-cells = <3>;
    2005             :  *                     #size-cells = <2>;
    2006             :  *
    2007             :  *                     ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
    2008             :  *                              <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
    2009             :  *                              <0x3000000 0x80 0 0x80 0 0x80 0>;
    2010             :  *             };
    2011             :  *
    2012             :  *             other: other@1 {
    2013             :  *                     reg = <0 1 1>;
    2014             :  *
    2015             :  *                     ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
    2016             :  *                              <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
    2017             :  *             };
    2018             :  *     };
    2019             :  * @endcode
    2020             :  *
    2021             :  * Example usage:
    2022             :  *
    2023             :  * @code{.c}
    2024             :  *     DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 0) // 0
    2025             :  *     DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x10000000
    2026             :  *     DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x8000000000
    2027             :  *     DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 0) // 0
    2028             :  *     DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 1) // 0x10000000
    2029             :  * @endcode
    2030             :  *
    2031             :  * @param node_id node identifier
    2032             :  * @param idx logical index into the ranges array
    2033             :  * @returns range child bus address field at idx
    2034             :  */
    2035           1 : #define DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(node_id, idx) \
    2036             :         DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_CHILD_BUS_ADDRESS)
    2037             : 
    2038             : /**
    2039             :  * @brief Get the ranges property parent bus address at index
    2040             :  *
    2041             :  * Similarly to DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(), this properly accounts
    2042             :  * for child bus flags cells when the node is a PCIe bus.
    2043             :  *
    2044             :  * Example devicetree fragment:
    2045             :  *
    2046             :  * @code{.dts}
    2047             :  *     parent {
    2048             :  *             #address-cells = <2>;
    2049             :  *
    2050             :  *             pcie0: pcie@0 {
    2051             :  *                     compatible = "pcie-controller";
    2052             :  *                     reg = <0 0 1>;
    2053             :  *                     #address-cells = <3>;
    2054             :  *                     #size-cells = <2>;
    2055             :  *
    2056             :  *                     ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
    2057             :  *                              <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
    2058             :  *                              <0x3000000 0x80 0 0x80 0 0x80 0>;
    2059             :  *             };
    2060             :  *
    2061             :  *             other: other@1 {
    2062             :  *                     reg = <0 1 1>;
    2063             :  *
    2064             :  *                     ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
    2065             :  *                              <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
    2066             :  *             };
    2067             :  *     };
    2068             :  * @endcode
    2069             :  *
    2070             :  * Example usage:
    2071             :  *
    2072             :  * @code{.c}
    2073             :  *     DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 0) // 0x3eff0000
    2074             :  *     DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x10000000
    2075             :  *     DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x8000000000
    2076             :  *     DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 0) // 0x3eff0000
    2077             :  *     DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 1) // 0x10000000
    2078             :  * @endcode
    2079             :  *
    2080             :  * @param node_id node identifier
    2081             :  * @param idx logical index into the ranges array
    2082             :  * @returns range parent bus address field at idx
    2083             :  */
    2084           1 : #define DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(node_id, idx) \
    2085             :         DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_PARENT_BUS_ADDRESS)
    2086             : 
    2087             : /**
    2088             :  * @brief Get the ranges property length at index
    2089             :  *
    2090             :  * Similarly to DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(), this properly accounts
    2091             :  * for child bus flags cells when the node is a PCIe bus.
    2092             :  *
    2093             :  * Example devicetree fragment:
    2094             :  *
    2095             :  * @code{.dts}
    2096             :  *     parent {
    2097             :  *             #address-cells = <2>;
    2098             :  *
    2099             :  *             pcie0: pcie@0 {
    2100             :  *                     compatible = "pcie-controller";
    2101             :  *                     reg = <0 0 1>;
    2102             :  *                     #address-cells = <3>;
    2103             :  *                     #size-cells = <2>;
    2104             :  *
    2105             :  *                     ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
    2106             :  *                              <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
    2107             :  *                              <0x3000000 0x80 0 0x80 0 0x80 0>;
    2108             :  *             };
    2109             :  *
    2110             :  *             other: other@1 {
    2111             :  *                     reg = <0 1 1>;
    2112             :  *
    2113             :  *                     ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
    2114             :  *                              <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
    2115             :  *             };
    2116             :  *     };
    2117             :  * @endcode
    2118             :  *
    2119             :  * Example usage:
    2120             :  *
    2121             :  * @code{.c}
    2122             :  *     DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(pcie0), 0) // 0x10000
    2123             :  *     DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x2eff0000
    2124             :  *     DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x8000000000
    2125             :  *     DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(other), 0) // 0x10000
    2126             :  *     DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(other), 1) // 0x2eff0000
    2127             :  * @endcode
    2128             :  *
    2129             :  * @param node_id node identifier
    2130             :  * @param idx logical index into the ranges array
    2131             :  * @returns range length field at idx
    2132             :  */
    2133           1 : #define DT_RANGES_LENGTH_BY_IDX(node_id, idx) \
    2134             :         DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_LENGTH)
    2135             : 
    2136             : /**
    2137             :  * @brief Invokes @p fn for each entry of @p node_id ranges property
    2138             :  *
    2139             :  * The macro @p fn must take two parameters, @p node_id which will be the node
    2140             :  * identifier of the node with the ranges property and @p idx the index of
    2141             :  * the ranges block.
    2142             :  *
    2143             :  * Example devicetree fragment:
    2144             :  *
    2145             :  * @code{.dts}
    2146             :  *     n: node@0 {
    2147             :  *             reg = <0 0 1>;
    2148             :  *
    2149             :  *             ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
    2150             :  *                      <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
    2151             :  *     };
    2152             :  * @endcode
    2153             :  *
    2154             :  * Example usage:
    2155             :  *
    2156             :  * @code{.c}
    2157             :  *     #define RANGE_LENGTH(node_id, idx) DT_RANGES_LENGTH_BY_IDX(node_id, idx),
    2158             :  *
    2159             :  *     const uint64_t *ranges_length[] = {
    2160             :  *             DT_FOREACH_RANGE(DT_NODELABEL(n), RANGE_LENGTH)
    2161             :  *     };
    2162             :  * @endcode
    2163             :  *
    2164             :  * This expands to:
    2165             :  *
    2166             :  * @code{.c}
    2167             :  *     const char *ranges_length[] = {
    2168             :  *         0x10000, 0x2eff0000,
    2169             :  *     };
    2170             :  * @endcode
    2171             :  *
    2172             :  * @param node_id node identifier
    2173             :  * @param fn macro to invoke
    2174             :  */
    2175           1 : #define DT_FOREACH_RANGE(node_id, fn) \
    2176             :         DT_CAT(node_id, _FOREACH_RANGE)(fn)
    2177             : 
    2178             : /**
    2179             :  * @}
    2180             :  */
    2181             : 
    2182             : /**
    2183             :  * @defgroup devicetree-generic-vendor Vendor and model name helpers
    2184             :  * @ingroup devicetree
    2185             :  * @{
    2186             :  */
    2187             : 
    2188             : /**
    2189             :  * @brief Get the vendor at index @p idx as a string literal
    2190             :  *
    2191             :  * The vendor is a string extracted from vendor prefixes if an entry exists
    2192             :  * that matches the node's compatible prefix. There may be as many as one
    2193             :  * vendor prefixes file per directory in DTS_ROOT.
    2194             :  *
    2195             :  * Example vendor-prefixes.txt:
    2196             :  *
    2197             :  *      vnd     A stand-in for a real vendor
    2198             :  *      zephyr  Zephyr-specific binding
    2199             :  *
    2200             :  * Example devicetree fragment:
    2201             :  *
    2202             :  * @code{.dts}
    2203             :  *      n1: node-1 {
    2204             :  *              compatible = "vnd,model1", "gpio", "zephyr,model2";
    2205             :  *      };
    2206             :  * @endcode
    2207             :  *
    2208             :  * Example usage:
    2209             :  *
    2210             :  * @code{.c}
    2211             :  *      DT_NODE_VENDOR_BY_IDX(DT_NODELABEL(n1), 0) // "A stand-in for a real vendor"
    2212             :  *      DT_NODE_VENDOR_BY_IDX(DT_NODELABEL(n1), 2) // "Zephyr-specific binding"
    2213             :  * @endcode
    2214             :  *
    2215             :  * Notice that the compatible at index 1 doesn't match any entries in the
    2216             :  * vendor prefix file and therefore index 1 is not a valid vendor index. Use
    2217             :  * DT_NODE_VENDOR_HAS_IDX(node_id, idx) to determine if an index is valid.
    2218             :  *
    2219             :  * @param node_id node identifier
    2220             :  * @param idx index of the vendor to return
    2221             :  * @return string literal of the idx-th vendor
    2222             :  */
    2223           1 : #define DT_NODE_VENDOR_BY_IDX(node_id, idx) \
    2224             :         DT_CAT3(node_id, _COMPAT_VENDOR_IDX_, idx)
    2225             : 
    2226             : /**
    2227             :  * @brief Does a node's compatible property have a vendor at an index?
    2228             :  *
    2229             :  * If this returns 1, then DT_NODE_VENDOR_BY_IDX(node_id, idx) is valid. If it
    2230             :  * returns 0, it is an error to use DT_NODE_VENDOR_BY_IDX(node_id, idx) with
    2231             :  * index @p idx.
    2232             :  *
    2233             :  * @param node_id node identifier
    2234             :  * @param idx index of the vendor to check
    2235             :  * @return 1 if @p idx is a valid vendor index,
    2236             :  *         0 otherwise.
    2237             :  */
    2238           1 : #define DT_NODE_VENDOR_HAS_IDX(node_id, idx) \
    2239             :         IS_ENABLED(DT_CAT4(node_id, _COMPAT_VENDOR_IDX_, idx, _EXISTS))
    2240             : 
    2241             : /**
    2242             :  * @brief Like DT_NODE_VENDOR_BY_IDX(), but with a fallback to default_value.
    2243             :  *
    2244             :  * If the value exists, this expands to DT_NODE_VENDOR_BY_IDX(node_id, idx).
    2245             :  * The default_value parameter is not expanded in this case.
    2246             :  *
    2247             :  * Otherwise, this expands to default_value.
    2248             :  *
    2249             :  * @param node_id node identifier
    2250             :  * @param idx index of the vendor to return
    2251             :  * @return string literal of the idx-th vendor
    2252             :  * @param default_value a fallback value to expand to
    2253             :  * @return string literal of the idx-th vendor or "default_value"
    2254             :  */
    2255           1 : #define DT_NODE_VENDOR_BY_IDX_OR(node_id, idx, default_value) \
    2256             :         COND_CODE_1(DT_NODE_VENDOR_HAS_IDX(node_id, idx), \
    2257             :                     (DT_NODE_VENDOR_BY_IDX(node_id, idx)), (default_value))
    2258             : 
    2259             : /**
    2260             :  * @brief Get the node's (only) vendor as a string literal
    2261             :  *
    2262             :  * Equivalent to DT_NODE_VENDOR_BY_IDX_OR(node_id, 0, default_value).
    2263             :  *
    2264             :  * @param node_id node identifier
    2265             :  * @param default_value a fallback value to expand to
    2266             :  */
    2267           1 : #define DT_NODE_VENDOR_OR(node_id, default_value) \
    2268             :         DT_NODE_VENDOR_BY_IDX_OR(node_id, 0, default_value)
    2269             : 
    2270             : /**
    2271             :  * @brief Get the model at index "idx" as a string literal
    2272             :  *
    2273             :  * The model is a string extracted from the compatible after the vendor prefix.
    2274             :  *
    2275             :  * Example vendor-prefixes.txt:
    2276             :  *
    2277             :  *      vnd     A stand-in for a real vendor
    2278             :  *      zephyr  Zephyr-specific binding
    2279             :  *
    2280             :  * Example devicetree fragment:
    2281             :  *
    2282             :  *      n1: node-1 {
    2283             :  *              compatible = "vnd,model1", "gpio", "zephyr,model2";
    2284             :  *      };
    2285             :  *
    2286             :  * Example usage:
    2287             :  *
    2288             :  *      DT_NODE_MODEL_BY_IDX(DT_NODELABEL(n1), 0) // "model1"
    2289             :  *      DT_NODE_MODEL_BY_IDX(DT_NODELABEL(n1), 2) // "model2"
    2290             :  *
    2291             :  * Notice that the compatible at index 1 doesn't match any entries in the
    2292             :  * vendor prefix file and therefore index 1 is not a valid model index. Use
    2293             :  * DT_NODE_MODEL_HAS_IDX(node_id, idx) to determine if an index is valid.
    2294             :  *
    2295             :  * @param node_id node identifier
    2296             :  * @param idx index of the model to return
    2297             :  * @return string literal of the idx-th model
    2298             :  */
    2299           1 : #define DT_NODE_MODEL_BY_IDX(node_id, idx) \
    2300             :         DT_CAT3(node_id, _COMPAT_MODEL_IDX_, idx)
    2301             : 
    2302             : /**
    2303             :  * @brief Does a node's compatible property have a model at an index?
    2304             :  *
    2305             :  * If this returns 1, then DT_NODE_MODEL_BY_IDX(node_id, idx) is valid. If it
    2306             :  * returns 0, it is an error to use DT_NODE_MODEL_BY_IDX(node_id, idx) with
    2307             :  * index "idx".
    2308             :  *
    2309             :  * @param node_id node identifier
    2310             :  * @param idx index of the model to check
    2311             :  * @return 1 if "idx" is a valid model index,
    2312             :  *         0 otherwise.
    2313             :  */
    2314           1 : #define DT_NODE_MODEL_HAS_IDX(node_id, idx) \
    2315             :         IS_ENABLED(DT_CAT4(node_id, _COMPAT_MODEL_IDX_, idx, _EXISTS))
    2316             : 
    2317             : /**
    2318             :  * @brief Like DT_NODE_MODEL_BY_IDX(), but with a fallback to default_value.
    2319             :  *
    2320             :  * If the value exists, this expands to DT_NODE_MODEL_BY_IDX(node_id, idx).
    2321             :  * The default_value parameter is not expanded in this case.
    2322             :  *
    2323             :  * Otherwise, this expands to default_value.
    2324             :  *
    2325             :  * @param node_id node identifier
    2326             :  * @param idx index of the model to return
    2327             :  * @return string literal of the idx-th model
    2328             :  * @param default_value a fallback value to expand to
    2329             :  * @return string literal of the idx-th model or "default_value"
    2330             :  */
    2331           1 : #define DT_NODE_MODEL_BY_IDX_OR(node_id, idx, default_value) \
    2332             :         COND_CODE_1(DT_NODE_MODEL_HAS_IDX(node_id, idx), \
    2333             :                     (DT_NODE_MODEL_BY_IDX(node_id, idx)), (default_value))
    2334             : 
    2335             : /**
    2336             :  * @brief Get the node's (only) model as a string literal
    2337             :  *
    2338             :  * Equivalent to DT_NODE_MODEL_BY_IDX_OR(node_id, 0, default_value).
    2339             :  *
    2340             :  * @param node_id node identifier
    2341             :  * @param default_value a fallback value to expand to
    2342             :  */
    2343           1 : #define DT_NODE_MODEL_OR(node_id, default_value) \
    2344             :         DT_NODE_MODEL_BY_IDX_OR(node_id, 0, default_value)
    2345             : 
    2346             : /**
    2347             :  * @}
    2348             :  */
    2349             : 
    2350             : /**
    2351             :  * @defgroup devicetree-reg-prop reg property
    2352             :  * @ingroup devicetree
    2353             :  * @{
    2354             :  */
    2355             : 
    2356             : /**
    2357             :  * @brief Get the number of register blocks in the reg property
    2358             :  *
    2359             :  * Use this instead of DT_PROP_LEN(node_id, reg).
    2360             :  * @param node_id node identifier
    2361             :  * @return Number of register blocks in the node's "reg" property.
    2362             :  */
    2363           1 : #define DT_NUM_REGS(node_id) DT_CAT(node_id, _REG_NUM)
    2364             : 
    2365             : /**
    2366             :  * @brief Is @p idx a valid register block index?
    2367             :  *
    2368             :  * If this returns 1, then DT_REG_ADDR_BY_IDX(node_id, idx) or
    2369             :  * DT_REG_SIZE_BY_IDX(node_id, idx) are valid.
    2370             :  * If it returns 0, it is an error to use those macros with index @p idx.
    2371             :  * @param node_id node identifier
    2372             :  * @param idx index to check
    2373             :  * @return 1 if @p idx is a valid register block index,
    2374             :  *         0 otherwise.
    2375             :  */
    2376           1 : #define DT_REG_HAS_IDX(node_id, idx) \
    2377             :         IS_ENABLED(DT_CAT4(node_id, _REG_IDX_, idx, _EXISTS))
    2378             : 
    2379             : /**
    2380             :  * @brief Is @p name a valid register block name?
    2381             :  *
    2382             :  * If this returns 1, then DT_REG_ADDR_BY_NAME(node_id, name) or
    2383             :  * DT_REG_SIZE_BY_NAME(node_id, name) are valid.
    2384             :  * If it returns 0, it is an error to use those macros with name @p name.
    2385             :  * @param node_id node identifier
    2386             :  * @param name name to check
    2387             :  * @return 1 if @p name is a valid register block name,
    2388             :  *         0 otherwise.
    2389             :  */
    2390           1 : #define DT_REG_HAS_NAME(node_id, name) \
    2391             :         IS_ENABLED(DT_CAT4(node_id, _REG_NAME_, name, _EXISTS))
    2392             : 
    2393             : /**
    2394             :  * @brief Get the base raw address of the register block at index @p idx
    2395             :  *
    2396             :  * Get the base address of the register block at index @p idx without any
    2397             :  * type suffix. This can be used to index other devicetree properties, use the
    2398             :  * non _RAW macros for assigning values in actual code.
    2399             :  *
    2400             :  * @param node_id node identifier
    2401             :  * @param idx index of the register whose address to return
    2402             :  * @return address of the idx-th register block
    2403             :  */
    2404           1 : #define DT_REG_ADDR_BY_IDX_RAW(node_id, idx) \
    2405             :         DT_CAT4(node_id, _REG_IDX_, idx, _VAL_ADDRESS)
    2406             : 
    2407             : /**
    2408             :  * @brief Get a node's (only) register block raw address
    2409             :  *
    2410             :  * Get a node's only register block address without any type suffix. This can
    2411             :  * be used to index other devicetree properties, use the non _RAW macros for
    2412             :  * assigning values in actual code.
    2413             :  *
    2414             :  * Equivalent to DT_REG_ADDR_BY_IDX_RAW(node_id, 0).
    2415             :  * @param node_id node identifier
    2416             :  * @return node's register block address
    2417             :  */
    2418           1 : #define DT_REG_ADDR_RAW(node_id) \
    2419             :         DT_REG_ADDR_BY_IDX_RAW(node_id, 0)
    2420             : 
    2421             : /**
    2422             :  * @brief Get the base address of the register block at index @p idx
    2423             :  * @param node_id node identifier
    2424             :  * @param idx index of the register whose address to return
    2425             :  * @return address of the idx-th register block
    2426             :  */
    2427           1 : #define DT_REG_ADDR_BY_IDX(node_id, idx) \
    2428             :         DT_U32_C(DT_REG_ADDR_BY_IDX_RAW(node_id, idx))
    2429             : 
    2430             : /**
    2431             :  * @brief Get the size of the register block at index @p idx
    2432             :  *
    2433             :  * This is the size of an individual register block, not the total
    2434             :  * number of register blocks in the property; use DT_NUM_REGS() for
    2435             :  * that.
    2436             :  *
    2437             :  * @param node_id node identifier
    2438             :  * @param idx index of the register whose size to return
    2439             :  * @return size of the idx-th register block
    2440             :  */
    2441           1 : #define DT_REG_SIZE_BY_IDX(node_id, idx) \
    2442             :         DT_U32_C(DT_CAT4(node_id, _REG_IDX_, idx, _VAL_SIZE))
    2443             : 
    2444             : /**
    2445             :  * @brief Get a node's (only) register block address
    2446             :  *
    2447             :  * Equivalent to DT_REG_ADDR_BY_IDX(node_id, 0).
    2448             :  * @param node_id node identifier
    2449             :  * @return node's register block address
    2450             :  */
    2451           1 : #define DT_REG_ADDR(node_id) DT_REG_ADDR_BY_IDX(node_id, 0)
    2452             : 
    2453             : /**
    2454             :  * @brief 64-bit version of DT_REG_ADDR()
    2455             :  *
    2456             :  * This macro version adds the appropriate suffix for 64-bit unsigned
    2457             :  * integer literals.
    2458             :  * Note that this macro is equivalent to DT_REG_ADDR() in linker/ASM context.
    2459             :  *
    2460             :  * @param node_id node identifier
    2461             :  * @return node's register block address
    2462             :  */
    2463           1 : #define DT_REG_ADDR_U64(node_id) DT_U64_C(DT_REG_ADDR_BY_IDX_RAW(node_id, 0))
    2464             : 
    2465             : /**
    2466             :  * @brief Get a node's (only) register block size
    2467             :  *
    2468             :  * Equivalent to DT_REG_SIZE_BY_IDX(node_id, 0).
    2469             :  * @param node_id node identifier
    2470             :  * @return node's only register block's size
    2471             :  */
    2472           1 : #define DT_REG_SIZE(node_id) DT_REG_SIZE_BY_IDX(node_id, 0)
    2473             : 
    2474             : /**
    2475             :  * @brief Get a register block's base address by name
    2476             :  * @param node_id node identifier
    2477             :  * @param name lowercase-and-underscores register specifier name
    2478             :  * @return address of the register block specified by name
    2479             :  */
    2480           1 : #define DT_REG_ADDR_BY_NAME(node_id, name) \
    2481             :         DT_U32_C(DT_CAT4(node_id, _REG_NAME_, name, _VAL_ADDRESS))
    2482             : 
    2483             : /**
    2484             :  * @brief Like DT_REG_ADDR_BY_NAME(), but with a fallback to @p default_value
    2485             :  * @param node_id node identifier
    2486             :  * @param name lowercase-and-underscores register specifier name
    2487             :  * @param default_value a fallback value to expand to
    2488             :  * @return address of the register block specified by name if present,
    2489             :  *         @p default_value otherwise
    2490             :  */
    2491           1 : #define DT_REG_ADDR_BY_NAME_OR(node_id, name, default_value) \
    2492             :         COND_CODE_1(DT_REG_HAS_NAME(node_id, name), \
    2493             :                     (DT_REG_ADDR_BY_NAME(node_id, name)), (default_value))
    2494             : 
    2495             : /**
    2496             :  * @brief 64-bit version of DT_REG_ADDR_BY_NAME()
    2497             :  *
    2498             :  * This macro version adds the appropriate suffix for 64-bit unsigned
    2499             :  * integer literals.
    2500             :  * Note that this macro is equivalent to DT_REG_ADDR_BY_NAME() in
    2501             :  * linker/ASM context.
    2502             :  *
    2503             :  * @param node_id node identifier
    2504             :  * @param name lowercase-and-underscores register specifier name
    2505             :  * @return address of the register block specified by name
    2506             :  */
    2507           1 : #define DT_REG_ADDR_BY_NAME_U64(node_id, name) \
    2508             :         DT_U64_C(DT_CAT4(node_id, _REG_NAME_, name, _VAL_ADDRESS))
    2509             : 
    2510             : /**
    2511             :  * @brief Get a register block's size by name
    2512             :  * @param node_id node identifier
    2513             :  * @param name lowercase-and-underscores register specifier name
    2514             :  * @return size of the register block specified by name
    2515             :  */
    2516           1 : #define DT_REG_SIZE_BY_NAME(node_id, name) \
    2517             :         DT_U32_C(DT_CAT4(node_id, _REG_NAME_, name, _VAL_SIZE))
    2518             : 
    2519             : /**
    2520             :  * @brief Like DT_REG_SIZE_BY_NAME(), but with a fallback to @p default_value
    2521             :  * @param node_id node identifier
    2522             :  * @param name lowercase-and-underscores register specifier name
    2523             :  * @param default_value a fallback value to expand to
    2524             :  * @return size of the register block specified by name if present,
    2525             :  *         @p default_value otherwise
    2526             :  */
    2527           1 : #define DT_REG_SIZE_BY_NAME_OR(node_id, name, default_value) \
    2528             :         COND_CODE_1(DT_REG_HAS_NAME(node_id, name), \
    2529             :                     (DT_REG_SIZE_BY_NAME(node_id, name)), (default_value))
    2530             : 
    2531             : 
    2532             : /**
    2533             :  * @}
    2534             :  */
    2535             : 
    2536             : /**
    2537             :  * @defgroup devicetree-interrupts-prop interrupts property
    2538             :  * @ingroup devicetree
    2539             :  * @{
    2540             :  */
    2541             : 
    2542             : /**
    2543             :  * @brief Get the number of interrupt sources for the node
    2544             :  *
    2545             :  * Use this instead of DT_PROP_LEN(node_id, interrupts).
    2546             :  *
    2547             :  * @param node_id node identifier
    2548             :  * @return Number of interrupt specifiers in the node's "interrupts" property.
    2549             :  */
    2550           1 : #define DT_NUM_IRQS(node_id) DT_CAT(node_id, _IRQ_NUM)
    2551             : 
    2552             : /**
    2553             :  * @brief Get the number of node labels that a node has
    2554             :  *
    2555             :  * Example devicetree fragment:
    2556             :  *
    2557             :  * @code{.dts}
    2558             :  *     / {
    2559             :  *         foo {};
    2560             :  *         bar: bar@1000 {};
    2561             :  *         baz: baz2: baz@2000 {};
    2562             :  *     };
    2563             :  * @endcode
    2564             :  *
    2565             :  * Example usage:
    2566             :  *
    2567             :  * @code{.c}
    2568             :  *     DT_NUM_NODELABELS(DT_PATH(foo))      // 0
    2569             :  *     DT_NUM_NODELABELS(DT_NODELABEL(bar)) // 1
    2570             :  *     DT_NUM_NODELABELS(DT_NODELABEL(baz)) // 2
    2571             :  * @endcode
    2572             :  *
    2573             :  * @param node_id node identifier
    2574             :  * @return number of node labels that the node has
    2575             :  */
    2576           1 : #define DT_NUM_NODELABELS(node_id) DT_CAT(node_id, _NODELABEL_NUM)
    2577             : 
    2578             : /**
    2579             :  * @brief Get the interrupt level for the node
    2580             :  *
    2581             :  * @param node_id node identifier
    2582             :  * @return interrupt level
    2583             :  */
    2584           1 : #define DT_IRQ_LEVEL(node_id) DT_CAT(node_id, _IRQ_LEVEL)
    2585             : 
    2586             : /**
    2587             :  * @brief Is @p idx a valid interrupt index?
    2588             :  *
    2589             :  * If this returns 1, then DT_IRQ_BY_IDX(node_id, idx) is valid.
    2590             :  * If it returns 0, it is an error to use that macro with this index.
    2591             :  * @param node_id node identifier
    2592             :  * @param idx index to check
    2593             :  * @return 1 if the idx is valid for the interrupt property
    2594             :  *         0 otherwise.
    2595             :  */
    2596           1 : #define DT_IRQ_HAS_IDX(node_id, idx) \
    2597             :         IS_ENABLED(DT_CAT4(node_id, _IRQ_IDX_, idx, _EXISTS))
    2598             : 
    2599             : /**
    2600             :  * @brief Does an interrupts property have a named cell specifier at an index?
    2601             :  * If this returns 1, then DT_IRQ_BY_IDX(node_id, idx, cell) is valid.
    2602             :  * If it returns 0, it is an error to use that macro.
    2603             :  * @param node_id node identifier
    2604             :  * @param idx index to check
    2605             :  * @param cell named cell value whose existence to check
    2606             :  * @return 1 if the named cell exists in the interrupt specifier at index idx
    2607             :  *         0 otherwise.
    2608             :  */
    2609           1 : #define DT_IRQ_HAS_CELL_AT_IDX(node_id, idx, cell) \
    2610             :         IS_ENABLED(DT_CAT6(node_id, _IRQ_IDX_, idx, _VAL_, cell, _EXISTS))
    2611             : 
    2612             : /**
    2613             :  * @brief Equivalent to DT_IRQ_HAS_CELL_AT_IDX(node_id, 0, cell)
    2614             :  * @param node_id node identifier
    2615             :  * @param cell named cell value whose existence to check
    2616             :  * @return 1 if the named cell exists in the interrupt specifier at index 0
    2617             :  *         0 otherwise.
    2618             :  */
    2619           1 : #define DT_IRQ_HAS_CELL(node_id, cell) DT_IRQ_HAS_CELL_AT_IDX(node_id, 0, cell)
    2620             : 
    2621             : /**
    2622             :  * @brief Does an interrupts property have a named specifier value at an index?
    2623             :  * If this returns 1, then DT_IRQ_BY_NAME(node_id, name, cell) is valid.
    2624             :  * If it returns 0, it is an error to use that macro.
    2625             :  * @param node_id node identifier
    2626             :  * @param name lowercase-and-underscores interrupt specifier name
    2627             :  * @return 1 if "name" is a valid named specifier
    2628             :  *         0 otherwise.
    2629             :  */
    2630           1 : #define DT_IRQ_HAS_NAME(node_id, name) \
    2631             :         IS_ENABLED(DT_CAT4(node_id, _IRQ_NAME_, name, _VAL_irq_EXISTS))
    2632             : 
    2633             : /**
    2634             :  * @brief Get a value within an interrupt specifier at an index
    2635             :  *
    2636             :  * It might help to read the argument order as being similar to
    2637             :  * "node->interrupts[index].cell".
    2638             :  *
    2639             :  * This can be used to get information about an individual interrupt
    2640             :  * when a device generates more than one.
    2641             :  *
    2642             :  * Example devicetree fragment:
    2643             :  *
    2644             :  * @code{.dts}
    2645             :  *     my-serial: serial@abcd1234 {
    2646             :  *             interrupts = < 33 0 >, < 34 1 >;
    2647             :  *     };
    2648             :  * @endcode
    2649             :  *
    2650             :  * Assuming the node's interrupt domain has "#interrupt-cells = <2>;" and
    2651             :  * the individual cells in each interrupt specifier are named "irq" and
    2652             :  * "priority" by the node's binding, here are some examples:
    2653             :  *
    2654             :  *     #define SERIAL DT_NODELABEL(my_serial)
    2655             :  *
    2656             :  *     Example usage                       Value
    2657             :  *     -------------                       -----
    2658             :  *     DT_IRQ_BY_IDX(SERIAL, 0, irq)          33
    2659             :  *     DT_IRQ_BY_IDX(SERIAL, 0, priority)      0
    2660             :  *     DT_IRQ_BY_IDX(SERIAL, 1, irq,          34
    2661             :  *     DT_IRQ_BY_IDX(SERIAL, 1, priority)      1
    2662             :  *
    2663             :  * @param node_id node identifier
    2664             :  * @param idx logical index into the interrupt specifier array
    2665             :  * @param cell cell name specifier
    2666             :  * @return the named value at the specifier given by the index
    2667             :  */
    2668           1 : #define DT_IRQ_BY_IDX(node_id, idx, cell)   \
    2669             :         DT_CAT5(node_id, _IRQ_IDX_, idx, _VAL_, cell)
    2670             : 
    2671             : /**
    2672             :  * @brief Get a value within an interrupt specifier by name
    2673             :  *
    2674             :  * It might help to read the argument order as being similar to
    2675             :  * `node->interrupts.name.cell`.
    2676             :  *
    2677             :  * This can be used to get information about an individual interrupt
    2678             :  * when a device generates more than one, if the bindings give each
    2679             :  * interrupt specifier a name.
    2680             :  *
    2681             :  * @param node_id node identifier
    2682             :  * @param name lowercase-and-underscores interrupt specifier name
    2683             :  * @param cell cell name specifier
    2684             :  * @return the named value at the specifier given by the index
    2685             :  */
    2686           1 : #define DT_IRQ_BY_NAME(node_id, name, cell) \
    2687             :         DT_CAT5(node_id, _IRQ_NAME_, name, _VAL_, cell)
    2688             : 
    2689             : /**
    2690             :  * @brief Get an interrupt specifier's value
    2691             :  * Equivalent to DT_IRQ_BY_IDX(node_id, 0, cell).
    2692             :  * @param node_id node identifier
    2693             :  * @param cell cell name specifier
    2694             :  * @return the named value at that index
    2695             :  */
    2696           1 : #define DT_IRQ(node_id, cell) DT_IRQ_BY_IDX(node_id, 0, cell)
    2697             : 
    2698             : /**
    2699             :  * @brief Get an interrupt specifier's interrupt controller by index
    2700             :  *
    2701             :  * @code{.dts}
    2702             :  *     gpio0: gpio0 {
    2703             :  *             interrupt-controller;
    2704             :  *             #interrupt-cells = <2>;
    2705             :  *     };
    2706             :  *
    2707             :  *     foo: foo {
    2708             :  *             interrupt-parent = <&gpio0>;
    2709             :  *             interrupts = <1 1>, <2 2>;
    2710             :  *     };
    2711             :  *
    2712             :  *     bar: bar {
    2713             :  *             interrupts-extended = <&gpio0 3 3>, <&pic0 4>;
    2714             :  *     };
    2715             :  *
    2716             :  *     pic0: pic0 {
    2717             :  *             interrupt-controller;
    2718             :  *             #interrupt-cells = <1>;
    2719             :  *
    2720             :  *             qux: qux {
    2721             :  *                     interrupts = <5>, <6>;
    2722             :  *                     interrupt-names = "int1", "int2";
    2723             :  *             };
    2724             :  *     };
    2725             :  * @endcode
    2726             :  *
    2727             :  * Example usage:
    2728             :  *
    2729             :  *     DT_IRQ_INTC_BY_IDX(DT_NODELABEL(foo), 0) // &gpio0
    2730             :  *     DT_IRQ_INTC_BY_IDX(DT_NODELABEL(foo), 1) // &gpio0
    2731             :  *     DT_IRQ_INTC_BY_IDX(DT_NODELABEL(bar), 0) // &gpio0
    2732             :  *     DT_IRQ_INTC_BY_IDX(DT_NODELABEL(bar), 1) // &pic0
    2733             :  *     DT_IRQ_INTC_BY_IDX(DT_NODELABEL(qux), 0) // &pic0
    2734             :  *     DT_IRQ_INTC_BY_IDX(DT_NODELABEL(qux), 1) // &pic0
    2735             :  *
    2736             :  * @param node_id node identifier
    2737             :  * @param idx interrupt specifier's index
    2738             :  * @return node_id of interrupt specifier's interrupt controller
    2739             :  */
    2740           1 : #define DT_IRQ_INTC_BY_IDX(node_id, idx) \
    2741             :         DT_CAT4(node_id, _IRQ_IDX_, idx, _CONTROLLER)
    2742             : 
    2743             : /**
    2744             :  * @brief Get an interrupt specifier's interrupt controller by name
    2745             :  *
    2746             :  * @code{.dts}
    2747             :  *     gpio0: gpio0 {
    2748             :  *             interrupt-controller;
    2749             :  *             #interrupt-cells = <2>;
    2750             :  *     };
    2751             :  *
    2752             :  *     foo: foo {
    2753             :  *             interrupt-parent = <&gpio0>;
    2754             :  *             interrupts = <1 1>, <2 2>;
    2755             :  *             interrupt-names = "int1", "int2";
    2756             :  *     };
    2757             :  *
    2758             :  *     bar: bar {
    2759             :  *             interrupts-extended = <&gpio0 3 3>, <&pic0 4>;
    2760             :  *             interrupt-names = "int1", "int2";
    2761             :  *     };
    2762             :  *
    2763             :  *     pic0: pic0 {
    2764             :  *             interrupt-controller;
    2765             :  *             #interrupt-cells = <1>;
    2766             :  *
    2767             :  *             qux: qux {
    2768             :  *                     interrupts = <5>, <6>;
    2769             :  *                     interrupt-names = "int1", "int2";
    2770             :  *             };
    2771             :  *     };
    2772             :  * @endcode
    2773             :  *
    2774             :  * Example usage:
    2775             :  *
    2776             :  *     DT_IRQ_INTC_BY_NAME(DT_NODELABEL(foo), int1) // &gpio0
    2777             :  *     DT_IRQ_INTC_BY_NAME(DT_NODELABEL(foo), int2) // &gpio0
    2778             :  *     DT_IRQ_INTC_BY_NAME(DT_NODELABEL(bar), int1) // &gpio0
    2779             :  *     DT_IRQ_INTC_BY_NAME(DT_NODELABEL(bar), int2) // &pic0
    2780             :  *     DT_IRQ_INTC_BY_NAME(DT_NODELABEL(qux), int1) // &pic0
    2781             :  *     DT_IRQ_INTC_BY_NAME(DT_NODELABEL(qux), int2) // &pic0
    2782             :  *
    2783             :  * @param node_id node identifier
    2784             :  * @param name interrupt specifier's name
    2785             :  * @return node_id of interrupt specifier's interrupt controller
    2786             :  */
    2787           1 : #define DT_IRQ_INTC_BY_NAME(node_id, name) \
    2788             :         DT_CAT4(node_id, _IRQ_NAME_, name, _CONTROLLER)
    2789             : 
    2790             : /**
    2791             :  * @brief Get an interrupt specifier's interrupt controller
    2792             :  * @note Equivalent to DT_IRQ_INTC_BY_IDX(node_id, 0)
    2793             :  *
    2794             :  * @code{.dts}
    2795             :  *     gpio0: gpio0 {
    2796             :  *             interrupt-controller;
    2797             :  *             #interrupt-cells = <2>;
    2798             :  *     };
    2799             :  *
    2800             :  *     foo: foo {
    2801             :  *             interrupt-parent = <&gpio0>;
    2802             :  *             interrupts = <1 1>;
    2803             :  *     };
    2804             :  *
    2805             :  *     bar: bar {
    2806             :  *             interrupts-extended = <&gpio0 3 3>;
    2807             :  *     };
    2808             :  *
    2809             :  *     pic0: pic0 {
    2810             :  *             interrupt-controller;
    2811             :  *             #interrupt-cells = <1>;
    2812             :  *
    2813             :  *             qux: qux {
    2814             :  *                     interrupts = <5>;
    2815             :  *             };
    2816             :  *     };
    2817             :  * @endcode
    2818             :  *
    2819             :  * Example usage:
    2820             :  *
    2821             :  *     DT_IRQ_INTC(DT_NODELABEL(foo)) // &gpio0
    2822             :  *     DT_IRQ_INTC(DT_NODELABEL(bar)) // &gpio0
    2823             :  *     DT_IRQ_INTC(DT_NODELABEL(qux)) // &pic0
    2824             :  *
    2825             :  * @param node_id node identifier
    2826             :  * @return node_id of interrupt specifier's interrupt controller
    2827             :  * @see DT_IRQ_INTC_BY_IDX()
    2828             :  */
    2829           1 : #define DT_IRQ_INTC(node_id) \
    2830             :         DT_IRQ_INTC_BY_IDX(node_id, 0)
    2831             : 
    2832             : /**
    2833             :  * @cond INTERNAL_HIDDEN
    2834             :  */
    2835             : 
    2836             : /* DT helper macro to encode a node's IRQN to level 1 according to the multi-level scheme */
    2837             : #define DT_IRQN_L1_INTERNAL(node_id, idx) DT_IRQ_BY_IDX(node_id, idx, irq)
    2838             : /* DT helper macro to encode a node's IRQN to level 2 according to the multi-level scheme */
    2839             : #define DT_IRQN_L2_INTERNAL(node_id, idx)                                                          \
    2840             :         (IRQ_TO_L2(DT_IRQN_L1_INTERNAL(node_id, idx)) |                                            \
    2841             :          DT_IRQ(DT_IRQ_INTC_BY_IDX(node_id, idx), irq))
    2842             : /* DT helper macro to encode a node's IRQN to level 3 according to the multi-level scheme */
    2843             : #define DT_IRQN_L3_INTERNAL(node_id, idx)                                                          \
    2844             :         (IRQ_TO_L3(DT_IRQN_L1_INTERNAL(node_id, idx)) |                                            \
    2845             :          IRQ_TO_L2(DT_IRQ(DT_IRQ_INTC_BY_IDX(node_id, idx), irq)) |                                \
    2846             :          DT_IRQ(DT_IRQ_INTC(DT_IRQ_INTC_BY_IDX(node_id, idx)), irq))
    2847             : /* DT helper macro for the macros above */
    2848             : #define DT_IRQN_LVL_INTERNAL(node_id, idx, level) DT_CAT3(DT_IRQN_L, level, _INTERNAL)(node_id, idx)
    2849             : 
    2850             : /**
    2851             :  * DT helper macro to encode a node's interrupt number according to the Zephyr's multi-level scheme
    2852             :  * See doc/kernel/services/interrupts.rst for details
    2853             :  */
    2854             : #define DT_MULTI_LEVEL_IRQN_INTERNAL(node_id, idx)                                                 \
    2855             :         DT_IRQN_LVL_INTERNAL(node_id, idx, DT_IRQ_LEVEL(node_id))
    2856             : 
    2857             : /**
    2858             :  * INTERNAL_HIDDEN @endcond
    2859             :  */
    2860             : 
    2861             : /**
    2862             :  * @brief Get the node's Zephyr interrupt number at index
    2863             :  * If @kconfig{CONFIG_MULTI_LEVEL_INTERRUPTS} is enabled, the interrupt number at index will be
    2864             :  * multi-level encoded
    2865             :  * @param node_id node identifier
    2866             :  * @param idx logical index into the interrupt specifier array
    2867             :  * @return the Zephyr interrupt number
    2868             :  */
    2869           1 : #define DT_IRQN_BY_IDX(node_id, idx)                                                               \
    2870             :         COND_CODE_1(IS_ENABLED(CONFIG_MULTI_LEVEL_INTERRUPTS),                                     \
    2871             :                     (DT_MULTI_LEVEL_IRQN_INTERNAL(node_id, idx)),                                  \
    2872             :                     (DT_IRQ_BY_IDX(node_id, idx, irq)))
    2873             : 
    2874             : /**
    2875             :  * @brief Get a node's (only) irq number
    2876             :  *
    2877             :  * Equivalent to DT_IRQ(node_id, irq). This is provided as a convenience
    2878             :  * for the common case where a node generates exactly one interrupt,
    2879             :  * and the IRQ number is in a cell named `irq`.
    2880             :  *
    2881             :  * @param node_id node identifier
    2882             :  * @return the interrupt number for the node's only interrupt
    2883             :  */
    2884           1 : #define DT_IRQN(node_id) DT_IRQN_BY_IDX(node_id, 0)
    2885             : 
    2886             : /**
    2887             :  * @}
    2888             :  */
    2889             : 
    2890             : /**
    2891             :  * @defgroup devicetree-generic-chosen Chosen nodes
    2892             :  * @ingroup devicetree
    2893             :  * @{
    2894             :  */
    2895             : 
    2896             : /**
    2897             :  * @brief Get a node identifier for a `/chosen` node property
    2898             :  *
    2899             :  * This is only valid to call if `DT_HAS_CHOSEN(prop)` is 1.
    2900             :  * @param prop lowercase-and-underscores property name for
    2901             :  *             the /chosen node
    2902             :  * @return a node identifier for the chosen node property
    2903             :  */
    2904           1 : #define DT_CHOSEN(prop) DT_CAT(DT_CHOSEN_, prop)
    2905             : 
    2906             : /**
    2907             :  * @brief Test if the devicetree has a `/chosen` node
    2908             :  * @param prop lowercase-and-underscores devicetree property
    2909             :  * @return 1 if the chosen property exists and refers to a node,
    2910             :  *         0 otherwise
    2911             :  */
    2912           1 : #define DT_HAS_CHOSEN(prop) IS_ENABLED(DT_CAT3(DT_CHOSEN_, prop, _EXISTS))
    2913             : 
    2914             : /**
    2915             :  * @}
    2916             :  */
    2917             : 
    2918             : /**
    2919             :  * @defgroup devicetree-generic-foreach "For-each" macros
    2920             :  * @ingroup devicetree
    2921             :  * @{
    2922             :  */
    2923             : 
    2924             : /**
    2925             :  * @brief Invokes @p fn for every node in the tree.
    2926             :  *
    2927             :  * The macro @p fn must take one parameter, which will be a node
    2928             :  * identifier. The macro is expanded once for each node in the tree.
    2929             :  * The order that nodes are visited in is not specified.
    2930             :  *
    2931             :  * @param fn macro to invoke
    2932             :  */
    2933           1 : #define DT_FOREACH_NODE(fn) DT_FOREACH_HELPER(fn)
    2934             : 
    2935             : /**
    2936             :  * @brief Invokes @p fn for every node in the tree with multiple arguments.
    2937             :  *
    2938             :  * The macro @p fn takes multiple arguments. The first should be the node
    2939             :  * identifier for the node. The remaining are passed-in by the caller.
    2940             :  *
    2941             :  * The macro is expanded once for each node in the tree. The order that nodes
    2942             :  * are visited in is not specified.
    2943             :  *
    2944             :  * @param fn macro to invoke
    2945             :  * @param ... variable number of arguments to pass to @p fn
    2946             :  */
    2947           1 : #define DT_FOREACH_NODE_VARGS(fn, ...) DT_FOREACH_VARGS_HELPER(fn, __VA_ARGS__)
    2948             : 
    2949             : /**
    2950             :  * @brief Invokes @p fn for every status `okay` node in the tree.
    2951             :  *
    2952             :  * The macro @p fn must take one parameter, which will be a node
    2953             :  * identifier. The macro is expanded once for each node in the tree
    2954             :  * with status `okay` (as usual, a missing status property is treated
    2955             :  * as status `okay`). The order that nodes are visited in is not
    2956             :  * specified.
    2957             :  *
    2958             :  * @param fn macro to invoke
    2959             :  */
    2960           1 : #define DT_FOREACH_STATUS_OKAY_NODE(fn) DT_FOREACH_OKAY_HELPER(fn)
    2961             : 
    2962             : /**
    2963             :  * @brief Invokes @p fn for every status `okay` node in the tree with multiple
    2964             :  *        arguments.
    2965             :  *
    2966             :  * The macro @p fn takes multiple arguments. The first should be the node
    2967             :  * identifier for the node. The remaining are passed-in by the caller.
    2968             :  *
    2969             :  * The macro is expanded once for each node in the tree with status `okay` (as
    2970             :  * usual, a missing status property is treated as status `okay`). The order
    2971             :  * that nodes are visited in is not specified.
    2972             :  *
    2973             :  * @param fn macro to invoke
    2974             :  * @param ... variable number of arguments to pass to @p fn
    2975             :  */
    2976           1 : #define DT_FOREACH_STATUS_OKAY_NODE_VARGS(fn, ...) DT_FOREACH_OKAY_VARGS_HELPER(fn, __VA_ARGS__)
    2977             : 
    2978             : /**
    2979             :  * @brief Invokes @p fn for each ancestor of @p node_id
    2980             :  *
    2981             :  * The macro @p fn must take one parameter, which will be the identifier
    2982             :  * of a child node of @p node_id to enable traversal of all ancestor nodes.
    2983             :  *
    2984             :  * The ancestor will be iterated over in the same order as they
    2985             :  * appear in the final devicetree.
    2986             :  *
    2987             :  * Example devicetree fragment:
    2988             :  *
    2989             :  * @code{.dts}
    2990             :  *     n: node1 {
    2991             :  *             foobar = "foo1";
    2992             :  *
    2993             :  *             n_2: node2 {
    2994             :  *                        foobar = "foo2";
    2995             :  *
    2996             :  *                        n_3: node3 {
    2997             :  *                                   foobar = "foo3";
    2998             :  *                        };
    2999             :  *             };
    3000             :  *     };
    3001             :  * @endcode
    3002             :  *
    3003             :  * Example usage:
    3004             :  *
    3005             :  * @code{.c}
    3006             :  *     #define GET_PROP(n) DT_PROP(n, foobar),
    3007             :  *
    3008             :  *     const char *ancestor_names[] = {
    3009             :  *         DT_FOREACH_ANCESTOR(DT_NODELABEL(n_3), GET_PROP)
    3010             :  *     };
    3011             :  * @endcode
    3012             :  *
    3013             :  * This expands to:
    3014             :  *
    3015             :  * @code{.c}
    3016             :  *     const char *ancestor_names[] = {
    3017             :  *         "foo2", "foo1",
    3018             :  *     };
    3019             :  * @endcode
    3020             :  *
    3021             :  * @param node_id node identifier
    3022             :  * @param fn macro to invoke
    3023             :  */
    3024           1 : #define DT_FOREACH_ANCESTOR(node_id, fn) \
    3025             :         DT_CAT(node_id, _FOREACH_ANCESTOR)(fn)
    3026             : 
    3027             : /**
    3028             :  * @brief Invokes @p fn for each child of @p node_id
    3029             :  *
    3030             :  * The macro @p fn must take one parameter, which will be the node
    3031             :  * identifier of a child node of @p node_id.
    3032             :  *
    3033             :  * The children will be iterated over in the same order as they
    3034             :  * appear in the final devicetree.
    3035             :  *
    3036             :  * Example devicetree fragment:
    3037             :  *
    3038             :  * @code{.dts}
    3039             :  *     n: node {
    3040             :  *             child-1 {
    3041             :  *                     foobar = "foo";
    3042             :  *             };
    3043             :  *             child-2 {
    3044             :  *                     foobar = "bar";
    3045             :  *             };
    3046             :  *     };
    3047             :  * @endcode
    3048             :  *
    3049             :  * Example usage:
    3050             :  *
    3051             :  * @code{.c}
    3052             :  *     #define FOOBAR_AND_COMMA(node_id) DT_PROP(node_id, foobar),
    3053             :  *
    3054             :  *     const char *child_foobars[] = {
    3055             :  *         DT_FOREACH_CHILD(DT_NODELABEL(n), FOOBAR_AND_COMMA)
    3056             :  *     };
    3057             :  * @endcode
    3058             :  *
    3059             :  * This expands to:
    3060             :  *
    3061             :  * @code{.c}
    3062             :  *     const char *child_foobars[] = {
    3063             :  *         "foo", "bar",
    3064             :  *     };
    3065             :  * @endcode
    3066             :  *
    3067             :  * @param node_id node identifier
    3068             :  * @param fn macro to invoke
    3069             :  */
    3070           1 : #define DT_FOREACH_CHILD(node_id, fn) \
    3071             :         DT_CAT(node_id, _FOREACH_CHILD)(fn)
    3072             : 
    3073             : /**
    3074             :  * @brief Invokes @p fn for each child of @p node_id with a separator
    3075             :  *
    3076             :  * The macro @p fn must take one parameter, which will be the node
    3077             :  * identifier of a child node of @p node_id.
    3078             :  *
    3079             :  * Example devicetree fragment:
    3080             :  *
    3081             :  * @code{.dts}
    3082             :  *     n: node {
    3083             :  *             child-1 {
    3084             :  *                     ...
    3085             :  *             };
    3086             :  *             child-2 {
    3087             :  *                     ...
    3088             :  *             };
    3089             :  *     };
    3090             :  * @endcode
    3091             :  *
    3092             :  * Example usage:
    3093             :  *
    3094             :  * @code{.c}
    3095             :  *     const char *child_names[] = {
    3096             :  *         DT_FOREACH_CHILD_SEP(DT_NODELABEL(n), DT_NODE_FULL_NAME, (,))
    3097             :  *     };
    3098             :  * @endcode
    3099             :  *
    3100             :  * This expands to:
    3101             :  *
    3102             :  * @code{.c}
    3103             :  *     const char *child_names[] = {
    3104             :  *         "child-1", "child-2"
    3105             :  *     };
    3106             :  * @endcode
    3107             :  *
    3108             :  * @param node_id node identifier
    3109             :  * @param fn macro to invoke
    3110             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    3111             :  *            this is required to enable providing a comma as separator.
    3112             :  */
    3113           1 : #define DT_FOREACH_CHILD_SEP(node_id, fn, sep) \
    3114             :         DT_CAT(node_id, _FOREACH_CHILD_SEP)(fn, sep)
    3115             : 
    3116             : /**
    3117             :  * @brief Invokes @p fn for each child of @p node_id with multiple arguments
    3118             :  *
    3119             :  * The macro @p fn takes multiple arguments. The first should be the node
    3120             :  * identifier for the child node. The remaining are passed-in by the caller.
    3121             :  *
    3122             :  * The children will be iterated over in the same order as they
    3123             :  * appear in the final devicetree.
    3124             :  *
    3125             :  * @param node_id node identifier
    3126             :  * @param fn macro to invoke
    3127             :  * @param ... variable number of arguments to pass to @p fn
    3128             :  *
    3129             :  * @see DT_FOREACH_CHILD
    3130             :  */
    3131           1 : #define DT_FOREACH_CHILD_VARGS(node_id, fn, ...) \
    3132             :         DT_CAT(node_id, _FOREACH_CHILD_VARGS)(fn, __VA_ARGS__)
    3133             : 
    3134             : /**
    3135             :  * @brief Invokes @p fn for each child of @p node_id with separator and multiple
    3136             :  *        arguments.
    3137             :  *
    3138             :  * The macro @p fn takes multiple arguments. The first should be the node
    3139             :  * identifier for the child node. The remaining are passed-in by the caller.
    3140             :  *
    3141             :  * @param node_id node identifier
    3142             :  * @param fn macro to invoke
    3143             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    3144             :  *            this is required to enable providing a comma as separator.
    3145             :  * @param ... variable number of arguments to pass to @p fn
    3146             :  *
    3147             :  * @see DT_FOREACH_CHILD_VARGS
    3148             :  */
    3149           1 : #define DT_FOREACH_CHILD_SEP_VARGS(node_id, fn, sep, ...) \
    3150             :         DT_CAT(node_id, _FOREACH_CHILD_SEP_VARGS)(fn, sep, __VA_ARGS__)
    3151             : 
    3152             : /**
    3153             :  * @brief Call @p fn on the child nodes with status `okay`
    3154             :  *
    3155             :  * The macro @p fn should take one argument, which is the node
    3156             :  * identifier for the child node.
    3157             :  *
    3158             :  * As usual, both a missing status and an `ok` status are
    3159             :  * treated as `okay`.
    3160             :  *
    3161             :  * The children will be iterated over in the same order as they
    3162             :  * appear in the final devicetree.
    3163             :  *
    3164             :  * @param node_id node identifier
    3165             :  * @param fn macro to invoke
    3166             :  */
    3167           1 : #define DT_FOREACH_CHILD_STATUS_OKAY(node_id, fn) \
    3168             :         DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY)(fn)
    3169             : 
    3170             : /**
    3171             :  * @brief Call @p fn on the child nodes with status `okay` with separator
    3172             :  *
    3173             :  * The macro @p fn should take one argument, which is the node
    3174             :  * identifier for the child node.
    3175             :  *
    3176             :  * As usual, both a missing status and an `ok` status are
    3177             :  * treated as `okay`.
    3178             :  *
    3179             :  * @param node_id node identifier
    3180             :  * @param fn macro to invoke
    3181             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    3182             :  *            this is required to enable providing a comma as separator.
    3183             :  *
    3184             :  * @see DT_FOREACH_CHILD_STATUS_OKAY
    3185             :  */
    3186           1 : #define DT_FOREACH_CHILD_STATUS_OKAY_SEP(node_id, fn, sep) \
    3187             :         DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY_SEP)(fn, sep)
    3188             : 
    3189             : /**
    3190             :  * @brief Call @p fn on the child nodes with status `okay` with multiple
    3191             :  * arguments
    3192             :  *
    3193             :  * The macro @p fn takes multiple arguments. The first should be the node
    3194             :  * identifier for the child node. The remaining are passed-in by the caller.
    3195             :  *
    3196             :  * As usual, both a missing status and an `ok` status are
    3197             :  * treated as `okay`.
    3198             :  *
    3199             :  * The children will be iterated over in the same order as they
    3200             :  * appear in the final devicetree.
    3201             :  *
    3202             :  * @param node_id node identifier
    3203             :  * @param fn macro to invoke
    3204             :  * @param ... variable number of arguments to pass to @p fn
    3205             :  *
    3206             :  * @see DT_FOREACH_CHILD_STATUS_OKAY
    3207             :  */
    3208           1 : #define DT_FOREACH_CHILD_STATUS_OKAY_VARGS(node_id, fn, ...) \
    3209             :         DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY_VARGS)(fn, __VA_ARGS__)
    3210             : 
    3211             : /**
    3212             :  * @brief Call @p fn on the child nodes with status `okay` with separator and
    3213             :  * multiple arguments
    3214             :  *
    3215             :  * The macro @p fn takes multiple arguments. The first should be the node
    3216             :  * identifier for the child node. The remaining are passed-in by the caller.
    3217             :  *
    3218             :  * As usual, both a missing status and an `ok` status are
    3219             :  * treated as `okay`.
    3220             :  *
    3221             :  * @param node_id node identifier
    3222             :  * @param fn macro to invoke
    3223             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    3224             :  *            this is required to enable providing a comma as separator.
    3225             :  * @param ... variable number of arguments to pass to @p fn
    3226             :  *
    3227             :  * @see DT_FOREACH_CHILD_SEP_STATUS_OKAY
    3228             :  */
    3229           1 : #define DT_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS(node_id, fn, sep, ...) \
    3230             :         DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY_SEP_VARGS)(fn, sep, __VA_ARGS__)
    3231             : 
    3232             : /**
    3233             :  * @brief Invokes @p fn for each element in the value of property @p prop.
    3234             :  *
    3235             :  * The macro @p fn must take three parameters: fn(node_id, prop, idx).
    3236             :  * @p node_id and @p prop are the same as what is passed to
    3237             :  * DT_FOREACH_PROP_ELEM(), and @p idx is the current index into the array.
    3238             :  * The @p idx values are integer literals starting from 0.
    3239             :  *
    3240             :  * The @p prop argument must refer to a property that can be passed to
    3241             :  * DT_PROP_LEN().
    3242             :  *
    3243             :  * Example devicetree fragment:
    3244             :  *
    3245             :  * @code{.dts}
    3246             :  *     n: node {
    3247             :  *             my-ints = <1 2 3>;
    3248             :  *     };
    3249             :  * @endcode
    3250             :  *
    3251             :  * Example usage:
    3252             :  *
    3253             :  * @code{.c}
    3254             :  *     #define TIMES_TWO(node_id, prop, idx) \
    3255             :  *             (2 * DT_PROP_BY_IDX(node_id, prop, idx)),
    3256             :  *
    3257             :  *     int array[] = {
    3258             :  *             DT_FOREACH_PROP_ELEM(DT_NODELABEL(n), my_ints, TIMES_TWO)
    3259             :  *     };
    3260             :  * @endcode
    3261             :  *
    3262             :  * This expands to:
    3263             :  *
    3264             :  * @code{.c}
    3265             :  *     int array[] = {
    3266             :  *             (2 * 1), (2 * 2), (2 * 3),
    3267             :  *     };
    3268             :  * @endcode
    3269             :  *
    3270             :  * In general, this macro expands to:
    3271             :  *
    3272             :  *     fn(node_id, prop, 0) fn(node_id, prop, 1) [...] fn(node_id, prop, n-1)
    3273             :  *
    3274             :  * where `n` is the number of elements in @p prop, as it would be
    3275             :  * returned by `DT_PROP_LEN(node_id, prop)`.
    3276             :  *
    3277             :  * @param node_id node identifier
    3278             :  * @param prop lowercase-and-underscores property name
    3279             :  * @param fn macro to invoke
    3280             :  * @see DT_PROP_LEN
    3281             :  */
    3282           1 : #define DT_FOREACH_PROP_ELEM(node_id, prop, fn)         \
    3283             :         DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM)(fn)
    3284             : 
    3285             : /**
    3286             :  * @brief Invokes @p fn for each element in the value of property @p prop with
    3287             :  *        separator.
    3288             :  *
    3289             :  * Example devicetree fragment:
    3290             :  *
    3291             :  * @code{.dts}
    3292             :  *     n: node {
    3293             :  *             my-gpios = <&gpioa 0 GPIO_ACTICE_HIGH>,
    3294             :  *                        <&gpiob 1 GPIO_ACTIVE_HIGH>;
    3295             :  *     };
    3296             :  * @endcode
    3297             :  *
    3298             :  * Example usage:
    3299             :  *
    3300             :  * @code{.c}
    3301             :  *     struct gpio_dt_spec specs[] = {
    3302             :  *             DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(n), my_gpios,
    3303             :  *                                      GPIO_DT_SPEC_GET_BY_IDX, (,))
    3304             :  *     };
    3305             :  * @endcode
    3306             :  *
    3307             :  * This expands as a first step to:
    3308             :  *
    3309             :  * @code{.c}
    3310             :  *     struct gpio_dt_spec specs[] = {
    3311             :  *             GPIO_DT_SPEC_GET_BY_IDX(DT_NODELABEL(n), my_gpios, 0),
    3312             :  *             GPIO_DT_SPEC_GET_BY_IDX(DT_NODELABEL(n), my_gpios, 1)
    3313             :  *     };
    3314             :  * @endcode
    3315             :  *
    3316             :  * The @p prop parameter has the same restrictions as the same parameter
    3317             :  * given to DT_FOREACH_PROP_ELEM().
    3318             :  *
    3319             :  * @param node_id node identifier
    3320             :  * @param prop lowercase-and-underscores property name
    3321             :  * @param fn macro to invoke
    3322             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    3323             :  *            this is required to enable providing a comma as separator.
    3324             :  *
    3325             :  * @see DT_FOREACH_PROP_ELEM
    3326             :  */
    3327           1 : #define DT_FOREACH_PROP_ELEM_SEP(node_id, prop, fn, sep) \
    3328             :         DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM_SEP)(fn, sep)
    3329             : 
    3330             : /**
    3331             :  * @brief Invokes @p fn for each element in the value of property @p prop with
    3332             :  * multiple arguments.
    3333             :  *
    3334             :  * The macro @p fn must take multiple parameters:
    3335             :  * `fn(node_id, prop, idx, ...)`. @p node_id and @p prop are the same as what
    3336             :  * is passed to DT_FOREACH_PROP_ELEM(), and @p idx is the current index into
    3337             :  * the array. The @p idx values are integer literals starting from 0. The
    3338             :  * remaining arguments are passed-in by the caller.
    3339             :  *
    3340             :  * The @p prop parameter has the same restrictions as the same parameter
    3341             :  * given to DT_FOREACH_PROP_ELEM().
    3342             :  *
    3343             :  * @param node_id node identifier
    3344             :  * @param prop lowercase-and-underscores property name
    3345             :  * @param fn macro to invoke
    3346             :  * @param ... variable number of arguments to pass to @p fn
    3347             :  *
    3348             :  * @see DT_FOREACH_PROP_ELEM
    3349             :  */
    3350           1 : #define DT_FOREACH_PROP_ELEM_VARGS(node_id, prop, fn, ...)              \
    3351             :         DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM_VARGS)(fn, __VA_ARGS__)
    3352             : 
    3353             : /**
    3354             :  * @brief Invokes @p fn for each element in the value of property @p prop with
    3355             :  * multiple arguments and a separator.
    3356             :  *
    3357             :  * The @p prop parameter has the same restrictions as the same parameter
    3358             :  * given to DT_FOREACH_PROP_ELEM().
    3359             :  *
    3360             :  * @param node_id node identifier
    3361             :  * @param prop lowercase-and-underscores property name
    3362             :  * @param fn macro to invoke
    3363             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    3364             :  *            this is required to enable providing a comma as separator.
    3365             :  * @param ... variable number of arguments to pass to fn
    3366             :  *
    3367             :  * @see DT_FOREACH_PROP_ELEM_VARGS
    3368             :  */
    3369           1 : #define DT_FOREACH_PROP_ELEM_SEP_VARGS(node_id, prop, fn, sep, ...)     \
    3370             :         DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM_SEP_VARGS)(      \
    3371             :                 fn, sep, __VA_ARGS__)
    3372             : 
    3373             : /**
    3374             :  * @brief Invokes @p fn for each status `okay` node of a compatible.
    3375             :  *
    3376             :  * This macro expands to:
    3377             :  *
    3378             :  *     fn(node_id_1) fn(node_id_2) ... fn(node_id_n)
    3379             :  *
    3380             :  * where each `node_id_<i>` is a node identifier for some node with
    3381             :  * compatible @p compat and status `okay`. Whitespace is added between
    3382             :  * expansions as shown above.
    3383             :  *
    3384             :  * Example devicetree fragment:
    3385             :  *
    3386             :  * @code{.dts}
    3387             :  *     / {
    3388             :  *             a {
    3389             :  *                     compatible = "foo";
    3390             :  *                     status = "okay";
    3391             :  *             };
    3392             :  *             b {
    3393             :  *                     compatible = "foo";
    3394             :  *                     status = "disabled";
    3395             :  *             };
    3396             :  *             c {
    3397             :  *                     compatible = "foo";
    3398             :  *             };
    3399             :  *     };
    3400             :  * @endcode
    3401             :  *
    3402             :  * Example usage:
    3403             :  *
    3404             :  * @code{.c}
    3405             :  *     DT_FOREACH_STATUS_OKAY(foo, DT_NODE_PATH)
    3406             :  * @endcode
    3407             :  *
    3408             :  * This expands to one of the following:
    3409             :  *
    3410             :  *     "/a" "/c"
    3411             :  *     "/c" "/a"
    3412             :  *
    3413             :  * "One of the following" is because no guarantees are made about the
    3414             :  * order that node identifiers are passed to @p fn in the expansion.
    3415             :  *
    3416             :  * (The `/c` string literal is present because a missing status
    3417             :  * property is always treated as if the status were set to `okay`.)
    3418             :  *
    3419             :  * Note also that @p fn is responsible for adding commas, semicolons,
    3420             :  * or other terminators as needed.
    3421             :  *
    3422             :  * @param compat lowercase-and-underscores devicetree compatible
    3423             :  * @param fn Macro to call for each enabled node. Must accept a
    3424             :  *           node_id as its only parameter.
    3425             :  */
    3426           1 : #define DT_FOREACH_STATUS_OKAY(compat, fn)                              \
    3427             :         COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat),                  \
    3428             :                     (UTIL_CAT(DT_FOREACH_OKAY_, compat)(fn)),           \
    3429             :                     ())
    3430             : 
    3431             : /**
    3432             :  * @brief Invokes @p fn for each status `okay` node of a compatible
    3433             :  *        with multiple arguments.
    3434             :  *
    3435             :  * This is like DT_FOREACH_STATUS_OKAY() except you can also pass
    3436             :  * additional arguments to @p fn.
    3437             :  *
    3438             :  * Example devicetree fragment:
    3439             :  *
    3440             :  * @code{.dts}
    3441             :  *     / {
    3442             :  *             a {
    3443             :  *                     compatible = "foo";
    3444             :  *                     val = <3>;
    3445             :  *             };
    3446             :  *             b {
    3447             :  *                     compatible = "foo";
    3448             :  *                     val = <4>;
    3449             :  *             };
    3450             :  *     };
    3451             :  * @endcode
    3452             :  *
    3453             :  * Example usage:
    3454             :  *
    3455             :  * @code{.c}
    3456             :  *     #define MY_FN(node_id, operator) DT_PROP(node_id, val) operator
    3457             :  *     x = DT_FOREACH_STATUS_OKAY_VARGS(foo, MY_FN, +) 0;
    3458             :  * @endcode
    3459             :  *
    3460             :  * This expands to one of the following:
    3461             :  *
    3462             :  * @code{.c}
    3463             :  *     x = 3 + 4 + 0;
    3464             :  *     x = 4 + 3 + 0;
    3465             :  * @endcode
    3466             :  *
    3467             :  * i.e. it sets `x` to 7. As with DT_FOREACH_STATUS_OKAY(), there are no
    3468             :  * guarantees about the order nodes appear in the expansion.
    3469             :  *
    3470             :  * @param compat lowercase-and-underscores devicetree compatible
    3471             :  * @param fn Macro to call for each enabled node. Must accept a
    3472             :  *           node_id as its only parameter.
    3473             :  * @param ... Additional arguments to pass to @p fn
    3474             :  */
    3475           1 : #define DT_FOREACH_STATUS_OKAY_VARGS(compat, fn, ...)                   \
    3476             :         COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat),                  \
    3477             :                     (DT_CAT(DT_FOREACH_OKAY_VARGS_,                     \
    3478             :                               compat)(fn, __VA_ARGS__)),                \
    3479             :                     ())
    3480             : 
    3481             : /**
    3482             :  * @brief Call @p fn on all nodes with compatible `compat`
    3483             :  *        and status `okay` with multiple arguments
    3484             :  *
    3485             :  *
    3486             :  * @param compat lowercase-and-underscores devicetree compatible
    3487             :  * @param fn Macro to call for each enabled node. Must accept a
    3488             :  *           devicetree compatible and instance number.
    3489             :  * @param ... Additional arguments to pass to @p fn
    3490             :  *
    3491             :  * @see DT_INST_FOREACH_STATUS_OKAY_VARGS
    3492             :  */
    3493           1 : #define DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(compat, fn, ...)            \
    3494             :         COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat),                  \
    3495             :                     (UTIL_CAT(DT_FOREACH_OKAY_INST_VARGS_,              \
    3496             :                               compat)(fn, compat, __VA_ARGS__)),        \
    3497             :                     ())
    3498             : 
    3499             : 
    3500             : /**
    3501             :  * @brief Invokes @p fn for each node label of a given node
    3502             :  *
    3503             :  * The order of the node labels in this macro's expansion matches
    3504             :  * the order in the final devicetree, with duplicates removed.
    3505             :  *
    3506             :  * Node labels are passed to @p fn as tokens. Note that devicetree
    3507             :  * node labels are always valid C tokens (see "6.2 Labels" in
    3508             :  * Devicetree Specification v0.4 for details). The node labels are
    3509             :  * passed as tokens to @p fn as-is, without any lowercasing or
    3510             :  * conversion of special characters to underscores.
    3511             :  *
    3512             :  * Example devicetree fragment:
    3513             :  *
    3514             :  * @code{.dts}
    3515             :  *     foo: bar: FOO: node@deadbeef {};
    3516             :  * @endcode
    3517             :  *
    3518             :  * Example usage:
    3519             :  *
    3520             :  * @code{.c}
    3521             :  *     int foo = 1;
    3522             :  *     int bar = 2;
    3523             :  *     int FOO = 3;
    3524             :  *
    3525             :  *     #define FN(nodelabel) + nodelabel
    3526             :  *     int sum = 0 DT_FOREACH_NODELABEL(DT_NODELABEL(foo), FN)
    3527             :  * @endcode
    3528             :  *
    3529             :  * This expands to:
    3530             :  *
    3531             :  * @code{.c}
    3532             :  *     int sum = 0 + 1 + 2 + 3;
    3533             :  * @endcode
    3534             :  *
    3535             :  * @param node_id node identifier whose node labels to use
    3536             :  * @param fn macro which will be passed each node label in order
    3537             :  */
    3538           1 : #define DT_FOREACH_NODELABEL(node_id, fn) DT_CAT(node_id, _FOREACH_NODELABEL)(fn)
    3539             : 
    3540             : /**
    3541             :  * @brief Invokes @p fn for each node label of a given node with
    3542             :  *        multiple arguments.
    3543             :  *
    3544             :  * This is like DT_FOREACH_NODELABEL() except you can also pass
    3545             :  * additional arguments to @p fn.
    3546             :  *
    3547             :  * Example devicetree fragment:
    3548             :  *
    3549             :  * @code{.dts}
    3550             :  *     foo: bar: node@deadbeef {};
    3551             :  * @endcode
    3552             :  *
    3553             :  * Example usage:
    3554             :  *
    3555             :  * @code{.c}
    3556             :  *     int foo = 0;
    3557             :  *     int bar = 1;
    3558             :  *
    3559             :  *     #define VAR_PLUS(nodelabel, to_add) int nodelabel ## _added = nodelabel + to_add;
    3560             :  *
    3561             :  *     DT_FOREACH_NODELABEL_VARGS(DT_NODELABEL(foo), VAR_PLUS, 1)
    3562             :  * @endcode
    3563             :  *
    3564             :  * This expands to:
    3565             :  *
    3566             :  * @code{.c}
    3567             :  *     int foo = 0;
    3568             :  *     int bar = 1;
    3569             :  *     int foo_added = foo + 1;
    3570             :  *     int bar_added = bar + 1;
    3571             :  * @endcode
    3572             :  *
    3573             :  * @param node_id node identifier whose node labels to use
    3574             :  * @param fn macro which will be passed each node label in order
    3575             :  * @param ... additional arguments to pass to @p fn
    3576             :  */
    3577           1 : #define DT_FOREACH_NODELABEL_VARGS(node_id, fn, ...) \
    3578             :         DT_CAT(node_id, _FOREACH_NODELABEL_VARGS)(fn, __VA_ARGS__)
    3579             : 
    3580             : /**
    3581             :  * @}
    3582             :  */
    3583             : 
    3584             : /**
    3585             :  * @defgroup devicetree-generic-exist Existence checks
    3586             :  * @ingroup devicetree
    3587             :  * @{
    3588             :  */
    3589             : 
    3590             : /**
    3591             :  * @brief Does a node identifier refer to a node?
    3592             :  *
    3593             :  * Tests whether a node identifier refers to a node which exists, i.e.
    3594             :  * is defined in the devicetree.
    3595             :  *
    3596             :  * It doesn't matter whether or not the node has a matching binding,
    3597             :  * or what the node's status value is. This is purely a check of
    3598             :  * whether the node exists at all.
    3599             :  *
    3600             :  * @param node_id a node identifier
    3601             :  * @return 1 if the node identifier refers to a node,
    3602             :  *         0 otherwise.
    3603             :  */
    3604           1 : #define DT_NODE_EXISTS(node_id) IS_ENABLED(DT_CAT(node_id, _EXISTS))
    3605             : 
    3606             : /**
    3607             :  * @brief Does a node identifier refer to a node with a status?
    3608             :  *
    3609             :  * Example uses:
    3610             :  *
    3611             :  * @code{.c}
    3612             :  *     DT_NODE_HAS_STATUS(DT_PATH(soc, i2c_12340000), okay)
    3613             :  *     DT_NODE_HAS_STATUS(DT_PATH(soc, i2c_12340000), disabled)
    3614             :  * @endcode
    3615             :  *
    3616             :  * Tests whether a node identifier refers to a node which:
    3617             :  *
    3618             :  * - exists in the devicetree, and
    3619             :  * - has a status property matching the second argument
    3620             :  *   (except that either a missing status or an `ok` status
    3621             :  *   in the devicetree is treated as if it were `okay` instead)
    3622             :  *
    3623             :  * @param node_id a node identifier
    3624             :  * @param status a status as one of the tokens okay or disabled, not a string
    3625             :  * @return 1 if the node has the given status, 0 otherwise.
    3626             :  */
    3627           1 : #define DT_NODE_HAS_STATUS(node_id, status) \
    3628             :         DT_NODE_HAS_STATUS_INTERNAL(node_id, status)
    3629             : 
    3630             : /**
    3631             :  * @brief Does a node identifier refer to a node with a status `okay`?
    3632             :  *
    3633             :  * Example uses:
    3634             :  *
    3635             :  * @code{.c}
    3636             :  *     DT_NODE_HAS_STATUS_OKAY(DT_PATH(soc, i2c_12340000))
    3637             :  * @endcode
    3638             :  *
    3639             :  * Tests whether a node identifier refers to a node which:
    3640             :  *
    3641             :  * - exists in the devicetree, and
    3642             :  * - has a status property as `okay`
    3643             :  *
    3644             :  * As usual, both a missing status and an `ok` status are treated as
    3645             :  * `okay`.
    3646             :  *
    3647             :  * @param node_id a node identifier
    3648             :  * @return 1 if the node has status as `okay`, 0 otherwise.
    3649             :  */
    3650           1 : #define DT_NODE_HAS_STATUS_OKAY(node_id) DT_NODE_HAS_STATUS(node_id, okay)
    3651             : 
    3652             : /**
    3653             :  * @brief Does the devicetree have a status `okay` node with a compatible?
    3654             :  *
    3655             :  * Test for whether the devicetree has any nodes with status `okay`
    3656             :  * and the given compatible. That is, this returns 1 if and only if
    3657             :  * there is at least one @p node_id for which both of these
    3658             :  * expressions return 1:
    3659             :  *
    3660             :  * @code{.c}
    3661             :  *     DT_NODE_HAS_STATUS(node_id, okay)
    3662             :  *     DT_NODE_HAS_COMPAT(node_id, compat)
    3663             :  * @endcode
    3664             :  *
    3665             :  * As usual, both a missing status and an `ok` status are treated as
    3666             :  * `okay`.
    3667             :  *
    3668             :  * @param compat lowercase-and-underscores compatible, without quotes
    3669             :  * @return 1 if both of the above conditions are met, 0 otherwise
    3670             :  */
    3671           1 : #define DT_HAS_COMPAT_STATUS_OKAY(compat) \
    3672             :         IS_ENABLED(DT_CAT(DT_COMPAT_HAS_OKAY_, compat))
    3673             : 
    3674             : /**
    3675             :  * @brief Get the number of instances of a given compatible with
    3676             :  *        status `okay`
    3677             :  * @param compat lowercase-and-underscores compatible, without quotes
    3678             :  * @return Number of instances with status `okay`
    3679             :  */
    3680           1 : #define DT_NUM_INST_STATUS_OKAY(compat)                 \
    3681             :         UTIL_AND(DT_HAS_COMPAT_STATUS_OKAY(compat),             \
    3682             :                  UTIL_CAT(DT_N_INST, DT_DASH(compat, NUM_OKAY)))
    3683             : 
    3684             : /**
    3685             :  * @brief Does a devicetree node match a compatible?
    3686             :  *
    3687             :  * Example devicetree fragment:
    3688             :  *
    3689             :  * @code{.dts}
    3690             :  *     n: node {
    3691             :  *             compatible = "vnd,specific-device", "generic-device";
    3692             :  *     }
    3693             :  * @endcode
    3694             :  *
    3695             :  * Example usages which evaluate to 1:
    3696             :  *
    3697             :  * @code{.c}
    3698             :  *     DT_NODE_HAS_COMPAT(DT_NODELABEL(n), vnd_specific_device)
    3699             :  *     DT_NODE_HAS_COMPAT(DT_NODELABEL(n), generic_device)
    3700             :  * @endcode
    3701             :  *
    3702             :  * This macro only uses the value of the compatible property. Whether
    3703             :  * or not a particular compatible has a matching binding has no effect
    3704             :  * on its value, nor does the node's status.
    3705             :  *
    3706             :  * @param node_id node identifier
    3707             :  * @param compat lowercase-and-underscores compatible, without quotes
    3708             :  * @return 1 if the node's compatible property contains @p compat,
    3709             :  *         0 otherwise.
    3710             :  */
    3711           1 : #define DT_NODE_HAS_COMPAT(node_id, compat) \
    3712             :         IS_ENABLED(DT_CAT3(node_id, _COMPAT_MATCHES_, compat))
    3713             : 
    3714             : /**
    3715             :  * @brief Does a devicetree node have a compatible and status?
    3716             :  *
    3717             :  * This is equivalent to:
    3718             :  *
    3719             :  * @code{.c}
    3720             :  *     (DT_NODE_HAS_COMPAT(node_id, compat) &&
    3721             :  *      DT_NODE_HAS_STATUS(node_id, status))
    3722             :  * @endcode
    3723             :  *
    3724             :  * @param node_id node identifier
    3725             :  * @param compat lowercase-and-underscores compatible, without quotes
    3726             :  * @param status okay or disabled as a token, not a string
    3727             :  */
    3728           1 : #define DT_NODE_HAS_COMPAT_STATUS(node_id, compat, status) \
    3729             :         UTIL_AND(DT_NODE_HAS_COMPAT(node_id, compat), DT_NODE_HAS_STATUS(node_id, status))
    3730             : 
    3731             : /**
    3732             :  * @brief Does a devicetree node have a property?
    3733             :  *
    3734             :  * Tests whether a devicetree node has a property defined.
    3735             :  *
    3736             :  * This tests whether the property is defined at all, not whether a
    3737             :  * boolean property is true or false. To get a boolean property's
    3738             :  * truth value, use DT_PROP(node_id, prop) instead.
    3739             :  *
    3740             :  * @param node_id node identifier
    3741             :  * @param prop lowercase-and-underscores property name
    3742             :  * @return 1 if the node has the property, 0 otherwise.
    3743             :  */
    3744           1 : #define DT_NODE_HAS_PROP(node_id, prop) \
    3745             :         IS_ENABLED(DT_CAT4(node_id, _P_, prop, _EXISTS))
    3746             : 
    3747             : 
    3748             : /**
    3749             :  * @brief Does a phandle array have a named cell specifier at an index?
    3750             :  *
    3751             :  * If this returns 1, then the phandle-array property @p pha has a cell
    3752             :  * named @p cell at index @p idx, and therefore DT_PHA_BY_IDX(node_id,
    3753             :  * pha, idx, cell) is valid. If it returns 0, it's an error to use
    3754             :  * DT_PHA_BY_IDX() with the same arguments.
    3755             :  *
    3756             :  * @param node_id node identifier
    3757             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    3758             :  * @param idx index to check within @p pha
    3759             :  * @param cell lowercase-and-underscores cell name whose existence to check
    3760             :  *             at index @p idx
    3761             :  * @return 1 if the named cell exists in the specifier at index idx,
    3762             :  *         0 otherwise.
    3763             :  */
    3764           1 : #define DT_PHA_HAS_CELL_AT_IDX(node_id, pha, idx, cell)             \
    3765             :         IS_ENABLED(DT_CAT8(node_id, _P_, pha,                       \
    3766             :                            _IDX_, idx, _VAL_, cell, _EXISTS))
    3767             : 
    3768             : /**
    3769             :  * @brief Equivalent to DT_PHA_HAS_CELL_AT_IDX(node_id, pha, 0, cell)
    3770             :  * @param node_id node identifier
    3771             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    3772             :  * @param cell lowercase-and-underscores cell name whose existence to check
    3773             :  *             at index @p idx
    3774             :  * @return 1 if the named cell exists in the specifier at index 0,
    3775             :  *         0 otherwise.
    3776             :  */
    3777           1 : #define DT_PHA_HAS_CELL(node_id, pha, cell) \
    3778             :         DT_PHA_HAS_CELL_AT_IDX(node_id, pha, 0, cell)
    3779             : 
    3780             : /**
    3781             :  * @}
    3782             :  */
    3783             : 
    3784             : /**
    3785             :  * @defgroup devicetree-generic-bus Bus helpers
    3786             :  * @ingroup devicetree
    3787             :  * @{
    3788             :  */
    3789             : 
    3790             : /**
    3791             :  * @brief Node's bus controller
    3792             :  *
    3793             :  * Get the node identifier of the node's bus controller. This can be
    3794             :  * used with DT_PROP() to get properties of the bus controller.
    3795             :  *
    3796             :  * It is an error to use this with nodes which do not have bus
    3797             :  * controllers.
    3798             :  *
    3799             :  * Example devicetree fragment:
    3800             :  *
    3801             :  * @code{.dts}
    3802             :  *     i2c@deadbeef {
    3803             :  *             status = "okay";
    3804             :  *             clock-frequency = < 100000 >;
    3805             :  *
    3806             :  *             i2c_device: accelerometer@12 {
    3807             :  *                     ...
    3808             :  *             };
    3809             :  *     };
    3810             :  * @endcode
    3811             :  *
    3812             :  * Example usage:
    3813             :  *
    3814             :  * @code{.c}
    3815             :  *     DT_PROP(DT_BUS(DT_NODELABEL(i2c_device)), clock_frequency) // 100000
    3816             :  * @endcode
    3817             :  *
    3818             :  * @param node_id node identifier
    3819             :  * @return a node identifier for the node's bus controller
    3820             :  */
    3821           1 : #define DT_BUS(node_id) DT_CAT(node_id, _BUS)
    3822             : 
    3823             : /**
    3824             :  * @brief Is a node on a bus of a given type?
    3825             :  *
    3826             :  * Example devicetree overlay:
    3827             :  *
    3828             :  * @code{.dts}
    3829             :  *     &i2c0 {
    3830             :  *            temp: temperature-sensor@76 {
    3831             :  *                     compatible = "vnd,some-sensor";
    3832             :  *                     reg = <0x76>;
    3833             :  *            };
    3834             :  *     };
    3835             :  * @endcode
    3836             :  *
    3837             :  * Example usage, assuming `i2c0` is an I2C bus controller node, and
    3838             :  * therefore `temp` is on an I2C bus:
    3839             :  *
    3840             :  * @code{.c}
    3841             :  *     DT_ON_BUS(DT_NODELABEL(temp), i2c) // 1
    3842             :  *     DT_ON_BUS(DT_NODELABEL(temp), spi) // 0
    3843             :  * @endcode
    3844             :  *
    3845             :  * @param node_id node identifier
    3846             :  * @param bus lowercase-and-underscores bus type as a C token (i.e.
    3847             :  *            without quotes)
    3848             :  * @return 1 if the node is on a bus of the given type,
    3849             :  *         0 otherwise
    3850             :  */
    3851           1 : #define DT_ON_BUS(node_id, bus) IS_ENABLED(DT_CAT3(node_id, _BUS_, bus))
    3852             : 
    3853             : /**
    3854             :  * @}
    3855             :  */
    3856             : 
    3857             : /**
    3858             :  * @defgroup devicetree-inst Instance-based devicetree APIs
    3859             :  * @ingroup devicetree
    3860             :  * @{
    3861             :  */
    3862             : 
    3863             : /**
    3864             :  * @brief Node identifier for an instance of a `DT_DRV_COMPAT` compatible
    3865             :  * @param inst instance number
    3866             :  * @return a node identifier for the node with `DT_DRV_COMPAT` compatible and
    3867             :  *         instance number @p inst
    3868             :  */
    3869           1 : #define DT_DRV_INST(inst) DT_INST(inst, DT_DRV_COMPAT)
    3870             : 
    3871             : /**
    3872             :  * @brief Get a `DT_DRV_COMPAT` parent's node identifier
    3873             :  * @param inst instance number
    3874             :  * @return a node identifier for the instance's parent
    3875             :  *
    3876             :  * @see DT_PARENT
    3877             :  */
    3878           1 : #define DT_INST_PARENT(inst) DT_PARENT(DT_DRV_INST(inst))
    3879             : 
    3880             : /**
    3881             :  * @brief Get a `DT_DRV_COMPAT` grandparent's node identifier
    3882             :  * @param inst instance number
    3883             :  * @return a node identifier for the instance's grandparent
    3884             :  *
    3885             :  * @see DT_GPARENT
    3886             :  */
    3887           1 : #define DT_INST_GPARENT(inst) DT_GPARENT(DT_DRV_INST(inst))
    3888             : 
    3889             : /**
    3890             :  * @brief Get a node identifier for a child node of DT_DRV_INST(inst)
    3891             :  *
    3892             :  * @param inst instance number
    3893             :  * @param child lowercase-and-underscores child node name
    3894             :  * @return node identifier for the node with the name referred to by 'child'
    3895             :  *
    3896             :  * @see DT_CHILD
    3897             :  */
    3898           1 : #define DT_INST_CHILD(inst, child) \
    3899             :         DT_CHILD(DT_DRV_INST(inst), child)
    3900             : 
    3901             : /**
    3902             :  * @brief Get the number of child nodes of a given node
    3903             :  *
    3904             :  * This is equivalent to @see
    3905             :  * <tt>DT_CHILD_NUM(DT_DRV_INST(inst))</tt>.
    3906             :  *
    3907             :  * @param inst Devicetree instance number
    3908             :  * @return Number of child nodes
    3909             :  */
    3910           1 : #define DT_INST_CHILD_NUM(inst) DT_CHILD_NUM(DT_DRV_INST(inst))
    3911             : 
    3912             : /**
    3913             :  * @brief Get the number of child nodes of a given node
    3914             :  *
    3915             :  * This is equivalent to @see
    3916             :  * <tt>DT_CHILD_NUM_STATUS_OKAY(DT_DRV_INST(inst))</tt>.
    3917             :  *
    3918             :  * @param inst Devicetree instance number
    3919             :  * @return Number of child nodes which status are okay
    3920             :  */
    3921           1 : #define DT_INST_CHILD_NUM_STATUS_OKAY(inst) \
    3922             :         DT_CHILD_NUM_STATUS_OKAY(DT_DRV_INST(inst))
    3923             : 
    3924             : /**
    3925             :  * @brief Get a string array of DT_DRV_INST(inst)'s node labels
    3926             :  *
    3927             :  * Equivalent to DT_NODELABEL_STRING_ARRAY(DT_DRV_INST(inst)).
    3928             :  *
    3929             :  * @param inst instance number
    3930             :  * @return an array initializer for an array of the instance's node labels as strings
    3931             :  */
    3932           1 : #define DT_INST_NODELABEL_STRING_ARRAY(inst) DT_NODELABEL_STRING_ARRAY(DT_DRV_INST(inst))
    3933             : 
    3934             : /**
    3935             :  * @brief Get the number of node labels by instance number
    3936             :  *
    3937             :  * Equivalent to DT_NUM_NODELABELS(DT_DRV_INST(inst)).
    3938             :  *
    3939             :  * @param inst instance number
    3940             :  * @return the number of node labels that the node with that instance number has
    3941             :  */
    3942           1 : #define DT_INST_NUM_NODELABELS(inst) DT_NUM_NODELABELS(DT_DRV_INST(inst))
    3943             : 
    3944             : /**
    3945             :  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst).
    3946             :  *
    3947             :  * The macro @p fn should take one argument, which is the node
    3948             :  * identifier for the child node.
    3949             :  *
    3950             :  * The children will be iterated over in the same order as they
    3951             :  * appear in the final devicetree.
    3952             :  *
    3953             :  * @param inst instance number
    3954             :  * @param fn macro to invoke on each child node identifier
    3955             :  *
    3956             :  * @see DT_FOREACH_CHILD
    3957             :  */
    3958           1 : #define DT_INST_FOREACH_CHILD(inst, fn) \
    3959             :         DT_FOREACH_CHILD(DT_DRV_INST(inst), fn)
    3960             : 
    3961             : /**
    3962             :  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with a separator
    3963             :  *
    3964             :  * The macro @p fn should take one argument, which is the node
    3965             :  * identifier for the child node.
    3966             :  *
    3967             :  * @param inst instance number
    3968             :  * @param fn macro to invoke on each child node identifier
    3969             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    3970             :  *            this is required to enable providing a comma as separator.
    3971             :  *
    3972             :  * @see DT_FOREACH_CHILD_SEP
    3973             :  */
    3974           1 : #define DT_INST_FOREACH_CHILD_SEP(inst, fn, sep) \
    3975             :         DT_FOREACH_CHILD_SEP(DT_DRV_INST(inst), fn, sep)
    3976             : 
    3977             : /**
    3978             :  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst).
    3979             :  *
    3980             :  * The macro @p fn takes multiple arguments. The first should be the node
    3981             :  * identifier for the child node. The remaining are passed-in by the caller.
    3982             :  *
    3983             :  * The children will be iterated over in the same order as they
    3984             :  * appear in the final devicetree.
    3985             :  *
    3986             :  * @param inst instance number
    3987             :  * @param fn macro to invoke on each child node identifier
    3988             :  * @param ... variable number of arguments to pass to @p fn
    3989             :  *
    3990             :  * @see DT_FOREACH_CHILD
    3991             :  */
    3992           1 : #define DT_INST_FOREACH_CHILD_VARGS(inst, fn, ...) \
    3993             :         DT_FOREACH_CHILD_VARGS(DT_DRV_INST(inst), fn, __VA_ARGS__)
    3994             : 
    3995             : /**
    3996             :  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with separator.
    3997             :  *
    3998             :  * The macro @p fn takes multiple arguments. The first should be the node
    3999             :  * identifier for the child node. The remaining are passed-in by the caller.
    4000             :  *
    4001             :  * @param inst instance number
    4002             :  * @param fn macro to invoke on each child node identifier
    4003             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    4004             :  *            this is required to enable providing a comma as separator.
    4005             :  * @param ... variable number of arguments to pass to @p fn
    4006             :  *
    4007             :  * @see DT_FOREACH_CHILD_SEP_VARGS
    4008             :  */
    4009           1 : #define DT_INST_FOREACH_CHILD_SEP_VARGS(inst, fn, sep, ...) \
    4010             :         DT_FOREACH_CHILD_SEP_VARGS(DT_DRV_INST(inst), fn, sep, __VA_ARGS__)
    4011             : 
    4012             : /**
    4013             :  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`.
    4014             :  *
    4015             :  * The macro @p fn should take one argument, which is the node
    4016             :  * identifier for the child node.
    4017             :  *
    4018             :  * @param inst instance number
    4019             :  * @param fn macro to invoke on each child node identifier
    4020             :  *
    4021             :  * @see DT_FOREACH_CHILD_STATUS_OKAY
    4022             :  */
    4023           1 : #define DT_INST_FOREACH_CHILD_STATUS_OKAY(inst, fn) \
    4024             :         DT_FOREACH_CHILD_STATUS_OKAY(DT_DRV_INST(inst), fn)
    4025             : 
    4026             : /**
    4027             :  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`
    4028             :  * and with separator.
    4029             :  *
    4030             :  * The macro @p fn should take one argument, which is the node
    4031             :  * identifier for the child node.
    4032             :  *
    4033             :  * @param inst instance number
    4034             :  * @param fn macro to invoke on each child node identifier
    4035             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    4036             :  *            this is required to enable providing a comma as separator.
    4037             :  *
    4038             :  * @see DT_FOREACH_CHILD_STATUS_OKAY_SEP
    4039             :  */
    4040           1 : #define DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(inst, fn, sep) \
    4041             :         DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_DRV_INST(inst), fn, sep)
    4042             : 
    4043             : /**
    4044             :  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`
    4045             :  * and multiple arguments.
    4046             :  *
    4047             :  * The macro @p fn takes multiple arguments. The first should be the node
    4048             :  * identifier for the child node. The remaining are passed-in by the caller.
    4049             :  *
    4050             :  * @param inst instance number
    4051             :  * @param fn macro to invoke on each child node identifier
    4052             :  * @param ... variable number of arguments to pass to @p fn
    4053             :  *
    4054             :  * @see DT_FOREACH_CHILD_STATUS_OKAY_VARGS
    4055             :  */
    4056           1 : #define DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(inst, fn, ...) \
    4057             :         DT_FOREACH_CHILD_STATUS_OKAY_VARGS(DT_DRV_INST(inst), fn, __VA_ARGS__)
    4058             : 
    4059             : /**
    4060             :  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`
    4061             :  * and with separator and multiple arguments.
    4062             :  *
    4063             :  * The macro @p fn takes multiple arguments. The first should be the node
    4064             :  * identifier for the child node. The remaining are passed-in by the caller.
    4065             :  *
    4066             :  * @param inst instance number
    4067             :  * @param fn macro to invoke on each child node identifier
    4068             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    4069             :  *            this is required to enable providing a comma as separator.
    4070             :  * @param ... variable number of arguments to pass to @p fn
    4071             :  *
    4072             :  * @see DT_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS
    4073             :  */
    4074           1 : #define DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS(inst, fn, sep, ...) \
    4075             :         DT_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS(DT_DRV_INST(inst), fn, sep, __VA_ARGS__)
    4076             : 
    4077             : /**
    4078             :  * @brief Get a `DT_DRV_COMPAT` property array value's index into its enumeration values
    4079             :  * @param inst instance number
    4080             :  * @param prop lowercase-and-underscores property name
    4081             :  * @param idx the index to get
    4082             :  * @return zero-based index of the property's value in its enum: list
    4083             :  */
    4084           1 : #define DT_INST_ENUM_IDX_BY_IDX(inst, prop, idx) \
    4085             :         DT_ENUM_IDX_BY_IDX(DT_DRV_INST(inst), prop, idx)
    4086             : 
    4087             : /**
    4088             :  * @brief Get a `DT_DRV_COMPAT` value's index into its enumeration values
    4089             :  * @param inst instance number
    4090             :  * @param prop lowercase-and-underscores property name
    4091             :  * @return zero-based index of the property's value in its enum: list
    4092             :  */
    4093           1 : #define DT_INST_ENUM_IDX(inst, prop) \
    4094             :         DT_ENUM_IDX(DT_DRV_INST(inst), prop)
    4095             : 
    4096             : /**
    4097             :  * @brief Like DT_INST_ENUM_IDX_BY_IDX(), but with a fallback to a default enum index
    4098             :  * @param inst instance number
    4099             :  * @param prop lowercase-and-underscores property name
    4100             :  * @param idx the index to get
    4101             :  * @param default_idx_value a fallback index value to expand to
    4102             :  * @return zero-based index of the property's value in its enum if present,
    4103             :  *         default_idx_value otherwise
    4104             :  */
    4105           1 : #define DT_INST_ENUM_IDX_BY_IDX_OR(inst, prop, idx, default_idx_value) \
    4106             :         DT_ENUM_IDX_BY_IDX_OR(DT_DRV_INST(inst), prop, idx, default_idx_value)
    4107             : 
    4108             : /**
    4109             :  * @brief Like DT_INST_ENUM_IDX(), but with a fallback to a default enum index
    4110             :  * @param inst instance number
    4111             :  * @param prop lowercase-and-underscores property name
    4112             :  * @param default_idx_value a fallback index value to expand to
    4113             :  * @return zero-based index of the property's value in its enum if present,
    4114             :  *         default_idx_value otherwise
    4115             :  */
    4116           1 : #define DT_INST_ENUM_IDX_OR(inst, prop, default_idx_value) \
    4117             :         DT_ENUM_IDX_OR(DT_DRV_INST(inst), prop, default_idx_value)
    4118             : 
    4119             : /**
    4120             :  * @brief Does a `DT_DRV_COMPAT` enumeration property have a given value by index?
    4121             :  * @param inst instance number
    4122             :  * @param prop lowercase-and-underscores property name
    4123             :  * @param idx the index to get
    4124             :  * @param value lowercase-and-underscores enumeration value
    4125             :  * @return zero-based index of the property's value in its enum
    4126             :  */
    4127           1 : #define DT_INST_ENUM_HAS_VALUE_BY_IDX(inst, prop, idx, value) \
    4128             :         DT_ENUM_HAS_VALUE_BY_IDX(DT_DRV_INST(inst), prop, idx, value)
    4129             : 
    4130             : /**
    4131             :  * @brief Does a `DT_DRV_COMPAT` enumeration property have a given value?
    4132             :  *
    4133             :  * @param inst instance number
    4134             :  * @param prop lowercase-and-underscores property name
    4135             :  * @param value lowercase-and-underscores enumeration value
    4136             :  * @return 1 if the node property has the value @a value, 0 otherwise.
    4137             :  */
    4138           1 : #define DT_INST_ENUM_HAS_VALUE(inst, prop, value) \
    4139             :         DT_ENUM_HAS_VALUE(DT_DRV_INST(inst), prop, value)
    4140             : 
    4141             : /**
    4142             :  * @brief Get a `DT_DRV_COMPAT` instance property
    4143             :  * @param inst instance number
    4144             :  * @param prop lowercase-and-underscores property name
    4145             :  * @return a representation of the property's value
    4146             :  */
    4147           1 : #define DT_INST_PROP(inst, prop) DT_PROP(DT_DRV_INST(inst), prop)
    4148             : 
    4149             : /**
    4150             :  * @brief Get a `DT_DRV_COMPAT` property length
    4151             :  * @param inst instance number
    4152             :  * @param prop lowercase-and-underscores property name
    4153             :  * @return logical length of the property
    4154             :  */
    4155           1 : #define DT_INST_PROP_LEN(inst, prop) DT_PROP_LEN(DT_DRV_INST(inst), prop)
    4156             : 
    4157             : /**
    4158             :  * @brief Is index @p idx valid for an array type property
    4159             :  *        on a `DT_DRV_COMPAT` instance?
    4160             :  * @param inst instance number
    4161             :  * @param prop lowercase-and-underscores property name
    4162             :  * @param idx index to check
    4163             :  * @return 1 if @p idx is a valid index into the given property,
    4164             :  *         0 otherwise.
    4165             :  */
    4166           1 : #define DT_INST_PROP_HAS_IDX(inst, prop, idx) \
    4167             :         DT_PROP_HAS_IDX(DT_DRV_INST(inst), prop, idx)
    4168             : 
    4169             : /**
    4170             :  * @brief Is name @p name available in a `foo-names` property?
    4171             :  * @param inst instance number
    4172             :  * @param prop a lowercase-and-underscores `prop-names` type property
    4173             :  * @param name a lowercase-and-underscores name to check
    4174             :  * @return An expression which evaluates to 1 if @p name is an available
    4175             :  *         name into the given property, and 0 otherwise.
    4176             :  */
    4177           1 : #define DT_INST_PROP_HAS_NAME(inst, prop, name) \
    4178             :         DT_PROP_HAS_NAME(DT_DRV_INST(inst), prop, name)
    4179             : 
    4180             : /**
    4181             :  * @brief Get a `DT_DRV_COMPAT` element value in an array property
    4182             :  * @param inst instance number
    4183             :  * @param prop lowercase-and-underscores property name
    4184             :  * @param idx the index to get
    4185             :  * @return a representation of the idx-th element of the property
    4186             :  */
    4187           1 : #define DT_INST_PROP_BY_IDX(inst, prop, idx) \
    4188             :         DT_PROP_BY_IDX(DT_DRV_INST(inst), prop, idx)
    4189             : 
    4190             : /**
    4191             :  * @brief Like DT_INST_PROP(), but with a fallback to @p default_value
    4192             :  * @param inst instance number
    4193             :  * @param prop lowercase-and-underscores property name
    4194             :  * @param default_value a fallback value to expand to
    4195             :  * @return DT_INST_PROP(inst, prop) or @p default_value
    4196             :  */
    4197           1 : #define DT_INST_PROP_OR(inst, prop, default_value) \
    4198             :         DT_PROP_OR(DT_DRV_INST(inst), prop, default_value)
    4199             : 
    4200             : /**
    4201             :  * @brief Like DT_INST_PROP_LEN(), but with a fallback to @p default_value
    4202             :  * @param inst instance number
    4203             :  * @param prop lowercase-and-underscores property name
    4204             :  * @param default_value a fallback value to expand to
    4205             :  * @return DT_INST_PROP_LEN(inst, prop) or @p default_value
    4206             :  */
    4207           1 : #define DT_INST_PROP_LEN_OR(inst, prop, default_value) \
    4208             :         DT_PROP_LEN_OR(DT_DRV_INST(inst), prop, default_value)
    4209             : 
    4210             : /**
    4211             :  * @brief Get a `DT_DRV_COMPAT` instance's string property's value as a
    4212             :  *        token.
    4213             :  *
    4214             :  * @param inst instance number
    4215             :  * @param prop lowercase-and-underscores property name
    4216             :  * @return the value of @p prop as a token, i.e. without any quotes
    4217             :  *         and with special characters converted to underscores
    4218             :  */
    4219           1 : #define DT_INST_STRING_TOKEN(inst, prop) \
    4220             :         DT_STRING_TOKEN(DT_DRV_INST(inst), prop)
    4221             : 
    4222             : /**
    4223             :  * @brief Like DT_INST_STRING_TOKEN(), but uppercased.
    4224             :  * @param inst instance number
    4225             :  * @param prop lowercase-and-underscores property name
    4226             :  * @return the value of @p prop as an uppercased token, i.e. without
    4227             :  *         any quotes and with special characters converted to underscores
    4228             :  */
    4229           1 : #define DT_INST_STRING_UPPER_TOKEN(inst, prop) \
    4230             :         DT_STRING_UPPER_TOKEN(DT_DRV_INST(inst), prop)
    4231             : 
    4232             : /**
    4233             :  * @brief Get a `DT_DRV_COMPAT` instance's string property's value as
    4234             :  *        an unquoted sequence of tokens.
    4235             :  *
    4236             :  * @param inst instance number
    4237             :  * @param prop lowercase-and-underscores property name
    4238             :  * @return the value of @p prop as a sequence of tokens, with no quotes
    4239             :  */
    4240           1 : #define DT_INST_STRING_UNQUOTED(inst, prop) \
    4241             :         DT_STRING_UNQUOTED(DT_DRV_INST(inst), prop)
    4242             : 
    4243             : /**
    4244             :  * @brief Get an element out of string-array property as a token.
    4245             :  * @param inst instance number
    4246             :  * @param prop lowercase-and-underscores property name
    4247             :  * @param idx the index to get
    4248             :  * @return the element in @p prop at index @p idx as a token
    4249             :  */
    4250           1 : #define DT_INST_STRING_TOKEN_BY_IDX(inst, prop, idx) \
    4251             :         DT_STRING_TOKEN_BY_IDX(DT_DRV_INST(inst), prop, idx)
    4252             : 
    4253             : /**
    4254             :  * @brief Like DT_INST_STRING_TOKEN_BY_IDX(), but uppercased.
    4255             :  * @param inst instance number
    4256             :  * @param prop lowercase-and-underscores property name
    4257             :  * @param idx the index to get
    4258             :  * @return the element in @p prop at index @p idx as an uppercased token
    4259             :  */
    4260           1 : #define DT_INST_STRING_UPPER_TOKEN_BY_IDX(inst, prop, idx) \
    4261             :         DT_STRING_UPPER_TOKEN_BY_IDX(DT_DRV_INST(inst), prop, idx)
    4262             : 
    4263             : /**
    4264             :  * @brief Get an element out of string-array property as an unquoted sequence of tokens.
    4265             :  * @param inst instance number
    4266             :  * @param prop lowercase-and-underscores property name
    4267             :  * @param idx the index to get
    4268             :  * @return the value of @p prop at index @p idx as a sequence of tokens, with no quotes
    4269             :  */
    4270           1 : #define DT_INST_STRING_UNQUOTED_BY_IDX(inst, prop, idx) \
    4271             :         DT_STRING_UNQUOTED_BY_IDX(DT_DRV_INST(inst), prop, idx)
    4272             : 
    4273             : /**
    4274             :  * @brief Get a `DT_DRV_COMPAT` instance's property value from a phandle's node
    4275             :  * @param inst instance number
    4276             :  * @param ph lowercase-and-underscores property of @p inst
    4277             :  *           with type `phandle`
    4278             :  * @param prop lowercase-and-underscores property of the phandle's node
    4279             :  * @return the value of @p prop as described in the DT_PROP() documentation
    4280             :  */
    4281           1 : #define DT_INST_PROP_BY_PHANDLE(inst, ph, prop) \
    4282             :         DT_INST_PROP_BY_PHANDLE_IDX(inst, ph, 0, prop)
    4283             : 
    4284             : /**
    4285             :  * @brief Get a `DT_DRV_COMPAT` instance's property value from a phandle in a
    4286             :  * property.
    4287             :  * @param inst instance number
    4288             :  * @param phs lowercase-and-underscores property with type `phandle`,
    4289             :  *            `phandles`, or `phandle-array`
    4290             :  * @param idx logical index into "phs", which must be zero if "phs"
    4291             :  *            has type `phandle`
    4292             :  * @param prop lowercase-and-underscores property of the phandle's node
    4293             :  * @return the value of @p prop as described in the DT_PROP() documentation
    4294             :  */
    4295           1 : #define DT_INST_PROP_BY_PHANDLE_IDX(inst, phs, idx, prop) \
    4296             :         DT_PROP_BY_PHANDLE_IDX(DT_DRV_INST(inst), phs, idx, prop)
    4297             : 
    4298             : /**
    4299             :  * @brief Get a `DT_DRV_COMPAT` instance's phandle-array specifier value at an index
    4300             :  * @param inst instance number
    4301             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    4302             :  * @param idx logical index into the property @p pha
    4303             :  * @param cell binding's cell name within the specifier at index @p idx
    4304             :  * @return the value of the cell inside the specifier at index @p idx
    4305             :  */
    4306           1 : #define DT_INST_PHA_BY_IDX(inst, pha, idx, cell) \
    4307             :         DT_PHA_BY_IDX(DT_DRV_INST(inst), pha, idx, cell)
    4308             : 
    4309             : /**
    4310             :  * @brief Like DT_INST_PHA_BY_IDX(), but with a fallback to default_value
    4311             :  * @param inst instance number
    4312             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    4313             :  * @param idx logical index into the property @p pha
    4314             :  * @param cell binding's cell name within the specifier at index @p idx
    4315             :  * @param default_value a fallback value to expand to
    4316             :  * @return DT_INST_PHA_BY_IDX(inst, pha, idx, cell) or default_value
    4317             :  */
    4318           1 : #define DT_INST_PHA_BY_IDX_OR(inst, pha, idx, cell, default_value) \
    4319             :         DT_PHA_BY_IDX_OR(DT_DRV_INST(inst), pha, idx, cell, default_value)
    4320             : 
    4321             : /**
    4322             :  * @brief Get a `DT_DRV_COMPAT` instance's phandle-array specifier value
    4323             :  * Equivalent to DT_INST_PHA_BY_IDX(inst, pha, 0, cell)
    4324             :  * @param inst instance number
    4325             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    4326             :  * @param cell binding's cell name for the specifier at @p pha index 0
    4327             :  * @return the cell value
    4328             :  */
    4329           1 : #define DT_INST_PHA(inst, pha, cell) DT_INST_PHA_BY_IDX(inst, pha, 0, cell)
    4330             : 
    4331             : /**
    4332             :  * @brief Like DT_INST_PHA(), but with a fallback to default_value
    4333             :  * @param inst instance number
    4334             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    4335             :  * @param cell binding's cell name for the specifier at @p pha index 0
    4336             :  * @param default_value a fallback value to expand to
    4337             :  * @return DT_INST_PHA(inst, pha, cell) or default_value
    4338             :  */
    4339           1 : #define DT_INST_PHA_OR(inst, pha, cell, default_value) \
    4340             :         DT_INST_PHA_BY_IDX_OR(inst, pha, 0, cell, default_value)
    4341             : 
    4342             : /**
    4343             :  * @brief Get a `DT_DRV_COMPAT` instance's value within a phandle-array
    4344             :  * specifier by name
    4345             :  * @param inst instance number
    4346             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    4347             :  * @param name lowercase-and-underscores name of a specifier in @p pha
    4348             :  * @param cell binding's cell name for the named specifier
    4349             :  * @return the cell value
    4350             :  */
    4351           1 : #define DT_INST_PHA_BY_NAME(inst, pha, name, cell) \
    4352             :         DT_PHA_BY_NAME(DT_DRV_INST(inst), pha, name, cell)
    4353             : 
    4354             : /**
    4355             :  * @brief Like DT_INST_PHA_BY_NAME(), but with a fallback to default_value
    4356             :  * @param inst instance number
    4357             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    4358             :  * @param name lowercase-and-underscores name of a specifier in @p pha
    4359             :  * @param cell binding's cell name for the named specifier
    4360             :  * @param default_value a fallback value to expand to
    4361             :  * @return DT_INST_PHA_BY_NAME(inst, pha, name, cell) or default_value
    4362             :  */
    4363           1 : #define DT_INST_PHA_BY_NAME_OR(inst, pha, name, cell, default_value) \
    4364             :         DT_PHA_BY_NAME_OR(DT_DRV_INST(inst), pha, name, cell, default_value)
    4365             : 
    4366             : /**
    4367             :  * @brief Get a `DT_DRV_COMPAT` instance's phandle node identifier from a
    4368             :  * phandle array by name
    4369             :  * @param inst instance number
    4370             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    4371             :  * @param name lowercase-and-underscores name of an element in @p pha
    4372             :  * @return node identifier for the phandle at the element named "name"
    4373             :  */
    4374           1 : #define DT_INST_PHANDLE_BY_NAME(inst, pha, name) \
    4375             :         DT_PHANDLE_BY_NAME(DT_DRV_INST(inst), pha, name) \
    4376             : 
    4377             : /**
    4378             :  * @brief Get a `DT_DRV_COMPAT` instance's node identifier for a phandle in
    4379             :  * a property.
    4380             :  * @param inst instance number
    4381             :  * @param prop lowercase-and-underscores property name in @p inst
    4382             :  *             with type `phandle`, `phandles` or `phandle-array`
    4383             :  * @param idx index into @p prop
    4384             :  * @return a node identifier for the phandle at index @p idx in @p prop
    4385             :  */
    4386           1 : #define DT_INST_PHANDLE_BY_IDX(inst, prop, idx) \
    4387             :         DT_PHANDLE_BY_IDX(DT_DRV_INST(inst), prop, idx)
    4388             : 
    4389             : /**
    4390             :  * @brief Get a `DT_DRV_COMPAT` instance's node identifier for a phandle
    4391             :  * property's value
    4392             :  * @param inst instance number
    4393             :  * @param prop lowercase-and-underscores property of @p inst
    4394             :  *             with type `phandle`
    4395             :  * @return a node identifier for the node pointed to by "ph"
    4396             :  */
    4397           1 : #define DT_INST_PHANDLE(inst, prop) DT_INST_PHANDLE_BY_IDX(inst, prop, 0)
    4398             : 
    4399             : /**
    4400             :  * @brief is @p idx a valid register block index on a `DT_DRV_COMPAT` instance?
    4401             :  * @param inst instance number
    4402             :  * @param idx index to check
    4403             :  * @return 1 if @p idx is a valid register block index,
    4404             :  *         0 otherwise.
    4405             :  */
    4406           1 : #define DT_INST_REG_HAS_IDX(inst, idx) DT_REG_HAS_IDX(DT_DRV_INST(inst), idx)
    4407             : 
    4408             : /**
    4409             :  * @brief is @p name a valid register block name on a `DT_DRV_COMPAT` instance?
    4410             :  * @param inst instance number
    4411             :  * @param name name to check
    4412             :  * @return 1 if @p name is a valid register block name,
    4413             :  *         0 otherwise.
    4414             :  */
    4415           1 : #define DT_INST_REG_HAS_NAME(inst, name) DT_REG_HAS_NAME(DT_DRV_INST(inst), name)
    4416             : 
    4417             : /**
    4418             :  * @brief Get a `DT_DRV_COMPAT` instance's idx-th register block's raw address
    4419             :  * @param inst instance number
    4420             :  * @param idx index of the register whose address to return
    4421             :  * @return address of the instance's idx-th register block
    4422             :  */
    4423           1 : #define DT_INST_REG_ADDR_BY_IDX_RAW(inst, idx) DT_REG_ADDR_BY_IDX_RAW(DT_DRV_INST(inst), idx)
    4424             : 
    4425             : /**
    4426             :  * @brief Get a `DT_DRV_COMPAT` instance's idx-th register block's address
    4427             :  * @param inst instance number
    4428             :  * @param idx index of the register whose address to return
    4429             :  * @return address of the instance's idx-th register block
    4430             :  */
    4431           1 : #define DT_INST_REG_ADDR_BY_IDX(inst, idx) DT_REG_ADDR_BY_IDX(DT_DRV_INST(inst), idx)
    4432             : 
    4433             : /**
    4434             :  * @brief Get a `DT_DRV_COMPAT` instance's idx-th register block's size
    4435             :  * @param inst instance number
    4436             :  * @param idx index of the register whose size to return
    4437             :  * @return size of the instance's idx-th register block
    4438             :  */
    4439           1 : #define DT_INST_REG_SIZE_BY_IDX(inst, idx) \
    4440             :         DT_REG_SIZE_BY_IDX(DT_DRV_INST(inst), idx)
    4441             : 
    4442             : /**
    4443             :  * @brief Get a `DT_DRV_COMPAT`'s register block address by  name
    4444             :  * @param inst instance number
    4445             :  * @param name lowercase-and-underscores register specifier name
    4446             :  * @return address of the register block with the given @p name
    4447             :  */
    4448           1 : #define DT_INST_REG_ADDR_BY_NAME(inst, name) \
    4449             :         DT_REG_ADDR_BY_NAME(DT_DRV_INST(inst), name)
    4450             : 
    4451             : /**
    4452             :  * @brief Like DT_INST_REG_ADDR_BY_NAME(), but with a fallback to @p default_value
    4453             :  * @param inst instance number
    4454             :  * @param name lowercase-and-underscores register specifier name
    4455             :  * @param default_value a fallback value to expand to
    4456             :  * @return address of the register block specified by name if present,
    4457             :  *         @p default_value otherwise
    4458             :  */
    4459           1 : #define DT_INST_REG_ADDR_BY_NAME_OR(inst, name, default_value) \
    4460             :         DT_REG_ADDR_BY_NAME_OR(DT_DRV_INST(inst), name, default_value)
    4461             : 
    4462             : /**
    4463             :  * @brief 64-bit version of DT_INST_REG_ADDR_BY_NAME()
    4464             :  *
    4465             :  * This macro version adds the appropriate suffix for 64-bit unsigned
    4466             :  * integer literals.
    4467             :  * Note that this macro is equivalent to DT_INST_REG_ADDR_BY_NAME() in
    4468             :  * linker/ASM context.
    4469             :  *
    4470             :  * @param inst instance number
    4471             :  * @param name lowercase-and-underscores register specifier name
    4472             :  * @return address of the register block with the given @p name
    4473             :  */
    4474           1 : #define DT_INST_REG_ADDR_BY_NAME_U64(inst, name) \
    4475             :         DT_REG_ADDR_BY_NAME_U64(DT_DRV_INST(inst), name)
    4476             : 
    4477             : /**
    4478             :  * @brief Get a `DT_DRV_COMPAT`'s register block size by name
    4479             :  * @param inst instance number
    4480             :  * @param name lowercase-and-underscores register specifier name
    4481             :  * @return size of the register block with the given @p name
    4482             :  */
    4483           1 : #define DT_INST_REG_SIZE_BY_NAME(inst, name) \
    4484             :         DT_REG_SIZE_BY_NAME(DT_DRV_INST(inst), name)
    4485             : 
    4486             : /**
    4487             :  * @brief Like DT_INST_REG_SIZE_BY_NAME(), but with a fallback to @p default_value
    4488             :  * @param inst instance number
    4489             :  * @param name lowercase-and-underscores register specifier name
    4490             :  * @param default_value a fallback value to expand to
    4491             :  * @return size of the register block specified by name if present,
    4492             :  *         @p default_value otherwise
    4493             :  */
    4494           1 : #define DT_INST_REG_SIZE_BY_NAME_OR(inst, name, default_value) \
    4495             :         DT_REG_SIZE_BY_NAME_OR(DT_DRV_INST(inst), name, default_value)
    4496             : 
    4497             : /**
    4498             :  * @brief Get a `DT_DRV_COMPAT`'s (only) register block raw address
    4499             :  * @param inst instance number
    4500             :  * @return instance's register block address
    4501             :  */
    4502           1 : #define DT_INST_REG_ADDR_RAW(inst) DT_INST_REG_ADDR_BY_IDX_RAW(inst, 0)
    4503             : 
    4504             : /**
    4505             :  * @brief Get a `DT_DRV_COMPAT`'s (only) register block address
    4506             :  * @param inst instance number
    4507             :  * @return instance's register block address
    4508             :  */
    4509           1 : #define DT_INST_REG_ADDR(inst) DT_INST_REG_ADDR_BY_IDX(inst, 0)
    4510             : 
    4511             : /**
    4512             :  * @brief 64-bit version of DT_INST_REG_ADDR()
    4513             :  *
    4514             :  * This macro version adds the appropriate suffix for 64-bit unsigned
    4515             :  * integer literals.
    4516             :  * Note that this macro is equivalent to DT_INST_REG_ADDR() in
    4517             :  * linker/ASM context.
    4518             :  *
    4519             :  * @param inst instance number
    4520             :  * @return instance's register block address
    4521             :  */
    4522           1 : #define DT_INST_REG_ADDR_U64(inst) DT_REG_ADDR_U64(DT_DRV_INST(inst))
    4523             : 
    4524             : /**
    4525             :  * @brief Get a `DT_DRV_COMPAT`'s (only) register block size
    4526             :  * @param inst instance number
    4527             :  * @return instance's register block size
    4528             :  */
    4529           1 : #define DT_INST_REG_SIZE(inst) DT_INST_REG_SIZE_BY_IDX(inst, 0)
    4530             : 
    4531             : /**
    4532             :  * @brief Get a `DT_DRV_COMPAT`'s number of interrupts
    4533             :  *
    4534             :  * @param inst instance number
    4535             :  * @return number of interrupts
    4536             :  */
    4537           1 : #define DT_INST_NUM_IRQS(inst) DT_NUM_IRQS(DT_DRV_INST(inst))
    4538             : 
    4539             : /**
    4540             :  * @brief Get a `DT_DRV_COMPAT` interrupt level
    4541             :  *
    4542             :  * @param inst instance number
    4543             :  * @return interrupt level
    4544             :  */
    4545           1 : #define DT_INST_IRQ_LEVEL(inst) DT_IRQ_LEVEL(DT_DRV_INST(inst))
    4546             : 
    4547             : /**
    4548             :  * @brief Get a `DT_DRV_COMPAT` interrupt specifier value at an index
    4549             :  * @param inst instance number
    4550             :  * @param idx logical index into the interrupt specifier array
    4551             :  * @param cell cell name specifier
    4552             :  * @return the named value at the specifier given by the index
    4553             :  */
    4554           1 : #define DT_INST_IRQ_BY_IDX(inst, idx, cell) \
    4555             :         DT_IRQ_BY_IDX(DT_DRV_INST(inst), idx, cell)
    4556             : 
    4557             : /**
    4558             :  * @brief Get a `DT_DRV_COMPAT` interrupt specifier's interrupt controller by index
    4559             :  * @param inst instance number
    4560             :  * @param idx interrupt specifier's index
    4561             :  * @return node_id of interrupt specifier's interrupt controller
    4562             :  */
    4563           1 : #define DT_INST_IRQ_INTC_BY_IDX(inst, idx) \
    4564             :         DT_IRQ_INTC_BY_IDX(DT_DRV_INST(inst), idx)
    4565             : 
    4566             : /**
    4567             :  * @brief Get a `DT_DRV_COMPAT` interrupt specifier's interrupt controller by name
    4568             :  * @param inst instance number
    4569             :  * @param name interrupt specifier's name
    4570             :  * @return node_id of interrupt specifier's interrupt controller
    4571             :  */
    4572           1 : #define DT_INST_IRQ_INTC_BY_NAME(inst, name) \
    4573             :         DT_IRQ_INTC_BY_NAME(DT_DRV_INST(inst), name)
    4574             : 
    4575             : /**
    4576             :  * @brief Get a `DT_DRV_COMPAT` interrupt specifier's interrupt controller
    4577             :  * @note Equivalent to DT_INST_IRQ_INTC_BY_IDX(node_id, 0)
    4578             :  * @param inst instance number
    4579             :  * @return node_id of interrupt specifier's interrupt controller
    4580             :  * @see DT_INST_IRQ_INTC_BY_IDX()
    4581             :  */
    4582           1 : #define DT_INST_IRQ_INTC(inst) \
    4583             :         DT_INST_IRQ_INTC_BY_IDX(inst, 0)
    4584             : 
    4585             : /**
    4586             :  * @brief Get a `DT_DRV_COMPAT` interrupt specifier value by name
    4587             :  * @param inst instance number
    4588             :  * @param name lowercase-and-underscores interrupt specifier name
    4589             :  * @param cell cell name specifier
    4590             :  * @return the named value at the specifier given by the index
    4591             :  */
    4592           1 : #define DT_INST_IRQ_BY_NAME(inst, name, cell) \
    4593             :         DT_IRQ_BY_NAME(DT_DRV_INST(inst), name, cell)
    4594             : 
    4595             : /**
    4596             :  * @brief Get a `DT_DRV_COMPAT` interrupt specifier's value
    4597             :  * @param inst instance number
    4598             :  * @param cell cell name specifier
    4599             :  * @return the named value at that index
    4600             :  */
    4601           1 : #define DT_INST_IRQ(inst, cell) DT_INST_IRQ_BY_IDX(inst, 0, cell)
    4602             : 
    4603             : /**
    4604             :  * @brief Get a `DT_DRV_COMPAT`'s (only) irq number
    4605             :  * @param inst instance number
    4606             :  * @return the interrupt number for the node's only interrupt
    4607             :  */
    4608           1 : #define DT_INST_IRQN(inst) DT_IRQN(DT_DRV_INST(inst))
    4609             : 
    4610             : /**
    4611             :  * @brief Get a `DT_DRV_COMPAT`'s irq number at index
    4612             :  * @param inst instance number
    4613             :  * @param idx logical index into the interrupt specifier array
    4614             :  * @return the interrupt number for the node's idx-th interrupt
    4615             :  */
    4616           1 : #define DT_INST_IRQN_BY_IDX(inst, idx) DT_IRQN_BY_IDX(DT_DRV_INST(inst), idx)
    4617             : 
    4618             : /**
    4619             :  * @brief Get a `DT_DRV_COMPAT`'s bus node identifier
    4620             :  * @param inst instance number
    4621             :  * @return node identifier for the instance's bus node
    4622             :  */
    4623           1 : #define DT_INST_BUS(inst) DT_BUS(DT_DRV_INST(inst))
    4624             : 
    4625             : /**
    4626             :  * @brief Test if a `DT_DRV_COMPAT`'s bus type is a given type
    4627             :  * @param inst instance number
    4628             :  * @param bus a binding's bus type as a C token, lowercased and without quotes
    4629             :  * @return 1 if the given instance is on a bus of the given type,
    4630             :  *         0 otherwise
    4631             :  */
    4632           1 : #define DT_INST_ON_BUS(inst, bus) DT_ON_BUS(DT_DRV_INST(inst), bus)
    4633             : 
    4634             : /**
    4635             :  * @brief Like DT_INST_STRING_TOKEN(), but with a fallback to @p default_value
    4636             :  * @param inst instance number
    4637             :  * @param name lowercase-and-underscores property name
    4638             :  * @param default_value a fallback value to expand to
    4639             :  * @return if @p prop exists, its value as a token, i.e. without any quotes and
    4640             :  *         with special characters converted to underscores. Otherwise
    4641             :  *         @p default_value
    4642             :  */
    4643           1 : #define DT_INST_STRING_TOKEN_OR(inst, name, default_value) \
    4644             :         DT_STRING_TOKEN_OR(DT_DRV_INST(inst), name, default_value)
    4645             : 
    4646             : /**
    4647             :  * @brief Like DT_INST_STRING_UPPER_TOKEN(), but with a fallback to
    4648             :  *        @p default_value
    4649             :  * @param inst instance number
    4650             :  * @param name lowercase-and-underscores property name
    4651             :  * @param default_value a fallback value to expand to
    4652             :  * @return the property's value as an uppercased token, or @p default_value
    4653             :  */
    4654           1 : #define DT_INST_STRING_UPPER_TOKEN_OR(inst, name, default_value) \
    4655             :         DT_STRING_UPPER_TOKEN_OR(DT_DRV_INST(inst), name, default_value)
    4656             : 
    4657             : /**
    4658             :  * @brief Like DT_INST_STRING_UNQUOTED(), but with a fallback to
    4659             :  *        @p default_value
    4660             :  * @param inst instance number
    4661             :  * @param name lowercase-and-underscores property name
    4662             :  * @param default_value a fallback value to expand to
    4663             :  * @return the property's value as a sequence of tokens, with no quotes, or @p default_value
    4664             :  */
    4665           1 : #define DT_INST_STRING_UNQUOTED_OR(inst, name, default_value) \
    4666             :         DT_STRING_UNQUOTED_OR(DT_DRV_INST(inst), name, default_value)
    4667             : 
    4668             : /*
    4669             :  * @brief Test if any enabled node with the given compatible is on
    4670             :  *        the given bus type
    4671             :  *
    4672             :  * This is like DT_ANY_INST_ON_BUS_STATUS_OKAY(), except it can also
    4673             :  * be useful for handling multiple compatibles in single source file.
    4674             :  *
    4675             :  * Example devicetree overlay:
    4676             :  *
    4677             :  * @code{.dts}
    4678             :  *     &i2c0 {
    4679             :  *            temp: temperature-sensor@76 {
    4680             :  *                     compatible = "vnd,some-sensor";
    4681             :  *                     reg = <0x76>;
    4682             :  *            };
    4683             :  *     };
    4684             :  * @endcode
    4685             :  *
    4686             :  * Example usage, assuming `i2c0` is an I2C bus controller node, and
    4687             :  * therefore `temp` is on an I2C bus:
    4688             :  *
    4689             :  * @code{.c}
    4690             :  *     DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(vnd_some_sensor, i2c) // 1
    4691             :  * @endcode
    4692             :  *
    4693             :  * @param compat lowercase-and-underscores compatible, without quotes
    4694             :  * @param bus a binding's bus type as a C token, lowercased and without quotes
    4695             :  * @return 1 if any enabled node with that compatible is on that bus type,
    4696             :  *         0 otherwise
    4697             :  */
    4698           0 : #define DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(compat, bus) \
    4699             :         IS_ENABLED(DT_CAT4(DT_COMPAT_, compat, _BUS_, bus))
    4700             : 
    4701             : /**
    4702             :  * @brief Test if any `DT_DRV_COMPAT` node is on a bus of a given type
    4703             :  *        and has status okay
    4704             :  *
    4705             :  * This is a special-purpose macro which can be useful when writing
    4706             :  * drivers for devices which can appear on multiple buses. One example
    4707             :  * is a sensor device which may be wired on an I2C or SPI bus.
    4708             :  *
    4709             :  * Example devicetree overlay:
    4710             :  *
    4711             :  * @code{.dts}
    4712             :  *     &i2c0 {
    4713             :  *            temp: temperature-sensor@76 {
    4714             :  *                     compatible = "vnd,some-sensor";
    4715             :  *                     reg = <0x76>;
    4716             :  *            };
    4717             :  *     };
    4718             :  * @endcode
    4719             :  *
    4720             :  * Example usage, assuming `i2c0` is an I2C bus controller node, and
    4721             :  * therefore `temp` is on an I2C bus:
    4722             :  *
    4723             :  * @code{.c}
    4724             :  *     #define DT_DRV_COMPAT vnd_some_sensor
    4725             :  *
    4726             :  *     DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) // 1
    4727             :  * @endcode
    4728             :  *
    4729             :  * @param bus a binding's bus type as a C token, lowercased and without quotes
    4730             :  * @return 1 if any enabled node with that compatible is on that bus type,
    4731             :  *         0 otherwise
    4732             :  */
    4733           1 : #define DT_ANY_INST_ON_BUS_STATUS_OKAY(bus) \
    4734             :         DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(DT_DRV_COMPAT, bus)
    4735             : 
    4736             : /**
    4737             :  * @brief Check if any `DT_DRV_COMPAT` node with status `okay` has a given
    4738             :  *        property.
    4739             :  *
    4740             :  * @param prop lowercase-and-underscores property name
    4741             :  *
    4742             :  * Example devicetree overlay:
    4743             :  *
    4744             :  * @code{.dts}
    4745             :  *     &i2c0 {
    4746             :  *         sensor0: sensor@0 {
    4747             :  *             compatible = "vnd,some-sensor";
    4748             :  *             status = "okay";
    4749             :  *             reg = <0>;
    4750             :  *             foo = <1>;
    4751             :  *             bar = <2>;
    4752             :  *         };
    4753             :  *
    4754             :  *         sensor1: sensor@1 {
    4755             :  *             compatible = "vnd,some-sensor";
    4756             :  *             status = "okay";
    4757             :  *             reg = <1>;
    4758             :  *             foo = <2>;
    4759             :  *         };
    4760             :  *
    4761             :  *         sensor2: sensor@2 {
    4762             :  *             compatible = "vnd,some-sensor";
    4763             :  *             status = "disabled";
    4764             :  *             reg = <2>;
    4765             :  *             baz = <1>;
    4766             :  *         };
    4767             :  *     };
    4768             :  * @endcode
    4769             :  *
    4770             :  * Example usage:
    4771             :  *
    4772             :  * @code{.c}
    4773             :  *     #define DT_DRV_COMPAT vnd_some_sensor
    4774             :  *
    4775             :  *     DT_ANY_INST_HAS_PROP_STATUS_OKAY(foo) // 1
    4776             :  *     DT_ANY_INST_HAS_PROP_STATUS_OKAY(bar) // 1
    4777             :  *     DT_ANY_INST_HAS_PROP_STATUS_OKAY(baz) // 0
    4778             :  * @endcode
    4779             :  */
    4780           1 : #define DT_ANY_INST_HAS_PROP_STATUS_OKAY(prop) \
    4781             :         COND_CODE_1(IS_EMPTY(DT_ANY_INST_HAS_PROP_STATUS_OKAY_(prop)), (0), (1))
    4782             : 
    4783             : /**
    4784             :  * @brief Check if any device node with status `okay` has a given
    4785             :  *        property.
    4786             :  *
    4787             :  * @param compat lowercase-and-underscores devicetree compatible
    4788             :  * @param prop lowercase-and-underscores property name
    4789             :  *
    4790             :  * Example devicetree overlay:
    4791             :  *
    4792             :  * @code{.dts}
    4793             :  *     &i2c0 {
    4794             :  *         sensor0: sensor@0 {
    4795             :  *             compatible = "vnd,some-sensor";
    4796             :  *             status = "okay";
    4797             :  *             reg = <0>;
    4798             :  *             foo = <1>;
    4799             :  *             bar = <2>;
    4800             :  *         };
    4801             :  *
    4802             :  *         sensor1: sensor@1 {
    4803             :  *             compatible = "vnd,some-sensor";
    4804             :  *             status = "okay";
    4805             :  *             reg = <1>;
    4806             :  *             foo = <2>;
    4807             :  *         };
    4808             :  *
    4809             :  *         sensor2: sensor@2 {
    4810             :  *             compatible = "vnd,some-sensor";
    4811             :  *             status = "disabled";
    4812             :  *             reg = <2>;
    4813             :  *             baz = <1>;
    4814             :  *         };
    4815             :  *     };
    4816             :  * @endcode
    4817             :  *
    4818             :  * Example usage:
    4819             :  *
    4820             :  * @code{.c}
    4821             :  *
    4822             :  *     DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, foo) // 1
    4823             :  *     DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, bar) // 1
    4824             :  *     DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(vnd_some_sensor, baz) // 0
    4825             :  * @endcode
    4826             :  */
    4827           1 : #define DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(compat, prop) \
    4828             :         (DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(compat, DT_COMPAT_NODE_HAS_PROP_AND_OR, prop) 0)
    4829             : 
    4830             : /**
    4831             :  * @brief Check if any `DT_DRV_COMPAT` node with status `okay` has a given
    4832             :  *        boolean property that exists.
    4833             :  *
    4834             :  * This differs from @ref DT_ANY_INST_HAS_PROP_STATUS_OKAY because even when not present
    4835             :  * on a node, the boolean property is generated with a value of 0 and therefore exists.
    4836             :  *
    4837             :  * @param prop lowercase-and-underscores property name
    4838             :  *
    4839             :  * Example devicetree overlay:
    4840             :  *
    4841             :  * @code{.dts}
    4842             :  *     &i2c0 {
    4843             :  *         sensor0: sensor@0 {
    4844             :  *             compatible = "vnd,some-sensor";
    4845             :  *             status = "okay";
    4846             :  *             reg = <0>;
    4847             :  *             foo;
    4848             :  *             bar;
    4849             :  *         };
    4850             :  *
    4851             :  *         sensor1: sensor@1 {
    4852             :  *             compatible = "vnd,some-sensor";
    4853             :  *             status = "okay";
    4854             :  *             reg = <1>;
    4855             :  *             foo;
    4856             :  *         };
    4857             :  *
    4858             :  *         sensor2: sensor@2 {
    4859             :  *             compatible = "vnd,some-sensor";
    4860             :  *             status = "disabled";
    4861             :  *             reg = <2>;
    4862             :  *             baz;
    4863             :  *         };
    4864             :  *     };
    4865             :  * @endcode
    4866             :  *
    4867             :  * Example usage:
    4868             :  *
    4869             :  * @code{.c}
    4870             :  *     #define DT_DRV_COMPAT vnd_some_sensor
    4871             :  *
    4872             :  *     DT_ANY_INST_HAS_BOOL_STATUS_OKAY(foo) // 1
    4873             :  *     DT_ANY_INST_HAS_BOOL_STATUS_OKAY(bar) // 1
    4874             :  *     DT_ANY_INST_HAS_BOOL_STATUS_OKAY(baz) // 0
    4875             :  * @endcode
    4876             :  */
    4877           1 : #define DT_ANY_INST_HAS_BOOL_STATUS_OKAY(prop) \
    4878             :         COND_CODE_1(IS_EMPTY(DT_ANY_INST_HAS_BOOL_STATUS_OKAY_(prop)), (0), (1))
    4879             : 
    4880             : /**
    4881             :  * @brief Call @p fn on all nodes with compatible `DT_DRV_COMPAT`
    4882             :  *        and status `okay`
    4883             :  *
    4884             :  * This macro calls `fn(inst)` on each `inst` number that refers to a
    4885             :  * node with status `okay`. Whitespace is added between invocations.
    4886             :  *
    4887             :  * Example devicetree fragment:
    4888             :  *
    4889             :  * @code{.dts}
    4890             :  *     a {
    4891             :  *             compatible = "vnd,device";
    4892             :  *             status = "okay";
    4893             :  *             foobar = "DEV_A";
    4894             :  *     };
    4895             :  *
    4896             :  *     b {
    4897             :  *             compatible = "vnd,device";
    4898             :  *             status = "okay";
    4899             :  *             foobar = "DEV_B";
    4900             :  *     };
    4901             :  *
    4902             :  *     c {
    4903             :  *             compatible = "vnd,device";
    4904             :  *             status = "disabled";
    4905             :  *             foobar = "DEV_C";
    4906             :  *     };
    4907             :  * @endcode
    4908             :  *
    4909             :  * Example usage:
    4910             :  *
    4911             :  * @code{.c}
    4912             :  *     #define DT_DRV_COMPAT vnd_device
    4913             :  *     #define MY_FN(inst) DT_INST_PROP(inst, foobar),
    4914             :  *
    4915             :  *     DT_INST_FOREACH_STATUS_OKAY(MY_FN)
    4916             :  * @endcode
    4917             :  *
    4918             :  * This expands to:
    4919             :  *
    4920             :  * @code{.c}
    4921             :  *     MY_FN(0) MY_FN(1)
    4922             :  * @endcode
    4923             :  *
    4924             :  * and from there, to either this:
    4925             :  *
    4926             :  *     "DEV_A", "DEV_B",
    4927             :  *
    4928             :  * or this:
    4929             :  *
    4930             :  *     "DEV_B", "DEV_A",
    4931             :  *
    4932             :  * No guarantees are made about the order that a and b appear in the
    4933             :  * expansion.
    4934             :  *
    4935             :  * Note that @p fn is responsible for adding commas, semicolons, or
    4936             :  * other separators or terminators.
    4937             :  *
    4938             :  * Device drivers should use this macro whenever possible to
    4939             :  * instantiate a struct device for each enabled node in the devicetree
    4940             :  * of the driver's compatible `DT_DRV_COMPAT`.
    4941             :  *
    4942             :  * @param fn Macro to call for each enabled node. Must accept an
    4943             :  *           instance number as its only parameter.
    4944             :  */
    4945           1 : #define DT_INST_FOREACH_STATUS_OKAY(fn) \
    4946             :         COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT),   \
    4947             :                     (UTIL_CAT(DT_FOREACH_OKAY_INST_,            \
    4948             :                               DT_DRV_COMPAT)(fn)),              \
    4949             :                     ())
    4950             : 
    4951             : /**
    4952             :  * @brief Call @p fn on all nodes with compatible `DT_DRV_COMPAT`
    4953             :  *        and status `okay` with multiple arguments
    4954             :  *
    4955             :  *
    4956             :  * @param fn Macro to call for each enabled node. Must accept an
    4957             :  *           instance number.
    4958             :  * @param ... variable number of arguments to pass to @p fn
    4959             :  *
    4960             :  * @see DT_INST_FOREACH_STATUS_OKAY
    4961             :  * @see DT_COMPAT_FOREACH_STATUS_OKAY_VARGS
    4962             :  */
    4963           1 : #define DT_INST_FOREACH_STATUS_OKAY_VARGS(fn, ...) \
    4964             :         COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT),   \
    4965             :                     (UTIL_CAT(DT_FOREACH_OKAY_INST_VARGS_,      \
    4966             :                               DT_DRV_COMPAT)(fn, __VA_ARGS__)), \
    4967             :                     ())
    4968             : 
    4969             : /**
    4970             :  * @brief Call @p fn on all node labels for a given `DT_DRV_COMPAT` instance
    4971             :  *
    4972             :  * Equivalent to DT_FOREACH_NODELABEL(DT_DRV_INST(inst), fn).
    4973             :  *
    4974             :  * @param inst instance number
    4975             :  * @param fn macro which will be passed each node label for the node
    4976             :  *           with that instance number
    4977             :  */
    4978           1 : #define DT_INST_FOREACH_NODELABEL(inst, fn) \
    4979             :         DT_FOREACH_NODELABEL(DT_DRV_INST(inst), fn)
    4980             : 
    4981             : /**
    4982             :  * @brief Call @p fn on all node labels for a given `DT_DRV_COMPAT` instance
    4983             :  *        with multiple arguments
    4984             :  *
    4985             :  * Equivalent to DT_FOREACH_NODELABEL_VARGS(DT_DRV_INST(inst), fn, ...).
    4986             :  *
    4987             :  * @param inst instance number
    4988             :  * @param fn macro which will be passed each node label for the node
    4989             :  *           with that instance number
    4990             :  * @param ... additional arguments to pass to @p fn
    4991             :  */
    4992           1 : #define DT_INST_FOREACH_NODELABEL_VARGS(inst, fn, ...) \
    4993             :         DT_FOREACH_NODELABEL_VARGS(DT_DRV_INST(inst), fn, __VA_ARGS__)
    4994             : 
    4995             : /**
    4996             :  * @brief Invokes @p fn for each element of property @p prop for
    4997             :  *        a `DT_DRV_COMPAT` instance.
    4998             :  *
    4999             :  * Equivalent to DT_FOREACH_PROP_ELEM(DT_DRV_INST(inst), prop, fn).
    5000             :  *
    5001             :  * @param inst instance number
    5002             :  * @param prop lowercase-and-underscores property name
    5003             :  * @param fn macro to invoke
    5004             :  */
    5005           1 : #define DT_INST_FOREACH_PROP_ELEM(inst, prop, fn) \
    5006             :         DT_FOREACH_PROP_ELEM(DT_DRV_INST(inst), prop, fn)
    5007             : 
    5008             : /**
    5009             :  * @brief Invokes @p fn for each element of property @p prop for
    5010             :  *        a `DT_DRV_COMPAT` instance with a separator.
    5011             :  *
    5012             :  * Equivalent to DT_FOREACH_PROP_ELEM_SEP(DT_DRV_INST(inst), prop, fn, sep).
    5013             :  *
    5014             :  * @param inst instance number
    5015             :  * @param prop lowercase-and-underscores property name
    5016             :  * @param fn macro to invoke
    5017             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    5018             :  *            this is required to enable providing a comma as separator.
    5019             :  */
    5020           1 : #define DT_INST_FOREACH_PROP_ELEM_SEP(inst, prop, fn, sep) \
    5021             :         DT_FOREACH_PROP_ELEM_SEP(DT_DRV_INST(inst), prop, fn, sep)
    5022             : 
    5023             : /**
    5024             :  * @brief Invokes @p fn for each element of property @p prop for
    5025             :  *        a `DT_DRV_COMPAT` instance with multiple arguments.
    5026             :  *
    5027             :  * Equivalent to
    5028             :  *      DT_FOREACH_PROP_ELEM_VARGS(DT_DRV_INST(inst), prop, fn, __VA_ARGS__)
    5029             :  *
    5030             :  * @param inst instance number
    5031             :  * @param prop lowercase-and-underscores property name
    5032             :  * @param fn macro to invoke
    5033             :  * @param ... variable number of arguments to pass to @p fn
    5034             :  *
    5035             :  * @see DT_INST_FOREACH_PROP_ELEM
    5036             :  */
    5037           1 : #define DT_INST_FOREACH_PROP_ELEM_VARGS(inst, prop, fn, ...) \
    5038             :         DT_FOREACH_PROP_ELEM_VARGS(DT_DRV_INST(inst), prop, fn, __VA_ARGS__)
    5039             : 
    5040             : /**
    5041             :  * @brief Invokes @p fn for each element of property @p prop for
    5042             :  *        a `DT_DRV_COMPAT` instance with multiple arguments and a separator.
    5043             :  *
    5044             :  * Equivalent to
    5045             :  *      DT_FOREACH_PROP_ELEM_SEP_VARGS(DT_DRV_INST(inst), prop, fn, sep,
    5046             :  *                                     __VA_ARGS__)
    5047             :  *
    5048             :  * @param inst instance number
    5049             :  * @param prop lowercase-and-underscores property name
    5050             :  * @param fn macro to invoke
    5051             :  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
    5052             :  *            this is required to enable providing a comma as separator.
    5053             :  * @param ... variable number of arguments to pass to fn
    5054             :  *
    5055             :  * @see DT_INST_FOREACH_PROP_ELEM
    5056             :  */
    5057           1 : #define DT_INST_FOREACH_PROP_ELEM_SEP_VARGS(inst, prop, fn, sep, ...)           \
    5058             :         DT_FOREACH_PROP_ELEM_SEP_VARGS(DT_DRV_INST(inst), prop, fn, sep,        \
    5059             :                                        __VA_ARGS__)
    5060             : 
    5061             : /**
    5062             :  * @brief Does a DT_DRV_COMPAT instance have a property?
    5063             :  * @param inst instance number
    5064             :  * @param prop lowercase-and-underscores property name
    5065             :  * @return 1 if the instance has the property, 0 otherwise.
    5066             :  */
    5067           1 : #define DT_INST_NODE_HAS_PROP(inst, prop) \
    5068             :         DT_NODE_HAS_PROP(DT_DRV_INST(inst), prop)
    5069             : 
    5070             : /**
    5071             :  * @brief Does a DT_DRV_COMPAT instance have the compatible?
    5072             :  * @param inst instance number
    5073             :  * @param compat lowercase-and-underscores compatible, without quotes
    5074             :  * @return 1 if the instance matches the compatible, 0 otherwise.
    5075             :  */
    5076           1 : #define DT_INST_NODE_HAS_COMPAT(inst, compat) \
    5077             :         DT_NODE_HAS_COMPAT(DT_DRV_INST(inst), compat)
    5078             : 
    5079             : /**
    5080             :  * @brief Does a phandle array have a named cell specifier at an index
    5081             :  *        for a `DT_DRV_COMPAT` instance?
    5082             :  * @param inst instance number
    5083             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    5084             :  * @param idx index to check
    5085             :  * @param cell named cell value whose existence to check
    5086             :  * @return 1 if the named @p cell exists in the specifier at index @p idx,
    5087             :  *         0 otherwise.
    5088             :  */
    5089           1 : #define DT_INST_PHA_HAS_CELL_AT_IDX(inst, pha, idx, cell) \
    5090             :         DT_PHA_HAS_CELL_AT_IDX(DT_DRV_INST(inst), pha, idx, cell)
    5091             : 
    5092             : /**
    5093             :  * @brief Does a phandle array have a named cell specifier at index 0
    5094             :  *        for a `DT_DRV_COMPAT` instance?
    5095             :  * @param inst instance number
    5096             :  * @param pha lowercase-and-underscores property with type `phandle-array`
    5097             :  * @param cell named cell value whose existence to check
    5098             :  * @return 1 if the named @p cell exists in the specifier at index 0,
    5099             :  *         0 otherwise.
    5100             :  */
    5101           1 : #define DT_INST_PHA_HAS_CELL(inst, pha, cell) \
    5102             :         DT_INST_PHA_HAS_CELL_AT_IDX(inst, pha, 0, cell)
    5103             : 
    5104             : /**
    5105             :  * @brief is index valid for interrupt property on a `DT_DRV_COMPAT` instance?
    5106             :  * @param inst instance number
    5107             :  * @param idx logical index into the interrupt specifier array
    5108             :  * @return 1 if the @p idx is valid for the interrupt property
    5109             :  *         0 otherwise.
    5110             :  */
    5111           1 : #define DT_INST_IRQ_HAS_IDX(inst, idx) DT_IRQ_HAS_IDX(DT_DRV_INST(inst), idx)
    5112             : 
    5113             : /**
    5114             :  * @brief Does a `DT_DRV_COMPAT` instance have an interrupt named cell specifier?
    5115             :  * @param inst instance number
    5116             :  * @param idx index to check
    5117             :  * @param cell named cell value whose existence to check
    5118             :  * @return 1 if the named @p cell exists in the interrupt specifier at index
    5119             :  *         @p idx 0 otherwise.
    5120             :  */
    5121           1 : #define DT_INST_IRQ_HAS_CELL_AT_IDX(inst, idx, cell) \
    5122             :         DT_IRQ_HAS_CELL_AT_IDX(DT_DRV_INST(inst), idx, cell)
    5123             : 
    5124             : /**
    5125             :  * @brief Does a `DT_DRV_COMPAT` instance have an interrupt value?
    5126             :  * @param inst instance number
    5127             :  * @param cell named cell value whose existence to check
    5128             :  * @return 1 if the named @p cell exists in the interrupt specifier at index 0
    5129             :  *         0 otherwise.
    5130             :  */
    5131           1 : #define DT_INST_IRQ_HAS_CELL(inst, cell) \
    5132             :         DT_INST_IRQ_HAS_CELL_AT_IDX(inst, 0, cell)
    5133             : 
    5134             : /**
    5135             :  * @brief Does a `DT_DRV_COMPAT` instance have an interrupt value?
    5136             :  * @param inst instance number
    5137             :  * @param name lowercase-and-underscores interrupt specifier name
    5138             :  * @return 1 if @p name is a valid named specifier
    5139             :  */
    5140           1 : #define DT_INST_IRQ_HAS_NAME(inst, name) \
    5141             :         DT_IRQ_HAS_NAME(DT_DRV_INST(inst), name)
    5142             : 
    5143             : /**
    5144             :  * @}
    5145             :  */
    5146             : 
    5147             : /** @cond INTERNAL_HIDDEN */
    5148             : 
    5149             : /** @brief Helper for DT_ANY_INST_HAS_PROP_STATUS_OKAY_
    5150             :  *
    5151             :  * This macro generates token "1," for instance of a device,
    5152             :  * identified by index @p idx, if instance has property @p prop.
    5153             :  *
    5154             :  * @param idx instance number
    5155             :  * @param prop property to check for
    5156             :  *
    5157             :  * @return Macro evaluates to `1,` if instance has the property,
    5158             :  * otherwise it evaluates to literal nothing.
    5159             :  */
    5160             : #define DT_ANY_INST_HAS_PROP_STATUS_OKAY__(idx, prop)   \
    5161             :         COND_CODE_1(DT_INST_NODE_HAS_PROP(idx, prop), (1,), ())
    5162             : /** @brief Helper for DT_ANY_INST_HAS_PROP_STATUS_OKAY
    5163             :  *
    5164             :  * This macro uses DT_ANY_INST_HAS_PROP_STATUS_OKAY_ with
    5165             :  * DT_INST_FOREACH_STATUS_OKAY_VARG to generate comma separated list of 1,
    5166             :  * where each 1 on the list represents instance that has a property
    5167             :  * @p prop; the list may be empty, and the upper bound on number of
    5168             :  * list elements is number of device instances.
    5169             :  *
    5170             :  * @param prop property to check
    5171             :  *
    5172             :  * @return Evaluates to list of 1s (e.g: 1,1,1,) or nothing.
    5173             :  */
    5174             : #define DT_ANY_INST_HAS_PROP_STATUS_OKAY_(prop) \
    5175             :         DT_INST_FOREACH_STATUS_OKAY_VARGS(DT_ANY_INST_HAS_PROP_STATUS_OKAY__, prop)
    5176             : 
    5177             : /** @brief Helper for DT_ANY_INST_HAS_BOOL_STATUS_OKAY_
    5178             :  *
    5179             :  * This macro generates token "1," for instance of a device,
    5180             :  * identified by index @p idx, if instance has boolean property
    5181             :  * @p prop with value 1.
    5182             :  *
    5183             :  * @param idx instance number
    5184             :  * @param prop property to check for
    5185             :  *
    5186             :  * @return Macro evaluates to `1,` if instance property value is 1,
    5187             :  * otherwise it evaluates to literal nothing.
    5188             :  */
    5189             : #define DT_ANY_INST_HAS_BOOL_STATUS_OKAY__(idx, prop)   \
    5190             :         COND_CODE_1(DT_INST_PROP(idx, prop), (1,), ())
    5191             : /** @brief Helper for DT_ANY_INST_HAS_BOOL_STATUS_OKAY
    5192             :  *
    5193             :  * This macro uses DT_ANY_INST_HAS_BOOL_STATUS_OKAY_ with
    5194             :  * DT_INST_FOREACH_STATUS_OKAY_VARG to generate comma separated list of 1,
    5195             :  * where each 1 on the list represents instance that has a property
    5196             :  * @p prop of value 1; the list may be empty, and the upper bound on number of
    5197             :  * list elements is number of device instances.
    5198             :  *
    5199             :  * @param prop property to check
    5200             :  *
    5201             :  * @return Evaluates to list of 1s (e.g: 1,1,1,) or nothing.
    5202             :  */
    5203             : #define DT_ANY_INST_HAS_BOOL_STATUS_OKAY_(prop) \
    5204             :         DT_INST_FOREACH_STATUS_OKAY_VARGS(DT_ANY_INST_HAS_BOOL_STATUS_OKAY__, prop)
    5205             : 
    5206             : #define DT_PATH_INTERNAL(...) \
    5207             :         UTIL_CAT(DT_ROOT, MACRO_MAP_CAT(DT_S_PREFIX, __VA_ARGS__))
    5208             : /** @brief DT_PATH_INTERNAL() helper: prepends _S_ to a node name
    5209             :  * We don't want to expand 'name' recursively before expansion
    5210             :  * in this case. The MACRO_MAP_CAT above is giving us the exact
    5211             :  * tokens it wants prefixed with _S_.
    5212             :  */
    5213             : #define DT_S_PREFIX(name) _S_##name
    5214             : 
    5215             : /**
    5216             :  * @brief Concatenation helper, 2 arguments
    5217             :  *
    5218             :  * This and the following macros are used to paste things together
    5219             :  * with "##" *after* forcing expansion on each argument.
    5220             :  *
    5221             :  * We could try to use something like UTIL_CAT(), but the compiler
    5222             :  * error messages from the util macros can be extremely long when they
    5223             :  * are misused. This unfortunately happens often with devicetree.h,
    5224             :  * since its macro-based API is fiddly and can be hard to get right.
    5225             :  *
    5226             :  * Keeping things brutally simple here hopefully makes some errors
    5227             :  * easier to read.
    5228             :  */
    5229             : #define DT_CAT(a1, a2) a1 ## a2
    5230             : /** @brief Concatenation helper, 3 arguments */
    5231             : #define DT_CAT3(a1, a2, a3) a1 ## a2 ## a3
    5232             : /** @brief Concatenation helper, 4 arguments */
    5233             : #define DT_CAT4(a1, a2, a3, a4) a1 ## a2 ## a3 ## a4
    5234             : /** @brief Internal concatenation helper, 5 arguments */
    5235             : #define DT_CAT5(a1, a2, a3, a4, a5) a1 ## a2 ## a3 ## a4 ## a5
    5236             : /** @brief Concatenation helper, 6 arguments */
    5237             : #define DT_CAT6(a1, a2, a3, a4, a5, a6) a1 ## a2 ## a3 ## a4 ## a5 ## a6
    5238             : /** @brief concatenation helper, 7 arguments */
    5239             : #define DT_CAT7(a1, a2, a3, a4, a5, a6, a7) \
    5240             :         a1 ## a2 ## a3 ## a4 ## a5 ## a6 ## a7
    5241             : /** @brief concatenation helper, 8 arguments */
    5242             : #define DT_CAT8(a1, a2, a3, a4, a5, a6, a7, a8) \
    5243             :         a1 ## a2 ## a3 ## a4 ## a5 ## a6 ## a7 ## a8
    5244             : /*
    5245             :  * If you need to define a bigger DT_CATN(), do so here. Don't leave
    5246             :  * any "holes" of undefined macros, please.
    5247             :  */
    5248             : 
    5249             : /** @brief Helper for node identifier macros to expand args */
    5250             : #define DT_DASH(...) MACRO_MAP_CAT(DT_DASH_PREFIX, __VA_ARGS__)
    5251             : /** @brief Helper for DT_DASH(): prepends _ to a name */
    5252             : #define DT_DASH_PREFIX(name) _##name
    5253             : /** @brief Helper for DT_NODE_HAS_STATUS */
    5254             : #define DT_NODE_HAS_STATUS_INTERNAL(node_id, status) \
    5255             :         IS_ENABLED(DT_CAT3(node_id, _STATUS_, status))
    5256             : 
    5257             : /** @brief Helper macro to OR multiple has property checks in a loop macro
    5258             :  *         (for the specified device)
    5259             :  */
    5260             : #define DT_COMPAT_NODE_HAS_PROP_AND_OR(inst, compat, prop) \
    5261             :         DT_NODE_HAS_PROP(DT_INST(inst, compat), prop) ||
    5262             : 
    5263             : /**
    5264             :  * @def DT_U32_C
    5265             :  * @brief Macro to add 32bit unsigned postfix to the devicetree address constants
    5266             :  */
    5267             : #if defined(_LINKER) || defined(_ASMLANGUAGE)
    5268             : #define DT_U32_C(_v) (_v)
    5269             : #else
    5270             : #define DT_U32_C(_v) UINT32_C(_v)
    5271             : #endif
    5272             : 
    5273             : /**
    5274             :  * @def DT_U64_C
    5275             :  * @brief Macro to add ULL postfix to the devicetree address constants
    5276             :  */
    5277             : #if defined(_LINKER) || defined(_ASMLANGUAGE)
    5278             : #define DT_U64_C(_v) (_v)
    5279             : #else
    5280             : #define DT_U64_C(_v) UINT64_C(_v)
    5281             : #endif
    5282             : 
    5283             : /* Helpers for DT_NODELABEL_STRING_ARRAY. We define our own stringify
    5284             :  * in order to avoid adding a dependency on toolchain.h..
    5285             :  */
    5286             : #define DT_NODELABEL_STRING_ARRAY_ENTRY_INTERNAL(nodelabel) DT_STRINGIFY_INTERNAL(nodelabel),
    5287             : #define DT_STRINGIFY_INTERNAL(arg) DT_STRINGIFY_INTERNAL_HELPER(arg)
    5288             : #define DT_STRINGIFY_INTERNAL_HELPER(arg) #arg
    5289             : 
    5290             : /** @endcond */
    5291             : 
    5292             : /* have these last so they have access to all previously defined macros */
    5293             : #include <zephyr/devicetree/io-channels.h>
    5294             : #include <zephyr/devicetree/clocks.h>
    5295             : #include <zephyr/devicetree/gpio.h>
    5296             : #include <zephyr/devicetree/spi.h>
    5297             : #include <zephyr/devicetree/dma.h>
    5298             : #include <zephyr/devicetree/pwms.h>
    5299             : #include <zephyr/devicetree/fixed-partitions.h>
    5300             : #include <zephyr/devicetree/ordinals.h>
    5301             : #include <zephyr/devicetree/pinctrl.h>
    5302             : #include <zephyr/devicetree/can.h>
    5303             : #include <zephyr/devicetree/reset.h>
    5304             : #include <zephyr/devicetree/mbox.h>
    5305             : #include <zephyr/devicetree/port-endpoint.h>
    5306             : 
    5307             : #endif /* ZEPHYR_INCLUDE_DEVICETREE_H_ */

Generated by: LCOV version 1.14