| .. _dt-phandles: | 
 |  | 
 | Phandles | 
 | ######## | 
 |  | 
 | The devicetree concept of a *phandle* is very similar to pointers in | 
 | C. You can use phandles to refer to nodes in devicetree similarly to the way | 
 | you can use pointers to refer to structures in C. | 
 |  | 
 | .. contents:: Contents | 
 |    :local: | 
 |  | 
 | Getting phandles | 
 | **************** | 
 |  | 
 | The usual way to get a phandle for a devicetree node is from one of its node | 
 | labels. For example, with this devicetree: | 
 |  | 
 | .. code-block:: DTS | 
 |  | 
 |    / { | 
 |            lbl_a: node-1 {}; | 
 |            lbl_b: lbl_c: node-2 {}; | 
 |    }; | 
 |  | 
 | You can write the phandle for: | 
 |  | 
 | - ``/node-1`` as ``&lbl_a`` | 
 | - ``/node-2`` as either ``&lbl_b`` or ``&lbl_c`` | 
 |  | 
 | Notice how the ``&nodelabel`` devicetree syntax is similar to the "address of" | 
 | C syntax. | 
 |  | 
 | Using phandles | 
 | ************** | 
 |  | 
 | .. note:: | 
 |  | 
 |    "Type" in this section refers to one of the type names documented in | 
 |    :ref:`dt-bindings-properties` in the devicetree bindings documentation. | 
 |  | 
 | Here are the main ways you will use phandles. | 
 |  | 
 | One node: phandle type | 
 | ====================== | 
 |  | 
 | You can use phandles to refer to ``node-b`` from ``node-a``, where ``node-b`` | 
 | is related to ``node-a`` in some way. | 
 |  | 
 | One common example is when ``node-a`` represents some hardware that | 
 | generates an interrupt, and ``node-b`` represents the interrupt | 
 | controller that receives the asserted interrupt. In this case, you could | 
 | write: | 
 |  | 
 | .. code-block:: DTS | 
 |  | 
 |    node_b: node-b { | 
 |            interrupt-controller; | 
 |    }; | 
 |  | 
 |    node-a { | 
 |            interrupt-parent = <&node_b>; | 
 |    }; | 
 |  | 
 | This uses the standard ``interrupt-parent`` property defined in the | 
 | devicetree specification to capture the relationship between the two nodes. | 
 |  | 
 | These properties have type ``phandle``. | 
 |  | 
 | Zero or more nodes: phandles type | 
 | ================================= | 
 |  | 
 | You can use phandles to make an array of references to other nodes. | 
 |  | 
 | One common example occurs in :ref:`pin control <pinctrl-guide>`. Pin control | 
 | properties like ``pinctrl-0``, ``pinctrl-1`` etc. may contain multiple | 
 | phandles, each of which "points" to a node containing information related to | 
 | pin configuration for that hardware peripheral. Here's an example of six | 
 | phandles in a single property: | 
 |  | 
 | .. code-block:: DTS | 
 |  | 
 |    pinctrl-0 = <&quadspi_clk_pe10 &quadspi_ncs_pe11 | 
 |                 &quadspi_bk1_io0_pe12 &quadspi_bk1_io1_pe13 | 
 |                 &quadspi_bk1_io2_pe14 &quadspi_bk1_io3_pe15>; | 
 |  | 
 | These properties have type ``phandles``. | 
 |  | 
 | Zero or more nodes with metadata: phandle-array type | 
 | ==================================================== | 
 |  | 
 | You can use phandles to refer to and configure one or more resources that are | 
 | "owned" by some other node. | 
 |  | 
 | This is the most complex case. There are examples and more details in the | 
 | next section. | 
 |  | 
 | These properties have type ``phandle-array``. | 
 |  | 
 | .. _dt-phandle-arrays: | 
 |  | 
 | phandle-array properties | 
 | ************************ | 
 |  | 
 | These properties are commonly used to specify a resource that is owned by | 
 | another node along with additional metadata about the resource. | 
 |  | 
 | High level description | 
 | ====================== | 
 |  | 
 | Usually, properties with this type are written like ``phandle-array-prop`` in | 
 | this example: | 
 |  | 
 | .. code-block:: dts | 
 |  | 
 |    node { | 
 |            phandle-array-prop = <&foo 1 2>, <&bar 3>, <&baz 4 5>; | 
 |    }; | 
 |  | 
 | That is, the property's value is written as a comma-separated sequence of | 
 | "groups", where each "group" is written inside of angle brackets (``< ... >``). | 
 | Each "group" starts with a phandle (``&foo``, ``&bar``, ``&baz``). The values | 
 | that follow the phandle in each "group" are called *specifiers*. There are | 
 | three specifiers in the above example: | 
 |  | 
 | #. ``1 2`` | 
 | #. ``3`` | 
 | #. ``4 5`` | 
 |  | 
 | The phandle in each "group" is used to "point" to the hardware that controls | 
 | the resource you are interested in. The specifier describes the resource | 
 | itself, along with any additional necessary metadata. | 
 |  | 
 | The rest of this section describes a common example. Subsequent sections | 
 | document more rules about how to use phandle-array properties in practice. | 
 |  | 
 | Example phandle-arrays: GPIOs | 
 | ============================= | 
 |  | 
 | Perhaps the most common use case for phandle-array properties is specifying one | 
 | or more GPIOs on your SoC that another chip on your board connects to. For that | 
 | reason, we'll focus on that use case here. However, there are **many other use | 
 | cases** that are handled in devicetree with phandle-array properties. | 
 |  | 
 | For example, consider an external chip with an interrupt pin that is connected | 
 | to a GPIO on your SoC. You will typically need to provide that GPIO's | 
 | information (GPIO controller and pin number) to the :ref:`device driver | 
 | <device_model_api>` for that chip. You usually also need to provide other | 
 | metadata about the GPIO, like whether it is active low or high, what kind of | 
 | internal pull resistor within the SoC should be enabled in order to communicate | 
 | with the device, etc., to the driver. | 
 |  | 
 | In the devicetree, there will be a node that represents the GPIO controller | 
 | that controls a group of pins. This reflects the way GPIO IP blocks are usually | 
 | developed in hardware. Therefore, there is no single node in the devicetree | 
 | that represents a GPIO pin, and you can't use a single phandle to represent it. | 
 |  | 
 | Instead, you would use a phandle-array property, like this: | 
 |  | 
 | .. code-block:: | 
 |  | 
 |    my-external-ic { | 
 |            irq-gpios = <&gpioX pin flags>; | 
 |    }; | 
 |  | 
 | In this example, ``irq-gpios`` is a phandle-array property with just one | 
 | "group" in its value. ``&gpioX`` is the phandle for the GPIO controller node | 
 | that controls the pin. ``pin`` is the pin number (0, 1, 2, ...). ``flags`` is a | 
 | bit mask describing pin metadata (for example ``(GPIO_ACTIVE_LOW | | 
 | GPIO_PULL_UP)``); see :zephyr_file:`include/zephyr/dt-bindings/gpio/gpio.h` for | 
 | more details. | 
 |  | 
 | The device driver handling the ``my-external-ic`` node can then use the | 
 | ``irq-gpios`` property's value to set up interrupt handling for the chip as it | 
 | is used on your board. This lets you configure the device driver in devicetree, | 
 | without changing the driver's source code. | 
 |  | 
 | Such properties can contain multiple values as well: | 
 |  | 
 | .. code-block:: | 
 |  | 
 |    my-other-external-ic { | 
 |            handshake-gpios = <&gpioX pinX flagsX>, <&gpioY pinY flagsY>; | 
 |    }; | 
 |  | 
 | The above example specifies two pins: | 
 |  | 
 | - ``pinX`` on the GPIO controller with phandle ``&gpioX``, flags ``flagsX`` | 
 | - ``pinY`` on ``&gpioY``, flags ``flagsY`` | 
 |  | 
 | You may be wondering how the "pin and flags" convention is established and | 
 | enforced. To answer this question, we'll need to introduce a concept called | 
 | specifier spaces before moving on to some information about devicetree | 
 | bindings. | 
 |  | 
 | .. _dt-specifier-spaces: | 
 |  | 
 | Specifier spaces | 
 | **************** | 
 |  | 
 | *Specifier spaces* are a way to allow nodes to describe how you should | 
 | use them in phandle-array properties. | 
 |  | 
 | We'll start with an abstract, high level description of how specifier spaces | 
 | work in DTS files, before moving on to a concrete example and providing | 
 | references to further reading for how this all works in practice using DTS | 
 | files and bindings files. | 
 |  | 
 | High level description | 
 | ====================== | 
 |  | 
 | As described above, a phandle-array property is a sequence of "groups" of | 
 | phandles followed by some number of cells: | 
 |  | 
 | .. code-block:: dts | 
 |  | 
 |    node { | 
 |            phandle-array-prop = <&foo 1 2>, <&bar 3>; | 
 |    }; | 
 |  | 
 | The cells that follow each phandle are called a *specifier*. In this example, | 
 | there are two specifiers: | 
 |  | 
 | #. ``1 2``: two cells | 
 | #. ``3``: one cell | 
 |  | 
 | Every phandle-array property has an associated *specifier space*. This sounds | 
 | complex, but it's really just a way to assign a meaning to the cells that | 
 | follow each phandle in a hardware specific way. Every specifier space has a | 
 | unique name. There are a few "standard" names for commonly used hardware, but | 
 | you can create your own as well. | 
 |  | 
 | Devicetree nodes encode the number of cells that must appear in a specifier, by | 
 | name, using the ``#SPACE_NAME-cells`` property. For example, let's assume that | 
 | ``phandle-array-prop``\ 's specifier space is named ``baz``. Then we would need | 
 | the ``foo`` and ``bar`` nodes to have the following ``#baz-cells`` properties: | 
 |  | 
 | .. code-block:: DTS | 
 |  | 
 |    foo: node@1000 { | 
 |            #baz-cells = <2>; | 
 |    }; | 
 |  | 
 |    bar: node@2000 { | 
 |            #baz-cells = <1>; | 
 |    }; | 
 |  | 
 | Without the ``#baz-cells`` property, the devicetree tooling would not be able | 
 | to validate the number of cells in each specifier in ``phandle-array-prop``. | 
 |  | 
 | This flexibility allows you to write down an array of hardware resources in a | 
 | single devicetree property, even though the amount of metadata you need to | 
 | describe each resource might be different for different nodes. | 
 |  | 
 | A single node can also have different numbers of cells in different specifier | 
 | spaces. For example, we might have: | 
 |  | 
 | .. code-block:: DTS | 
 |  | 
 |    foo: node@1000 { | 
 |            #baz-cells = <2>; | 
 |            #bob-cells = <1>; | 
 |    }; | 
 |  | 
 |  | 
 | With that, if ``phandle-array-prop-2`` has specifier space ``bob``, we could | 
 | write: | 
 |  | 
 | .. code-block:: DTS | 
 |  | 
 |    node { | 
 |            phandle-array-prop = <&foo 1 2>, <&bar 3>; | 
 |            phandle-array-prop-2 = <&foo 4>; | 
 |    }; | 
 |  | 
 | This flexibility allows you to have a node that manages multiple different | 
 | kinds of resources at the same time. The node describes the amount of metadata | 
 | needed to describe each kind of resource (how many cells are needed in each | 
 | case) using different ``#SPACE_NAME-cells`` properties. | 
 |  | 
 | Example specifier space: gpio | 
 | ============================= | 
 |  | 
 | From the above example, you're already familiar with how one specifier space | 
 | works: in the "gpio" space, specifiers almost always have two cells: | 
 |  | 
 | #. a pin number | 
 | #. a bit mask of flags related to the pin | 
 |  | 
 | Therefore, almost all GPIO controller nodes you will see in practice will look | 
 | like this: | 
 |  | 
 | .. code-block:: DTS | 
 |  | 
 |    gpioX: gpio-controller@deadbeef { | 
 |            gpio-controller; | 
 |            #gpio-cells = <2>; | 
 |    }; | 
 |  | 
 | Associating properties with specifier spaces | 
 | ******************************************** | 
 |  | 
 | Above, we have described that: | 
 |  | 
 | - each phandle-array property has an associated specifier space | 
 | - specifier spaces are identified by name | 
 | - devicetree nodes use ``#SPECIFIER_NAME-cells`` properties to | 
 |   configure the number of cells which must appear in a specifier | 
 |  | 
 | In this section, we explain how phandle-array properties get their specifier | 
 | spaces. | 
 |  | 
 | High level description | 
 | ====================== | 
 |  | 
 | In general, a ``phandle-array`` property named ``foos`` implicitly has | 
 | specifier space ``foo``. For example: | 
 |  | 
 | .. code-block:: YAML | 
 |  | 
 |    properties: | 
 |      dmas: | 
 |        type: phandle-array | 
 |      pwms: | 
 |        type: phandle-array | 
 |  | 
 | The ``dmas`` property's specifier space is "dma". The ``pwm`` property's | 
 | specifier space is ``pwm``. | 
 |  | 
 | Special case: GPIO | 
 | ================== | 
 |  | 
 | ``*-gpios`` properties are special-cased so that e.g. ``foo-gpios`` resolves to | 
 | ``#gpio-cells`` rather than ``#foo-gpio-cells``. | 
 |  | 
 | Manually specifying a space | 
 | =========================== | 
 |  | 
 | You can manually specify the specifier space for any ``phandle-array`` | 
 | property. See :ref:`dt-bindings-specifier-space`. | 
 |  | 
 | Naming the cells in a specifier | 
 | ******************************* | 
 |  | 
 | You should name the cells in each specifier space your hardware supports when | 
 | writing bindings. For details on how to do this, see :ref:`dt-bindings-cells`. | 
 |  | 
 | This allows C code to query information about and retrieve the values of cells | 
 | in a specifier by name using devicetree APIs like these: | 
 |  | 
 | - :c:macro:`DT_PHA_BY_IDX` | 
 | - :c:macro:`DT_PHA_BY_NAME` | 
 |  | 
 | This feature and these macros are used internally by numerous hardware-specific | 
 | APIs. Here are a few examples: | 
 |  | 
 | - :c:macro:`DT_GPIO_PIN_BY_IDX` | 
 | - :c:macro:`DT_PWMS_CHANNEL_BY_IDX` | 
 | - :c:macro:`DT_DMAS_CELL_BY_NAME` | 
 | - :c:macro:`DT_IO_CHANNELS_INPUT_BY_IDX` | 
 | - :c:macro:`DT_CLOCKS_CELL_BY_NAME` | 
 |  | 
 | See also | 
 | ******** | 
 |  | 
 | - :ref:`dt-writing-property-values`: how to write phandles in devicetree | 
 |   properties | 
 |  | 
 | - :ref:`dt-bindings-properties`: how to write bindings for properties with | 
 |   phandle types (``phandle``, ``phandles``, ``phandle-array``) | 
 |  | 
 | - :ref:`dt-bindings-specifier-space`: how to manually specify a phandle-array | 
 |   property's specifier space |