1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  * Copyright (c) 2020 Nordic Semiconductor
4  * Copyright (c) 2020, Linaro Ltd.
5  *
6  * Not a generated file. Feel free to modify.
7  */
8 
9 /**
10  * @file
11  * @brief Devicetree main header
12  *
13  * API for accessing the current application's devicetree macros.
14  */
15 
16 #ifndef DEVICETREE_H
17 #define DEVICETREE_H
18 
19 #include <devicetree_generated.h>
20 
21 #if !defined(_LINKER) && !defined(_ASMLANGUAGE)
22 #include <stdint.h>
23 #endif
24 
25 #include <zephyr/sys/util.h>
26 
27 /**
28  * @brief devicetree.h API
29  * @defgroup devicetree Devicetree
30  * @{
31  * @}
32  */
33 
34 /*
35  * Property suffixes
36  * -----------------
37  *
38  * These are the optional parts that come after the _P_<property>
39  * part in DT_N_<path-id>_P_<property-id> macros, or the "prop-suf"
40  * nonterminal in the DT guide's macros.bnf file.
41  *
42  * Before adding new ones, check this list to avoid conflicts. If any
43  * are missing from this list, please add them. It should be complete.
44  *
45  * _ENUM_IDX: property's value as an index into bindings enum
46  * _ENUM_VAL_<val>_EXISTS property's value as a token exists
47  * _ENUM_TOKEN: property's value as a token into bindings enum (string
48  *              enum values are identifiers) [deprecated, use _STRING_TOKEN]
49  * _ENUM_UPPER_TOKEN: like _ENUM_TOKEN, but uppercased [deprecated, use
50  *		      _STRING_UPPER_TOKEN]
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 Get a node identifier for an instance of a compatible
241  *
242  * All nodes with a particular compatible property value are assigned
243  * instance numbers, which are zero-based indexes specific to that
244  * compatible. You can get a node identifier for these nodes by
245  * passing DT_INST() an instance number, @p inst, along with the
246  * lowercase-and-underscores version of the compatible, @p compat.
247  *
248  * Instance numbers have the following properties:
249  *
250  * - for each compatible, instance numbers start at 0 and are contiguous
251  * - exactly one instance number is assigned for each node with a compatible,
252  *   **including disabled nodes**
253  * - enabled nodes (status property is `okay` or missing) are assigned the
254  *   instance numbers starting from 0, and disabled nodes have instance
255  *   numbers which are greater than those of any enabled node
256  *
257  * No other guarantees are made. In particular:
258  *
259  * - instance numbers **in no way reflect** any numbering scheme that
260  *   might exist in SoC documentation, node labels or unit addresses,
261  *   or properties of the /aliases node (use DT_NODELABEL() or DT_ALIAS()
262  *   for those)
263  * - there **is no general guarantee** that the same node will have
264  *   the same instance number between builds, even if you are building
265  *   the same application again in the same build directory
266  *
267  * Example devicetree fragment:
268  *
269  * @code{.dts}
270  *     serial1: serial@40001000 {
271  *             compatible = "vnd,soc-serial";
272  *             status = "disabled";
273  *             current-speed = <9600>;
274  *             ...
275  *     };
276  *
277  *     serial2: serial@40002000 {
278  *             compatible = "vnd,soc-serial";
279  *             status = "okay";
280  *             current-speed = <57600>;
281  *             ...
282  *     };
283  *
284  *     serial3: serial@40003000 {
285  *             compatible = "vnd,soc-serial";
286  *             current-speed = <115200>;
287  *             ...
288  *     };
289  * @endcode
290  *
291  * Assuming no other nodes in the devicetree have compatible
292  * `"vnd,soc-serial"`, that compatible has nodes with instance numbers
293  * 0, 1, and 2.
294  *
295  * The nodes `serial@40002000` and `serial@40003000` are both enabled, so
296  * their instance numbers are 0 and 1, but no guarantees are made
297  * regarding which node has which instance number.
298  *
299  * Since `serial@40001000` is the only disabled node, it has instance
300  * number 2, since disabled nodes are assigned the largest instance
301  * numbers. Therefore:
302  *
303  * @code{.c}
304  *     // Could be 57600 or 115200. There is no way to be sure:
305  *     // either serial@40002000 or serial@40003000 could
306  *     // have instance number 0, so this could be the current-speed
307  *     // property of either of those nodes.
308  *     DT_PROP(DT_INST(0, vnd_soc_serial), current_speed)
309  *
310  *     // Could be 57600 or 115200, for the same reason.
311  *     // If the above expression expands to 57600, then
312  *     // this expands to 115200, and vice-versa.
313  *     DT_PROP(DT_INST(1, vnd_soc_serial), current_speed)
314  *
315  *     // 9600, because there is only one disabled node, and
316  *     // disabled nodes are "at the the end" of the instance
317  *     // number "list".
318  *     DT_PROP(DT_INST(2, vnd_soc_serial), current_speed)
319  * @endcode
320  *
321  * Notice how `"vnd,soc-serial"` in the devicetree becomes `vnd_soc_serial`
322  * (without quotes) in the DT_INST() arguments. (As usual, `current-speed`
323  * in the devicetree becomes `current_speed` as well.)
324  *
325  * Nodes whose `compatible` property has multiple values are assigned
326  * independent instance numbers for each compatible.
327  *
328  * @param inst instance number for compatible @p compat
329  * @param compat lowercase-and-underscores compatible, without quotes
330  * @return node identifier for the node with that instance number and
331  *         compatible
332  */
333 #define DT_INST(inst, compat) UTIL_CAT(DT_N_INST, DT_DASH(inst, compat))
334 
335 /**
336  * @brief Get a node identifier for a parent node
337  *
338  * Example devicetree fragment:
339  *
340  * @code{.dts}
341  *     parent: parent-node {
342  *             child: child-node {
343  *                     ...
344  *             };
345  *     };
346  * @endcode
347  *
348  * The following are equivalent ways to get the same node identifier:
349  *
350  * @code{.c}
351  *     DT_NODELABEL(parent)
352  *     DT_PARENT(DT_NODELABEL(child))
353  * @endcode
354  *
355  * @param node_id node identifier
356  * @return a node identifier for the node's parent
357  */
358 #define DT_PARENT(node_id) UTIL_CAT(node_id, _PARENT)
359 
360 /**
361  * @brief Get a node identifier for a grandparent node
362  *
363  * Example devicetree fragment:
364  *
365  * @code{.dts}
366  *     gparent: grandparent-node {
367  *             parent: parent-node {
368  *                     child: child-node { ... }
369  *             };
370  *     };
371  * @endcode
372  *
373  * The following are equivalent ways to get the same node identifier:
374  *
375  * @code{.c}
376  *     DT_GPARENT(DT_NODELABEL(child))
377  *     DT_PARENT(DT_PARENT(DT_NODELABEL(child))
378  * @endcode
379  *
380  * @param node_id node identifier
381  * @return a node identifier for the node's parent's parent
382  */
383 #define DT_GPARENT(node_id) DT_PARENT(DT_PARENT(node_id))
384 
385 /**
386  * @brief Get a node identifier for a child node
387  *
388  * Example devicetree fragment:
389  *
390  * @code{.dts}
391  *     / {
392  *             soc-label: soc {
393  *                     serial1: serial@40001000 {
394  *                             status = "okay";
395  *                             current-speed = <115200>;
396  *                             ...
397  *                     };
398  *             };
399  *     };
400  * @endcode
401  *
402  * Example usage with DT_PROP() to get the status of the
403  * `serial@40001000` node:
404  *
405  * @code{.c}
406  *     #define SOC_NODE DT_NODELABEL(soc_label)
407  *     DT_PROP(DT_CHILD(SOC_NODE, serial_40001000), status) // "okay"
408  * @endcode
409  *
410  * Node labels like `serial1` cannot be used as the @p child argument
411  * to this macro. Use DT_NODELABEL() for that instead.
412  *
413  * You can also use DT_FOREACH_CHILD() to iterate over node
414  * identifiers for all of a node's children.
415  *
416  * @param node_id node identifier
417  * @param child lowercase-and-underscores child node name
418  * @return node identifier for the node with the name referred to by 'child'
419  */
420 #define DT_CHILD(node_id, child) UTIL_CAT(node_id, DT_S_PREFIX(child))
421 
422 /**
423  * @brief Get a node identifier for a status `okay` node with a compatible
424  *
425  * Use this if you want to get an arbitrary enabled node with a given
426  * compatible, and you do not care which one you get. If any enabled
427  * nodes with the given compatible exist, a node identifier for one
428  * of them is returned. Otherwise, @ref DT_INVALID_NODE is returned.
429  *
430  * Example devicetree fragment:
431  *
432  * @code{.dts}
433  *	node-a {
434  *		compatible = "vnd,device";
435  *		status = "okay";
436  *	};
437  *
438  *	node-b {
439  *		compatible = "vnd,device";
440  *		status = "okay";
441  *	};
442  *
443  *	node-c {
444  *		compatible = "vnd,device";
445  *		status = "disabled";
446  *	};
447  * @endcode
448  *
449  * Example usage:
450  *
451  * @code{.c}
452  *     DT_COMPAT_GET_ANY_STATUS_OKAY(vnd_device)
453  * @endcode
454  *
455  * This expands to a node identifier for either `node-a` or `node-b`.
456  * It will not expand to a node identifier for `node-c`, because that
457  * node does not have status `okay`.
458  *
459  * @param compat lowercase-and-underscores compatible, without quotes
460  * @return node identifier for a node with that compatible, or
461  *         @ref DT_INVALID_NODE
462  */
463 #define DT_COMPAT_GET_ANY_STATUS_OKAY(compat)			\
464 	COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat),	\
465 		    (DT_INST(0, compat)),		\
466 		    (DT_INVALID_NODE))
467 
468 /**
469  * @brief Get a devicetree node's full path as a string literal
470  *
471  * This returns the path to a node from a node identifier. To get a
472  * node identifier from path components instead, use DT_PATH().
473  *
474  * Example devicetree fragment:
475  *
476  * @code{.dts}
477  *     / {
478  *             soc {
479  *                     node: my-node@12345678 { ... };
480  *             };
481  *     };
482  * @endcode
483  *
484  * Example usage:
485  *
486  * @code{.c}
487  *    DT_NODE_PATH(DT_NODELABEL(node)) // "/soc/my-node@12345678"
488  *    DT_NODE_PATH(DT_PATH(soc))       // "/soc"
489  *    DT_NODE_PATH(DT_ROOT)            // "/"
490  * @endcode
491  *
492  * @param node_id node identifier
493  * @return the node's full path in the devicetree
494  */
495 #define DT_NODE_PATH(node_id) DT_CAT(node_id, _PATH)
496 
497 /**
498  * @brief Get a devicetree node's name with unit-address as a string literal
499  *
500  * This returns the node name and unit-address from a node identifier.
501  *
502  * Example devicetree fragment:
503  *
504  * @code{.dts}
505  *     / {
506  *             soc {
507  *                     node: my-node@12345678 { ... };
508  *             };
509  *     };
510  * @endcode
511  *
512  * Example usage:
513  *
514  * @code{.c}
515  *    DT_NODE_FULL_NAME(DT_NODELABEL(node)) // "my-node@12345678"
516  * @endcode
517  *
518  * @param node_id node identifier
519  * @return the node's name with unit-address as a string in the devicetree
520  */
521 #define DT_NODE_FULL_NAME(node_id) DT_CAT(node_id, _FULL_NAME)
522 
523 /**
524  * @brief Get a devicetree node's index into its parent's list of children
525  *
526  * Indexes are zero-based.
527  *
528  * It is an error to use this macro with the root node.
529  *
530  * Example devicetree fragment:
531  *
532  * @code{.dts}
533  *     parent {
534  *             c1: child-1 {};
535  *             c2: child-2 {};
536  *     };
537  * @endcode
538  *
539  * Example usage:
540  *
541  * @code{.c}
542  *     DT_NODE_CHILD_IDX(DT_NODELABEL(c1)) // 0
543  *     DT_NODE_CHILD_IDX(DT_NODELABEL(c2)) // 1
544  * @endcode
545  *
546  * @param node_id node identifier
547  * @return the node's index in its parent node's list of children
548  */
549 #define DT_NODE_CHILD_IDX(node_id) DT_CAT(node_id, _CHILD_IDX)
550 
551 /**
552  * @brief Do @p node_id1 and @p node_id2 refer to the same node?
553  *
554  * Both @p node_id1 and @p node_id2 must be node identifiers for nodes
555  * that exist in the devicetree (if unsure, you can check with
556  * DT_NODE_EXISTS()).
557  *
558  * The expansion evaluates to 0 or 1, but may not be a literal integer
559  * 0 or 1.
560  *
561  * @internal
562  * Implementation note: distinct nodes have distinct node identifiers.
563  * See include/zephyr/devicetree/ordinals.h.
564  * @endinternal
565  *
566  * @param node_id1 first node identifier
567  * @param node_id2 second node identifier
568  * @return an expression that evaluates to 1 if the node identifiers
569  *         refer to the same node, and evaluates to 0 otherwise
570  */
571 #define DT_SAME_NODE(node_id1, node_id2) \
572 	(DT_DEP_ORD(node_id1) == (DT_DEP_ORD(node_id2)))
573 
574 /**
575  * @}
576  */
577 
578 /**
579  * @defgroup devicetree-generic-prop Property accessors
580  * @ingroup devicetree
581  * @{
582  */
583 
584 /**
585  * @brief Get a devicetree property value
586  *
587  * For properties whose bindings have the following types, this macro
588  * expands to:
589  *
590  * - string: a string literal
591  * - boolean: `0` if the property is false, or `1` if it is true
592  * - int: the property's value as an integer literal
593  * - array, uint8-array, string-array: an initializer expression in braces,
594  *   whose elements are integer or string literals (like `{0, 1, 2}`,
595  *   `{"hello", "world"}`, etc.)
596  * - phandle: a node identifier for the node with that phandle
597  *
598  * A property's type is usually defined by its binding. In some
599  * special cases, it has an assumed type defined by the devicetree
600  * specification even when no binding is available: `compatible` has
601  * type string-array, `status` has type string, and
602  * `interrupt-controller` has type boolean.
603  *
604  * For other properties or properties with unknown type due to a
605  * missing binding, behavior is undefined.
606  *
607  * For usage examples, see DT_PATH(), DT_ALIAS(), DT_NODELABEL(),
608  * and DT_INST() above.
609  *
610  * @param node_id node identifier
611  * @param prop lowercase-and-underscores property name
612  * @return a representation of the property's value
613  */
614 #define DT_PROP(node_id, prop) DT_CAT3(node_id, _P_, prop)
615 
616 /**
617  * @brief Get a property's logical length
618  *
619  * Here, "length" is a number of elements, which may differ from the
620  * property's size in bytes.
621  *
622  * The return value depends on the property's type:
623  *
624  * - for types array, string-array, and uint8-array, this expands
625  *   to the number of elements in the array
626  * - for type phandles, this expands to the number of phandles
627  * - for type phandle-array, this expands to the number of
628  *   phandle and specifier blocks in the property
629  * - for type phandle, this expands to 1 (so that a phandle
630  *   can be treated as a degenerate case of phandles with length 1)
631  * - for type string, this expands to 1 (so that a string can be
632  *   treated as a degenerate case of string-array with length 1)
633  *
634  * These properties are handled as special cases:
635  *
636  * - reg property: use `DT_NUM_REGS(node_id)` instead
637  * - interrupts property: use `DT_NUM_IRQS(node_id)` instead
638  *
639  * It is an error to use this macro with the `ranges`, `dma-ranges`, `reg`
640  * or `interrupts` properties.
641  *
642  * For other properties, behavior is undefined.
643  *
644  * @param node_id node identifier
645  * @param prop a lowercase-and-underscores property with a logical length
646  * @return the property's length
647  */
648 #define DT_PROP_LEN(node_id, prop) DT_CAT4(node_id, _P_, prop, _LEN)
649 
650 /**
651  * @brief Like DT_PROP_LEN(), but with a fallback to @p default_value
652  *
653  * If the property is defined (as determined by DT_NODE_HAS_PROP()),
654  * this expands to DT_PROP_LEN(node_id, prop). The @p default_value
655  * parameter is not expanded in this case.
656  *
657  * Otherwise, this expands to @p default_value.
658  *
659  * @param node_id node identifier
660  * @param prop a lowercase-and-underscores property with a logical length
661  * @param default_value a fallback value to expand to
662  * @return the property's length or the given default value
663  */
664 #define DT_PROP_LEN_OR(node_id, prop, default_value) \
665 	COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
666 		    (DT_PROP_LEN(node_id, prop)), (default_value))
667 
668 /**
669  * @brief Is index @p idx valid for an array type property?
670  *
671  * If this returns 1, then DT_PROP_BY_IDX(node_id, prop, idx) or
672  * DT_PHA_BY_IDX(node_id, prop, idx, ...) are valid at index @p idx.
673  * If it returns 0, it is an error to use those macros with that index.
674  *
675  * These properties are handled as special cases:
676  *
677  * - `reg` property: use DT_REG_HAS_IDX(node_id, idx) instead
678  * - `interrupts` property: use DT_IRQ_HAS_IDX(node_id, idx) instead
679  *
680  * It is an error to use this macro with the `reg` or `interrupts` properties.
681  *
682  * @param node_id node identifier
683  * @param prop a lowercase-and-underscores property with a logical length
684  * @param idx index to check
685  * @return An expression which evaluates to 1 if @p idx is a valid index
686  *         into the given property, and 0 otherwise.
687  */
688 #define DT_PROP_HAS_IDX(node_id, prop, idx) \
689 	IS_ENABLED(DT_CAT6(node_id, _P_, prop, _IDX_, idx, _EXISTS))
690 
691 /**
692  * @brief Is name @p name available in a `foo-names` property?
693  *
694  * This property is handled as special case:
695  *
696  * - `interrupts` property: use DT_IRQ_HAS_NAME(node_id, idx) instead
697  *
698  * It is an error to use this macro with the `interrupts` property.
699  *
700  * Example devicetree fragment:
701  *
702  * @code{.dts}
703  *	nx: node-x {
704  *		foos = <&bar xx yy>, <&baz xx zz>;
705  *		foo-names = "event", "error";
706  *		status = "okay";
707  *	};
708  * @endcode
709  *
710  * Example usage:
711  *
712  * @code{.c}
713  *     DT_PROP_HAS_NAME(DT_NODELABEL(nx), foos, event)    // 1
714  *     DT_PROP_HAS_NAME(DT_NODELABEL(nx), foos, failure)  // 0
715  * @endcode
716  *
717  * @param node_id node identifier
718  * @param prop a lowercase-and-underscores `prop-names` type property
719  * @param name a lowercase-and-underscores name to check
720  * @return An expression which evaluates to 1 if "name" is an available
721  *         name into the given property, and 0 otherwise.
722  */
723 #define DT_PROP_HAS_NAME(node_id, prop, name) \
724 	IS_ENABLED(DT_CAT6(node_id, _P_, prop, _NAME_, name, _EXISTS))
725 
726 /**
727  * @brief Get the value at index @p idx in an array type property
728  *
729  * It might help to read the argument order as being similar to
730  * `node->property[index]`.
731  *
732  * The return value depends on the property's type:
733  *
734  * - for types array, string-array, uint8-array, and phandles,
735  *   this expands to the idx-th array element as an
736  *   integer, string literal, integer, and node identifier
737  *   respectively
738  *
739  * - for type phandle, idx must be 0 and the expansion is a node
740  *   identifier (this treats phandle like a phandles of length 1)
741  *
742  * - for type string, idx must be 0 and the expansion is the the
743  *   entire string (this treats string like string-array of length 1)
744  *
745  * These properties are handled as special cases:
746  *
747  * - `reg`: use DT_REG_ADDR_BY_IDX() or DT_REG_SIZE_BY_IDX() instead
748  * - `interrupts`: use DT_IRQ_BY_IDX()
749  * - `ranges`: use DT_NUM_RANGES()
750  * - `dma-ranges`: it is an error to use this property with
751  *   DT_PROP_BY_IDX()
752  *
753  * For properties of other types, behavior is undefined.
754  *
755  * @param node_id node identifier
756  * @param prop lowercase-and-underscores property name
757  * @param idx the index to get
758  * @return a representation of the idx-th element of the property
759  */
760 #define DT_PROP_BY_IDX(node_id, prop, idx) \
761 	DT_CAT5(node_id, _P_, prop, _IDX_, idx)
762 
763 /**
764  * @brief Like DT_PROP(), but with a fallback to @p default_value
765  *
766  * If the value exists, this expands to DT_PROP(node_id, prop).
767  * The @p default_value parameter is not expanded in this case.
768  *
769  * Otherwise, this expands to @p default_value.
770  *
771  * @param node_id node identifier
772  * @param prop lowercase-and-underscores property name
773  * @param default_value a fallback value to expand to
774  * @return the property's value or @p default_value
775  */
776 #define DT_PROP_OR(node_id, prop, default_value) \
777 	COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
778 		    (DT_PROP(node_id, prop)), (default_value))
779 
780 /**
781  * @deprecated Use DT_PROP(node_id, label)
782  * @brief Equivalent to DT_PROP(node_id, label)
783  *
784  * This is a convenience for the Zephyr device API, which uses label
785  * properties as device_get_binding() arguments.
786  * @param node_id node identifier
787  * @return node's label property value
788  */
789 #define DT_LABEL(node_id) DT_PROP(node_id, label) __DEPRECATED_MACRO
790 
791 /**
792  * @brief Get a property value's index into its enumeration values
793  *
794  * The return values start at zero.
795  *
796  * Example devicetree fragment:
797  *
798  * @code{.dts}
799  *     usb1: usb@12340000 {
800  *             maximum-speed = "full-speed";
801  *     };
802  *     usb2: usb@12341000 {
803  *             maximum-speed = "super-speed";
804  *     };
805  * @endcode
806  *
807  * Example bindings fragment:
808  *
809  * @code{.yaml}
810  *     properties:
811  *       maximum-speed:
812  *         type: string
813  *         enum:
814  *            - "low-speed"
815  *            - "full-speed"
816  *            - "high-speed"
817  *            - "super-speed"
818  * @endcode
819  *
820  * Example usage:
821  *
822  * @code{.c}
823  *     DT_ENUM_IDX(DT_NODELABEL(usb1), maximum_speed) // 1
824  *     DT_ENUM_IDX(DT_NODELABEL(usb2), maximum_speed) // 3
825  * @endcode
826  *
827  * @param node_id node identifier
828  * @param prop lowercase-and-underscores property name
829  * @return zero-based index of the property's value in its enum: list
830  */
831 #define DT_ENUM_IDX(node_id, prop) DT_CAT4(node_id, _P_, prop, _ENUM_IDX)
832 
833 /**
834  * @brief Like DT_ENUM_IDX(), but with a fallback to a default enum index
835  *
836  * If the value exists, this expands to its zero based index value thanks to
837  * DT_ENUM_IDX(node_id, prop).
838  *
839  * Otherwise, this expands to provided default index enum value.
840  *
841  * @param node_id node identifier
842  * @param prop lowercase-and-underscores property name
843  * @param default_idx_value a fallback index value to expand to
844  * @return zero-based index of the property's value in its enum if present,
845  *         default_idx_value otherwise
846  */
847 #define DT_ENUM_IDX_OR(node_id, prop, default_idx_value) \
848 	COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
849 		    (DT_ENUM_IDX(node_id, prop)), (default_idx_value))
850 
851 /**
852  * @brief Does a node enumeration property have a given value?
853  *
854  * @param node_id node identifier
855  * @param prop lowercase-and-underscores property name
856  * @param value lowercase-and-underscores enumeration value
857  * @return 1 if the node property has the value @a value, 0 otherwise.
858  */
859 #define DT_ENUM_HAS_VALUE(node_id, prop, value) \
860 	IS_ENABLED(DT_CAT6(node_id, _P_, prop, _ENUM_VAL_, value, _EXISTS))
861 
862 /**
863  * @brief Get a string property's value as a token.
864  *
865  * This removes "the quotes" from a string property's value,
866  * converting any non-alphanumeric characters to underscores. This can
867  * be useful, for example, when programmatically using the value to
868  * form a C variable or code.
869  *
870  * DT_STRING_TOKEN() can only be used for properties with string type.
871  *
872  * It is an error to use DT_STRING_TOKEN() in other circumstances.
873  *
874  * Example devicetree fragment:
875  *
876  * @code{.dts}
877  *     n1: node-1 {
878  *             prop = "foo";
879  *     };
880  *     n2: node-2 {
881  *             prop = "FOO";
882  *     }
883  *     n3: node-3 {
884  *             prop = "123 foo";
885  *     };
886  * @endcode
887  *
888  * Example bindings fragment:
889  *
890  * @code{.yaml}
891  *     properties:
892  *       prop:
893  *         type: string
894  * @endcode
895  *
896  * Example usage:
897  *
898  * @code{.c}
899  *     DT_STRING_TOKEN(DT_NODELABEL(n1), prop) // foo
900  *     DT_STRING_TOKEN(DT_NODELABEL(n2), prop) // FOO
901  *     DT_STRING_TOKEN(DT_NODELABEL(n3), prop) // 123_foo
902  * @endcode
903  *
904  * Notice how:
905  *
906  * - Unlike C identifiers, the property values may begin with a
907  *   number. It's the user's responsibility not to use such values as
908  *   the name of a C identifier.
909  *
910  * - The uppercased `"FOO"` in the DTS remains `FOO` as a token. It is
911  *   *not* converted to `foo`.
912  *
913  * - The whitespace in the DTS `"123 foo"` string is converted to
914  *   `123_foo` as a token.
915  *
916  * @param node_id node identifier
917  * @param prop lowercase-and-underscores property name
918  * @return the value of @p prop as a token, i.e. without any quotes
919  *         and with special characters converted to underscores
920  */
921 #define DT_STRING_TOKEN(node_id, prop) \
922 	DT_CAT4(node_id, _P_, prop, _STRING_TOKEN)
923 
924 /**
925  * @brief Like DT_STRING_TOKEN(), but with a fallback to @p default_value
926  *
927  * If the value exists, this expands to DT_STRING_TOKEN(node_id, prop).
928  * The @p default_value parameter is not expanded in this case.
929  *
930  * Otherwise, this expands to @p default_value.
931  *
932  * @param node_id node identifier
933  * @param prop lowercase-and-underscores property name
934  * @param default_value a fallback value to expand to
935  * @return the property's value as a token, or @p default_value
936  */
937 #define DT_STRING_TOKEN_OR(node_id, prop, default_value) \
938 	COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
939 		(DT_STRING_TOKEN(node_id, prop)), (default_value))
940 
941 /**
942  * @brief Like DT_STRING_TOKEN(), but uppercased.
943  *
944  * This removes "the quotes" from a string property's value,
945  * converting any non-alphanumeric characters to underscores, and
946  * capitalizing the result. This can be useful, for example, when
947  * programmatically using the value to form a C variable or code.
948  *
949  * DT_STRING_UPPER_TOKEN() can only be used for properties with string type.
950  *
951  * It is an error to use DT_STRING_UPPER_TOKEN() in other circumstances.
952  *
953  * Example devicetree fragment:
954  *
955  * @code{.dts}
956  *     n1: node-1 {
957  *             prop = "foo";
958  *     };
959  *     n2: node-2 {
960  *             prop = "123 foo";
961  *     };
962  * @endcode
963  *
964  * Example bindings fragment:
965  *
966  * @code{.yaml}
967  *     properties:
968  *       prop:
969  *         type: string
970  *
971  * @endcode
972  *
973  * Example usage:
974  *
975  * @code{.c}
976  *     DT_STRING_UPPER_TOKEN(DT_NODELABEL(n1), prop) // FOO
977  *     DT_STRING_UPPER_TOKEN(DT_NODELABEL(n2), prop) // 123_FOO
978  * @endcode
979  *
980  * Notice how:
981  *
982  * - Unlike C identifiers, the property values may begin with a
983  *   number. It's the user's responsibility not to use such values as
984  *   the name of a C identifier.
985  *
986  * - The lowercased `"foo"` in the DTS becomes `FOO` as a token, i.e.
987  *   it is uppercased.
988  *
989  * - The whitespace in the DTS `"123 foo"` string is converted to
990  *   `123_FOO` as a token, i.e. it is uppercased and whitespace becomes
991  *   an underscore.
992  *
993  * @param node_id node identifier
994  * @param prop lowercase-and-underscores property name
995  * @return the value of @p prop as an uppercased token, i.e. without
996  *         any quotes and with special characters converted to underscores
997  */
998 #define DT_STRING_UPPER_TOKEN(node_id, prop) \
999 	DT_CAT4(node_id, _P_, prop, _STRING_UPPER_TOKEN)
1000 
1001 /**
1002  * @brief Like DT_STRING_UPPER_TOKEN(), but with a fallback to @p default_value
1003  *
1004  * If the value exists, this expands to DT_STRING_UPPER_TOKEN(node_id, prop).
1005  * The @p default_value parameter is not expanded in this case.
1006  *
1007  * Otherwise, this expands to @p default_value.
1008  *
1009  * @param node_id node identifier
1010  * @param prop lowercase-and-underscores property name
1011  * @param default_value a fallback value to expand to
1012  * @return the property's value as an uppercased token,
1013  *         or @p default_value
1014  */
1015 #define DT_STRING_UPPER_TOKEN_OR(node_id, prop, default_value) \
1016 	COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
1017 		(DT_STRING_UPPER_TOKEN(node_id, prop)), (default_value))
1018 
1019 /**
1020  * @brief Get a string property's value as an unquoted sequence of tokens
1021  *
1022  * This removes "the quotes" from string-valued properties.
1023  * That can be useful, for example,
1024  * when defining floating point values as a string in devicetree
1025  * that you would like to use to initialize a float or double variable in C.
1026  *
1027  * DT_STRING_UNQUOTED() can only be used for properties with string type.
1028  *
1029  * It is an error to use DT_STRING_UNQUOTED() in other circumstances.
1030  *
1031  * Example devicetree fragment:
1032  *
1033  *     n1: node-1 {
1034  *             prop = "12.7";
1035  *     };
1036  *     n2: node-2 {
1037  *             prop = "0.5";
1038  *     }
1039  *     n3: node-3 {
1040  *             prop = "A B C";
1041  *     };
1042  *
1043  * Example bindings fragment:
1044  *
1045  *     properties:
1046  *       prop:
1047  *         type: string
1048  *
1049  * Example usage:
1050  *
1051  *     DT_STRING_UNQUOTED(DT_NODELABEL(n1), prop) // 12.7
1052  *     DT_STRING_UNQUOTED(DT_NODELABEL(n2), prop) // 0.5
1053  *     DT_STRING_UNQUOTED(DT_NODELABEL(n3), prop) // A B C
1054  *
1055  * @param node_id node identifier
1056  * @param prop lowercase-and-underscores property name
1057  * @return the property's value as a sequence of tokens, with no quotes
1058  */
1059 #define DT_STRING_UNQUOTED(node_id, prop) \
1060 	DT_CAT4(node_id, _P_, prop, _STRING_UNQUOTED)
1061 
1062 /**
1063  * @brief Like DT_STRING_UNQUOTED(), but with a fallback to @p default_value
1064  *
1065  * If the value exists, this expands to DT_STRING_UNQUOTED(node_id, prop).
1066  * The @p default_value parameter is not expanded in this case.
1067  *
1068  * Otherwise, this expands to @p default_value.
1069  *
1070  * @param node_id node identifier
1071  * @param prop lowercase-and-underscores property name
1072  * @param default_value a fallback value to expand to
1073  * @return the property's value as a sequence of tokens, with no quotes,
1074  *         or @p default_value
1075  */
1076 #define DT_STRING_UNQUOTED_OR(node_id, prop, default_value) \
1077 	COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \
1078 		(DT_STRING_UNQUOTED(node_id, prop)), (default_value))
1079 
1080 /**
1081  * @brief Get an element out of a string-array property as a token.
1082  *
1083  * This removes "the quotes" from an element in the array, and converts
1084  * non-alphanumeric characters to underscores. That can be useful, for example,
1085  * when programmatically using the value to form a C variable or code.
1086  *
1087  * DT_STRING_TOKEN_BY_IDX() can only be used for properties with
1088  * string-array type.
1089  *
1090  * It is an error to use DT_STRING_TOKEN_BY_IDX() in other circumstances.
1091  *
1092  * Example devicetree fragment:
1093  *
1094  * @code{.dts}
1095  *     n1: node-1 {
1096  *             prop = "f1", "F2";
1097  *     };
1098  *     n2: node-2 {
1099  *             prop = "123 foo", "456 FOO";
1100  *     };
1101  * @endcode
1102  *
1103  * Example bindings fragment:
1104  *
1105  * @code{.yaml}
1106  *     properties:
1107  *       prop:
1108  *         type: string-array
1109  * @endcode
1110  *
1111  * Example usage:
1112  *
1113  * @code{.c}
1114  *     DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 0) // f1
1115  *     DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 1) // F2
1116  *     DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 0) // 123_foo
1117  *     DT_STRING_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 1) // 456_FOO
1118  * @endcode
1119  *
1120  * For more information, see @ref DT_STRING_TOKEN.
1121  *
1122  * @param node_id node identifier
1123  * @param prop lowercase-and-underscores property name
1124  * @param idx the index to get
1125  * @return the element in @p prop at index @p idx as a token
1126  */
1127 #define DT_STRING_TOKEN_BY_IDX(node_id, prop, idx) \
1128 	DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_TOKEN)
1129 
1130 /**
1131  * @brief Like DT_STRING_TOKEN_BY_IDX(), but uppercased.
1132  *
1133  * This removes "the quotes" and capitalizes an element in the array, and
1134  * converts non-alphanumeric characters to underscores. That can be useful, for
1135  * example, when programmatically using the value to form a C variable or code.
1136  *
1137  * DT_STRING_UPPER_TOKEN_BY_IDX() can only be used for properties with
1138  * string-array type.
1139  *
1140  * It is an error to use DT_STRING_UPPER_TOKEN_BY_IDX() in other circumstances.
1141  *
1142  * Example devicetree fragment:
1143  *
1144  * @code{.dts}
1145  *     n1: node-1 {
1146  *             prop = "f1", "F2";
1147  *     };
1148  *     n2: node-2 {
1149  *             prop = "123 foo", "456 FOO";
1150  *     };
1151  * @endcode
1152  *
1153  * Example bindings fragment:
1154  *
1155  * @code{.yaml}
1156  *     properties:
1157  *       prop:
1158  *         type: string-array
1159  * @endcode
1160  *
1161  * Example usage:
1162  *
1163  * @code{.c}
1164  *     DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 0) // F1
1165  *     DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n1), prop, 1) // F2
1166  *     DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 0) // 123_FOO
1167  *     DT_STRING_UPPER_TOKEN_BY_IDX(DT_NODELABEL(n2), prop, 1) // 456_FOO
1168  * @endcode
1169  *
1170  * For more information, see @ref DT_STRING_UPPER_TOKEN.
1171  *
1172  * @param node_id node identifier
1173  * @param prop lowercase-and-underscores property name
1174  * @param idx the index to get
1175  * @return the element in @p prop at index @p idx as an uppercased token
1176  */
1177 #define DT_STRING_UPPER_TOKEN_BY_IDX(node_id, prop, idx) \
1178 	DT_CAT6(node_id, _P_, prop, _IDX_, idx, _STRING_UPPER_TOKEN)
1179 
1180 /**
1181  * @brief Get a string array item value as an unquoted sequence of tokens.
1182  *
1183  * This removes "the quotes" from string-valued item.
1184  * That can be useful, for example,
1185  * when defining floating point values as a string in devicetree
1186  * that you would like to use to initialize a float or double variable in C.
1187  *
1188  * DT_STRING_UNQUOTED_BY_IDX() can only be used for properties with
1189  * string-array type.
1190  *
1191  * It is an error to use DT_STRING_UNQUOTED_BY_IDX() in other circumstances.
1192  *
1193  * Example devicetree fragment:
1194  *
1195  *     n1: node-1 {
1196  *             prop = "12.7", "34.1";
1197  *     };
1198  *     n2: node-2 {
1199  *             prop = "A B", "C D";
1200  *     }
1201  *
1202  * Example bindings fragment:
1203  *
1204  *     properties:
1205  *       prop:
1206  *         type: string-array
1207  *
1208  * Example usage:
1209  *
1210  *     DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n1), prop, 0) // 12.7
1211  *     DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n1), prop, 1) // 34.1
1212  *     DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n2), prop, 0) // A B
1213  *     DT_STRING_UNQUOTED_BY_IDX(DT_NODELABEL(n2), prop, 1) // C D
1214  *
1215  * @param node_id node identifier
1216  * @param prop lowercase-and-underscores property name
1217  * @param idx the index to get
1218  * @return the property's value as a sequence of tokens, with no quotes
1219  */
1220 #define DT_STRING_UNQUOTED_BY_IDX(node_id, prop, idx) \
1221 	DT_CAT4(node_id, _P_, prop##_IDX_##idx, _STRING_UNQUOTED)
1222 
1223 /*
1224  * phandle properties
1225  *
1226  * These are special-cased to manage the impedance mismatch between
1227  * phandles, which are just uint32_t node properties that only make sense
1228  * within the tree itself, and C values.
1229  */
1230 
1231 /**
1232  * @brief Get a property value from a phandle in a property.
1233  *
1234  * This is a shorthand for:
1235  *
1236  * @code{.c}
1237  *     DT_PROP(DT_PHANDLE_BY_IDX(node_id, phs, idx), prop)
1238  * @endcode
1239  *
1240  * That is, @p prop is a property of the phandle's node, not a
1241  * property of @p node_id.
1242  *
1243  * Example devicetree fragment:
1244  *
1245  * @code{.dts}
1246  *     n1: node-1 {
1247  *             foo = <&n2 &n3>;
1248  *     };
1249  *
1250  *     n2: node-2 {
1251  *             bar = <42>;
1252  *     };
1253  *
1254  *     n3: node-3 {
1255  *             baz = <43>;
1256  *     };
1257  * @endcode
1258  *
1259  * Example usage:
1260  *
1261  * @code{.c}
1262  *     #define N1 DT_NODELABEL(n1)
1263  *
1264  *     DT_PROP_BY_PHANDLE_IDX(N1, foo, 0, bar) // 42
1265  *     DT_PROP_BY_PHANDLE_IDX(N1, foo, 1, baz) // 43
1266  * @endcode
1267  *
1268  * @param node_id node identifier
1269  * @param phs lowercase-and-underscores property with type `phandle`,
1270  *            `phandles`, or `phandle-array`
1271  * @param idx logical index into @p phs, which must be zero if @p phs
1272  *            has type `phandle`
1273  * @param prop lowercase-and-underscores property of the phandle's node
1274  * @return the property's value
1275  */
1276 #define DT_PROP_BY_PHANDLE_IDX(node_id, phs, idx, prop) \
1277 	DT_PROP(DT_PHANDLE_BY_IDX(node_id, phs, idx), prop)
1278 
1279 /**
1280  * @brief Like DT_PROP_BY_PHANDLE_IDX(), but with a fallback to
1281  * @p default_value.
1282  *
1283  * If the value exists, this expands to DT_PROP_BY_PHANDLE_IDX(node_id, phs,
1284  * idx, prop). The @p default_value parameter is not expanded in this
1285  * case.
1286  *
1287  * Otherwise, this expands to @p default_value.
1288  *
1289  * @param node_id node identifier
1290  * @param phs lowercase-and-underscores property with type `phandle`,
1291  *            `phandles`, or `phandle-array`
1292  * @param idx logical index into @p phs, which must be zero if @p phs
1293  *            has type `phandle`
1294  * @param prop lowercase-and-underscores property of the phandle's node
1295  * @param default_value a fallback value to expand to
1296  * @return the property's value
1297  */
1298 #define DT_PROP_BY_PHANDLE_IDX_OR(node_id, phs, idx, prop, default_value) \
1299 	DT_PROP_OR(DT_PHANDLE_BY_IDX(node_id, phs, idx), prop, default_value)
1300 
1301 /**
1302  * @brief Get a property value from a phandle's node
1303  *
1304  * This is equivalent to DT_PROP_BY_PHANDLE_IDX(node_id, ph, 0, prop).
1305  *
1306  * @param node_id node identifier
1307  * @param ph lowercase-and-underscores property of @p node_id
1308  *           with type `phandle`
1309  * @param prop lowercase-and-underscores property of the phandle's node
1310  * @return the property's value
1311  */
1312 #define DT_PROP_BY_PHANDLE(node_id, ph, prop) \
1313 	DT_PROP_BY_PHANDLE_IDX(node_id, ph, 0, prop)
1314 
1315 /**
1316  * @brief Get a phandle-array specifier cell value at an index
1317  *
1318  * It might help to read the argument order as being similar to
1319  * `node->phandle_array[index].cell`. That is, the cell value is in
1320  * the @p pha property of @p node_id, inside the specifier at index
1321  * @p idx.
1322  *
1323  * Example devicetree fragment:
1324  *
1325  * @code{.dts}
1326  *     gpio0: gpio@abcd1234 {
1327  *             #gpio-cells = <2>;
1328  *     };
1329  *
1330  *     gpio1: gpio@1234abcd {
1331  *             #gpio-cells = <2>;
1332  *     };
1333  *
1334  *     led: led_0 {
1335  *             gpios = <&gpio0 17 0x1>, <&gpio1 5 0x3>;
1336  *     };
1337  * @endcode
1338  *
1339  * Bindings fragment for the `gpio0` and `gpio1` nodes:
1340  *
1341  * @code{.yaml}
1342  *     gpio-cells:
1343  *       - pin
1344  *       - flags
1345  * @endcode
1346  *
1347  * Above, `gpios` has two elements:
1348  *
1349  * - index 0 has specifier <17 0x1>, so its `pin` cell is 17, and its
1350  *   `flags` cell is 0x1
1351  * - index 1 has specifier <5 0x3>, so `pin` is 5 and `flags` is 0x3
1352  *
1353  * Example usage:
1354  *
1355  * @code{.c}
1356  *     #define LED DT_NODELABEL(led)
1357  *
1358  *     DT_PHA_BY_IDX(LED, gpios, 0, pin)   // 17
1359  *     DT_PHA_BY_IDX(LED, gpios, 1, flags) // 0x3
1360  * @endcode
1361  *
1362  * @param node_id node identifier
1363  * @param pha lowercase-and-underscores property with type `phandle-array`
1364  * @param idx logical index into @p pha
1365  * @param cell lowercase-and-underscores cell name within the specifier
1366  *             at @p pha index @p idx
1367  * @return the cell's value
1368  */
1369 #define DT_PHA_BY_IDX(node_id, pha, idx, cell) \
1370 	DT_CAT7(node_id, _P_, pha, _IDX_, idx, _VAL_, cell)
1371 
1372 /**
1373  * @brief Like DT_PHA_BY_IDX(), but with a fallback to @p default_value.
1374  *
1375  * If the value exists, this expands to DT_PHA_BY_IDX(node_id, pha,
1376  * idx, cell). The @p default_value parameter is not expanded in this
1377  * case.
1378  *
1379  * Otherwise, this expands to @p default_value.
1380  *
1381  * @internal
1382  * Implementation note: the _IDX_##idx##_VAL_##cell##_EXISTS macros are
1383  * defined, so it's safe to use DT_PROP_OR() here, because that uses an
1384  * IS_ENABLED() on the _EXISTS macro.
1385  * @endinternal
1386  *
1387  * @param node_id node identifier
1388  * @param pha lowercase-and-underscores property with type `phandle-array`
1389  * @param idx logical index into @p pha
1390  * @param cell lowercase-and-underscores cell name within the specifier
1391  *             at @p pha index @p idx
1392  * @param default_value a fallback value to expand to
1393  * @return the cell's value or @p default_value
1394  */
1395 #define DT_PHA_BY_IDX_OR(node_id, pha, idx, cell, default_value) \
1396 	DT_PROP_OR(node_id, pha##_IDX_##idx##_VAL_##cell, default_value)
1397 
1398 /**
1399  * @brief Equivalent to DT_PHA_BY_IDX(node_id, pha, 0, cell)
1400  * @param node_id node identifier
1401  * @param pha lowercase-and-underscores property with type `phandle-array`
1402  * @param cell lowercase-and-underscores cell name
1403  * @return the cell's value
1404  */
1405 #define DT_PHA(node_id, pha, cell) DT_PHA_BY_IDX(node_id, pha, 0, cell)
1406 
1407 /**
1408  * @brief Like DT_PHA(), but with a fallback to @p default_value
1409  *
1410  * If the value exists, this expands to DT_PHA(node_id, pha, cell).
1411  * The @p default_value parameter is not expanded in this case.
1412  *
1413  * Otherwise, this expands to @p default_value.
1414  *
1415  * @param node_id node identifier
1416  * @param pha lowercase-and-underscores property with type `phandle-array`
1417  * @param cell lowercase-and-underscores cell name
1418  * @param default_value a fallback value to expand to
1419  * @return the cell's value or @p default_value
1420  */
1421 #define DT_PHA_OR(node_id, pha, cell, default_value) \
1422 	DT_PHA_BY_IDX_OR(node_id, pha, 0, cell, default_value)
1423 
1424 /**
1425  * @brief Get a value within a phandle-array specifier by name
1426  *
1427  * This is like DT_PHA_BY_IDX(), except it treats @p pha as a structure
1428  * where each array element has a name.
1429  *
1430  * It might help to read the argument order as being similar to
1431  * `node->phandle_struct.name.cell`. That is, the cell value is in the
1432  * @p pha property of @p node_id, treated as a data structure where
1433  * each array element has a name.
1434  *
1435  * Example devicetree fragment:
1436  *
1437  * @code{.dts}
1438  *     n: node {
1439  *             io-channels = <&adc1 10>, <&adc2 20>;
1440  *             io-channel-names = "SENSOR", "BANDGAP";
1441  *     };
1442  * @endcode
1443  *
1444  * Bindings fragment for the "adc1" and "adc2" nodes:
1445  *
1446  * @code{.yaml}
1447  *     io-channel-cells:
1448  *       - input
1449  * @endcode
1450  *
1451  * Example usage:
1452  *
1453  * @code{.c}
1454  *     DT_PHA_BY_NAME(DT_NODELABEL(n), io_channels, sensor, input)  // 10
1455  *     DT_PHA_BY_NAME(DT_NODELABEL(n), io_channels, bandgap, input) // 20
1456  * @endcode
1457  *
1458  * @param node_id node identifier
1459  * @param pha lowercase-and-underscores property with type `phandle-array`
1460  * @param name lowercase-and-underscores name of a specifier in @p pha
1461  * @param cell lowercase-and-underscores cell name in the named specifier
1462  * @return the cell's value
1463  */
1464 #define DT_PHA_BY_NAME(node_id, pha, name, cell) \
1465 	DT_CAT7(node_id, _P_, pha, _NAME_, name, _VAL_, cell)
1466 
1467 /**
1468  * @brief Like DT_PHA_BY_NAME(), but with a fallback to @p default_value
1469  *
1470  * If the value exists, this expands to DT_PHA_BY_NAME(node_id, pha,
1471  * name, cell). The @p default_value parameter is not expanded in this case.
1472  *
1473  * Otherwise, this expands to @p default_value.
1474  *
1475  * @internal
1476  * Implementation note: the `_NAME_##name##_VAL_##cell##_EXISTS` macros are
1477  * defined, so it's safe to use DT_PROP_OR() here, because that uses an
1478  * IS_ENABLED() on the `_EXISTS` macro.
1479  * @endinternal
1480  *
1481  * @param node_id node identifier
1482  * @param pha lowercase-and-underscores property with type `phandle-array`
1483  * @param name lowercase-and-underscores name of a specifier in @p pha
1484  * @param cell lowercase-and-underscores cell name in the named specifier
1485  * @param default_value a fallback value to expand to
1486  * @return the cell's value or @p default_value
1487  */
1488 #define DT_PHA_BY_NAME_OR(node_id, pha, name, cell, default_value) \
1489 	DT_PROP_OR(node_id, pha##_NAME_##name##_VAL_##cell, default_value)
1490 
1491 /**
1492  * @brief Get a phandle's node identifier from a phandle array by @p name
1493  *
1494  * It might help to read the argument order as being similar to
1495  * `node->phandle_struct.name.phandle`. That is, the phandle array is
1496  * treated as a structure with named elements. The return value is
1497  * the node identifier for a phandle inside the structure.
1498  *
1499  * Example devicetree fragment:
1500  *
1501  * @code{.dts}
1502  *     adc1: adc@abcd1234 {
1503  *             foobar = "ADC_1";
1504  *     };
1505  *
1506  *     adc2: adc@1234abcd {
1507  *             foobar = "ADC_2";
1508  *     };
1509  *
1510  *     n: node {
1511  *             io-channels = <&adc1 10>, <&adc2 20>;
1512  *             io-channel-names = "SENSOR", "BANDGAP";
1513  *     };
1514  * @endcode
1515  *
1516  * Above, "io-channels" has two elements:
1517  *
1518  * - the element named `"SENSOR"` has phandle `&adc1`
1519  * - the element named `"BANDGAP"` has phandle `&adc2`
1520  *
1521  * Example usage:
1522  *
1523  * @code{.c}
1524  *     #define NODE DT_NODELABEL(n)
1525  *
1526  *     DT_PROP(DT_PHANDLE_BY_NAME(NODE, io_channels, sensor), foobar)  // "ADC_1"
1527  *     DT_PROP(DT_PHANDLE_BY_NAME(NODE, io_channels, bandgap), foobar) // "ADC_2"
1528  * @endcode
1529  *
1530  * Notice how devicetree properties and names are lowercased, and
1531  * non-alphanumeric characters are converted to underscores.
1532  *
1533  * @param node_id node identifier
1534  * @param pha lowercase-and-underscores property with type `phandle-array`
1535  * @param name lowercase-and-underscores name of an element in @p pha
1536  * @return a node identifier for the node with that phandle
1537  */
1538 #define DT_PHANDLE_BY_NAME(node_id, pha, name) \
1539 	DT_CAT6(node_id, _P_, pha, _NAME_, name, _PH)
1540 
1541 /**
1542  * @brief Get a node identifier for a phandle in a property.
1543  *
1544  * When a node's value at a logical index contains a phandle, this
1545  * macro returns a node identifier for the node with that phandle.
1546  *
1547  * Therefore, if @p prop has type `phandle`, @p idx must be zero. (A
1548  * `phandle` type is treated as a `phandles` with a fixed length of
1549  * 1).
1550  *
1551  * Example devicetree fragment:
1552  *
1553  * @code{.dts}
1554  *     n1: node-1 {
1555  *             foo = <&n2 &n3>;
1556  *     };
1557  *
1558  *     n2: node-2 { ... };
1559  *     n3: node-3 { ... };
1560  * @endcode
1561  *
1562  * Above, `foo` has type phandles and has two elements:
1563  *
1564  * - index 0 has phandle `&n2`, which is `node-2`'s phandle
1565  * - index 1 has phandle `&n3`, which is `node-3`'s phandle
1566  *
1567  * Example usage:
1568  *
1569  * @code{.c}
1570  *     #define N1 DT_NODELABEL(n1)
1571  *
1572  *     DT_PHANDLE_BY_IDX(N1, foo, 0) // node identifier for node-2
1573  *     DT_PHANDLE_BY_IDX(N1, foo, 1) // node identifier for node-3
1574  * @endcode
1575  *
1576  * Behavior is analogous for phandle-arrays.
1577  *
1578  * @internal
1579  * Implementation note: using DT_CAT6 above defers concatenation until
1580  * after expansion of each parameter. This is important when 'idx' is
1581  * expandable to a number, but it isn't one "yet".
1582  * @endinternal
1583  *
1584  * @param node_id node identifier
1585  * @param prop lowercase-and-underscores property name in @p node_id
1586  *             with type `phandle`, `phandles` or `phandle-array`
1587  * @param idx index into @p prop
1588  * @return node identifier for the node with the phandle at that index
1589  */
1590 #define DT_PHANDLE_BY_IDX(node_id, prop, idx) \
1591 	DT_CAT6(node_id, _P_, prop, _IDX_, idx, _PH)
1592 
1593 /**
1594  * @brief Get a node identifier for a phandle property's value
1595  *
1596  * This is equivalent to DT_PHANDLE_BY_IDX(node_id, prop, 0). Its primary
1597  * benefit is readability when @p prop has type `phandle`.
1598  *
1599  * @param node_id node identifier
1600  * @param prop lowercase-and-underscores property of @p node_id
1601  *             with type `phandle`
1602  * @return a node identifier for the node pointed to by "ph"
1603  */
1604 #define DT_PHANDLE(node_id, prop) DT_PHANDLE_BY_IDX(node_id, prop, 0)
1605 
1606 /**
1607  * @}
1608  */
1609 
1610 /**
1611  * @defgroup devicetree-ranges-prop ranges property
1612  * @ingroup devicetree
1613  * @{
1614  */
1615 
1616 /**
1617  * @brief Get the number of range blocks in the ranges property
1618  *
1619  * Use this instead of DT_PROP_LEN(node_id, ranges).
1620  *
1621  * Example devicetree fragment:
1622  *
1623  * @code{.dts}
1624  *     pcie0: pcie@0 {
1625  *             compatible = "intel,pcie";
1626  *             reg = <0 1>;
1627  *             #address-cells = <3>;
1628  *             #size-cells = <2>;
1629  *
1630  *             ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
1631  *                      <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
1632  *                      <0x3000000 0x80 0 0x80 0 0x80 0>;
1633  *     };
1634  *
1635  *     other: other@1 {
1636  *             reg = <1 1>;
1637  *
1638  *             ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
1639  *                      <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
1640  *     };
1641  * @endcode
1642  *
1643  * Example usage:
1644  *
1645  * @code{.c}
1646  *     DT_NUM_RANGES(DT_NODELABEL(pcie0)) // 3
1647  *     DT_NUM_RANGES(DT_NODELABEL(other)) // 2
1648  * @endcode
1649  *
1650  * @param node_id node identifier
1651  */
1652 #define DT_NUM_RANGES(node_id) DT_CAT(node_id, _RANGES_NUM)
1653 
1654 /**
1655  * @brief Is @p idx a valid range block index?
1656  *
1657  * If this returns 1, then DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(node_id, idx),
1658  * DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(node_id, idx) or
1659  * DT_RANGES_LENGTH_BY_IDX(node_id, idx) are valid.
1660  * For DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx) the return value
1661  * of DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(node_id, idx) will indicate
1662  * validity.
1663  * If it returns 0, it is an error to use those macros with index @p idx,
1664  * including DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx).
1665  *
1666  * Example devicetree fragment:
1667  *
1668  * @code{.dts}
1669  *     pcie0: pcie@0 {
1670  *             compatible = "intel,pcie";
1671  *             reg = <0 1>;
1672  *             #address-cells = <3>;
1673  *             #size-cells = <2>;
1674  *
1675  *             ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
1676  *                      <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
1677  *                      <0x3000000 0x80 0 0x80 0 0x80 0>;
1678  *     };
1679  *
1680  *     other: other@1 {
1681  *             reg = <1 1>;
1682  *
1683  *             ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
1684  *                      <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
1685  *     };
1686  * @endcode
1687  *
1688  * Example usage:
1689  *
1690  * @code{.c}
1691  *     DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 0) // 1
1692  *     DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 1) // 1
1693  *     DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 2) // 1
1694  *     DT_RANGES_HAS_IDX(DT_NODELABEL(pcie0), 3) // 0
1695  *     DT_RANGES_HAS_IDX(DT_NODELABEL(other), 0) // 1
1696  *     DT_RANGES_HAS_IDX(DT_NODELABEL(other), 1) // 1
1697  *     DT_RANGES_HAS_IDX(DT_NODELABEL(other), 2) // 0
1698  *     DT_RANGES_HAS_IDX(DT_NODELABEL(other), 3) // 0
1699  * @endcode
1700  *
1701  * @param node_id node identifier
1702  * @param idx index to check
1703  * @return 1 if @p idx is a valid register block index,
1704  *         0 otherwise.
1705  */
1706 #define DT_RANGES_HAS_IDX(node_id, idx) \
1707 	IS_ENABLED(DT_CAT4(node_id, _RANGES_IDX_, idx, _EXISTS))
1708 
1709 /**
1710  * @brief Does a ranges property have child bus flags at index?
1711  *
1712  * If this returns 1, then DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx) is valid.
1713  * If it returns 0, it is an error to use this macro with index @p idx.
1714  * This macro only returns 1 for PCIe buses (i.e. nodes whose bindings specify they
1715  * are "pcie" bus nodes.)
1716  *
1717  * Example devicetree fragment:
1718  *
1719  * @code{.dts}
1720  *     parent {
1721  *             #address-cells = <2>;
1722  *
1723  *             pcie0: pcie@0 {
1724  *                     compatible = "intel,pcie";
1725  *                     reg = <0 0 1>;
1726  *                     #address-cells = <3>;
1727  *                     #size-cells = <2>;
1728  *
1729  *                     ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
1730  *                              <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
1731  *                              <0x3000000 0x80 0 0x80 0 0x80 0>;
1732  *             };
1733  *
1734  *             other: other@1 {
1735  *                     reg = <0 1 1>;
1736  *
1737  *                     ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
1738  *                              <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
1739  *             };
1740  *     };
1741  * @endcode
1742  *
1743  * Example usage:
1744  *
1745  * @code{.c}
1746  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 0) // 1
1747  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 1) // 1
1748  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 2) // 1
1749  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(pcie0), 3) // 0
1750  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 0) // 0
1751  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 1) // 0
1752  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 2) // 0
1753  *     DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(DT_NODELABEL(other), 3) // 0
1754  * @endcode
1755  *
1756  * @param node_id node identifier
1757  * @param idx logical index into the ranges array
1758  * @return 1 if @p idx is a valid child bus flags index,
1759  *         0 otherwise.
1760  */
1761 #define DT_RANGES_HAS_CHILD_BUS_FLAGS_AT_IDX(node_id, idx) \
1762 	IS_ENABLED(DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_CHILD_BUS_FLAGS_EXISTS))
1763 
1764 /**
1765  * @brief Get the ranges property child bus flags at index
1766  *
1767  * When the node is a PCIe bus, the Child Bus Address has an extra cell used to store some
1768  * flags, thus this cell is extracted from the Child Bus Address as Child Bus Flags field.
1769  *
1770  * Example devicetree fragments:
1771  *
1772  * @code{.dts}
1773  *     parent {
1774  *             #address-cells = <2>;
1775  *
1776  *             pcie0: pcie@0 {
1777  *                     compatible = "intel,pcie";
1778  *                     reg = <0 0 1>;
1779  *                     #address-cells = <3>;
1780  *                     #size-cells = <2>;
1781  *
1782  *                     ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
1783  *                              <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
1784  *                              <0x3000000 0x80 0 0x80 0 0x80 0>;
1785  *             };
1786  *     };
1787  * @endcode
1788  *
1789  * Example usage:
1790  *
1791  * @code{.c}
1792  *     DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(DT_NODELABEL(pcie0), 0) // 0x1000000
1793  *     DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x2000000
1794  *     DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x3000000
1795  * @endcode
1796  *
1797  * @param node_id node identifier
1798  * @param idx logical index into the ranges array
1799  * @returns range child bus flags field at idx
1800  */
1801 #define DT_RANGES_CHILD_BUS_FLAGS_BY_IDX(node_id, idx) \
1802 	DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_CHILD_BUS_FLAGS)
1803 
1804 /**
1805  * @brief Get the ranges property child bus address at index
1806  *
1807  * When the node is a PCIe bus, the Child Bus Address has an extra cell used to store some
1808  * flags, thus this cell is removed from the Child Bus Address.
1809  *
1810  * Example devicetree fragments:
1811  *
1812  * @code{.dts}
1813  *     parent {
1814  *             #address-cells = <2>;
1815  *
1816  *             pcie0: pcie@0 {
1817  *                     compatible = "intel,pcie";
1818  *                     reg = <0 0 1>;
1819  *                     #address-cells = <3>;
1820  *                     #size-cells = <2>;
1821  *
1822  *                     ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
1823  *                              <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
1824  *                              <0x3000000 0x80 0 0x80 0 0x80 0>;
1825  *             };
1826  *
1827  *             other: other@1 {
1828  *                     reg = <0 1 1>;
1829  *
1830  *                     ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
1831  *                              <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
1832  *             };
1833  *     };
1834  * @endcode
1835  *
1836  * Example usage:
1837  *
1838  * @code{.c}
1839  *     DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 0) // 0
1840  *     DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x10000000
1841  *     DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x8000000000
1842  *     DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 0) // 0
1843  *     DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 1) // 0x10000000
1844  * @endcode
1845  *
1846  * @param node_id node identifier
1847  * @param idx logical index into the ranges array
1848  * @returns range child bus address field at idx
1849  */
1850 #define DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(node_id, idx) \
1851 	DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_CHILD_BUS_ADDRESS)
1852 
1853 /**
1854  * @brief Get the ranges property parent bus address at index
1855  *
1856  * Similarly to DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(), this properly accounts
1857  * for child bus flags cells when the node is a PCIe bus.
1858  *
1859  * Example devicetree fragment:
1860  *
1861  * @code{.dts}
1862  *     parent {
1863  *             #address-cells = <2>;
1864  *
1865  *             pcie0: pcie@0 {
1866  *                     compatible = "intel,pcie";
1867  *                     reg = <0 0 1>;
1868  *                     #address-cells = <3>;
1869  *                     #size-cells = <2>;
1870  *
1871  *                     ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
1872  *                              <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
1873  *                              <0x3000000 0x80 0 0x80 0 0x80 0>;
1874  *             };
1875  *
1876  *             other: other@1 {
1877  *                     reg = <0 1 1>;
1878  *
1879  *                     ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
1880  *                              <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
1881  *             };
1882  *     };
1883  * @endcode
1884  *
1885  * Example usage:
1886  *
1887  * @code{.c}
1888  *     DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 0) // 0x3eff0000
1889  *     DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x10000000
1890  *     DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x8000000000
1891  *     DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 0) // 0x3eff0000
1892  *     DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(DT_NODELABEL(other), 1) // 0x10000000
1893  * @endcode
1894  *
1895  * @param node_id node identifier
1896  * @param idx logical index into the ranges array
1897  * @returns range parent bus address field at idx
1898  */
1899 #define DT_RANGES_PARENT_BUS_ADDRESS_BY_IDX(node_id, idx) \
1900 	DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_PARENT_BUS_ADDRESS)
1901 
1902 /**
1903  * @brief Get the ranges property length at index
1904  *
1905  * Similarly to DT_RANGES_CHILD_BUS_ADDRESS_BY_IDX(), this properly accounts
1906  * for child bus flags cells when the node is a PCIe bus.
1907  *
1908  * Example devicetree fragment:
1909  *
1910  * @code{.dts}
1911  *     parent {
1912  *             #address-cells = <2>;
1913  *
1914  *             pcie0: pcie@0 {
1915  *                     compatible = "intel,pcie";
1916  *                     reg = <0 0 1>;
1917  *                     #address-cells = <3>;
1918  *                     #size-cells = <2>;
1919  *
1920  *                     ranges = <0x1000000 0 0 0 0x3eff0000 0 0x10000>,
1921  *                              <0x2000000 0 0x10000000 0 0x10000000 0 0x2eff0000>,
1922  *                              <0x3000000 0x80 0 0x80 0 0x80 0>;
1923  *             };
1924  *
1925  *             other: other@1 {
1926  *                     reg = <0 1 1>;
1927  *
1928  *                     ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
1929  *                              <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
1930  *             };
1931  *     };
1932  * @endcode
1933  *
1934  * Example usage:
1935  *
1936  * @code{.c}
1937  *     DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(pcie0), 0) // 0x10000
1938  *     DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(pcie0), 1) // 0x2eff0000
1939  *     DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(pcie0), 2) // 0x8000000000
1940  *     DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(other), 0) // 0x10000
1941  *     DT_RANGES_LENGTH_BY_IDX(DT_NODELABEL(other), 1) // 0x2eff0000
1942  * @endcode
1943  *
1944  * @param node_id node identifier
1945  * @param idx logical index into the ranges array
1946  * @returns range length field at idx
1947  */
1948 #define DT_RANGES_LENGTH_BY_IDX(node_id, idx) \
1949 	DT_CAT4(node_id, _RANGES_IDX_, idx, _VAL_LENGTH)
1950 
1951 /**
1952  * @brief Invokes @p fn for each entry of @p node_id ranges property
1953  *
1954  * The macro @p fn must take two parameters, @p node_id which will be the node
1955  * identifier of the node with the ranges property and @p idx the index of
1956  * the ranges block.
1957  *
1958  * Example devicetree fragment:
1959  *
1960  * @code{.dts}
1961  *     n: node@0 {
1962  *             reg = <0 0 1>;
1963  *
1964  *             ranges = <0x0 0x0 0x0 0x3eff0000 0x10000>,
1965  *                      <0x0 0x10000000 0x0 0x10000000 0x2eff0000>;
1966  *     };
1967  * @endcode
1968  *
1969  * Example usage:
1970  *
1971  * @code{.c}
1972  *     #define RANGE_LENGTH(node_id, idx) DT_RANGES_LENGTH_BY_IDX(node_id, idx),
1973  *
1974  *     const uint64_t *ranges_length[] = {
1975  *             DT_FOREACH_RANGE(DT_NODELABEL(n), RANGE_LENGTH)
1976  *     };
1977  * @endcode
1978  *
1979  * This expands to:
1980  *
1981  * @code{.c}
1982  *     const char *ranges_length[] = {
1983  *         0x10000, 0x2eff0000,
1984  *     };
1985  * @endcode
1986  *
1987  * @param node_id node identifier
1988  * @param fn macro to invoke
1989  */
1990 #define DT_FOREACH_RANGE(node_id, fn) \
1991 	DT_CAT(node_id, _FOREACH_RANGE)(fn)
1992 
1993 /**
1994  * @}
1995  */
1996 
1997 /**
1998  * @defgroup devicetree-generic-vendor Vendor and model name helpers
1999  * @ingroup devicetree
2000  * @{
2001  */
2002 
2003 /**
2004  * @brief Get the vendor at index @p idx as a string literal
2005  *
2006  * The vendor is a string extracted from vendor prefixes if an entry exists
2007  * that matches the node's compatible prefix. There may be as many as one
2008  * vendor prefixes file per directory in DTS_ROOT.
2009  *
2010  * Example vendor-prefixes.txt:
2011  *
2012  *	vnd	A stand-in for a real vendor
2013  *	zephyr	Zephyr-specific binding
2014  *
2015  * Example devicetree fragment:
2016  *
2017  * @code{.dts}
2018  *	n1: node-1 {
2019  *		compatible = "vnd,model1", "gpio", "zephyr,model2";
2020  *	};
2021  * @endcode
2022  *
2023  * Example usage:
2024  *
2025  * @code{.c}
2026  *	DT_NODE_VENDOR_BY_IDX(DT_NODELABEL(n1), 0) // "A stand-in for a real vendor"
2027  *	DT_NODE_VENDOR_BY_IDX(DT_NODELABEL(n1), 2) // "Zephyr-specific binding"
2028  * @endcode
2029  *
2030  * Notice that the compatible at index 1 doesn't match any entries in the
2031  * vendor prefix file and therefore index 1 is not a valid vendor index. Use
2032  * DT_NODE_VENDOR_HAS_IDX(node_id, idx) to determine if an index is valid.
2033  *
2034  * @param node_id node identifier
2035  * @param idx index of the vendor to return
2036  * @return string literal of the idx-th vendor
2037  */
2038 #define DT_NODE_VENDOR_BY_IDX(node_id, idx) \
2039 	DT_CAT3(node_id, _COMPAT_VENDOR_IDX_, idx)
2040 
2041 /**
2042  * @brief Does a node's compatible property have a vendor at an index?
2043  *
2044  * If this returns 1, then DT_NODE_VENDOR_BY_IDX(node_id, idx) is valid. If it
2045  * returns 0, it is an error to use DT_NODE_VENDOR_BY_IDX(node_id, idx) with
2046  * index @p idx.
2047  *
2048  * @param node_id node identifier
2049  * @param idx index of the vendor to check
2050  * @return 1 if @p idx is a valid vendor index,
2051  *         0 otherwise.
2052  */
2053 #define DT_NODE_VENDOR_HAS_IDX(node_id, idx) \
2054 	IS_ENABLED(DT_CAT4(node_id, _COMPAT_VENDOR_IDX_, idx, _EXISTS))
2055 
2056 /**
2057  * @brief Like DT_NODE_VENDOR_BY_IDX(), but with a fallback to default_value.
2058  *
2059  * If the value exists, this expands to DT_NODE_VENDOR_BY_IDX(node_id, idx).
2060  * The default_value parameter is not expanded in this case.
2061  *
2062  * Otherwise, this expands to default_value.
2063  *
2064  * @param node_id node identifier
2065  * @param idx index of the vendor to return
2066  * @return string literal of the idx-th vendor
2067  * @param default_value a fallback value to expand to
2068  * @return string literal of the idx-th vendor or "default_value"
2069  */
2070 #define DT_NODE_VENDOR_BY_IDX_OR(node_id, idx, default_value) \
2071 	COND_CODE_1(DT_NODE_VENDOR_HAS_IDX(node_id, idx), \
2072 		    (DT_NODE_VENDOR_BY_IDX(node_id, idx)), (default_value))
2073 
2074 /**
2075  * @brief Get the node's (only) vendor as a string literal
2076  *
2077  * Equivalent to DT_NODE_VENDOR_BY_IDX_OR(node_id, 0, default_value).
2078  *
2079  * @param node_id node identifier
2080  * @param default_value a fallback value to expand to
2081  */
2082 #define DT_NODE_VENDOR_OR(node_id, default_value) \
2083 	DT_NODE_VENDOR_BY_IDX_OR(node_id, 0, default_value)
2084 
2085 /**
2086  * @brief Get the model at index "idx" as a string literal
2087  *
2088  * The model is a string extracted from the compatible after the vendor prefix.
2089  *
2090  * Example vendor-prefixes.txt:
2091  *
2092  *	vnd	A stand-in for a real vendor
2093  *	zephyr	Zephyr-specific binding
2094  *
2095  * Example devicetree fragment:
2096  *
2097  *	n1: node-1 {
2098  *		compatible = "vnd,model1", "gpio", "zephyr,model2";
2099  *	};
2100  *
2101  * Example usage:
2102  *
2103  *	DT_NODE_MODEL_BY_IDX(DT_NODELABEL(n1), 0) // "model1"
2104  *	DT_NODE_MODEL_BY_IDX(DT_NODELABEL(n1), 2) // "model2"
2105  *
2106  * Notice that the compatible at index 1 doesn't match any entries in the
2107  * vendor prefix file and therefore index 1 is not a valid model index. Use
2108  * DT_NODE_MODEL_HAS_IDX(node_id, idx) to determine if an index is valid.
2109  *
2110  * @param node_id node identifier
2111  * @param idx index of the model to return
2112  * @return string literal of the idx-th model
2113  */
2114 #define DT_NODE_MODEL_BY_IDX(node_id, idx) \
2115 	DT_CAT3(node_id, _COMPAT_MODEL_IDX_, idx)
2116 
2117 /**
2118  * @brief Does a node's compatible property have a model at an index?
2119  *
2120  * If this returns 1, then DT_NODE_MODEL_BY_IDX(node_id, idx) is valid. If it
2121  * returns 0, it is an error to use DT_NODE_MODEL_BY_IDX(node_id, idx) with
2122  * index "idx".
2123  *
2124  * @param node_id node identifier
2125  * @param idx index of the model to check
2126  * @return 1 if "idx" is a valid model index,
2127  *         0 otherwise.
2128  */
2129 #define DT_NODE_MODEL_HAS_IDX(node_id, idx) \
2130 	IS_ENABLED(DT_CAT4(node_id, _COMPAT_MODEL_IDX_, idx, _EXISTS))
2131 
2132 /**
2133  * @brief Like DT_NODE_MODEL_BY_IDX(), but with a fallback to default_value.
2134  *
2135  * If the value exists, this expands to DT_NODE_MODEL_BY_IDX(node_id, idx).
2136  * The default_value parameter is not expanded in this case.
2137  *
2138  * Otherwise, this expands to default_value.
2139  *
2140  * @param node_id node identifier
2141  * @param idx index of the model to return
2142  * @return string literal of the idx-th model
2143  * @param default_value a fallback value to expand to
2144  * @return string literal of the idx-th model or "default_value"
2145  */
2146 #define DT_NODE_MODEL_BY_IDX_OR(node_id, idx, default_value) \
2147 	COND_CODE_1(DT_NODE_MODEL_HAS_IDX(node_id, idx), \
2148 		    (DT_NODE_MODEL_BY_IDX(node_id, idx)), (default_value))
2149 
2150 /**
2151  * @brief Get the node's (only) model as a string literal
2152  *
2153  * Equivalent to DT_NODE_MODEL_BY_IDX_OR(node_id, 0, default_value).
2154  *
2155  * @param node_id node identifier
2156  * @param default_value a fallback value to expand to
2157  */
2158 #define DT_NODE_MODEL_OR(node_id, default_value) \
2159 	DT_NODE_MODEL_BY_IDX_OR(node_id, 0, default_value)
2160 
2161 /**
2162  * @}
2163  */
2164 
2165 /**
2166  * @defgroup devicetree-reg-prop reg property
2167  * @ingroup devicetree
2168  * @{
2169  */
2170 
2171 /**
2172  * @brief Get the number of register blocks in the reg property
2173  *
2174  * Use this instead of DT_PROP_LEN(node_id, reg).
2175  * @param node_id node identifier
2176  * @return Number of register blocks in the node's "reg" property.
2177  */
2178 #define DT_NUM_REGS(node_id) DT_CAT(node_id, _REG_NUM)
2179 
2180 /**
2181  * @brief Is @p idx a valid register block index?
2182  *
2183  * If this returns 1, then DT_REG_ADDR_BY_IDX(node_id, idx) or
2184  * DT_REG_SIZE_BY_IDX(node_id, idx) are valid.
2185  * If it returns 0, it is an error to use those macros with index @p idx.
2186  * @param node_id node identifier
2187  * @param idx index to check
2188  * @return 1 if @p idx is a valid register block index,
2189  *         0 otherwise.
2190  */
2191 #define DT_REG_HAS_IDX(node_id, idx) \
2192 	IS_ENABLED(DT_CAT4(node_id, _REG_IDX_, idx, _EXISTS))
2193 
2194 /**
2195  * @brief Get the base address of the register block at index @p idx
2196  * @param node_id node identifier
2197  * @param idx index of the register whose address to return
2198  * @return address of the idx-th register block
2199  */
2200 #define DT_REG_ADDR_BY_IDX(node_id, idx) \
2201 	DT_CAT4(node_id, _REG_IDX_, idx, _VAL_ADDRESS)
2202 
2203 /**
2204  * @brief Get the size of the register block at index @p idx
2205  *
2206  * This is the size of an individual register block, not the total
2207  * number of register blocks in the property; use DT_NUM_REGS() for
2208  * that.
2209  *
2210  * @param node_id node identifier
2211  * @param idx index of the register whose size to return
2212  * @return size of the idx-th register block
2213  */
2214 #define DT_REG_SIZE_BY_IDX(node_id, idx) \
2215 	DT_CAT4(node_id, _REG_IDX_, idx, _VAL_SIZE)
2216 
2217 /**
2218  * @brief Get a node's (only) register block address
2219  *
2220  * Equivalent to DT_REG_ADDR_BY_IDX(node_id, 0).
2221  * @param node_id node identifier
2222  * @return node's register block address
2223  */
2224 #define DT_REG_ADDR(node_id) DT_REG_ADDR_BY_IDX(node_id, 0)
2225 
2226 /**
2227  * @brief 64-bit version of DT_REG_ADDR()
2228  *
2229  * This macro version adds the appropriate suffix for 64-bit unsigned
2230  * integer literals.
2231  * Note that this macro is equivalent to DT_REG_ADDR() in linker/ASM context.
2232  *
2233  * @param node_id node identifier
2234  * @return node's register block address
2235  */
2236 #define DT_REG_ADDR_U64(node_id) DT_U64_C(DT_REG_ADDR(node_id))
2237 
2238 /**
2239  * @brief Get a node's (only) register block size
2240  *
2241  * Equivalent to DT_REG_SIZE_BY_IDX(node_id, 0).
2242  * @param node_id node identifier
2243  * @return node's only register block's size
2244  */
2245 #define DT_REG_SIZE(node_id) DT_REG_SIZE_BY_IDX(node_id, 0)
2246 
2247 /**
2248  * @brief Get a register block's base address by name
2249  * @param node_id node identifier
2250  * @param name lowercase-and-underscores register specifier name
2251  * @return address of the register block specified by name
2252  */
2253 #define DT_REG_ADDR_BY_NAME(node_id, name) \
2254 	DT_CAT4(node_id, _REG_NAME_, name, _VAL_ADDRESS)
2255 
2256 /**
2257  * @brief 64-bit version of DT_REG_ADDR_BY_NAME()
2258  *
2259  * This macro version adds the appropriate suffix for 64-bit unsigned
2260  * integer literals.
2261  * Note that this macro is equivalent to DT_REG_ADDR_BY_NAME() in
2262  * linker/ASM context.
2263  *
2264  * @param node_id node identifier
2265  * @param name lowercase-and-underscores register specifier name
2266  * @return address of the register block specified by name
2267  */
2268 #define DT_REG_ADDR_BY_NAME_U64(node_id, name) \
2269 	DT_U64_C(DT_REG_ADDR_BY_NAME(node_id, name))
2270 
2271 /**
2272  * @brief Get a register block's size by name
2273  * @param node_id node identifier
2274  * @param name lowercase-and-underscores register specifier name
2275  * @return size of the register block specified by name
2276  */
2277 #define DT_REG_SIZE_BY_NAME(node_id, name) \
2278 	DT_CAT4(node_id, _REG_NAME_, name, _VAL_SIZE)
2279 
2280 /**
2281  * @}
2282  */
2283 
2284 /**
2285  * @defgroup devicetree-interrupts-prop interrupts property
2286  * @ingroup devicetree
2287  * @{
2288  */
2289 
2290 /**
2291  * @brief Get the number of interrupt sources for the node
2292  *
2293  * Use this instead of DT_PROP_LEN(node_id, interrupts).
2294  *
2295  * @param node_id node identifier
2296  * @return Number of interrupt specifiers in the node's "interrupts" property.
2297  */
2298 #define DT_NUM_IRQS(node_id) DT_CAT(node_id, _IRQ_NUM)
2299 
2300 /**
2301  * @brief Is @p idx a valid interrupt index?
2302  *
2303  * If this returns 1, then DT_IRQ_BY_IDX(node_id, idx) is valid.
2304  * If it returns 0, it is an error to use that macro with this index.
2305  * @param node_id node identifier
2306  * @param idx index to check
2307  * @return 1 if the idx is valid for the interrupt property
2308  *         0 otherwise.
2309  */
2310 #define DT_IRQ_HAS_IDX(node_id, idx) \
2311 	IS_ENABLED(DT_CAT4(node_id, _IRQ_IDX_, idx, _EXISTS))
2312 
2313 /**
2314  * @brief Does an interrupts property have a named cell specifier at an index?
2315  * If this returns 1, then DT_IRQ_BY_IDX(node_id, idx, cell) is valid.
2316  * If it returns 0, it is an error to use that macro.
2317  * @param node_id node identifier
2318  * @param idx index to check
2319  * @param cell named cell value whose existence to check
2320  * @return 1 if the named cell exists in the interrupt specifier at index idx
2321  *         0 otherwise.
2322  */
2323 #define DT_IRQ_HAS_CELL_AT_IDX(node_id, idx, cell) \
2324 	IS_ENABLED(DT_CAT6(node_id, _IRQ_IDX_, idx, _VAL_, cell, _EXISTS))
2325 
2326 /**
2327  * @brief Equivalent to DT_IRQ_HAS_CELL_AT_IDX(node_id, 0, cell)
2328  * @param node_id node identifier
2329  * @param cell named cell value whose existence to check
2330  * @return 1 if the named cell exists in the interrupt specifier at index 0
2331  *         0 otherwise.
2332  */
2333 #define DT_IRQ_HAS_CELL(node_id, cell) DT_IRQ_HAS_CELL_AT_IDX(node_id, 0, cell)
2334 
2335 /**
2336  * @brief Does an interrupts property have a named specifier value at an index?
2337  * If this returns 1, then DT_IRQ_BY_NAME(node_id, name, cell) is valid.
2338  * If it returns 0, it is an error to use that macro.
2339  * @param node_id node identifier
2340  * @param name lowercase-and-underscores interrupt specifier name
2341  * @return 1 if "name" is a valid named specifier
2342  *         0 otherwise.
2343  */
2344 #define DT_IRQ_HAS_NAME(node_id, name) \
2345 	IS_ENABLED(DT_CAT4(node_id, _IRQ_NAME_, name, _VAL_irq_EXISTS))
2346 
2347 /**
2348  * @brief Get a value within an interrupt specifier at an index
2349  *
2350  * It might help to read the argument order as being similar to
2351  * "node->interrupts[index].cell".
2352  *
2353  * This can be used to get information about an individual interrupt
2354  * when a device generates more than one.
2355  *
2356  * Example devicetree fragment:
2357  *
2358  * @code{.dts}
2359  *     my-serial: serial@abcd1234 {
2360  *             interrupts = < 33 0 >, < 34 1 >;
2361  *     };
2362  * @endcode
2363  *
2364  * Assuming the node's interrupt domain has "#interrupt-cells = <2>;" and
2365  * the individual cells in each interrupt specifier are named "irq" and
2366  * "priority" by the node's binding, here are some examples:
2367  *
2368  *     #define SERIAL DT_NODELABEL(my_serial)
2369  *
2370  *     Example usage                       Value
2371  *     -------------                       -----
2372  *     DT_IRQ_BY_IDX(SERIAL, 0, irq)          33
2373  *     DT_IRQ_BY_IDX(SERIAL, 0, priority)      0
2374  *     DT_IRQ_BY_IDX(SERIAL, 1, irq,          34
2375  *     DT_IRQ_BY_IDX(SERIAL, 1, priority)      1
2376  *
2377  * @param node_id node identifier
2378  * @param idx logical index into the interrupt specifier array
2379  * @param cell cell name specifier
2380  * @return the named value at the specifier given by the index
2381  */
2382 #define DT_IRQ_BY_IDX(node_id, idx, cell)   \
2383 	DT_CAT5(node_id, _IRQ_IDX_, idx, _VAL_, cell)
2384 
2385 /**
2386  * @brief Get a value within an interrupt specifier by name
2387  *
2388  * It might help to read the argument order as being similar to
2389  * `node->interrupts.name.cell`.
2390  *
2391  * This can be used to get information about an individual interrupt
2392  * when a device generates more than one, if the bindings give each
2393  * interrupt specifier a name.
2394  *
2395  * @param node_id node identifier
2396  * @param name lowercase-and-underscores interrupt specifier name
2397  * @param cell cell name specifier
2398  * @return the named value at the specifier given by the index
2399  */
2400 #define DT_IRQ_BY_NAME(node_id, name, cell) \
2401 	DT_CAT5(node_id, _IRQ_NAME_, name, _VAL_, cell)
2402 
2403 /**
2404  * @brief Get an interrupt specifier's value
2405  * Equivalent to DT_IRQ_BY_IDX(node_id, 0, cell).
2406  * @param node_id node identifier
2407  * @param cell cell name specifier
2408  * @return the named value at that index
2409  */
2410 #define DT_IRQ(node_id, cell) DT_IRQ_BY_IDX(node_id, 0, cell)
2411 
2412 /**
2413  * @brief Get a node's (only) irq number
2414  *
2415  * Equivalent to DT_IRQ(node_id, irq). This is provided as a convenience
2416  * for the common case where a node generates exactly one interrupt,
2417  * and the IRQ number is in a cell named `irq`.
2418  *
2419  * @param node_id node identifier
2420  * @return the interrupt number for the node's only interrupt
2421  */
2422 #define DT_IRQN(node_id) DT_IRQ(node_id, irq)
2423 
2424 /**
2425  * @}
2426  */
2427 
2428 /**
2429  * @defgroup devicetree-generic-chosen Chosen nodes
2430  * @ingroup devicetree
2431  * @{
2432  */
2433 
2434 /**
2435  * @brief Get a node identifier for a `/chosen` node property
2436  *
2437  * This is only valid to call if `DT_HAS_CHOSEN(prop)` is 1.
2438  * @param prop lowercase-and-underscores property name for
2439  *             the /chosen node
2440  * @return a node identifier for the chosen node property
2441  */
2442 #define DT_CHOSEN(prop) DT_CAT(DT_CHOSEN_, prop)
2443 
2444 /**
2445  * @brief Test if the devicetree has a `/chosen` node
2446  * @param prop lowercase-and-underscores devicetree property
2447  * @return 1 if the chosen property exists and refers to a node,
2448  *         0 otherwise
2449  */
2450 #define DT_HAS_CHOSEN(prop) IS_ENABLED(DT_CAT3(DT_CHOSEN_, prop, _EXISTS))
2451 
2452 /**
2453  * @}
2454  */
2455 
2456 /**
2457  * @defgroup devicetree-generic-foreach "For-each" macros
2458  * @ingroup devicetree
2459  * @{
2460  */
2461 
2462 /**
2463  * @brief Invokes @p fn for every node in the tree.
2464  *
2465  * The macro @p fn must take one parameter, which will be a node
2466  * identifier. The macro is expanded once for each node in the tree.
2467  * The order that nodes are visited in is not specified.
2468  *
2469  * @param fn macro to invoke
2470  */
2471 #define DT_FOREACH_NODE(fn) DT_FOREACH_HELPER(fn)
2472 
2473 /**
2474  * @brief Invokes @p fn for every node in the tree with multiple arguments.
2475  *
2476  * The macro @p fn takes multiple arguments. The first should be the node
2477  * identifier for the node. The remaining are passed-in by the caller.
2478  *
2479  * The macro is expanded once for each node in the tree. The order that nodes
2480  * are visited in is not specified.
2481  *
2482  * @param fn macro to invoke
2483  * @param ... variable number of arguments to pass to @p fn
2484  */
2485 #define DT_FOREACH_NODE_VARGS(fn, ...) DT_FOREACH_VARGS_HELPER(fn, __VA_ARGS__)
2486 
2487 /**
2488  * @brief Invokes @p fn for every status `okay` node in the tree.
2489  *
2490  * The macro @p fn must take one parameter, which will be a node
2491  * identifier. The macro is expanded once for each node in the tree
2492  * with status `okay` (as usual, a missing status property is treated
2493  * as status `okay`). The order that nodes are visited in is not
2494  * specified.
2495  *
2496  * @param fn macro to invoke
2497  */
2498 #define DT_FOREACH_STATUS_OKAY_NODE(fn) DT_FOREACH_OKAY_HELPER(fn)
2499 
2500 /**
2501  * @brief Invokes @p fn for every status `okay` node in the tree with multiple
2502  *        arguments.
2503  *
2504  * The macro @p fn takes multiple arguments. The first should be the node
2505  * identifier for the node. The remaining are passed-in by the caller.
2506  *
2507  * The macro is expanded once for each node in the tree with status `okay` (as
2508  * usual, a missing status property is treated as status `okay`). The order
2509  * that nodes are visited in is not specified.
2510  *
2511  * @param fn macro to invoke
2512  * @param ... variable number of arguments to pass to @p fn
2513  */
2514 #define DT_FOREACH_STATUS_OKAY_NODE_VARGS(fn, ...) DT_FOREACH_OKAY_VARGS_HELPER(fn, __VA_ARGS__)
2515 
2516 /**
2517  * @brief Invokes @p fn for each child of @p node_id
2518  *
2519  * The macro @p fn must take one parameter, which will be the node
2520  * identifier of a child node of @p node_id.
2521  *
2522  * The children will be iterated over in the same order as they
2523  * appear in the final devicetree.
2524  *
2525  * Example devicetree fragment:
2526  *
2527  * @code{.dts}
2528  *     n: node {
2529  *             child-1 {
2530  *                     foobar = "foo";
2531  *             };
2532  *             child-2 {
2533  *                     foobar = "bar";
2534  *             };
2535  *     };
2536  * @endcode
2537  *
2538  * Example usage:
2539  *
2540  * @code{.c}
2541  *     #define FOOBAR_AND_COMMA(node_id) DT_PROP(node_id, foobar),
2542  *
2543  *     const char *child_foobars[] = {
2544  *         DT_FOREACH_CHILD(DT_NODELABEL(n), FOOBAR_AND_COMMA)
2545  *     };
2546  * @endcode
2547  *
2548  * This expands to:
2549  *
2550  * @code{.c}
2551  *     const char *child_foobars[] = {
2552  *         "foo", "bar",
2553  *     };
2554  * @endcode
2555  *
2556  * @param node_id node identifier
2557  * @param fn macro to invoke
2558  */
2559 #define DT_FOREACH_CHILD(node_id, fn) \
2560 	DT_CAT(node_id, _FOREACH_CHILD)(fn)
2561 
2562 /**
2563  * @brief Invokes @p fn for each child of @p node_id with a separator
2564  *
2565  * The macro @p fn must take one parameter, which will be the node
2566  * identifier of a child node of @p node_id.
2567  *
2568  * Example devicetree fragment:
2569  *
2570  * @code{.dts}
2571  *     n: node {
2572  *             child-1 {
2573  *                     ...
2574  *             };
2575  *             child-2 {
2576  *                     ...
2577  *             };
2578  *     };
2579  * @endcode
2580  *
2581  * Example usage:
2582  *
2583  * @code{.c}
2584  *     const char *child_names[] = {
2585  *         DT_FOREACH_CHILD_SEP(DT_NODELABEL(n), DT_NODE_FULL_NAME, (,))
2586  *     };
2587  * @endcode
2588  *
2589  * This expands to:
2590  *
2591  * @code{.c}
2592  *     const char *child_names[] = {
2593  *         "child-1", "child-2"
2594  *     };
2595  * @endcode
2596  *
2597  * @param node_id node identifier
2598  * @param fn macro to invoke
2599  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
2600  *            this is required to enable providing a comma as separator.
2601  */
2602 #define DT_FOREACH_CHILD_SEP(node_id, fn, sep) \
2603 	DT_CAT(node_id, _FOREACH_CHILD_SEP)(fn, sep)
2604 
2605 /**
2606  * @brief Invokes @p fn for each child of @p node_id with multiple arguments
2607  *
2608  * The macro @p fn takes multiple arguments. The first should be the node
2609  * identifier for the child node. The remaining are passed-in by the caller.
2610  *
2611  * The children will be iterated over in the same order as they
2612  * appear in the final devicetree.
2613  *
2614  * @param node_id node identifier
2615  * @param fn macro to invoke
2616  * @param ... variable number of arguments to pass to @p fn
2617  *
2618  * @see DT_FOREACH_CHILD
2619  */
2620 #define DT_FOREACH_CHILD_VARGS(node_id, fn, ...) \
2621 	DT_CAT(node_id, _FOREACH_CHILD_VARGS)(fn, __VA_ARGS__)
2622 
2623 /**
2624  * @brief Invokes @p fn for each child of @p node_id with separator and multiple
2625  *        arguments.
2626  *
2627  * The macro @p fn takes multiple arguments. The first should be the node
2628  * identifier for the child node. The remaining are passed-in by the caller.
2629  *
2630  * @param node_id node identifier
2631  * @param fn macro to invoke
2632  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
2633  *            this is required to enable providing a comma as separator.
2634  * @param ... variable number of arguments to pass to @p fn
2635  *
2636  * @see DT_FOREACH_CHILD_VARGS
2637  */
2638 #define DT_FOREACH_CHILD_SEP_VARGS(node_id, fn, sep, ...) \
2639 	DT_CAT(node_id, _FOREACH_CHILD_SEP_VARGS)(fn, sep, __VA_ARGS__)
2640 
2641 /**
2642  * @brief Call @p fn on the child nodes with status `okay`
2643  *
2644  * The macro @p fn should take one argument, which is the node
2645  * identifier for the child node.
2646  *
2647  * As usual, both a missing status and an `ok` status are
2648  * treated as `okay`.
2649  *
2650  * The children will be iterated over in the same order as they
2651  * appear in the final devicetree.
2652  *
2653  * @param node_id node identifier
2654  * @param fn macro to invoke
2655  */
2656 #define DT_FOREACH_CHILD_STATUS_OKAY(node_id, fn) \
2657 	DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY)(fn)
2658 
2659 /**
2660  * @brief Call @p fn on the child nodes with status `okay` with separator
2661  *
2662  * The macro @p fn should take one argument, which is the node
2663  * identifier for the child node.
2664  *
2665  * As usual, both a missing status and an `ok` status are
2666  * treated as `okay`.
2667  *
2668  * @param node_id node identifier
2669  * @param fn macro to invoke
2670  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
2671  *            this is required to enable providing a comma as separator.
2672  *
2673  * @see DT_FOREACH_CHILD_STATUS_OKAY
2674  */
2675 #define DT_FOREACH_CHILD_STATUS_OKAY_SEP(node_id, fn, sep) \
2676 	DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY_SEP)(fn, sep)
2677 
2678 /**
2679  * @brief Call @p fn on the child nodes with status `okay` with multiple
2680  * arguments
2681  *
2682  * The macro @p fn takes multiple arguments. The first should be the node
2683  * identifier for the child node. The remaining are passed-in by the caller.
2684  *
2685  * As usual, both a missing status and an `ok` status are
2686  * treated as `okay`.
2687  *
2688  * The children will be iterated over in the same order as they
2689  * appear in the final devicetree.
2690  *
2691  * @param node_id node identifier
2692  * @param fn macro to invoke
2693  * @param ... variable number of arguments to pass to @p fn
2694  *
2695  * @see DT_FOREACH_CHILD_STATUS_OKAY
2696  */
2697 #define DT_FOREACH_CHILD_STATUS_OKAY_VARGS(node_id, fn, ...) \
2698 	DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY_VARGS)(fn, __VA_ARGS__)
2699 
2700 /**
2701  * @brief Call @p fn on the child nodes with status `okay` with separator and
2702  * multiple arguments
2703  *
2704  * The macro @p fn takes multiple arguments. The first should be the node
2705  * identifier for the child node. The remaining are passed-in by the caller.
2706  *
2707  * As usual, both a missing status and an `ok` status are
2708  * treated as `okay`.
2709  *
2710  * @param node_id node identifier
2711  * @param fn macro to invoke
2712  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
2713  *            this is required to enable providing a comma as separator.
2714  * @param ... variable number of arguments to pass to @p fn
2715  *
2716  * @see DT_FOREACH_CHILD_SEP_STATUS_OKAY
2717  */
2718 #define DT_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS(node_id, fn, sep, ...) \
2719 	DT_CAT(node_id, _FOREACH_CHILD_STATUS_OKAY_SEP_VARGS)(fn, sep, __VA_ARGS__)
2720 
2721 /**
2722  * @brief Invokes @p fn for each element in the value of property @p prop.
2723  *
2724  * The macro @p fn must take three parameters: fn(node_id, prop, idx).
2725  * @p node_id and @p prop are the same as what is passed to
2726  * DT_FOREACH_PROP_ELEM(), and @p idx is the current index into the array.
2727  * The @p idx values are integer literals starting from 0.
2728  *
2729  * The @p prop argument must refer to a property that can be passed to
2730  * DT_PROP_LEN().
2731  *
2732  * Example devicetree fragment:
2733  *
2734  * @code{.dts}
2735  *     n: node {
2736  *             my-ints = <1 2 3>;
2737  *     };
2738  * @endcode
2739  *
2740  * Example usage:
2741  *
2742  * @code{.c}
2743  *     #define TIMES_TWO(node_id, prop, idx) \
2744  *	       (2 * DT_PROP_BY_IDX(node_id, prop, idx)),
2745  *
2746  *     int array[] = {
2747  *             DT_FOREACH_PROP_ELEM(DT_NODELABEL(n), my_ints, TIMES_TWO)
2748  *     };
2749  * @endcode
2750  *
2751  * This expands to:
2752  *
2753  * @code{.c}
2754  *     int array[] = {
2755  *             (2 * 1), (2 * 2), (2 * 3),
2756  *     };
2757  * @endcode
2758  *
2759  * In general, this macro expands to:
2760  *
2761  *     fn(node_id, prop, 0) fn(node_id, prop, 1) [...] fn(node_id, prop, n-1)
2762  *
2763  * where `n` is the number of elements in @p prop, as it would be
2764  * returned by `DT_PROP_LEN(node_id, prop)`.
2765  *
2766  * @param node_id node identifier
2767  * @param prop lowercase-and-underscores property name
2768  * @param fn macro to invoke
2769  * @see DT_PROP_LEN
2770  */
2771 #define DT_FOREACH_PROP_ELEM(node_id, prop, fn)		\
2772 	DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM)(fn)
2773 
2774 /**
2775  * @brief Invokes @p fn for each element in the value of property @p prop with
2776  *        separator.
2777  *
2778  * Example devicetree fragment:
2779  *
2780  * @code{.dts}
2781  *     n: node {
2782  *             my-gpios = <&gpioa 0 GPIO_ACTICE_HIGH>,
2783  *                        <&gpiob 1 GPIO_ACTIVE_HIGH>;
2784  *     };
2785  * @endcode
2786  *
2787  * Example usage:
2788  *
2789  * @code{.c}
2790  *     struct gpio_dt_spec specs[] = {
2791  *             DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(n), my_gpios,
2792  *                                      GPIO_DT_SPEC_GET_BY_IDX, (,))
2793  *     };
2794  * @endcode
2795  *
2796  * This expands as a first step to:
2797  *
2798  * @code{.c}
2799  *     struct gpio_dt_spec specs[] = {
2800  *             GPIO_DT_SPEC_GET_BY_IDX(DT_NODELABEL(n), my_gpios, 0),
2801  *             GPIO_DT_SPEC_GET_BY_IDX(DT_NODELABEL(n), my_gpios, 1)
2802  *     };
2803  * @endcode
2804  *
2805  * The @p prop parameter has the same restrictions as the same parameter
2806  * given to DT_FOREACH_PROP_ELEM().
2807  *
2808  * @param node_id node identifier
2809  * @param prop lowercase-and-underscores property name
2810  * @param fn macro to invoke
2811  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
2812  *            this is required to enable providing a comma as separator.
2813  *
2814  * @see DT_FOREACH_PROP_ELEM
2815  */
2816 #define DT_FOREACH_PROP_ELEM_SEP(node_id, prop, fn, sep) \
2817 	DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM_SEP)(fn, sep)
2818 
2819 /**
2820  * @brief Invokes @p fn for each element in the value of property @p prop with
2821  * multiple arguments.
2822  *
2823  * The macro @p fn must take multiple parameters:
2824  * `fn(node_id, prop, idx, ...)`. @p node_id and @p prop are the same as what
2825  * is passed to DT_FOREACH_PROP_ELEM(), and @p idx is the current index into
2826  * the array. The @p idx values are integer literals starting from 0. The
2827  * remaining arguments are passed-in by the caller.
2828  *
2829  * The @p prop parameter has the same restrictions as the same parameter
2830  * given to DT_FOREACH_PROP_ELEM().
2831  *
2832  * @param node_id node identifier
2833  * @param prop lowercase-and-underscores property name
2834  * @param fn macro to invoke
2835  * @param ... variable number of arguments to pass to @p fn
2836  *
2837  * @see DT_FOREACH_PROP_ELEM
2838  */
2839 #define DT_FOREACH_PROP_ELEM_VARGS(node_id, prop, fn, ...)		\
2840 	DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM_VARGS)(fn, __VA_ARGS__)
2841 
2842 /**
2843  * @brief Invokes @p fn for each element in the value of property @p prop with
2844  * multiple arguments and a separator.
2845  *
2846  * The @p prop parameter has the same restrictions as the same parameter
2847  * given to DT_FOREACH_PROP_ELEM().
2848  *
2849  * @param node_id node identifier
2850  * @param prop lowercase-and-underscores property name
2851  * @param fn macro to invoke
2852  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
2853  *            this is required to enable providing a comma as separator.
2854  * @param ... variable number of arguments to pass to fn
2855  *
2856  * @see DT_FOREACH_PROP_ELEM_VARGS
2857  */
2858 #define DT_FOREACH_PROP_ELEM_SEP_VARGS(node_id, prop, fn, sep, ...)	\
2859 	DT_CAT4(node_id, _P_, prop, _FOREACH_PROP_ELEM_SEP_VARGS)(	\
2860 		fn, sep, __VA_ARGS__)
2861 
2862 /**
2863  * @brief Invokes @p fn for each status `okay` node of a compatible.
2864  *
2865  * This macro expands to:
2866  *
2867  *     fn(node_id_1) fn(node_id_2) ... fn(node_id_n)
2868  *
2869  * where each `node_id_<i>` is a node identifier for some node with
2870  * compatible @p compat and status `okay`. Whitespace is added between
2871  * expansions as shown above.
2872  *
2873  * Example devicetree fragment:
2874  *
2875  * @code{.dts}
2876  *     / {
2877  *             a {
2878  *                     compatible = "foo";
2879  *                     status = "okay";
2880  *             };
2881  *             b {
2882  *                     compatible = "foo";
2883  *                     status = "disabled";
2884  *             };
2885  *             c {
2886  *                     compatible = "foo";
2887  *             };
2888  *     };
2889  * @endcode
2890  *
2891  * Example usage:
2892  *
2893  * @code{.c}
2894  *     DT_FOREACH_STATUS_OKAY(foo, DT_NODE_PATH)
2895  * @endcode
2896  *
2897  * This expands to one of the following:
2898  *
2899  *     "/a" "/c"
2900  *     "/c" "/a"
2901  *
2902  * "One of the following" is because no guarantees are made about the
2903  * order that node identifiers are passed to @p fn in the expansion.
2904  *
2905  * (The `/c` string literal is present because a missing status
2906  * property is always treated as if the status were set to `okay`.)
2907  *
2908  * Note also that @p fn is responsible for adding commas, semicolons,
2909  * or other terminators as needed.
2910  *
2911  * @param compat lowercase-and-underscores devicetree compatible
2912  * @param fn Macro to call for each enabled node. Must accept a
2913  *           node_id as its only parameter.
2914  */
2915 #define DT_FOREACH_STATUS_OKAY(compat, fn)				\
2916 	COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat),			\
2917 		    (UTIL_CAT(DT_FOREACH_OKAY_, compat)(fn)),	\
2918 		    ())
2919 
2920 /**
2921  * @brief Invokes @p fn for each status `okay` node of a compatible
2922  *        with multiple arguments.
2923  *
2924  * This is like DT_FOREACH_STATUS_OKAY() except you can also pass
2925  * additional arguments to @p fn.
2926  *
2927  * Example devicetree fragment:
2928  *
2929  * @code{.dts}
2930  *     / {
2931  *             a {
2932  *                     compatible = "foo";
2933  *                     val = <3>;
2934  *             };
2935  *             b {
2936  *                     compatible = "foo";
2937  *                     val = <4>;
2938  *             };
2939  *     };
2940  * @endcode
2941  *
2942  * Example usage:
2943  *
2944  * @code{.c}
2945  *     #define MY_FN(node_id, operator) DT_PROP(node_id, val) operator
2946  *     x = DT_FOREACH_STATUS_OKAY_VARGS(foo, MY_FN, +) 0;
2947  * @endcode
2948  *
2949  * This expands to one of the following:
2950  *
2951  * @code{.c}
2952  *     x = 3 + 4 + 0;
2953  *     x = 4 + 3 + 0;
2954  * @endcode
2955  *
2956  * i.e. it sets `x` to 7. As with DT_FOREACH_STATUS_OKAY(), there are no
2957  * guarantees about the order nodes appear in the expansion.
2958  *
2959  * @param compat lowercase-and-underscores devicetree compatible
2960  * @param fn Macro to call for each enabled node. Must accept a
2961  *           node_id as its only parameter.
2962  * @param ... Additional arguments to pass to @p fn
2963  */
2964 #define DT_FOREACH_STATUS_OKAY_VARGS(compat, fn, ...)			\
2965 	COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat),			\
2966 		    (UTIL_CAT(DT_FOREACH_OKAY_VARGS_,			\
2967 			      compat)(fn, __VA_ARGS__)),		\
2968 		    ())
2969 
2970 /**
2971  * @}
2972  */
2973 
2974 /**
2975  * @defgroup devicetree-generic-exist Existence checks
2976  * @ingroup devicetree
2977  * @{
2978  */
2979 
2980 /**
2981  * @brief Does a node identifier refer to a node?
2982  *
2983  * Tests whether a node identifier refers to a node which exists, i.e.
2984  * is defined in the devicetree.
2985  *
2986  * It doesn't matter whether or not the node has a matching binding,
2987  * or what the node's status value is. This is purely a check of
2988  * whether the node exists at all.
2989  *
2990  * @param node_id a node identifier
2991  * @return 1 if the node identifier refers to a node,
2992  *         0 otherwise.
2993  */
2994 #define DT_NODE_EXISTS(node_id) IS_ENABLED(DT_CAT(node_id, _EXISTS))
2995 
2996 /**
2997  * @brief Does a node identifier refer to a node with a status?
2998  *
2999  * Example uses:
3000  *
3001  * @code{.c}
3002  *     DT_NODE_HAS_STATUS(DT_PATH(soc, i2c_12340000), okay)
3003  *     DT_NODE_HAS_STATUS(DT_PATH(soc, i2c_12340000), disabled)
3004  * @endcode
3005  *
3006  * Tests whether a node identifier refers to a node which:
3007  *
3008  * - exists in the devicetree, and
3009  * - has a status property matching the second argument
3010  *   (except that either a missing status or an `ok` status
3011  *   in the devicetree is treated as if it were `okay` instead)
3012  *
3013  * @param node_id a node identifier
3014  * @param status a status as one of the tokens okay or disabled, not a string
3015  * @return 1 if the node has the given status, 0 otherwise.
3016  */
3017 #define DT_NODE_HAS_STATUS(node_id, status) \
3018 	DT_NODE_HAS_STATUS_INTERNAL(node_id, status)
3019 
3020 /**
3021  * @brief Does the devicetree have a status `okay` node with a compatible?
3022  *
3023  * Test for whether the devicetree has any nodes with status `okay`
3024  * and the given compatible. That is, this returns 1 if and only if
3025  * there is at least one @p node_id for which both of these
3026  * expressions return 1:
3027  *
3028  * @code{.c}
3029  *     DT_NODE_HAS_STATUS(node_id, okay)
3030  *     DT_NODE_HAS_COMPAT(node_id, compat)
3031  * @endcode
3032  *
3033  * As usual, both a missing status and an `ok` status are treated as
3034  * `okay`.
3035  *
3036  * @param compat lowercase-and-underscores compatible, without quotes
3037  * @return 1 if both of the above conditions are met, 0 otherwise
3038  */
3039 #define DT_HAS_COMPAT_STATUS_OKAY(compat) \
3040 	IS_ENABLED(DT_CAT(DT_COMPAT_HAS_OKAY_, compat))
3041 
3042 /**
3043  * @brief Get the number of instances of a given compatible with
3044  *        status `okay`
3045  * @param compat lowercase-and-underscores compatible, without quotes
3046  * @return Number of instances with status `okay`
3047  */
3048 #define DT_NUM_INST_STATUS_OKAY(compat)			\
3049 	UTIL_AND(DT_HAS_COMPAT_STATUS_OKAY(compat),		\
3050 		 UTIL_CAT(DT_N_INST, DT_DASH(compat, NUM_OKAY)))
3051 
3052 /**
3053  * @brief Does a devicetree node match a compatible?
3054  *
3055  * Example devicetree fragment:
3056  *
3057  * @code{.dts}
3058  *     n: node {
3059  *             compatible = "vnd,specific-device", "generic-device";
3060  *     }
3061  * @endcode
3062  *
3063  * Example usages which evaluate to 1:
3064  *
3065  * @code{.c}
3066  *     DT_NODE_HAS_COMPAT(DT_NODELABEL(n), vnd_specific_device)
3067  *     DT_NODE_HAS_COMPAT(DT_NODELABEL(n), generic_device)
3068  * @endcode
3069  *
3070  * This macro only uses the value of the compatible property. Whether
3071  * or not a particular compatible has a matching binding has no effect
3072  * on its value, nor does the node's status.
3073  *
3074  * @param node_id node identifier
3075  * @param compat lowercase-and-underscores compatible, without quotes
3076  * @return 1 if the node's compatible property contains @p compat,
3077  *         0 otherwise.
3078  */
3079 #define DT_NODE_HAS_COMPAT(node_id, compat) \
3080 	IS_ENABLED(DT_CAT3(node_id, _COMPAT_MATCHES_, compat))
3081 
3082 /**
3083  * @brief Does a devicetree node have a compatible and status?
3084  *
3085  * This is equivalent to:
3086  *
3087  * @code{.c}
3088  *     (DT_NODE_HAS_COMPAT(node_id, compat) &&
3089  *      DT_NODE_HAS_STATUS(node_id, status))
3090  * @endcode
3091  *
3092  * @param node_id node identifier
3093  * @param compat lowercase-and-underscores compatible, without quotes
3094  * @param status okay or disabled as a token, not a string
3095  */
3096 #define DT_NODE_HAS_COMPAT_STATUS(node_id, compat, status) \
3097 	DT_NODE_HAS_COMPAT(node_id, compat) && DT_NODE_HAS_STATUS(node_id, status)
3098 
3099 /**
3100  * @brief Does a devicetree node have a property?
3101  *
3102  * Tests whether a devicetree node has a property defined.
3103  *
3104  * This tests whether the property is defined at all, not whether a
3105  * boolean property is true or false. To get a boolean property's
3106  * truth value, use DT_PROP(node_id, prop) instead.
3107  *
3108  * @param node_id node identifier
3109  * @param prop lowercase-and-underscores property name
3110  * @return 1 if the node has the property, 0 otherwise.
3111  */
3112 #define DT_NODE_HAS_PROP(node_id, prop) \
3113 	IS_ENABLED(DT_CAT4(node_id, _P_, prop, _EXISTS))
3114 
3115 
3116 /**
3117  * @brief Does a phandle array have a named cell specifier at an index?
3118  *
3119  * If this returns 1, then the phandle-array property @p pha has a cell
3120  * named @p cell at index @p idx, and therefore DT_PHA_BY_IDX(node_id,
3121  * pha, idx, cell) is valid. If it returns 0, it's an error to use
3122  * DT_PHA_BY_IDX() with the same arguments.
3123  *
3124  * @param node_id node identifier
3125  * @param pha lowercase-and-underscores property with type `phandle-array`
3126  * @param idx index to check within @p pha
3127  * @param cell lowercase-and-underscores cell name whose existence to check
3128  *             at index @p idx
3129  * @return 1 if the named cell exists in the specifier at index idx,
3130  *         0 otherwise.
3131  */
3132 #define DT_PHA_HAS_CELL_AT_IDX(node_id, pha, idx, cell)             \
3133 	IS_ENABLED(DT_CAT8(node_id, _P_, pha,			    \
3134 			   _IDX_, idx, _VAL_, cell, _EXISTS))
3135 
3136 /**
3137  * @brief Equivalent to DT_PHA_HAS_CELL_AT_IDX(node_id, pha, 0, cell)
3138  * @param node_id node identifier
3139  * @param pha lowercase-and-underscores property with type `phandle-array`
3140  * @param cell lowercase-and-underscores cell name whose existence to check
3141  *             at index @p idx
3142  * @return 1 if the named cell exists in the specifier at index 0,
3143  *         0 otherwise.
3144  */
3145 #define DT_PHA_HAS_CELL(node_id, pha, cell) \
3146 	DT_PHA_HAS_CELL_AT_IDX(node_id, pha, 0, cell)
3147 
3148 /**
3149  * @}
3150  */
3151 
3152 /**
3153  * @defgroup devicetree-generic-bus Bus helpers
3154  * @ingroup devicetree
3155  * @{
3156  */
3157 
3158 /**
3159  * @brief Node's bus controller
3160  *
3161  * Get the node identifier of the node's bus controller. This can be
3162  * used with DT_PROP() to get properties of the bus controller.
3163  *
3164  * It is an error to use this with nodes which do not have bus
3165  * controllers.
3166  *
3167  * Example devicetree fragment:
3168  *
3169  * @code{.dts}
3170  *     i2c@deadbeef {
3171  *             status = "okay";
3172  *             clock-frequency = < 100000 >;
3173  *
3174  *             i2c_device: accelerometer@12 {
3175  *                     ...
3176  *             };
3177  *     };
3178  * @endcode
3179  *
3180  * Example usage:
3181  *
3182  * @code{.c}
3183  *     DT_PROP(DT_BUS(DT_NODELABEL(i2c_device)), clock_frequency) // 100000
3184  * @endcode
3185  *
3186  * @param node_id node identifier
3187  * @return a node identifier for the node's bus controller
3188  */
3189 #define DT_BUS(node_id) DT_CAT(node_id, _BUS)
3190 
3191 /**
3192  * @deprecated If used to obtain a device instance with device_get_binding,
3193  * consider using @c DEVICE_DT_GET(DT_BUS(node)).
3194  *
3195  * @brief Node's bus controller's `label` property
3196  * @param node_id node identifier
3197  * @return the label property of the node's bus controller DT_BUS(node)
3198  */
3199 #define DT_BUS_LABEL(node_id) DT_PROP(DT_BUS(node_id), label) __DEPRECATED_MACRO
3200 
3201 /**
3202  * @brief Is a node on a bus of a given type?
3203  *
3204  * Example devicetree overlay:
3205  *
3206  * @code{.dts}
3207  *     &i2c0 {
3208  *            temp: temperature-sensor@76 {
3209  *                     compatible = "vnd,some-sensor";
3210  *                     reg = <0x76>;
3211  *            };
3212  *     };
3213  * @endcode
3214  *
3215  * Example usage, assuming `i2c0` is an I2C bus controller node, and
3216  * therefore `temp` is on an I2C bus:
3217  *
3218  * @code{.c}
3219  *     DT_ON_BUS(DT_NODELABEL(temp), i2c) // 1
3220  *     DT_ON_BUS(DT_NODELABEL(temp), spi) // 0
3221  * @endcode
3222  *
3223  * @param node_id node identifier
3224  * @param bus lowercase-and-underscores bus type as a C token (i.e.
3225  *            without quotes)
3226  * @return 1 if the node is on a bus of the given type,
3227  *         0 otherwise
3228  */
3229 #define DT_ON_BUS(node_id, bus) IS_ENABLED(DT_CAT3(node_id, _BUS_, bus))
3230 
3231 /**
3232  * @}
3233  */
3234 
3235 /**
3236  * @defgroup devicetree-inst Instance-based devicetree APIs
3237  * @ingroup devicetree
3238  * @{
3239  */
3240 
3241 /**
3242  * @brief Node identifier for an instance of a `DT_DRV_COMPAT` compatible
3243  * @param inst instance number
3244  * @return a node identifier for the node with `DT_DRV_COMPAT` compatible and
3245  *         instance number @p inst
3246  */
3247 #define DT_DRV_INST(inst) DT_INST(inst, DT_DRV_COMPAT)
3248 
3249 /**
3250  * @brief Get a `DT_DRV_COMPAT` parent's node identifier
3251  * @param inst instance number
3252  * @return a node identifier for the instance's parent
3253  *
3254  * @see DT_PARENT
3255  */
3256 #define DT_INST_PARENT(inst) DT_PARENT(DT_DRV_INST(inst))
3257 
3258 /**
3259  * @brief Get a `DT_DRV_COMPAT` grandparent's node identifier
3260  * @param inst instance number
3261  * @return a node identifier for the instance's grandparent
3262  *
3263  * @see DT_GPARENT
3264  */
3265 #define DT_INST_GPARENT(inst) DT_GPARENT(DT_DRV_INST(inst))
3266 
3267 /**
3268  * @brief Get a node identifier for a child node of DT_DRV_INST(inst)
3269  *
3270  * @param inst instance number
3271  * @param child lowercase-and-underscores child node name
3272  * @return node identifier for the node with the name referred to by 'child'
3273  *
3274  * @see DT_CHILD
3275  */
3276 #define DT_INST_CHILD(inst, child) \
3277 	DT_CHILD(DT_DRV_INST(inst), child)
3278 
3279 /**
3280  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst).
3281  *
3282  * The macro @p fn should take one argument, which is the node
3283  * identifier for the child node.
3284  *
3285  * The children will be iterated over in the same order as they
3286  * appear in the final devicetree.
3287  *
3288  * @param inst instance number
3289  * @param fn macro to invoke on each child node identifier
3290  *
3291  * @see DT_FOREACH_CHILD
3292  */
3293 #define DT_INST_FOREACH_CHILD(inst, fn) \
3294 	DT_FOREACH_CHILD(DT_DRV_INST(inst), fn)
3295 
3296 /**
3297  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with a separator
3298  *
3299  * The macro @p fn should take one argument, which is the node
3300  * identifier for the child node.
3301  *
3302  * @param inst instance number
3303  * @param fn macro to invoke on each child node identifier
3304  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
3305  *            this is required to enable providing a comma as separator.
3306  *
3307  * @see DT_FOREACH_CHILD_SEP
3308  */
3309 #define DT_INST_FOREACH_CHILD_SEP(inst, fn, sep) \
3310 	DT_FOREACH_CHILD_SEP(DT_DRV_INST(inst), fn, sep)
3311 
3312 /**
3313  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst).
3314  *
3315  * The macro @p fn takes multiple arguments. The first should be the node
3316  * identifier for the child node. The remaining are passed-in by the caller.
3317  *
3318  * The children will be iterated over in the same order as they
3319  * appear in the final devicetree.
3320  *
3321  * @param inst instance number
3322  * @param fn macro to invoke on each child node identifier
3323  * @param ... variable number of arguments to pass to @p fn
3324  *
3325  * @see DT_FOREACH_CHILD
3326  */
3327 #define DT_INST_FOREACH_CHILD_VARGS(inst, fn, ...) \
3328 	DT_FOREACH_CHILD_VARGS(DT_DRV_INST(inst), fn, __VA_ARGS__)
3329 
3330 /**
3331  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with separator.
3332  *
3333  * The macro @p fn takes multiple arguments. The first should be the node
3334  * identifier for the child node. The remaining are passed-in by the caller.
3335  *
3336  * @param inst instance number
3337  * @param fn macro to invoke on each child node identifier
3338  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
3339  *            this is required to enable providing a comma as separator.
3340  * @param ... variable number of arguments to pass to @p fn
3341  *
3342  * @see DT_FOREACH_CHILD_SEP_VARGS
3343  */
3344 #define DT_INST_FOREACH_CHILD_SEP_VARGS(inst, fn, sep, ...) \
3345 	DT_FOREACH_CHILD_SEP_VARGS(DT_DRV_INST(inst), fn, sep, __VA_ARGS__)
3346 
3347 /**
3348  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`.
3349  *
3350  * The macro @p fn should take one argument, which is the node
3351  * identifier for the child node.
3352  *
3353  * @param inst instance number
3354  * @param fn macro to invoke on each child node identifier
3355  *
3356  * @see DT_FOREACH_CHILD_STATUS_OKAY
3357  */
3358 #define DT_INST_FOREACH_CHILD_STATUS_OKAY(inst, fn) \
3359 	DT_FOREACH_CHILD_STATUS_OKAY(DT_DRV_INST(inst), fn)
3360 
3361 /**
3362  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`
3363  * and with separator.
3364  *
3365  * The macro @p fn should take one argument, which is the node
3366  * identifier for the child node.
3367  *
3368  * @param inst instance number
3369  * @param fn macro to invoke on each child node identifier
3370  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
3371  *            this is required to enable providing a comma as separator.
3372  *
3373  * @see DT_FOREACH_CHILD_STATUS_OKAY_SEP
3374  */
3375 #define DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(inst, fn, sep) \
3376 	DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_DRV_INST(inst), fn, sep)
3377 
3378 /**
3379  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`
3380  * and multiple arguments.
3381  *
3382  * The macro @p fn takes multiple arguments. The first should be the node
3383  * identifier for the child node. The remaining are passed-in by the caller.
3384  *
3385  * @param inst instance number
3386  * @param fn macro to invoke on each child node identifier
3387  * @param ... variable number of arguments to pass to @p fn
3388  *
3389  * @see DT_FOREACH_CHILD_STATUS_OKAY_VARGS
3390  */
3391 #define DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(inst, fn, ...) \
3392 	DT_FOREACH_CHILD_STATUS_OKAY_VARGS(DT_DRV_INST(inst), fn, __VA_ARGS__)
3393 
3394 /**
3395  * @brief Call @p fn on all child nodes of DT_DRV_INST(inst) with status `okay`
3396  * and with separator and multiple arguments.
3397  *
3398  * The macro @p fn takes multiple arguments. The first should be the node
3399  * identifier for the child node. The remaining are passed-in by the caller.
3400  *
3401  * @param inst instance number
3402  * @param fn macro to invoke on each child node identifier
3403  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
3404  *            this is required to enable providing a comma as separator.
3405  * @param ... variable number of arguments to pass to @p fn
3406  *
3407  * @see DT_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS
3408  */
3409 #define DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS(inst, fn, sep, ...) \
3410 	DT_FOREACH_CHILD_STATUS_OKAY_SEP_VARGS(DT_DRV_INST(inst), fn, sep, __VA_ARGS__)
3411 
3412 /**
3413  * @brief Get a `DT_DRV_COMPAT` value's index into its enumeration values
3414  * @param inst instance number
3415  * @param prop lowercase-and-underscores property name
3416  * @return zero-based index of the property's value in its enum: list
3417  */
3418 #define DT_INST_ENUM_IDX(inst, prop) \
3419 	DT_ENUM_IDX(DT_DRV_INST(inst), prop)
3420 
3421 /**
3422  * @brief Like DT_INST_ENUM_IDX(), but with a fallback to a default enum index
3423  * @param inst instance number
3424  * @param prop lowercase-and-underscores property name
3425  * @param default_idx_value a fallback index value to expand to
3426  * @return zero-based index of the property's value in its enum if present,
3427  *         default_idx_value otherwise
3428  */
3429 #define DT_INST_ENUM_IDX_OR(inst, prop, default_idx_value) \
3430 	DT_ENUM_IDX_OR(DT_DRV_INST(inst), prop, default_idx_value)
3431 
3432 /**
3433  * @brief Does a `DT_DRV_COMPAT` enumeration property have a given value?
3434  *
3435  * @param inst instance number
3436  * @param prop lowercase-and-underscores property name
3437  * @param value lowercase-and-underscores enumeration value
3438  * @return 1 if the node property has the value @a value, 0 otherwise.
3439  */
3440 #define DT_INST_ENUM_HAS_VALUE(inst, prop, value) \
3441 	DT_ENUM_HAS_VALUE(DT_DRV_INST(inst), prop, value)
3442 
3443 /**
3444  * @brief Get a `DT_DRV_COMPAT` instance property
3445  * @param inst instance number
3446  * @param prop lowercase-and-underscores property name
3447  * @return a representation of the property's value
3448  */
3449 #define DT_INST_PROP(inst, prop) DT_PROP(DT_DRV_INST(inst), prop)
3450 
3451 /**
3452  * @brief Get a `DT_DRV_COMPAT` property length
3453  * @param inst instance number
3454  * @param prop lowercase-and-underscores property name
3455  * @return logical length of the property
3456  */
3457 #define DT_INST_PROP_LEN(inst, prop) DT_PROP_LEN(DT_DRV_INST(inst), prop)
3458 
3459 /**
3460  * @brief Is index @p idx valid for an array type property
3461  *        on a `DT_DRV_COMPAT` instance?
3462  * @param inst instance number
3463  * @param prop lowercase-and-underscores property name
3464  * @param idx index to check
3465  * @return 1 if @p idx is a valid index into the given property,
3466  *         0 otherwise.
3467  */
3468 #define DT_INST_PROP_HAS_IDX(inst, prop, idx) \
3469 	DT_PROP_HAS_IDX(DT_DRV_INST(inst), prop, idx)
3470 
3471 /**
3472  * @brief Is name @p name available in a `foo-names` property?
3473  * @param inst instance number
3474  * @param prop a lowercase-and-underscores `prop-names` type property
3475  * @param name a lowercase-and-underscores name to check
3476  * @return An expression which evaluates to 1 if @p name is an available
3477  *         name into the given property, and 0 otherwise.
3478  */
3479 #define DT_INST_PROP_HAS_NAME(inst, prop, name) \
3480 	DT_PROP_HAS_NAME(DT_DRV_INST(inst), prop, name)
3481 
3482 /**
3483  * @brief Get a `DT_DRV_COMPAT` element value in an array property
3484  * @param inst instance number
3485  * @param prop lowercase-and-underscores property name
3486  * @param idx the index to get
3487  * @return a representation of the idx-th element of the property
3488  */
3489 #define DT_INST_PROP_BY_IDX(inst, prop, idx) \
3490 	DT_PROP_BY_IDX(DT_DRV_INST(inst), prop, idx)
3491 
3492 /**
3493  * @brief Like DT_INST_PROP(), but with a fallback to @p default_value
3494  * @param inst instance number
3495  * @param prop lowercase-and-underscores property name
3496  * @param default_value a fallback value to expand to
3497  * @return DT_INST_PROP(inst, prop) or @p default_value
3498  */
3499 #define DT_INST_PROP_OR(inst, prop, default_value) \
3500 	DT_PROP_OR(DT_DRV_INST(inst), prop, default_value)
3501 
3502 /**
3503  * @brief Like DT_INST_PROP_LEN(), but with a fallback to @p default_value
3504  * @param inst instance number
3505  * @param prop lowercase-and-underscores property name
3506  * @param default_value a fallback value to expand to
3507  * @return DT_INST_PROP_LEN(inst, prop) or @p default_value
3508  */
3509 #define DT_INST_PROP_LEN_OR(inst, prop, default_value) \
3510 	DT_PROP_LEN_OR(DT_DRV_INST(inst), prop, default_value)
3511 
3512 /**
3513  * @deprecated Use DT_INST_PROP(inst, label)
3514  * @brief Get a `DT_DRV_COMPAT` instance's `label` property
3515  * @param inst instance number
3516  * @return instance's label property value
3517  */
3518 #define DT_INST_LABEL(inst) DT_INST_PROP(inst, label) __DEPRECATED_MACRO
3519 
3520 /**
3521  * @brief Get a `DT_DRV_COMPAT` instance's string property's value as a
3522  *        token.
3523  *
3524  * @param inst instance number
3525  * @param prop lowercase-and-underscores property name
3526  * @return the value of @p prop as a token, i.e. without any quotes
3527  *         and with special characters converted to underscores
3528  */
3529 #define DT_INST_STRING_TOKEN(inst, prop) \
3530 	DT_STRING_TOKEN(DT_DRV_INST(inst), prop)
3531 
3532 /**
3533  * @brief Like DT_INST_STRING_TOKEN(), but uppercased.
3534  * @param inst instance number
3535  * @param prop lowercase-and-underscores property name
3536  * @return the value of @p prop as an uppercased token, i.e. without
3537  *         any quotes and with special characters converted to underscores
3538  */
3539 #define DT_INST_STRING_UPPER_TOKEN(inst, prop) \
3540 	DT_STRING_UPPER_TOKEN(DT_DRV_INST(inst), prop)
3541 
3542 /**
3543  * @brief Get a `DT_DRV_COMPAT` instance's string property's value as
3544  *        an unquoted sequence of tokens.
3545  *
3546  * @param inst instance number
3547  * @param prop lowercase-and-underscores property name
3548  * @return the value of @p prop as a sequence of tokens, with no quotes
3549  */
3550 #define DT_INST_STRING_UNQUOTED(inst, prop) \
3551 	DT_STRING_UNQUOTED(DT_DRV_INST(inst), prop)
3552 
3553 /**
3554  * @brief Get an element out of string-array property as a token.
3555  * @param inst instance number
3556  * @param prop lowercase-and-underscores property name
3557  * @param idx the index to get
3558  * @return the element in @p prop at index @p idx as a token
3559  */
3560 #define DT_INST_STRING_TOKEN_BY_IDX(inst, prop, idx) \
3561 	DT_STRING_TOKEN_BY_IDX(DT_DRV_INST(inst), prop, idx)
3562 
3563 /**
3564  * @brief Like DT_INST_STRING_TOKEN_BY_IDX(), but uppercased.
3565  * @param inst instance number
3566  * @param prop lowercase-and-underscores property name
3567  * @param idx the index to get
3568  * @return the element in @p prop at index @p idx as an uppercased token
3569  */
3570 #define DT_INST_STRING_UPPER_TOKEN_BY_IDX(inst, prop, idx) \
3571 	DT_STRING_UPPER_TOKEN_BY_IDX(DT_DRV_INST(inst), prop, idx)
3572 
3573 /**
3574  * @brief Get an element out of string-array property as an unquoted sequence of tokens.
3575  * @param inst instance number
3576  * @param prop lowercase-and-underscores property name
3577  * @param idx the index to get
3578  * @return the value of @p prop at index @p idx as a sequence of tokens, with no quotes
3579  */
3580 #define DT_INST_STRING_UNQUOTED_BY_IDX(inst, prop, idx) \
3581 	DT_STRING_UNQUOTED_BY_IDX(DT_DRV_INST(inst), prop, idx)
3582 
3583 /**
3584  * @brief Get a `DT_DRV_COMPAT` instance's property value from a phandle's node
3585  * @param inst instance number
3586  * @param ph lowercase-and-underscores property of @p inst
3587  *           with type `phandle`
3588  * @param prop lowercase-and-underscores property of the phandle's node
3589  * @return the value of @p prop as described in the DT_PROP() documentation
3590  */
3591 #define DT_INST_PROP_BY_PHANDLE(inst, ph, prop) \
3592 	DT_INST_PROP_BY_PHANDLE_IDX(inst, ph, 0, prop)
3593 
3594 /**
3595  * @brief Get a `DT_DRV_COMPAT` instance's property value from a phandle in a
3596  * property.
3597  * @param inst instance number
3598  * @param phs lowercase-and-underscores property with type `phandle`,
3599  *            `phandles`, or `phandle-array`
3600  * @param idx logical index into "phs", which must be zero if "phs"
3601  *            has type `phandle`
3602  * @param prop lowercase-and-underscores property of the phandle's node
3603  * @return the value of @p prop as described in the DT_PROP() documentation
3604  */
3605 #define DT_INST_PROP_BY_PHANDLE_IDX(inst, phs, idx, prop) \
3606 	DT_PROP_BY_PHANDLE_IDX(DT_DRV_INST(inst), phs, idx, prop)
3607 
3608 /**
3609  * @brief Get a `DT_DRV_COMPAT` instance's phandle-array specifier value at an index
3610  * @param inst instance number
3611  * @param pha lowercase-and-underscores property with type `phandle-array`
3612  * @param idx logical index into the property @p pha
3613  * @param cell binding's cell name within the specifier at index @p idx
3614  * @return the value of the cell inside the specifier at index @p idx
3615  */
3616 #define DT_INST_PHA_BY_IDX(inst, pha, idx, cell) \
3617 	DT_PHA_BY_IDX(DT_DRV_INST(inst), pha, idx, cell)
3618 
3619 /**
3620  * @brief Like DT_INST_PHA_BY_IDX(), but with a fallback to default_value
3621  * @param inst instance number
3622  * @param pha lowercase-and-underscores property with type `phandle-array`
3623  * @param idx logical index into the property @p pha
3624  * @param cell binding's cell name within the specifier at index @p idx
3625  * @param default_value a fallback value to expand to
3626  * @return DT_INST_PHA_BY_IDX(inst, pha, idx, cell) or default_value
3627  */
3628 #define DT_INST_PHA_BY_IDX_OR(inst, pha, idx, cell, default_value) \
3629 	DT_PHA_BY_IDX_OR(DT_DRV_INST(inst), pha, idx, cell, default_value)
3630 
3631 /**
3632  * @brief Get a `DT_DRV_COMPAT` instance's phandle-array specifier value
3633  * Equivalent to DT_INST_PHA_BY_IDX(inst, pha, 0, cell)
3634  * @param inst instance number
3635  * @param pha lowercase-and-underscores property with type `phandle-array`
3636  * @param cell binding's cell name for the specifier at @p pha index 0
3637  * @return the cell value
3638  */
3639 #define DT_INST_PHA(inst, pha, cell) DT_INST_PHA_BY_IDX(inst, pha, 0, cell)
3640 
3641 /**
3642  * @brief Like DT_INST_PHA(), but with a fallback to default_value
3643  * @param inst instance number
3644  * @param pha lowercase-and-underscores property with type `phandle-array`
3645  * @param cell binding's cell name for the specifier at @p pha index 0
3646  * @param default_value a fallback value to expand to
3647  * @return DT_INST_PHA(inst, pha, cell) or default_value
3648  */
3649 #define DT_INST_PHA_OR(inst, pha, cell, default_value) \
3650 	DT_INST_PHA_BY_IDX_OR(inst, pha, 0, cell, default_value)
3651 
3652 /**
3653  * @brief Get a `DT_DRV_COMPAT` instance's value within a phandle-array
3654  * specifier by name
3655  * @param inst instance number
3656  * @param pha lowercase-and-underscores property with type `phandle-array`
3657  * @param name lowercase-and-underscores name of a specifier in @p pha
3658  * @param cell binding's cell name for the named specifier
3659  * @return the cell value
3660  */
3661 #define DT_INST_PHA_BY_NAME(inst, pha, name, cell) \
3662 	DT_PHA_BY_NAME(DT_DRV_INST(inst), pha, name, cell)
3663 
3664 /**
3665  * @brief Like DT_INST_PHA_BY_NAME(), but with a fallback to default_value
3666  * @param inst instance number
3667  * @param pha lowercase-and-underscores property with type `phandle-array`
3668  * @param name lowercase-and-underscores name of a specifier in @p pha
3669  * @param cell binding's cell name for the named specifier
3670  * @param default_value a fallback value to expand to
3671  * @return DT_INST_PHA_BY_NAME(inst, pha, name, cell) or default_value
3672  */
3673 #define DT_INST_PHA_BY_NAME_OR(inst, pha, name, cell, default_value) \
3674 	DT_PHA_BY_NAME_OR(DT_DRV_INST(inst), pha, name, cell, default_value)
3675 
3676 /**
3677  * @brief Get a `DT_DRV_COMPAT` instance's phandle node identifier from a
3678  * phandle array by name
3679  * @param inst instance number
3680  * @param pha lowercase-and-underscores property with type `phandle-array`
3681  * @param name lowercase-and-underscores name of an element in @p pha
3682  * @return node identifier for the phandle at the element named "name"
3683  */
3684 #define DT_INST_PHANDLE_BY_NAME(inst, pha, name) \
3685 	DT_PHANDLE_BY_NAME(DT_DRV_INST(inst), pha, name) \
3686 
3687 /**
3688  * @brief Get a `DT_DRV_COMPAT` instance's node identifier for a phandle in
3689  * a property.
3690  * @param inst instance number
3691  * @param prop lowercase-and-underscores property name in @p inst
3692  *             with type `phandle`, `phandles` or `phandle-array`
3693  * @param idx index into @p prop
3694  * @return a node identifier for the phandle at index @p idx in @p prop
3695  */
3696 #define DT_INST_PHANDLE_BY_IDX(inst, prop, idx) \
3697 	DT_PHANDLE_BY_IDX(DT_DRV_INST(inst), prop, idx)
3698 
3699 /**
3700  * @brief Get a `DT_DRV_COMPAT` instance's node identifier for a phandle
3701  * property's value
3702  * @param inst instance number
3703  * @param prop lowercase-and-underscores property of @p inst
3704  *             with type `phandle`
3705  * @return a node identifier for the node pointed to by "ph"
3706  */
3707 #define DT_INST_PHANDLE(inst, prop) DT_INST_PHANDLE_BY_IDX(inst, prop, 0)
3708 
3709 /**
3710  * @brief is @p idx a valid register block index on a `DT_DRV_COMPAT` instance?
3711  * @param inst instance number
3712  * @param idx index to check
3713  * @return 1 if @p idx is a valid register block index,
3714  *         0 otherwise.
3715  */
3716 #define DT_INST_REG_HAS_IDX(inst, idx) DT_REG_HAS_IDX(DT_DRV_INST(inst), idx)
3717 
3718 /**
3719  * @brief Get a `DT_DRV_COMPAT` instance's idx-th register block's address
3720  * @param inst instance number
3721  * @param idx index of the register whose address to return
3722  * @return address of the instance's idx-th register block
3723  */
3724 #define DT_INST_REG_ADDR_BY_IDX(inst, idx) DT_REG_ADDR_BY_IDX(DT_DRV_INST(inst), idx)
3725 
3726 /**
3727  * @brief Get a `DT_DRV_COMPAT` instance's idx-th register block's size
3728  * @param inst instance number
3729  * @param idx index of the register whose size to return
3730  * @return size of the instance's idx-th register block
3731  */
3732 #define DT_INST_REG_SIZE_BY_IDX(inst, idx) \
3733 	DT_REG_SIZE_BY_IDX(DT_DRV_INST(inst), idx)
3734 
3735 /**
3736  * @brief Get a `DT_DRV_COMPAT`'s register block address by  name
3737  * @param inst instance number
3738  * @param name lowercase-and-underscores register specifier name
3739  * @return address of the register block with the given @p name
3740  */
3741 #define DT_INST_REG_ADDR_BY_NAME(inst, name) \
3742 	DT_REG_ADDR_BY_NAME(DT_DRV_INST(inst), name)
3743 
3744 /**
3745  * @brief 64-bit version of DT_INST_REG_ADDR_BY_NAME()
3746  *
3747  * This macro version adds the appropriate suffix for 64-bit unsigned
3748  * integer literals.
3749  * Note that this macro is equivalent to DT_INST_REG_ADDR_BY_NAME() in
3750  * linker/ASM context.
3751  *
3752  * @param inst instance number
3753  * @param name lowercase-and-underscores register specifier name
3754  * @return address of the register block with the given @p name
3755  */
3756 #define DT_INST_REG_ADDR_BY_NAME_U64(inst, name) \
3757 	DT_U64_C(DT_INST_REG_ADDR_BY_NAME(inst, name))
3758 
3759 /**
3760  * @brief Get a `DT_DRV_COMPAT`'s register block size by name
3761  * @param inst instance number
3762  * @param name lowercase-and-underscores register specifier name
3763  * @return size of the register block with the given @p name
3764  */
3765 #define DT_INST_REG_SIZE_BY_NAME(inst, name) \
3766 	DT_REG_SIZE_BY_NAME(DT_DRV_INST(inst), name)
3767 
3768 /**
3769  * @brief Get a `DT_DRV_COMPAT`'s (only) register block address
3770  * @param inst instance number
3771  * @return instance's register block address
3772  */
3773 #define DT_INST_REG_ADDR(inst) DT_INST_REG_ADDR_BY_IDX(inst, 0)
3774 
3775 /**
3776  * @brief 64-bit version of DT_INST_REG_ADDR()
3777  *
3778  * This macro version adds the appropriate suffix for 64-bit unsigned
3779  * integer literals.
3780  * Note that this macro is equivalent to DT_INST_REG_ADDR() in
3781  * linker/ASM context.
3782  *
3783  * @param inst instance number
3784  * @return instance's register block address
3785  */
3786 #define DT_INST_REG_ADDR_U64(inst) DT_U64_C(DT_INST_REG_ADDR(inst))
3787 
3788 /**
3789  * @brief Get a `DT_DRV_COMPAT`'s (only) register block size
3790  * @param inst instance number
3791  * @return instance's register block size
3792  */
3793 #define DT_INST_REG_SIZE(inst) DT_INST_REG_SIZE_BY_IDX(inst, 0)
3794 
3795 /**
3796  * @brief Get a `DT_DRV_COMPAT` interrupt specifier value at an index
3797  * @param inst instance number
3798  * @param idx logical index into the interrupt specifier array
3799  * @param cell cell name specifier
3800  * @return the named value at the specifier given by the index
3801  */
3802 #define DT_INST_IRQ_BY_IDX(inst, idx, cell) \
3803 	DT_IRQ_BY_IDX(DT_DRV_INST(inst), idx, cell)
3804 
3805 /**
3806  * @brief Get a `DT_DRV_COMPAT` interrupt specifier value by name
3807  * @param inst instance number
3808  * @param name lowercase-and-underscores interrupt specifier name
3809  * @param cell cell name specifier
3810  * @return the named value at the specifier given by the index
3811  */
3812 #define DT_INST_IRQ_BY_NAME(inst, name, cell) \
3813 	DT_IRQ_BY_NAME(DT_DRV_INST(inst), name, cell)
3814 
3815 /**
3816  * @brief Get a `DT_DRV_COMPAT` interrupt specifier's value
3817  * @param inst instance number
3818  * @param cell cell name specifier
3819  * @return the named value at that index
3820  */
3821 #define DT_INST_IRQ(inst, cell) DT_INST_IRQ_BY_IDX(inst, 0, cell)
3822 
3823 /**
3824  * @brief Get a `DT_DRV_COMPAT`'s (only) irq number
3825  * @param inst instance number
3826  * @return the interrupt number for the node's only interrupt
3827  */
3828 #define DT_INST_IRQN(inst) DT_INST_IRQ(inst, irq)
3829 
3830 /**
3831  * @brief Get a `DT_DRV_COMPAT`'s bus node identifier
3832  * @param inst instance number
3833  * @return node identifier for the instance's bus node
3834  */
3835 #define DT_INST_BUS(inst) DT_BUS(DT_DRV_INST(inst))
3836 
3837 /**
3838  * @deprecated If used to obtain a device instance with device_get_binding,
3839  * consider using @c DEVICE_DT_GET(DT_INST_BUS(inst)).
3840  *
3841  * @brief Get a `DT_DRV_COMPAT`'s bus node's label property
3842  * @param inst instance number
3843  * @return the label property of the instance's bus controller
3844  */
3845 #define DT_INST_BUS_LABEL(inst) DT_BUS_LABEL(DT_DRV_INST(inst)) __DEPRECATED_MACRO
3846 
3847 /**
3848  * @brief Test if a `DT_DRV_COMPAT`'s bus type is a given type
3849  * @param inst instance number
3850  * @param bus a binding's bus type as a C token, lowercased and without quotes
3851  * @return 1 if the given instance is on a bus of the given type,
3852  *         0 otherwise
3853  */
3854 #define DT_INST_ON_BUS(inst, bus) DT_ON_BUS(DT_DRV_INST(inst), bus)
3855 
3856 /**
3857  * @brief Like DT_INST_STRING_TOKEN(), but with a fallback to @p default_value
3858  * @param inst instance number
3859  * @param name lowercase-and-underscores property name
3860  * @param default_value a fallback value to expand to
3861  * @return if @p prop exists, its value as a token, i.e. without any quotes and
3862  *         with special characters converted to underscores. Othewise
3863  *         @p default_value
3864  */
3865 #define DT_INST_STRING_TOKEN_OR(inst, name, default_value) \
3866 	DT_STRING_TOKEN_OR(DT_DRV_INST(inst), name, default_value)
3867 
3868 /**
3869  * @brief Like DT_INST_STRING_UPPER_TOKEN(), but with a fallback to
3870  *        @p default_value
3871  * @param inst instance number
3872  * @param name lowercase-and-underscores property name
3873  * @param default_value a fallback value to expand to
3874  * @return the property's value as an uppercased token, or @p default_value
3875  */
3876 #define DT_INST_STRING_UPPER_TOKEN_OR(inst, name, default_value) \
3877 	DT_STRING_UPPER_TOKEN_OR(DT_DRV_INST(inst), name, default_value)
3878 
3879 /**
3880  * @brief Like DT_INST_STRING_UNQUOTED(), but with a fallback to
3881  *        @p default_value
3882  * @param inst instance number
3883  * @param name lowercase-and-underscores property name
3884  * @param default_value a fallback value to expand to
3885  * @return the property's value as a sequence of tokens, with no quotes, or @p default_value
3886  */
3887 #define DT_INST_STRING_UNQUOTED_OR(inst, name, default_value) \
3888 	DT_STRING_UNQUOTED_OR(DT_DRV_INST(inst), name, default_value)
3889 
3890 /*
3891  * @brief Test if any enabled node with the given compatible is on
3892  *        the given bus type
3893  *
3894  * This is like DT_ANY_INST_ON_BUS_STATUS_OKAY(), except it can also
3895  * be useful for handling multiple compatibles in single source file.
3896  *
3897  * Example devicetree overlay:
3898  *
3899  * @code{.dts}
3900  *     &i2c0 {
3901  *            temp: temperature-sensor@76 {
3902  *                     compatible = "vnd,some-sensor";
3903  *                     reg = <0x76>;
3904  *            };
3905  *     };
3906  * @endcode
3907  *
3908  * Example usage, assuming `i2c0` is an I2C bus controller node, and
3909  * therefore `temp` is on an I2C bus:
3910  *
3911  * @code{.c}
3912  *     DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(vnd_some_sensor, i2c) // 1
3913  * @endcode
3914  *
3915  * @param compat lowercase-and-underscores compatible, without quotes
3916  * @param bus a binding's bus type as a C token, lowercased and without quotes
3917  * @return 1 if any enabled node with that compatible is on that bus type,
3918  *         0 otherwise
3919  */
3920 #define DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(compat, bus) \
3921 	IS_ENABLED(UTIL_CAT(DT_CAT(DT_COMPAT_, compat), _BUS_##bus))
3922 
3923 /**
3924  * @brief Test if any `DT_DRV_COMPAT` node is on a bus of a given type
3925  *        and has status okay
3926  *
3927  * This is a special-purpose macro which can be useful when writing
3928  * drivers for devices which can appear on multiple buses. One example
3929  * is a sensor device which may be wired on an I2C or SPI bus.
3930  *
3931  * Example devicetree overlay:
3932  *
3933  * @code{.dts}
3934  *     &i2c0 {
3935  *            temp: temperature-sensor@76 {
3936  *                     compatible = "vnd,some-sensor";
3937  *                     reg = <0x76>;
3938  *            };
3939  *     };
3940  * @endcode
3941  *
3942  * Example usage, assuming `i2c0` is an I2C bus controller node, and
3943  * therefore `temp` is on an I2C bus:
3944  *
3945  * @code{.c}
3946  *     #define DT_DRV_COMPAT vnd_some_sensor
3947  *
3948  *     DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) // 1
3949  * @endcode
3950  *
3951  * @param bus a binding's bus type as a C token, lowercased and without quotes
3952  * @return 1 if any enabled node with that compatible is on that bus type,
3953  *         0 otherwise
3954  */
3955 #define DT_ANY_INST_ON_BUS_STATUS_OKAY(bus) \
3956 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(DT_DRV_COMPAT, bus)
3957 
3958 /**
3959  * @brief Check if any `DT_DRV_COMPAT` node with status `okay` has a given
3960  *        property.
3961  *
3962  * @param prop lowercase-and-underscores property name
3963  *
3964  * Example devicetree overlay:
3965  *
3966  * @code{.dts}
3967  *     &i2c0 {
3968  *         sensor0: sensor@0 {
3969  *             compatible = "vnd,some-sensor";
3970  *             status = "okay";
3971  *             reg = <0>;
3972  *             foo = <1>;
3973  *             bar = <2>;
3974  *         };
3975  *
3976  *         sensor1: sensor@1 {
3977  *             compatible = "vnd,some-sensor";
3978  *             status = "okay";
3979  *             reg = <1>;
3980  *             foo = <2>;
3981  *         };
3982  *
3983  *         sensor2: sensor@2 {
3984  *             compatible = "vnd,some-sensor";
3985  *             status = "disabled";
3986  *             reg = <2>;
3987  *             baz = <1>;
3988  *         };
3989  *     };
3990  * @endcode
3991  *
3992  * Example usage:
3993  *
3994  * @code{.c}
3995  *     #define DT_DRV_COMPAT vnd_some_sensor
3996  *
3997  *     DT_ANY_INST_HAS_PROP_STATUS_OKAY(foo) // 1
3998  *     DT_ANY_INST_HAS_PROP_STATUS_OKAY(bar) // 1
3999  *     DT_ANY_INST_HAS_PROP_STATUS_OKAY(baz) // 0
4000  * @endcode
4001  */
4002 #define DT_ANY_INST_HAS_PROP_STATUS_OKAY(prop) \
4003 	(DT_INST_FOREACH_STATUS_OKAY_VARGS(DT_INST_NODE_HAS_PROP_AND_OR, prop) 0)
4004 
4005 /**
4006  * @brief Call @p fn on all nodes with compatible `DT_DRV_COMPAT`
4007  *        and status `okay`
4008  *
4009  * This macro calls `fn(inst)` on each `inst` number that refers to a
4010  * node with status `okay`. Whitespace is added between invocations.
4011  *
4012  * Example devicetree fragment:
4013  *
4014  * @code{.dts}
4015  *     a {
4016  *             compatible = "vnd,device";
4017  *             status = "okay";
4018  *             foobar = "DEV_A";
4019  *     };
4020  *
4021  *     b {
4022  *             compatible = "vnd,device";
4023  *             status = "okay";
4024  *             foobar = "DEV_B";
4025  *     };
4026  *
4027  *     c {
4028  *             compatible = "vnd,device";
4029  *             status = "disabled";
4030  *             foobar = "DEV_C";
4031  *     };
4032  * @endcode
4033  *
4034  * Example usage:
4035  *
4036  * @code{.c}
4037  *     #define DT_DRV_COMPAT vnd_device
4038  *     #define MY_FN(inst) DT_INST_PROP(inst, foobar),
4039  *
4040  *     DT_INST_FOREACH_STATUS_OKAY(MY_FN)
4041  * @endcode
4042  *
4043  * This expands to:
4044  *
4045  * @code{.c}
4046  *     MY_FN(0) MY_FN(1)
4047  * @endcode
4048  *
4049  * and from there, to either this:
4050  *
4051  *     "DEV_A", "DEV_B",
4052  *
4053  * or this:
4054  *
4055  *     "DEV_B", "DEV_A",
4056  *
4057  * No guarantees are made about the order that a and b appear in the
4058  * expansion.
4059  *
4060  * Note that @p fn is responsible for adding commas, semicolons, or
4061  * other separators or terminators.
4062  *
4063  * Device drivers should use this macro whenever possible to
4064  * instantiate a struct device for each enabled node in the devicetree
4065  * of the driver's compatible `DT_DRV_COMPAT`.
4066  *
4067  * @param fn Macro to call for each enabled node. Must accept an
4068  *           instance number as its only parameter.
4069  */
4070 #define DT_INST_FOREACH_STATUS_OKAY(fn) \
4071 	COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT),	\
4072 		    (UTIL_CAT(DT_FOREACH_OKAY_INST_,		\
4073 			      DT_DRV_COMPAT)(fn)),		\
4074 		    ())
4075 
4076 /**
4077  * @brief Call @p fn on all nodes with compatible `DT_DRV_COMPAT`
4078  *        and status `okay` with multiple arguments
4079  *
4080  *
4081  * @param fn Macro to call for each enabled node. Must accept an
4082  *           instance number as its only parameter.
4083  * @param ... variable number of arguments to pass to @p fn
4084  *
4085  * @see DT_INST_FOREACH_STATUS_OKAY
4086  */
4087 #define DT_INST_FOREACH_STATUS_OKAY_VARGS(fn, ...) \
4088 	COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT),	\
4089 		    (UTIL_CAT(DT_FOREACH_OKAY_INST_VARGS_,	\
4090 			      DT_DRV_COMPAT)(fn, __VA_ARGS__)),	\
4091 		    ())
4092 
4093 /**
4094  * @brief Invokes @p fn for each element of property @p prop for
4095  *        a `DT_DRV_COMPAT` instance.
4096  *
4097  * Equivalent to DT_FOREACH_PROP_ELEM(DT_DRV_INST(inst), prop, fn).
4098  *
4099  * @param inst instance number
4100  * @param prop lowercase-and-underscores property name
4101  * @param fn macro to invoke
4102  */
4103 #define DT_INST_FOREACH_PROP_ELEM(inst, prop, fn) \
4104 	DT_FOREACH_PROP_ELEM(DT_DRV_INST(inst), prop, fn)
4105 
4106 /**
4107  * @brief Invokes @p fn for each element of property @p prop for
4108  *        a `DT_DRV_COMPAT` instance with a separator.
4109  *
4110  * Equivalent to DT_FOREACH_PROP_ELEM_SEP(DT_DRV_INST(inst), prop, fn, sep).
4111  *
4112  * @param inst instance number
4113  * @param prop lowercase-and-underscores property name
4114  * @param fn macro to invoke
4115  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
4116  *            this is required to enable providing a comma as separator.
4117  */
4118 #define DT_INST_FOREACH_PROP_ELEM_SEP(inst, prop, fn, sep) \
4119 	DT_FOREACH_PROP_ELEM_SEP(DT_DRV_INST(inst), prop, fn, sep)
4120 
4121 /**
4122  * @brief Invokes @p fn for each element of property @p prop for
4123  *        a `DT_DRV_COMPAT` instance with multiple arguments.
4124  *
4125  * Equivalent to
4126  *      DT_FOREACH_PROP_ELEM_VARGS(DT_DRV_INST(inst), prop, fn, __VA_ARGS__)
4127  *
4128  * @param inst instance number
4129  * @param prop lowercase-and-underscores property name
4130  * @param fn macro to invoke
4131  * @param ... variable number of arguments to pass to @p fn
4132  *
4133  * @see DT_INST_FOREACH_PROP_ELEM
4134  */
4135 #define DT_INST_FOREACH_PROP_ELEM_VARGS(inst, prop, fn, ...) \
4136 	DT_FOREACH_PROP_ELEM_VARGS(DT_DRV_INST(inst), prop, fn, __VA_ARGS__)
4137 
4138 /**
4139  * @brief Invokes @p fn for each element of property @p prop for
4140  *        a `DT_DRV_COMPAT` instance with multiple arguments and a sepatator.
4141  *
4142  * Equivalent to
4143  *      DT_FOREACH_PROP_ELEM_SEP_VARGS(DT_DRV_INST(inst), prop, fn, sep,
4144  *                                     __VA_ARGS__)
4145  *
4146  * @param inst instance number
4147  * @param prop lowercase-and-underscores property name
4148  * @param fn macro to invoke
4149  * @param sep Separator (e.g. comma or semicolon). Must be in parentheses;
4150  *            this is required to enable providing a comma as separator.
4151  * @param ... variable number of arguments to pass to fn
4152  *
4153  * @see DT_INST_FOREACH_PROP_ELEM
4154  */
4155 #define DT_INST_FOREACH_PROP_ELEM_SEP_VARGS(inst, prop, fn, sep, ...)		\
4156 	DT_FOREACH_PROP_ELEM_SEP_VARGS(DT_DRV_INST(inst), prop, fn, sep,	\
4157 				       __VA_ARGS__)
4158 
4159 /**
4160  * @brief Does a DT_DRV_COMPAT instance have a property?
4161  * @param inst instance number
4162  * @param prop lowercase-and-underscores property name
4163  * @return 1 if the instance has the property, 0 otherwise.
4164  */
4165 #define DT_INST_NODE_HAS_PROP(inst, prop) \
4166 	DT_NODE_HAS_PROP(DT_DRV_INST(inst), prop)
4167 
4168 /**
4169  * @brief Does a phandle array have a named cell specifier at an index
4170  *        for a `DT_DRV_COMPAT` instance?
4171  * @param inst instance number
4172  * @param pha lowercase-and-underscores property with type `phandle-array`
4173  * @param idx index to check
4174  * @param cell named cell value whose existence to check
4175  * @return 1 if the named @p cell exists in the specifier at index @p idx,
4176  *         0 otherwise.
4177  */
4178 #define DT_INST_PHA_HAS_CELL_AT_IDX(inst, pha, idx, cell) \
4179 	DT_PHA_HAS_CELL_AT_IDX(DT_DRV_INST(inst), pha, idx, cell)
4180 
4181 /**
4182  * @brief Does a phandle array have a named cell specifier at index 0
4183  *        for a `DT_DRV_COMPAT` instance?
4184  * @param inst instance number
4185  * @param pha lowercase-and-underscores property with type `phandle-array`
4186  * @param cell named cell value whose existence to check
4187  * @return 1 if the named @p cell exists in the specifier at index 0,
4188  *         0 otherwise.
4189  */
4190 #define DT_INST_PHA_HAS_CELL(inst, pha, cell) \
4191 	DT_INST_PHA_HAS_CELL_AT_IDX(inst, pha, 0, cell)
4192 
4193 /**
4194  * @brief is index valid for interrupt property on a `DT_DRV_COMPAT` instance?
4195  * @param inst instance number
4196  * @param idx logical index into the interrupt specifier array
4197  * @return 1 if the @p idx is valid for the interrupt property
4198  *         0 otherwise.
4199  */
4200 #define DT_INST_IRQ_HAS_IDX(inst, idx) DT_IRQ_HAS_IDX(DT_DRV_INST(inst), idx)
4201 
4202 /**
4203  * @brief Does a `DT_DRV_COMPAT` instance have an interrupt named cell specifier?
4204  * @param inst instance number
4205  * @param idx index to check
4206  * @param cell named cell value whose existence to check
4207  * @return 1 if the named @p cell exists in the interrupt specifier at index
4208  *         @p idx 0 otherwise.
4209  */
4210 #define DT_INST_IRQ_HAS_CELL_AT_IDX(inst, idx, cell) \
4211 	DT_IRQ_HAS_CELL_AT_IDX(DT_DRV_INST(inst), idx, cell)
4212 
4213 /**
4214  * @brief Does a `DT_DRV_COMPAT` instance have an interrupt value?
4215  * @param inst instance number
4216  * @param cell named cell value whose existence to check
4217  * @return 1 if the named @p cell exists in the interrupt specifier at index 0
4218  *         0 otherwise.
4219  */
4220 #define DT_INST_IRQ_HAS_CELL(inst, cell) \
4221 	DT_INST_IRQ_HAS_CELL_AT_IDX(inst, 0, cell)
4222 
4223 /**
4224  * @brief Does a `DT_DRV_COMPAT` instance have an interrupt value?
4225  * @param inst instance number
4226  * @param name lowercase-and-underscores interrupt specifier name
4227  * @return 1 if @p name is a valid named specifier
4228  */
4229 #define DT_INST_IRQ_HAS_NAME(inst, name) \
4230 	DT_IRQ_HAS_NAME(DT_DRV_INST(inst), name)
4231 
4232 /**
4233  * @}
4234  */
4235 
4236 /** @cond INTERNAL_HIDDEN */
4237 
4238 #define DT_PATH_INTERNAL(...) \
4239 	UTIL_CAT(DT_ROOT, MACRO_MAP_CAT(DT_S_PREFIX, __VA_ARGS__))
4240 /** @brief DT_PATH_INTERNAL() helper: prepends _S_ to a node name
4241  * We don't want to expand 'name' recursively before expansion
4242  * in this case. The MACRO_MAP_CAT above is giving us the exact
4243  * tokens it wants prefixed with _S_.
4244  */
4245 #define DT_S_PREFIX(name) _S_##name
4246 
4247 /**
4248  * @brief Concatenation helper, 2 arguments
4249  *
4250  * This and the following macros are used to paste things together
4251  * with "##" *after* forcing expansion on each argument.
4252  *
4253  * We could try to use something like UTIL_CAT(), but the compiler
4254  * error messages from the util macros can be extremely long when they
4255  * are misused. This unfortunately happens often with devicetree.h,
4256  * since its macro-based API is fiddly and can be hard to get right.
4257  *
4258  * Keeping things brutally simple here hopefully makes some errors
4259  * easier to read.
4260  */
4261 #define DT_CAT(a1, a2) a1 ## a2
4262 /** @brief Concatenation helper, 3 arguments */
4263 #define DT_CAT3(a1, a2, a3) a1 ## a2 ## a3
4264 /** @brief Concatenation helper, 4 arguments */
4265 #define DT_CAT4(a1, a2, a3, a4) a1 ## a2 ## a3 ## a4
4266 /** @brief Internal concatenation helper, 5 arguments */
4267 #define DT_CAT5(a1, a2, a3, a4, a5) a1 ## a2 ## a3 ## a4 ## a5
4268 /** @brief Concatenation helper, 6 arguments */
4269 #define DT_CAT6(a1, a2, a3, a4, a5, a6) a1 ## a2 ## a3 ## a4 ## a5 ## a6
4270 /** @brief concatenation helper, 7 arguments */
4271 #define DT_CAT7(a1, a2, a3, a4, a5, a6, a7) \
4272 	a1 ## a2 ## a3 ## a4 ## a5 ## a6 ## a7
4273 /** @brief concatenation helper, 8 arguments */
4274 #define DT_CAT8(a1, a2, a3, a4, a5, a6, a7, a8) \
4275 	a1 ## a2 ## a3 ## a4 ## a5 ## a6 ## a7 ## a8
4276 /*
4277  * If you need to define a bigger DT_CATN(), do so here. Don't leave
4278  * any "holes" of undefined macros, please.
4279  */
4280 
4281 /** @brief Helper for node identifier macros to expand args */
4282 #define DT_DASH(...) MACRO_MAP_CAT(DT_DASH_PREFIX, __VA_ARGS__)
4283 /** @brief Helper for DT_DASH(): prepends _ to a name */
4284 #define DT_DASH_PREFIX(name) _##name
4285 /** @brief Helper for DT_NODE_HAS_STATUS */
4286 #define DT_NODE_HAS_STATUS_INTERNAL(node_id, status) \
4287 	IS_ENABLED(DT_CAT3(node_id, _STATUS_, status))
4288 
4289 /** @brief Helper macro to OR multiple has property checks in a loop macro */
4290 #define DT_INST_NODE_HAS_PROP_AND_OR(inst, prop) \
4291 	DT_INST_NODE_HAS_PROP(inst, prop) ||
4292 
4293 /**
4294  * @def DT_U64_C
4295  * @brief Macro to add ULL postfix to the devicetree address constants
4296  */
4297 #if defined(_LINKER) || defined(_ASMLANGUAGE)
4298 #define DT_U64_C(_v) (_v)
4299 #else
4300 #define DT_U64_C(_v) UINT64_C(_v)
4301 #endif
4302 
4303 /** @endcond */
4304 
4305 /* have these last so they have access to all previously defined macros */
4306 #include <zephyr/devicetree/io-channels.h>
4307 #include <zephyr/devicetree/clocks.h>
4308 #include <zephyr/devicetree/gpio.h>
4309 #include <zephyr/devicetree/spi.h>
4310 #include <zephyr/devicetree/dma.h>
4311 #include <zephyr/devicetree/pwms.h>
4312 #include <zephyr/devicetree/fixed-partitions.h>
4313 #include <zephyr/devicetree/ordinals.h>
4314 #include <zephyr/devicetree/pinctrl.h>
4315 #include <zephyr/devicetree/can.h>
4316 #include <zephyr/devicetree/reset.h>
4317 #include <zephyr/devicetree/mbox.h>
4318 
4319 #endif /* DEVICETREE_H */
4320