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