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