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