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