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",