doc: some devicetree fixes and updates
Some updates to the reference page for the "core" APIs, and associated
follow-ups in the guides:
- centralize documentation of chosen zephyr nodes in a non-legacy
file, provide a reference to them from the intro page in the guide
- review doxygen docstrings and correct errors for generic APIs
- add introductory text to each section in the API reference
- add missing hardware-specific pages
Documentation for layers built on top of these is mostly left to future
commits, but I do have a smattering of fixes in the guides that I
noticed while I was doing this.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
diff --git a/doc/guides/dts/bindings.rst b/doc/guides/dts/bindings.rst
index 19d2a91..c718e7a 100644
--- a/doc/guides/dts/bindings.rst
+++ b/doc/guides/dts/bindings.rst
@@ -148,4 +148,6 @@
- cells
The legacy syntax is still supported for backwards compatibility, but generates
-deprecation warnings. Support will be dropped in the Zephyr 2.3 release.
+deprecation warnings. Support for the legacy bindings syntax was originally
+scheduled to be dropped in the Zephyr 2.3 release, but will now be maintained
+until Zephyr 2.4.
diff --git a/doc/guides/dts/howtos.rst b/doc/guides/dts/howtos.rst
index f0702d6..441cb3f 100644
--- a/doc/guides/dts/howtos.rst
+++ b/doc/guides/dts/howtos.rst
@@ -168,9 +168,9 @@
***********************
Devicetree overlays are explained in :ref:`devicetree-intro`. The CMake
-variable :makevar:`DTC_OVERLAY_FILE` contains a space- or colon-separated list
-of overlays. If :makevar:`DTC_OVERLAY_FILE` specifies multiple files, they are
-included in that order by the C preprocessor.
+variable :makevar:`DTC_OVERLAY_FILE` contains a space- or semicolon-separated
+list of overlays. If :makevar:`DTC_OVERLAY_FILE` specifies multiple files, they
+are included in that order by the C preprocessor.
Here are some ways to set it:
@@ -676,7 +676,7 @@
==========================
If the build fails to :ref:`dts-find-binding` for a node, then either the
-node's ``compatible`` property is missing, or its value has no matching
+node's ``compatible`` property is not defined, or its value has no matching
binding. If the property is set, check for typos in its name. In a devicetree
source file, ``compatible`` should look like ``"vnd,some-device"`` --
:ref:`dt-use-the-right-names`.
diff --git a/doc/guides/dts/intro.rst b/doc/guides/dts/intro.rst
index 1f6aa2d..1264cdd 100644
--- a/doc/guides/dts/intro.rst
+++ b/doc/guides/dts/intro.rst
@@ -247,7 +247,8 @@
``fixed-clock`` when the hardware's behavior is generic.
The build system uses the compatible property to find the right
- :ref:`bindings <dt-bindings>` for the node.
+ :ref:`bindings <dt-bindings>` for the node. Within Zephyr's bindings
+ syntax, this property has type ``string-array``.
label
The device's name according to Zephyr's :ref:`device_model_api`. The value
@@ -281,6 +282,22 @@
property can be seen as a more detailed view of the addressable resources
within a device than its unit address.
+status
+ A string which describes whether the node is enabled.
+
+ The devicetree specification allows this property to have values
+ ``"okay"``, ``"disabled"``, ``"reserved"``, ``"fail"``, and ``"fail-sss"``.
+ Only the values ``"okay"`` and ``"disabled"`` are currently relevant to
+ Zephyr; use of other values currently results in undefined behavior.
+
+ A node is considered enabled if its status property is either ``"okay"`` or
+ not defined (i.e. does not exist in the devicetree source). Nodes with
+ status ``"disabled"`` are explicitly disabled. (For backwards
+ compatibility, the value ``"ok"`` is treated the same as ``"okay"``, but
+ this usage is deprecated.) Devicetree nodes which correspond to physical
+ devices must be enabled for the corresponding ``struct device`` in the
+ Zephyr driver model to be allocated and initialized.
+
interrupts
Information about interrupts generated by the device, encoded as an array
of one or more *interrupt specifiers*. Each interrupt specifier has some
@@ -290,6 +307,13 @@
Zephyr's devicetree bindings language lets you give a name to each cell in
an interrupt specifier.
+Chosen nodes
+************
+
+The devicetree may contain a special node with path ``/chosen``. This node does
+not refer to an actual device; its properties are used to configure system- or
+subsystem-wide values. See :ref:`devicetree-chosen-nodes` for more information.
+
.. _devicetree-in-out-files:
Input and output files
diff --git a/doc/reference/devicetree/index.rst b/doc/reference/devicetree/index.rst
index 1181d80..b53bf33 100644
--- a/doc/reference/devicetree/index.rst
+++ b/doc/reference/devicetree/index.rst
@@ -9,46 +9,113 @@
Some of these require a special macro named ``DT_DRV_COMPAT`` to be defined
before they can be used; these are discussed individually below. These macros
-are generally meant for use within device drivers.
+are generally meant for use within :ref:`device drivers <device_model_api>`,
+though they can be used outside of drivers with appropriate care.
.. _devicetree-generic-apis:
Generic APIs
************
-These APIs can be used anywhere.
+The APIs in this section can be used anywhere and do not require
+``DT_DRV_COMPAT`` to be defined.
Node identifiers
================
-You can use node identifiers for devicetree nodes which are enabled (i.e. have
-``status = "okay";`` properties) and have matching compatibles. This can be
-tested with :c:func:`DT_NODE_HAS_STATUS`.
+A *node identifier* is a way to refer to a devicetree node at C preprocessor
+time. While node identifiers are not C values, you can use them to access
+devicetree data in C rvalue form using, for example, the
+:ref:`devicetree-property-access` API.
+
+The root node ``/`` has node identifier ``DT_ROOT``. You can create node
+identifiers for other devicetree nodes using :c:func:`DT_PATH`,
+:c:func:`DT_NODELABEL`, :c:func:`DT_ALIAS`, and :c:func:`DT_INST`.
+
+There are also :c:func:`DT_PARENT` and :c:func:`DT_CHILD` macros which can be
+used to create node identifiers for a given node's parent node or a particular
+child node, respectively.
.. doxygengroup:: devicetree-generic-id
:project: Zephyr
+.. _devicetree-property-access:
+
Property access
===============
+The following general-purpose macros can be used to access node properties.
+There are special-purpose APIs for accessing the :ref:`devicetree-reg-property`
+and :ref:`devicetree-interrupts-property`.
+
+Property values can be read using these macros even if the node is disabled,
+as long as it has a matching binding.
+
.. doxygengroup:: devicetree-generic-prop
:project: Zephyr
-Chosen nodes
-============
+.. _devicetree-reg-property:
-.. doxygengroup:: devicetree-generic-chosen
+``reg`` property
+================
+
+Use these APIs instead of :ref:`devicetree-property-access` to access the
+``reg`` property. Because this property's semantics are defined by the
+devicetree specification, these macros can be used even for nodes without
+matching bindings.
+
+.. doxygengroup:: devicetree-reg-prop
+ :project: Zephyr
+
+.. _devicetree-interrupts-property:
+
+``interrupts`` property
+=======================
+
+Use these APIs instead of :ref:`devicetree-property-access` to access the
+``interrupts`` property.
+
+Because this property's semantics are defined by the devicetree specification,
+some of these macros can be used even for nodes without matching bindings. This
+does not apply to macros which take cell names as arguments.
+
+.. doxygengroup:: devicetree-interrupts-prop
+ :project: Zephyr
+
+For-each macros
+===============
+
+There is currently only one "generic" for-each macro,
+:c:func:`DT_FOREACH_CHILD`, which allows iterating over the children of a
+devicetree node.
+
+There are special-purpose for-each macros, like
+:c:func:`DT_INST_FOREACH_STATUS_OKAY`, but these require ``DT_DRV_COMPAT`` to
+be defined before use.
+
+.. doxygengroup:: devicetree-generic-foreach
:project: Zephyr
Existence checks
================
+This section documents miscellaneous macros that can be used to test if a node
+exists, how many nodes of a certain type exist, whether a node has certain
+properties, etc. Some macros used for special purposes (such as
+:c:func:`DT_IRQ_HAS_IDX` and all macros which require ``DT_DRV_COMPAT``) are
+documented elsewhere on this page.
+
.. doxygengroup:: devicetree-generic-exist
:project: Zephyr
Bus helpers
===========
+Zephyr's devicetree bindings language supports a ``bus:`` key which allows
+bindings to declare that nodes with a given compatible describe system buses.
+In this case, child nodes are considered to be on a bus of the given type, and
+the following APIs may be used.
+
.. doxygengroup:: devicetree-generic-bus
:project: Zephyr
@@ -60,7 +127,7 @@
These are recommended for use within device drivers. To use them, define
``DT_DRV_COMPAT`` to the lowercase-and-underscores compatible the device driver
implements support for. Note that there are also helpers available for
-specific hardware; these are documented in the following sections.
+specific hardware; these are documented in :ref:`devicetree-hw-api`.
It is an error to use these macros without ``DT_DRV_COMPAT`` defined.
@@ -78,34 +145,145 @@
ADC
===
+These are commonly used by sensor device drivers which need to use an ADC
+channel for conversion.
+
.. doxygengroup:: devicetree-adc
:project: Zephyr
Clocks
======
+These conveniences may be used for nodes which describe clock sources, and
+properties related to them.
+
.. doxygengroup:: devicetree-clocks
:project: Zephyr
+DMA
+===
+
+These conveniences may be used for nodes which describe direct memory access
+controllers or channels, and properties related to them.
+
+.. doxygengroup:: devicetree-dmas
+ :project: Zephyr
+
+Fixed flash partitions
+======================
+
+These conveniences may be used for the special-purpose ``fixed-partitions``
+compatible used to encode information about flash memory partitions in the
+device tree.
+
+.. doxygengroup:: devicetree-fixed-partition
+ :project: Zephyr
+
.. _devicetree-gpio-api:
GPIO
====
+These conveniences may be used for nodes which describe GPIO controllers/pins,
+and properties related to them.
+
.. doxygengroup:: devicetree-gpio
:project: Zephyr
+PWM
+===
+
+These conveniences may be used for nodes which describe PWM controllers and
+properties related to them.
+
+.. doxygengroup:: devicetree-pwms
+ :project: Zephyr
+
SPI
===
+These conveniences may be used for nodes which describe either SPI controllers
+or devices, depending on the case.
+
.. doxygengroup:: devicetree-spi
:project: Zephyr
-Zephyr specific /chosen nodes
-=============================
+.. _devicetree-chosen-nodes:
-These are conveniences for commonly used zephyr-specific properties of the
-``/chosen`` node. They may have fallbacks from :file:`dts_fixup.h` files.
+Chosen nodes
+************
+
+The special ``/chosen`` node contains properties whose values describe
+system-wide settings. The :c:func:`DT_CHOSEN()` macro can be used to get a node
+identifier for a chosen node.
+
+.. doxygengroup:: devicetree-generic-chosen
+ :project: Zephyr
+
+There are also conveniences for commonly used zephyr-specific properties of the
+``/chosen`` node. (These may also be set in :file:`dts_fixup.h` files for now,
+though this mechanism is deprecated.)
.. doxygengroup:: devicetree-zephyr
:project: Zephyr
+
+The following table documents some commonly used Zephyr-specific chosen nodes.
+
+Often, a chosen node's label property will be used to set the default value of
+a Kconfig option which in turn configures a hardware-specific subsystem
+setting. This is usually for backwards compatibility in cases when the Kconfig
+option predates devicetree support in Zephyr. In other cases, there is no
+Kconfig option, and the devicetree node's label property is used directly in
+the source code to specify a device name.
+
+.. Documentation maintainers: please keep this sorted by property name
+
+.. list-table:: Zephyr-specific chosen properties
+ :header-rows: 1
+
+ * - Property
+ - Purpose
+ * - zephyr,bt-c2h-uart
+ - Sets default :option:`CONFIG_BT_CTLR_TO_HOST_UART_DEV_NAME`
+ * - zephyr,bt-mon-uart
+ - Sets default :option:`CONFIG_BT_MONITOR_ON_DEV_NAME`
+ * - zephyr,bt-uart
+ - Sets default :option:`CONFIG_BT_UART_ON_DEV_NAME`
+ * - zephyr,can-primary
+ - Sets the primary CAN controller
+ * - zephyr,ccm
+ - Core-Coupled Memory node on some STM32 SoCs
+ * - zephyr,code-partition
+ - Flash partition that the Zephyr image's text section should be linked
+ into
+ * - zephyr,console
+ - Sets default :option:`CONFIG_UART_CONSOLE_ON_DEV_NAME`
+ * - zephyr,dtcm
+ - Data Tightly Coupled Memory node on some Arm SoCs
+ * - zephyr,entropy
+ - A device which can be used as a system-wide entropy source
+ * - zephyr,flash
+ - A node whose ``reg`` is sometimes used to set the defaults for
+ :option:`CONFIG_FLASH_BASE_ADDRESS` and :option:`CONFIG_FLASH_SIZE`
+ * - zephyr,flash-controller
+ - The node corresponding to the flash controller device for
+ the ``zephyr,flash`` node
+ * - zephyr,ipc
+ - Used by the OpenAMP subsystem to specify the inter-process communication
+ (IPC) device
+ * - zephyr,ipc_shm
+ - A node whose ``reg`` is used by the OpenAMP subsystem to determine the
+ base address and size of the shared memory (SHM) usable for
+ interprocess-communication (IPC)
+ * - zephyr,shell-uart
+ - Sets default :option:`CONFIG_UART_SHELL_ON_DEV_NAME`
+ * - zephyr,sram
+ - A node whose ``reg`` sets the base address and size of SRAM memory
+ available to the Zephyr image, used during linking
+ * - zephyr,uart-mcumgr
+ - UART used for :ref:`device_mgmt`
+ * - zephyr,uart-pipe
+ - Sets default :option:`CONFIG_UART_PIPE_ON_DEV_NAME`
+ * - zephyr,usb-device
+ - USB device node. If defined and has a ``vbus-gpios`` property, these
+ will be used by the USB subsystem to enable/disable VBUS
diff --git a/include/devicetree.h b/include/devicetree.h
index e52b0ce..c6f7487 100644
--- a/include/devicetree.h
+++ b/include/devicetree.h
@@ -78,11 +78,16 @@
/**
* @brief Get a node identifier for a devicetree path
*
+ * The arguments to this macro are the names of non-root nodes in the
+ * tree required to reach the desired node, starting from the root.
+ * Non-alphanumeric characters in each name must be converted to
+ * underscores to form valid C tokens, and letters must be lowercased.
+ *
* Example devicetree fragment:
*
* / {
* soc {
- * my-serial: serial@40002000 {
+ * serial1: serial@40001000 {
* status = "okay";
* current-speed = <115200>;
* ...
@@ -90,22 +95,24 @@
* };
* };
*
- * Example usage with @ref DT_PROP() to get current-speed:
+ * You can use DT_PATH(soc, serial_40001000) to get a node identifier
+ * for the serial@40001000 node. Node labels like "serial1" cannot be
+ * used as DT_PATH() arguments; use DT_NODELABEL() for those instead.
*
- * DT_PROP(DT_PATH(soc, serial_40002000), current_speed) // 115200
+ * Example usage with DT_PROP() to get the current-speed property:
*
- * The arguments to this macro are the names of non-root nodes in the
- * tree required to reach the desired node, starting from the root.
- * Non-alphanumeric characters in each name must be converted to
- * underscores to form valid C tokens, and letters must be lowercased.
+ * DT_PROP(DT_PATH(soc, serial_40001000), current_speed) // 115200
*
- * That is:
+ * (The current-speed property is also in "lowercase-and-underscores"
+ * form when used with this API.)
*
- * - a first argument corresponds to a child node of the root ("soc" above)
+ * When determining arguments to DT_PATH():
+ *
+ * - the first argument corresponds to a child node of the root ("soc" above)
* - a second argument corresponds to a child of the first argument
- * ("serial_40002000" above, from the node name "serial@40002000"
- * after changing "@" to "_")
- * - and so on for deeper nodes until the desired path is given
+ * ("serial_40001000" above, from the node name "serial@40001000"
+ * after lowercasing and changing "@" to "_")
+ * - and so on for deeper nodes in the desired node's path
*
* @param ... lowercase-and-underscores node names along the node's path,
* with each name given as a separate argument
@@ -116,25 +123,29 @@
/**
* @brief Get a node identifier for a node label
*
+ * Convert non-alphanumeric characters in the node label to
+ * underscores to form valid C tokens, and lowercase all letters. Note
+ * that node labels are not the same thing as label properties.
+ *
* Example devicetree fragment:
*
- * my-serial: serial@40002000 {
+ * serial1: serial@40001000 {
* label = "UART_0";
* status = "okay";
* current-speed = <115200>;
* ...
* };
*
- * The only node label in this example is "my-serial".
+ * The only node label in this example is "serial1".
+ *
* The string "UART_0" is *not* a node label; it's the value of a
- * property named "label".
+ * property named label.
*
- * Example usage to get current-speed:
+ * You can use DT_NODELABEL(serial1) to get a node identifier for the
+ * serial@40001000 node. Example usage with DT_PROP() to get the
+ * current-speed property:
*
- * DT_PROP(DT_NODELABEL(my_serial), current_speed) // 115200
- *
- * Convert non-alphanumeric characters in the label to underscores as
- * shown, and lowercase all letters.
+ * DT_PROP(DT_NODELABEL(serial1), current_speed) // 115200
*
* Another example devicetree fragment:
*
@@ -145,12 +156,12 @@
* };
* };
*
- * Example usage to get cache-level:
+ * Example usage to get the cache-level property:
*
* DT_PROP(DT_NODELABEL(l2_0), cache_level) // 2
*
- * Notice how "L2_0" in the devicetree is lowercased to "l2_0"
- * for this macro's argument.
+ * Notice how "L2_0" in the devicetree is lowercased to "l2_0" in the
+ * DT_NODELABEL() argument.
*
* @param label lowercase-and-underscores node label name
* @return node identifier for the node with that label
@@ -158,27 +169,36 @@
#define DT_NODELABEL(label) DT_CAT(DT_N_NODELABEL_, label)
/**
- * @brief Get a node identifier for an alias
+ * @brief Get a node identifier from /aliases
+ *
+ * This macro's argument is a property of the /aliases node. It
+ * returns a node identifier for the node which is aliased. Convert
+ * non-alphanumeric characters in the alias property to underscores to
+ * form valid C tokens, and lowercase all letters.
*
* Example devicetree fragment:
*
- * aliases {
- * my-serial = &serial0;
+ * / {
+ * aliases {
+ * my-serial = &serial1;
+ * };
+ *
+ * soc {
+ * serial1: serial@40001000 {
+ * status = "okay";
+ * current-speed = <115200>;
+ * ...
+ * };
+ * };
* };
*
- * serial0: serial@40002000 {
- * status = "okay";
- * current-speed = <115200>;
- * ...
- * };
- *
- * Example usage to get current-speed:
+ * You can use DT_ALIAS(my_serial) to get a node identifier for the
+ * serial@40001000 node. Notice how my-serial in the devicetree
+ * becomes my_serial in the DT_ALIAS() argument. Example usage with
+ * DT_PROP() to get the current-speed property:
*
* DT_PROP(DT_ALIAS(my_serial), current_speed) // 115200
*
- * Convert non-alphanumeric characters in the alias to underscores as
- * shown, and lowercase all letters.
- *
* @param alias lowercase-and-underscores alias name.
* @return node identifier for the node with that alias
*/
@@ -187,38 +207,89 @@
/**
* @brief Get a node identifier for an instance of a compatible
*
- * Instance numbers are just indexes among *all* nodes with the same
- * compatible. This complicates their use outside of device drivers.
- * The **only guarantees** are:
+ * All nodes with a particular compatible property value are assigned
+ * instance numbers, which are zero-based indexes specific to that
+ * compatible. You can get a node identifier for these nodes by
+ * passing DT_INST() an instance number, "inst", along with the
+ * lowercase-and-underscores version of the compatible, "compat".
*
- * - instance numbers start at 0,
- * - are contiguous, and
- * - exactly one is assigned for *each* node with a matching compatible,
- * **including disabled ones**
+ * Instance numbers have the following properties:
*
- * Instance numbers **in no way reflect** any numbering scheme that
- * might exist in SoC documentation, node labels or unit addresses, or
- * properties of the /aliases node.
+ * - for each compatible, instance numbers start at 0 and are contiguous
+ * - exactly one instance number is assigned for each node with a compatible,
+ * **including disabled nodes**
+ * - enabled nodes (status property is "okay" or missing) are assigned the
+ * instance numbers starting from 0, and disabled nodes have instance
+ * numbers which are greater than those of any enabled node
*
- * There **is no guarantee** that the same node will have the same
- * instance number between builds, even if you are building the same
- * application again in the same build directory.
+ * No other guarantees are made. In particular:
+ *
+ * - instance numbers **in no way reflect** any numbering scheme that
+ * might exist in SoC documentation, node labels or unit addresses,
+ * or properties of the /aliases node (use DT_NODELABEL() or DT_ALIAS()
+ * for those)
+ * - there **is no general guarantee** that the same node will have
+ * the same instance number between builds, even if you are building
+ * the same application again in the same build directory
*
* Example devicetree fragment:
*
- * serial@40002000 {
+ * serial1: serial@40001000 {
+ * compatible = "vnd,soc-serial";
+ * status = "disabled";
+ * current-speed = <9600>;
+ * ...
+ * };
+ *
+ * serial2: serial@40002000 {
* compatible = "vnd,soc-serial";
* status = "okay";
+ * current-speed = <57600>;
+ * ...
+ * };
+ *
+ * serial3: serial@40003000 {
+ * compatible = "vnd,soc-serial";
* current-speed = <115200>;
* ...
* };
*
- * Example usage to get current-speed, **assuming that** this node is
- * instance number zero of the compatible "vnd,soc-serial":
+ * Assuming no other nodes in the devicetree have compatible
+ * "vnd,soc-serial", that compatible has nodes with instance numbers
+ * 0, 1, and 2.
*
- * DT_PROP(DT_INST(0, vnd_soc_serial), current_speed) // 115200
+ * The nodes serial@40002000 and serial@40003000 are both enabled, so
+ * their instance numbers are 0 and 1, but no guarantees are made
+ * regarding which node has which instance number.
*
- * @param inst instance number
+ * Since serial@40001000 is the only disabled node, it has instance
+ * number 2, since disabled nodes are assigned the largest instance
+ * numbers. Therefore:
+ *
+ * // Could be 57600 or 115200. There is no way to be sure:
+ * // either serial@40002000 or serial@40003000 could
+ * // have instance number 0, so this could be the current-speed
+ * // property of either of those nodes.
+ * DT_PROP(DT_INST(0, vnd_soc_serial), current_speed)
+ *
+ * // Could be 57600 or 115200, for the same reason.
+ * // If the above expression expands to 57600, then
+ * // this expands to 115200, and vice-versa.
+ * DT_PROP(DT_INST(1, vnd_soc_serial), current_speed)
+ *
+ * // 9600, because there is only one disabled node, and
+ * // disabled nodes are "at the the end" of the instance
+ * // number "list".
+ * DT_PROP(DT_INST(2, vnd_soc_serial), current_speed)
+ *
+ * Notice how "vnd,soc-serial" in the devicetree becomes vnd_soc_serial
+ * (without quotes) in the DT_INST() arguments. (As usual, current-speed
+ * in the devicetree becomes current_speed as well.)
+ *
+ * Nodes whose "compatible" property has multiple values are assigned
+ * independent instance numbers for each compatible.
+ *
+ * @param inst instance number for compatible "compat"
* @param compat lowercase-and-underscores compatible, without quotes
* @return node identifier for the node with that instance number and
* compatible
@@ -236,12 +307,13 @@
* };
* };
*
- * The following generate equivalent node identifiers:
+ * The following are equivalent ways to get the same node identifier:
*
* DT_NODELABEL(parent)
* DT_PARENT(DT_NODELABEL(child))
*
* @param node_id node identifier
+ * @return a node identifier for the node's parent
*/
#define DT_PARENT(node_id) UTIL_CAT(node_id, _PARENT)
@@ -252,7 +324,7 @@
*
* / {
* soc-label: soc {
- * my-serial: serial@4 {
+ * serial1: serial@40001000 {
* status = "okay";
* current-speed = <115200>;
* ...
@@ -260,10 +332,17 @@
* };
* };
*
- * Example usage with @ref DT_PROP() to get the status of the child node
- * "serial@4" of the node referenced by node label "soc-label":
+ * Example usage with @ref DT_PROP() to get the status of the
+ * serial@40001000 node:
*
- * DT_PROP(DT_CHILD(DT_NODELABEL(soc_label), serial_4), status) // "okay"
+ * #define SOC_NODE DT_NODELABEL(soc_label)
+ * DT_PROP(DT_CHILD(SOC_NODE, serial_40001000), status) // "okay"
+ *
+ * Node labels like "serial1" cannot be used as the "child" argument
+ * to this macro. Use DT_NODELABEL() for that instead.
+ *
+ * You can also use DT_FOREACH_CHILD() to iterate over node
+ * identifiers for all of a node's children.
*
* @param node_id node identifier
* @param child lowercase-and-underscores child node name
@@ -272,18 +351,6 @@
#define DT_CHILD(node_id, child) UTIL_CAT(node_id, DT_S_PREFIX(child))
/**
- * @brief Invokes given macro for all child nodes of a parent.
- *
- * @param node_id node identifier
- * @param fn macro to invoke
- *
- * Macro should be defined to take one parameter, which will be a node
- * identifier for each child node of node_id.
- */
-#define DT_FOREACH_CHILD(node_id, fn) \
- DT_CAT(node_id, _FOREACH_CHILD)(fn)
-
-/**
* @}
*/
@@ -305,12 +372,19 @@
* - array, uint8-array, string-array: an initializer expression in braces,
* whose elements are integer or string literals (like {0, 1, 2},
* {"hello", "world"}, etc.)
- * - phandle: a node identifier
+ * - phandle: a node identifier for the node with that phandle
*
- * For other properties, behavior is undefined.
+ * A property's type is usually defined by its binding. In some
+ * special cases, it has an assumed type defined by the devicetree
+ * specification even when no binding is available: "compatible" has
+ * type string-array, "status" and "label" have type string, and
+ * "interrupt-controller" has type boolean.
*
- * For examples, see @ref DT_PATH(), @ref DT_ALIAS(), @ref DT_NODELABEL(),
- * and @ref DT_INST().
+ * For other properties or properties with unknown type due to a
+ * missing binding, behavior is undefined.
+ *
+ * For usage examples, see @ref DT_PATH(), @ref DT_ALIAS(), @ref
+ * DT_NODELABEL(), and @ref DT_INST() above.
*
* @param node_id node identifier
* @param prop lowercase-and-underscores property name
@@ -321,21 +395,23 @@
/**
* @brief Get a property's logical length
*
- * Here, "length" is a number of elements, which may not
- * be a size in bytes.
+ * Here, "length" is a number of elements, which may differ from the
+ * property's size in bytes.
*
- * For properties whose binding has type array, string-array, or
- * uint8-array, this expands to the number of elements in the array.
+ * The return value depends on the property's type:
*
- * For properties of type phandles or phandle-array, it expands to the
- * number of phandles or phandle+specifiers respectively.
+ * - for types array, string-array, and uint8-array, this expands
+ * to the number of elements in the array
+ * - for type phandles, this expands to the number of phandles
+ * - for type phandle-array, this expands to the number of
+ * phandle and specifier blocks in the property
*
* These properties are handled as special cases:
*
* - reg property: use DT_NUM_REGS(node_id) instead
* - interrupts property: use DT_NUM_IRQS(node_id) instead
*
- * It is an error to use this macro with the above properties.
+ * It is an error to use this macro with the reg or interrupts properties.
*
* For other properties, behavior is undefined.
*
@@ -349,7 +425,7 @@
* @brief Is index "idx" valid for an array type property?
*
* If this returns 1, then DT_PROP_BY_IDX(node_id, prop, idx) or
- * DT_PHA_BY_IDX(node_id, pha, idx, cell) are valid at index "idx".
+ * DT_PHA_BY_IDX(node_id, prop, idx, ...) are valid at index "idx".
* If it returns 0, it is an error to use those macros with that index.
*
* These properties are handled as special cases:
@@ -357,13 +433,13 @@
* - reg property: use DT_REG_HAS_IDX(node_id, idx) instead
* - interrupts property: use DT_IRQ_HAS_IDX(node_id, idx) instead
*
- * It is an error to use this macro with the above properties.
+ * It is an error to use this macro with the reg or interrupts properties.
*
* @param node_id node identifier
* @param prop a lowercase-and-underscores property with a logical length
* @param idx index to check
- * @return 1 if "idx" is a valid index into the given property,
- * 0 otherwise.
+ * @return An expression which evaluates to 1 if "idx" is a valid index
+ * into the given property, and 0 otherwise.
*/
#define DT_PROP_HAS_IDX(node_id, prop, idx) \
((idx) < DT_PROP_LEN(node_id, prop))
@@ -447,21 +523,6 @@
*/
/**
- * @brief Get a property value from a phandle's node
- *
- * This is a shorthand for DT_PROP_BY_PHANDLE_IDX(node_id, ph, 0, prop).
- * It helps readability when "ph" has type "phandle".
- *
- * @param node_id node identifier
- * @param ph lowercase-and-underscores property of "node_id"
- * with type "phandle"
- * @param prop lowercase-and-underscores property of the phandle's node
- * @return the value of "prop" as described in the DT_PROP() documentation
- */
-#define DT_PROP_BY_PHANDLE(node_id, ph, prop) \
- DT_PROP_BY_PHANDLE_IDX(node_id, ph, 0, prop)
-
-/**
* @brief Get a property value from a phandle in a property.
*
* This is a shorthand for:
@@ -498,46 +559,72 @@
* @param idx logical index into "phs", which must be zero if "phs"
* has type "phandle"
* @param prop lowercase-and-underscores property of the phandle's node
- * @return the value of "prop" as described in the DT_PROP() documentation
+ * @return the property's value
*/
#define DT_PROP_BY_PHANDLE_IDX(node_id, phs, idx, prop) \
DT_PROP(DT_PHANDLE_BY_IDX(node_id, phs, idx), prop)
/**
- * @brief Get a phandle-array specifier value at an index
+ * @brief Get a property value from a phandle's node
+ *
+ * This is equivalent to DT_PROP_BY_PHANDLE_IDX(node_id, ph, 0, prop).
+ *
+ * @param node_id node identifier
+ * @param ph lowercase-and-underscores property of "node_id"
+ * with type "phandle"
+ * @param prop lowercase-and-underscores property of the phandle's node
+ * @return the property's value
+ */
+#define DT_PROP_BY_PHANDLE(node_id, ph, prop) \
+ DT_PROP_BY_PHANDLE_IDX(node_id, ph, 0, prop)
+
+/**
+ * @brief Get a phandle-array specifier cell value at an index
*
* It might help to read the argument order as being similar to
- * "node->phandle[index].cell". That is, the cell value is in the
- * "pha" property of "node_id".
+ * "node->phandle_array[index].cell". That is, the cell value is in
+ * the "pha" property of "node_id", inside the specifier at index
+ * "idx".
*
* Example devicetree fragment:
*
- * gpio0: gpio@12340000 {
- * #gpio-cells = < 2 >;
+ * gpio0: gpio@... {
+ * #gpio-cells = <2>;
+ * };
+ *
+ * gpio1: gpio@... {
+ * #gpio-cells = <2>;
* };
*
* led: led_0 {
- * gpios = < &gpio0 17 0x1 >;
+ * gpios = <&gpio0 17 0x1>, <&gpio1 5 0x3>;
* };
*
- * Bindings fragment for the gpio0 node:
+ * Bindings fragment for the gpio0 and gpio1 nodes:
*
* gpio-cells:
* - pin
* - flags
*
+ * Above, "gpios" has two elements:
+ *
+ * - index 0 has specifier <17 0x1>, so its "pin" cell is 17, and its
+ * "flags" cell is 0x1
+ * - index 1 has specifier <5 0x3>, so "pin" is 5 and "flags" is 0x3
+ *
* Example usage:
*
* #define LED DT_NODELABEL(led)
*
- * DT_PHA_BY_IDX(LED, gpios, pin, 0) // 17
- * DT_PHA_BY_IDX(LED, gpios, flags, 0) // 0x1
+ * DT_PHA_BY_IDX(LED, gpios, 0, pin) // 17
+ * DT_PHA_BY_IDX(LED, gpios, 1, flags) // 0x3
*
* @param node_id node identifier
* @param pha lowercase-and-underscores property with type "phandle-array"
- * @param idx logical index into the property "pha"
- * @param cell binding's cell name within the specifier at index "idx"
- * @return the value of the cell inside the specifier at index "idx"
+ * @param idx logical index into "pha"
+ * @param cell lowercase-and-underscores cell name within the specifier
+ * at "pha" index "idx"
+ * @return the cell's value
*/
#define DT_PHA_BY_IDX(node_id, pha, idx, cell) \
DT_PROP(node_id, pha##_IDX_##idx##_VAL_##cell)
@@ -546,8 +633,8 @@
* @brief Equivalent to DT_PHA_BY_IDX(node_id, pha, 0, cell)
* @param node_id node identifier
* @param pha lowercase-and-underscores property with type "phandle-array"
- * @param cell binding's cell name for the specifier at "pha" index 0
- * @return the cell value
+ * @param cell lowercase-and-underscores cell name
+ * @return the cell's value
*/
#define DT_PHA(node_id, pha, cell) DT_PHA_BY_IDX(node_id, pha, 0, cell)
@@ -555,12 +642,12 @@
* @brief Get a value within a phandle-array specifier by name
*
* This is like DT_PHA_BY_IDX(), except it treats "pha" as a structure
- * where each specifier has a name.
+ * where each array element has a name.
*
* It might help to read the argument order as being similar to
* "node->phandle_struct.name.cell". That is, the cell value is in the
- * "pha" property of "node_id", treated as a data structure with named
- * components.
+ * "pha" property of "node_id", treated as a data structure where
+ * each array element has a name.
*
* Example devicetree fragment:
*
@@ -582,8 +669,8 @@
* @param node_id node identifier
* @param pha lowercase-and-underscores property with type "phandle-array"
* @param name lowercase-and-underscores name of a specifier in "pha"
- * @param cell binding's cell name for the named specifier
- * @return the cell value
+ * @param cell lowercase-and-underscores cell name in the named specifier
+ * @return the cell's value
*/
#define DT_PHA_BY_NAME(node_id, pha, name, cell) \
DT_PROP(node_id, pha##_NAME_##name##_VAL_##cell)
@@ -593,7 +680,7 @@
*
* It might help to read the argument order as being similar to
* "node->phandle_struct.name.phandle". That is, the phandle array is
- * treated as a structure with named components. The return value is
+ * treated as a structure with named elements. The return value is
* the node identifier for a phandle inside the structure.
*
* Example devicetree fragment:
@@ -611,6 +698,11 @@
* io-channel-names = "SENSOR", "BANDGAP";
* };
*
+ * Above, "io-channels" has two elements:
+ *
+ * - the element named "SENSOR" has phandle &adc1
+ * - the element named "BANDGAP" has phandle &adc2
+ *
* Example usage:
*
* #define NODE DT_NODELABEL(n)
@@ -618,10 +710,13 @@
* DT_LABEL(DT_PHANDLE_BY_NAME(NODE, io_channels, sensor)) // "ADC_1"
* DT_LABEL(DT_PHANDLE_BY_NAME(NODE, io_channels, bandgap)) // "ADC_2"
*
+ * Notice how devicetree properties and names are lowercased, and
+ * non-alphanumeric characters are converted to underscores.
+ *
* @param node_id node identifier
* @param pha lowercase-and-underscores property with type "phandle-array"
* @param name lowercase-and-underscores name of an element in "pha"
- * @return node identifier for the phandle at the element named "name"
+ * @return a node identifier for the node with that phandle
*/
#define DT_PHANDLE_BY_NAME(node_id, pha, name) \
DT_PROP(node_id, pha##_NAME_##name##_PH)
@@ -645,6 +740,11 @@
* n2: node-2 { ... };
* n3: node-3 { ... };
*
+ * Above, "foo" has type phandles and has two elements:
+ *
+ * - index 0 has phandle &n2, which is node-2's phandle
+ * - index 1 has phandle &n3, which is node-3's phandle
+ *
* Example usage:
*
* #define N1 DT_NODELABEL(n1)
@@ -658,7 +758,7 @@
* @param prop lowercase-and-underscores property name in "node_id"
* with type "phandle", "phandles" or "phandle-array"
* @param idx index into "prop"
- * @return a node identifier for the phandle at index "idx" in "prop"
+ * @return node identifier for the node with the phandle at that index
*/
#define DT_PHANDLE_BY_IDX(node_id, prop, idx) \
DT_PROP(node_id, prop##_IDX_##idx##_PH)
@@ -676,8 +776,14 @@
*/
#define DT_PHANDLE(node_id, prop) DT_PHANDLE_BY_IDX(node_id, prop, 0)
-/*
- * reg property
+/**
+ * @}
+ */
+
+/**
+ * @defgroup devicetree-reg-prop reg property
+ * @ingroup devicetree
+ * @{
*/
/**
@@ -762,8 +868,14 @@
#define DT_REG_SIZE_BY_NAME(node_id, name) \
DT_CAT(node_id, _REG_NAME_##name##_VAL_SIZE)
-/*
- * interrupts property
+/**
+ * @}
+ */
+
+/**
+ * @defgroup devicetree-interrupts-prop interrupts property
+ * @ingroup devicetree
+ * @{
*/
/**
@@ -790,6 +902,40 @@
IS_ENABLED(DT_CAT(node_id, _IRQ_IDX_##idx##_EXISTS))
/**
+ * @brief Does an interrupts property have a named cell specifier at an index?
+ * If this returns 1, then DT_IRQ_BY_IDX(node_id, idx, cell) is valid.
+ * If it returns 0, it is an error to use that macro.
+ * @param node_id node identifier
+ * @param idx index to check
+ * @param cell named cell value whose existence to check
+ * @return 1 if the named cell exists in the interrupt specifier at index idx
+ * 0 otherwise.
+ */
+#define DT_IRQ_HAS_CELL_AT_IDX(node_id, idx, cell) \
+ IS_ENABLED(DT_CAT(node_id, _IRQ_IDX_##idx##_VAL_##cell##_EXISTS))
+
+/**
+ * @brief Equivalent to DT_IRQ_HAS_CELL_AT_IDX(node_id, 0, cell)
+ * @param node_id node identifier
+ * @param cell named cell value whose existence to check
+ * @return 1 if the named cell exists in the interrupt specifier at index 0
+ * 0 otherwise.
+ */
+#define DT_IRQ_HAS_CELL(node_id, cell) DT_IRQ_HAS_CELL_AT_IDX(node_id, 0, cell)
+
+/**
+ * @brief Does an interrupts property have a named specifier value at an index?
+ * If this returns 1, then DT_IRQ_BY_NAME(node_id, name, cell) is valid.
+ * If it returns 0, it is an error to use that macro.
+ * @param node_id node identifier
+ * @param name lowercase-and-underscores interrupt specifier name
+ * @return 1 if "name" is a valid named specifier
+ * 0 otherwise.
+ */
+#define DT_IRQ_HAS_NAME(node_id, name) \
+ IS_ENABLED(DT_CAT(node_id, _IRQ_NAME_##name##_VAL_irq_EXISTS))
+
+/**
* @brief Get a value within an interrupt specifier at an index
*
* It might help to read the argument order as being similar to
@@ -810,8 +956,8 @@
*
* #define SERIAL DT_NODELABEL(my_serial)
*
- * Example usage Value
- * ------------- -----
+ * Example usage Value
+ * ------------- -----
* DT_IRQ_BY_IDX(SERIAL, 0, irq) 33
* DT_IRQ_BY_IDX(SERIAL, 0, priority) 0
* DT_IRQ_BY_IDX(SERIAL, 1, irq, 34
@@ -876,6 +1022,7 @@
/**
* @brief Get a node identifier for a /chosen node property
+ *
* This is only valid to call if DT_HAS_CHOSEN(prop) is 1.
* @param prop lowercase-and-underscores property name for
* the /chosen node
@@ -884,6 +1031,62 @@
#define DT_CHOSEN(prop) DT_CAT(DT_CHOSEN_, prop)
/**
+ * @brief Test if the devicetree has a /chosen node
+ * @param prop lowercase-and-underscores devicetree property
+ * @return 1 if the chosen property exists and refers to a node,
+ * 0 otherwise
+ */
+#define DT_HAS_CHOSEN(prop) IS_ENABLED(DT_CHOSEN_##prop##_EXISTS)
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup devicetree-generic-foreach "For-each" macros
+ * @ingroup devicetree
+ * @{
+ */
+
+/**
+ * @brief Invokes "fn" for each child of "node_id"
+ *
+ * The macro "fn" must take one parameter, which will be the node
+ * identifier of a child node of "node_id".
+ *
+ * Example devicetree fragment:
+ *
+ * n: node {
+ * child-1 {
+ * label = "foo";
+ * };
+ * child-2 {
+ * label = "bar";
+ * };
+ * };
+ *
+ * Example usage:
+ *
+ * #define LABEL_AND_COMMA(node_id) DT_LABEL(node_id),
+ *
+ * const char *child_labels[] = {
+ * DT_FOREACH_CHILD(DT_NODELABEL(n), LABEL_AND_COMMA)
+ * };
+ *
+ * This expands to:
+ *
+ * const char *child_labels[] = {
+ * "foo", "bar",
+ * };
+ *
+ * @param node_id node identifier
+ * @param fn macro to invoke
+ */
+#define DT_FOREACH_CHILD(node_id, fn) \
+ DT_CAT(node_id, _FOREACH_CHILD)(fn)
+
+
+/**
* @}
*/
@@ -925,15 +1128,14 @@
* in the devicetree is treated as if it were "okay" instead)
*
* @param node_id a node identifier
- * @param status a status as a token (not a string), e.g. okay or disabled
- * @return 1 if the node identifier refers to a usable node,
- * 0 otherwise.
+ * @param status a status as one of the tokens okay or disabled, not a string
+ * @return 1 if the node has the given status, 0 otherwise.
*/
#define DT_NODE_HAS_STATUS(node_id, status) \
DT_NODE_HAS_STATUS_INTERNAL(node_id, status)
/**
- * @brief Does the devicetree have an "okay" node with a compatible?
+ * @brief Does the devicetree have a status "okay" node with a compatible?
*
* Test for whether the devicetree has any nodes with status "okay"
* and the given compatible. That is, this returns 1 if and only if
@@ -943,9 +1145,11 @@
* DT_NODE_HAS_STATUS(node_id, okay)
* DT_NODE_HAS_COMPAT(node_id, compat)
*
+ * As usual, both a missing status and an "ok" status are treated as
+ * "okay".
+ *
* @param compat lowercase-and-underscores version of a compatible
- * @return 0 if no nodes of the compatible are available for use,
- * 1 if at least one is enabled and has a matching binding
+ * @return 1 if both of the above conditions are met, 0 otherwise
*/
#define DT_HAS_COMPAT_STATUS_OKAY(compat) \
IS_ENABLED(DT_CAT(DT_COMPAT_HAS_OKAY_, compat))
@@ -961,14 +1165,6 @@
UTIL_CAT(DT_N_INST, DT_DASH(compat, NUM_OKAY)))
/**
- * @brief Test if the devicetree has a /chosen node
- * @param prop lowercase-and-underscores devicetree property
- * @return 1 if the chosen property exists and refers to a node,
- * 0 otherwise
- */
-#define DT_HAS_CHOSEN(prop) IS_ENABLED(DT_CHOSEN_##prop##_EXISTS)
-
-/**
* @brief Does a devicetree node match a compatible?
*
* Example devicetree fragment:
@@ -984,7 +1180,7 @@
*
* This macro only uses the value of the compatible property. Whether
* or not a particular compatible has a matching binding has no effect
- * on its value.
+ * on its value, nor does the node's status.
*
* @param node_id node identifier
* @param compat lowercase-and-underscorse compatible value
@@ -994,15 +1190,29 @@
#define DT_NODE_HAS_COMPAT(node_id, compat) \
IS_ENABLED(DT_CAT(node_id, _COMPAT_MATCHES_##compat))
+/**
+ * @brief Does a devicetree node have a compatible and status?
+ *
+ * This is equivalent to:
+ *
+ * (DT_NODE_HAS_COMPAT(node_id, compat) &&
+ * DT_NODE_HAS_STATUS(node_id, status))
+ *
+ * @param node_id node identifier
+ * @param compat lowercase-and-underscores compatible
+ * @param status okay or disabled as a token, not a string
+ */
#define DT_NODE_HAS_COMPAT_STATUS(node_id, compat, status) \
DT_NODE_HAS_COMPAT(node_id, compat) && DT_NODE_HAS_STATUS(node_id, status)
/**
* @brief Does a devicetree node have a property?
*
- * Tests whether a devicetree node has a property defined. This
- * tests whether the property is part of the node at all, not whether
- * a boolean property is true or not.
+ * Tests whether a devicetree node has a property defined.
+ *
+ * This tests whether the property is defined at all, not whether a
+ * boolean property is true or false. To get a boolean property's
+ * truth value, use DT_PROP(node_id, prop) instead.
*
* @param node_id node identifier
* @param prop lowercase-and-underscores property name
@@ -1014,13 +1224,17 @@
/**
* @brief Does a phandle array have a named cell specifier at an index?
- * If this returns 1, then the cell argument to
- * DT_PHA_BY_IDX(node_id, pha, idx, cell) is valid.
- * If it returns 0, it is an error.
+ *
+ * If this returns 1, then the phandle-array property "pha" has a cell
+ * named "cell" at index "idx", and therefore DT_PHA_BY_IDX(node_id,
+ * pha, idx, cell) is valid. If it returns 0, it's an error to use
+ * DT_PHA_BY_IDX() with the same arguments.
+ *
* @param node_id node identifier
* @param pha lowercase-and-underscores property with type "phandle-array"
- * @param idx index to check
- * @param cell named cell value whose existence to check
+ * @param idx index to check within "pha"
+ * @param cell lowercase-and-underscores cell name whose existence to check
+ * at index "idx"
* @return 1 if the named cell exists in the specifier at index idx,
* 0 otherwise.
*/
@@ -1032,48 +1246,15 @@
* @brief Equivalent to DT_PHA_HAS_CELL_AT_IDX(node_id, pha, 0, cell)
* @param node_id node identifier
* @param pha lowercase-and-underscores property with type "phandle-array"
- * @param cell named cell value whose existence to check
- * @return 1 if the named ceell exists in the specifier at index 0,
+ * @param cell lowercase-and-underscores cell name whose existence to check
+ * at index "idx"
+ * @return 1 if the named cell exists in the specifier at index 0,
* 0 otherwise.
*/
#define DT_PHA_HAS_CELL(node_id, pha, cell) \
DT_PHA_HAS_CELL_AT_IDX(node_id, pha, 0, cell)
/**
- * @brief Does an interrupts property have a named cell specifier at an index?
- * If this returns 1, then DT_IRQ_BY_IDX(node_id, idx, cell) is valid.
- * If it returns 0, it is an error to use that macro.
- * @param node_id node identifier
- * @param idx index to check
- * @param cell named cell value whose existence to check
- * @return 1 if the named cell exists in the interrupt specifier at index idx
- * 0 otherwise.
- */
-#define DT_IRQ_HAS_CELL_AT_IDX(node_id, idx, cell) \
- IS_ENABLED(DT_CAT(node_id, _IRQ_IDX_##idx##_VAL_##cell##_EXISTS))
-
-/**
- * @brief Equivalent to DT_IRQ_HAS_CELL_AT_IDX(node_id, 0, cell)
- * @param node_id node identifier
- * @param cell named cell value whose existence to check
- * @return 1 if the named cell exists in the interrupt specifier at index 0
- * 0 otherwise.
- */
-#define DT_IRQ_HAS_CELL(node_id, cell) DT_IRQ_HAS_CELL_AT_IDX(node_id, 0, cell)
-
-/**
- * @brief Does an interrupts property have a named specifier value at an index?
- * If this returns 1, then DT_IRQ_BY_NAME(node_id, name, cell) is valid.
- * If it returns 0, it is an error to use that macro.
- * @param node_id node identifier
- * @param name lowercase-and-underscores interrupt specifier name
- * @return 1 if "name" is a valid named specifier
- * 0 otherwise.
- */
-#define DT_IRQ_HAS_NAME(node_id, name) \
- IS_ENABLED(DT_CAT(node_id, _IRQ_NAME_##name##_VAL_irq_EXISTS))
-
-/**
* @}
*/
@@ -1578,7 +1759,7 @@
#define DT_COMPAT_ON_BUS_INTERNAL(compat, bus) \
IS_ENABLED(UTIL_CAT(DT_CAT(DT_COMPAT_, compat), _BUS_##bus))
-/* have these last so the have access to all previously defined macros */
+/* have these last so they have access to all previously defined macros */
#include <devicetree/adc.h>
#include <devicetree/clocks.h>
#include <devicetree/gpio.h>
diff --git a/scripts/dts/edtlib.py b/scripts/dts/edtlib.py
index a665ab5..451df6d 100644
--- a/scripts/dts/edtlib.py
+++ b/scripts/dts/edtlib.py
@@ -2342,6 +2342,8 @@
yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
lambda loader, node: OrderedDict(loader.construct_pairs(node)))
+# Zephyr: do not change this list without updating the documentation
+# for the DT_PROP() macro in include/devicetree.h.
_DEFAULT_PROP_TYPES = {
"compatible": "string-array",
"status": "string",