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