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