1.. _dt-phandles: 2 3Phandles 4######## 5 6The devicetree concept of a *phandle* is very similar to pointers in 7C. You can use phandles to refer to nodes in devicetree similarly to the way 8you can use pointers to refer to structures in C. 9 10.. contents:: Contents 11 :local: 12 13Getting phandles 14**************** 15 16The usual way to get a phandle for a devicetree node is from one of its node 17labels. For example, with this devicetree: 18 19.. code-block:: DTS 20 21 / { 22 lbl_a: node-1 {}; 23 lbl_b: lbl_c: node-2 {}; 24 }; 25 26You can write the phandle for: 27 28- ``/node-1`` as ``&lbl_a`` 29- ``/node-2`` as either ``&lbl_b`` or ``&lbl_c`` 30 31Notice how the ``&nodelabel`` devicetree syntax is similar to the "address of" 32C syntax. 33 34Using phandles 35************** 36 37.. note:: 38 39 "Type" in this section refers to one of the type names documented in 40 :ref:`dt-bindings-properties` in the devicetree bindings documentation. 41 42Here are the main ways you will use phandles. 43 44One node: phandle type 45====================== 46 47You can use phandles to refer to ``node-b`` from ``node-a``, where ``node-b`` 48is related to ``node-a`` in some way. 49 50One common example is when ``node-a`` represents some hardware that 51generates an interrupt, and ``node-b`` represents the interrupt 52controller that receives the asserted interrupt. In this case, you could 53write: 54 55.. code-block:: DTS 56 57 node_b: node-b { 58 interrupt-controller; 59 }; 60 61 node-a { 62 interrupt-parent = <&node_b>; 63 }; 64 65This uses the standard ``interrupt-parent`` property defined in the 66devicetree specification to capture the relationship between the two nodes. 67 68These properties have type ``phandle``. 69 70Zero or more nodes: phandles type 71================================= 72 73You can use phandles to make an array of references to other nodes. 74 75One common example occurs in :ref:`pin control <pinctrl-guide>`. Pin control 76properties like ``pinctrl-0``, ``pinctrl-1`` etc. may contain multiple 77phandles, each of which "points" to a node containing information related to 78pin configuration for that hardware peripheral. Here's an example of six 79phandles in a single property: 80 81.. code-block:: DTS 82 83 pinctrl-0 = <&quadspi_clk_pe10 &quadspi_ncs_pe11 84 &quadspi_bk1_io0_pe12 &quadspi_bk1_io1_pe13 85 &quadspi_bk1_io2_pe14 &quadspi_bk1_io3_pe15>; 86 87These properties have type ``phandles``. 88 89Zero or more nodes with metadata: phandle-array type 90==================================================== 91 92You can use phandles to refer to and configure one or more resources that are 93"owned" by some other node. 94 95This is the most complex case. There are examples and more details in the 96next section. 97 98These properties have type ``phandle-array``. 99 100.. _dt-phandle-arrays: 101 102phandle-array properties 103************************ 104 105These properties are commonly used to specify a resource that is owned by 106another node along with additional metadata about the resource. 107 108High level description 109====================== 110 111Usually, properties with this type are written like ``phandle-array-prop`` in 112this example: 113 114.. code-block:: dts 115 116 node { 117 phandle-array-prop = <&foo 1 2>, <&bar 3>, <&baz 4 5>; 118 }; 119 120That is, the property's value is written as a comma-separated sequence of 121"groups", where each "group" is written inside of angle brackets (``< ... >``). 122Each "group" starts with a phandle (``&foo``, ``&bar``, ``&baz``). The values 123that follow the phandle in each "group" are called *specifiers*. There are 124three specifiers in the above example: 125 126#. ``1 2`` 127#. ``3`` 128#. ``4 5`` 129 130The phandle in each "group" is used to "point" to the hardware that controls 131the resource you are interested in. The specifier describes the resource 132itself, along with any additional necessary metadata. 133 134The rest of this section describes a common example. Subsequent sections 135document more rules about how to use phandle-array properties in practice. 136 137Example phandle-arrays: GPIOs 138============================= 139 140Perhaps the most common use case for phandle-array properties is specifying one 141or more GPIOs on your SoC that another chip on your board connects to. For that 142reason, we'll focus on that use case here. However, there are **many other use 143cases** that are handled in devicetree with phandle-array properties. 144 145For example, consider an external chip with an interrupt pin that is connected 146to a GPIO on your SoC. You will typically need to provide that GPIO's 147information (GPIO controller and pin number) to the :ref:`device driver 148<device_model_api>` for that chip. You usually also need to provide other 149metadata about the GPIO, like whether it is active low or high, what kind of 150internal pull resistor within the SoC should be enabled in order to communicate 151with the device, etc., to the driver. 152 153In the devicetree, there will be a node that represents the GPIO controller 154that controls a group of pins. This reflects the way GPIO IP blocks are usually 155developed in hardware. Therefore, there is no single node in the devicetree 156that represents a GPIO pin, and you can't use a single phandle to represent it. 157 158Instead, you would use a phandle-array property, like this: 159 160.. code-block:: 161 162 my-external-ic { 163 irq-gpios = <&gpioX pin flags>; 164 }; 165 166In this example, ``irq-gpios`` is a phandle-array property with just one 167"group" in its value. ``&gpioX`` is the phandle for the GPIO controller node 168that controls the pin. ``pin`` is the pin number (0, 1, 2, ...). ``flags`` is a 169bit mask describing pin metadata (for example ``(GPIO_ACTIVE_LOW | 170GPIO_PULL_UP)``); see :zephyr_file:`include/zephyr/dt-bindings/gpio/gpio.h` for 171more details. 172 173The device driver handling the ``my-external-ic`` node can then use the 174``irq-gpios`` property's value to set up interrupt handling for the chip as it 175is used on your board. This lets you configure the device driver in devicetree, 176without changing the driver's source code. 177 178Such properties can contain multiple values as well: 179 180.. code-block:: 181 182 my-other-external-ic { 183 handshake-gpios = <&gpioX pinX flagsX>, <&gpioY pinY flagsY>; 184 }; 185 186The above example specifies two pins: 187 188- ``pinX`` on the GPIO controller with phandle ``&gpioX``, flags ``flagsX`` 189- ``pinY`` on ``&gpioY``, flags ``flagsY`` 190 191You may be wondering how the "pin and flags" convention is established and 192enforced. To answer this question, we'll need to introduce a concept called 193specifier spaces before moving on to some information about devicetree 194bindings. 195 196.. _dt-specifier-spaces: 197 198Specifier spaces 199**************** 200 201*Specifier spaces* are a way to allow nodes to describe how you should 202use them in phandle-array properties. 203 204We'll start with an abstract, high level description of how specifier spaces 205work in DTS files, before moving on to a concrete example and providing 206references to further reading for how this all works in practice using DTS 207files and bindings files. 208 209High level description 210====================== 211 212As described above, a phandle-array property is a sequence of "groups" of 213phandles followed by some number of cells: 214 215.. code-block:: dts 216 217 node { 218 phandle-array-prop = <&foo 1 2>, <&bar 3>; 219 }; 220 221The cells that follow each phandle are called a *specifier*. In this example, 222there are two specifiers: 223 224#. ``1 2``: two cells 225#. ``3``: one cell 226 227Every phandle-array property has an associated *specifier space*. This sounds 228complex, but it's really just a way to assign a meaning to the cells that 229follow each phandle in a hardware specific way. Every specifier space has a 230unique name. There are a few "standard" names for commonly used hardware, but 231you can create your own as well. 232 233Devicetree nodes encode the number of cells that must appear in a specifier, by 234name, using the ``#SPACE_NAME-cells`` property. For example, let's assume that 235``phandle-array-prop``\ 's specifier space is named ``baz``. Then we would need 236the ``foo`` and ``bar`` nodes to have the following ``#baz-cells`` properties: 237 238.. code-block:: DTS 239 240 foo: node@1000 { 241 #baz-cells = <2>; 242 }; 243 244 bar: node@2000 { 245 #baz-cells = <1>; 246 }; 247 248Without the ``#baz-cells`` property, the devicetree tooling would not be able 249to validate the number of cells in each specifier in ``phandle-array-prop``. 250 251This flexibility allows you to write down an array of hardware resources in a 252single devicetree property, even though the amount of metadata you need to 253describe each resource might be different for different nodes. 254 255A single node can also have different numbers of cells in different specifier 256spaces. For example, we might have: 257 258.. code-block:: DTS 259 260 foo: node@1000 { 261 #baz-cells = <2>; 262 #bob-cells = <1>; 263 }; 264 265 266With that, if ``phandle-array-prop-2`` has specifier space ``bob``, we could 267write: 268 269.. code-block:: DTS 270 271 node { 272 phandle-array-prop = <&foo 1 2>, <&bar 3>; 273 phandle-array-prop-2 = <&foo 4>; 274 }; 275 276This flexibility allows you to have a node that manages multiple different 277kinds of resources at the same time. The node describes the amount of metadata 278needed to describe each kind of resource (how many cells are needed in each 279case) using different ``#SPACE_NAME-cells`` properties. 280 281Example specifier space: gpio 282============================= 283 284From the above example, you're already familiar with how one specifier space 285works: in the "gpio" space, specifiers almost always have two cells: 286 287#. a pin number 288#. a bit mask of flags related to the pin 289 290Therefore, almost all GPIO controller nodes you will see in practice will look 291like this: 292 293.. code-block:: DTS 294 295 gpioX: gpio-controller@deadbeef { 296 gpio-controller; 297 #gpio-cells = <2>; 298 }; 299 300Associating properties with specifier spaces 301******************************************** 302 303Above, we have described that: 304 305- each phandle-array property has an associated specifier space 306- specifier spaces are identified by name 307- devicetree nodes use ``#SPECIFIER_NAME-cells`` properties to 308 configure the number of cells which must appear in a specifier 309 310In this section, we explain how phandle-array properties get their specifier 311spaces. 312 313High level description 314====================== 315 316In general, a ``phandle-array`` property named ``foos`` implicitly has 317specifier space ``foo``. For example: 318 319.. code-block:: YAML 320 321 properties: 322 dmas: 323 type: phandle-array 324 pwms: 325 type: phandle-array 326 327The ``dmas`` property's specifier space is "dma". The ``pwm`` property's 328specifier space is ``pwm``. 329 330Special case: GPIO 331================== 332 333``*-gpios`` properties are special-cased so that e.g. ``foo-gpios`` resolves to 334``#gpio-cells`` rather than ``#foo-gpio-cells``. 335 336Manually specifying a space 337=========================== 338 339You can manually specify the specifier space for any ``phandle-array`` 340property. See :ref:`dt-bindings-specifier-space`. 341 342Naming the cells in a specifier 343******************************* 344 345You should name the cells in each specifier space your hardware supports when 346writing bindings. For details on how to do this, see :ref:`dt-bindings-cells`. 347 348This allows C code to query information about and retrieve the values of cells 349in a specifier by name using devicetree APIs like these: 350 351- :c:macro:`DT_PHA_BY_IDX` 352- :c:macro:`DT_PHA_BY_NAME` 353 354This feature and these macros are used internally by numerous hardware-specific 355APIs. Here are a few examples: 356 357- :c:macro:`DT_GPIO_PIN_BY_IDX` 358- :c:macro:`DT_PWMS_CHANNEL_BY_IDX` 359- :c:macro:`DT_DMAS_CELL_BY_NAME` 360- :c:macro:`DT_IO_CHANNELS_INPUT_BY_IDX` 361- :c:macro:`DT_CLOCKS_CELL_BY_NAME` 362 363See also 364******** 365 366- :ref:`dt-writing-property-values`: how to write phandles in devicetree 367 properties 368 369- :ref:`dt-bindings-properties`: how to write bindings for properties with 370 phandle types (``phandle``, ``phandles``, ``phandle-array``) 371 372- :ref:`dt-bindings-specifier-space`: how to manually specify a phandle-array 373 property's specifier space 374