LCOV - code coverage report
Current view: top level - zephyr - devicetree.h Coverage Total Hit
Test: new.info Lines: 100.0 % 246 246
Test Date: 2025-09-05 20:47:19

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

Generated by: LCOV version 2.0-1