Re: [PATCH] Add new `export-symbols` node
Andrew Davis <[email protected]>
| Newsgroups | org.kernel.vger.devicetree-spec |
|---|---|
| Message-ID | <[email protected]> |
On 2/25/25 12:02 AM, Ayush Singh wrote: > `export-symbols` is designed to be a local replacement of global > `__symbols__` allowing nodes to define aliases to nodes in a tree, which > will take precedence over the aliases defined in the global `__symbols__`. > > Having a way to allow node local aliases helps in usecases such as > connectors and addon-boards, by allowing decoupling of > overlays/devicetree nodes of addon-board from the base connector. > > Signed-off-by: Ayush Singh <[email protected]> > --- > This patch series follows the initial RFC [9] sent a few weeks ago. I > will be reiterating the RFC here for anyone who might be seeing this the > first time, since there was not much feedback in that thread. > > The patch series adds export-symbols to base devicetree specification to > allow for support of base board + runtime connector setups using devicetree > overlays. The idea was actually proposed in the linux kernel mailing list > by Herve Codina [0] with the devicetree schema and linux kernel > implementation. Initial implementations for devicetree compiler [1] and > fdtoverlay [2] have also been sent to the mailing lists. > > Introduction > ************* > > There are a lot of setups, especially in embedded systems that consist of > a base connector and addon boards that can be connected to this connector. > Here are some examples: > - MikroBus > - GE SUNH > - BeagleCapes, etc > > Some of these connectors have runtime detection capabilities (GE SUNH), > while some do not (MikroBUS without 1-wire EEPROM). The goal is to decouple > the connector on base device tree with the overlay for addon boards. This > will allow having 1 overlay for each board that would work with connector > devicetree on any board. > > One of the issue was referencing resources available on the base board > device tree from the addon overlay device tree. Using a nexus node [3] > helps decoupling resources and avoid the knowledge of the full base board > from the overlay. Indeed, with nexus node, the overlay need to know only > about the nexus node itself. > > For instance, suppose a connector where a GPIO is connected at PinA. On the > base board this GPIO is connected to the GPIO 12 of the SoC GPIO controller. > > The base board can describe this GPIO using a nexus node: > > soc_gpio: gpio-controller { > #gpio-cells = <2>; > }; > > connector1: connector1 { > /* > * Nexus node for the GPIO available on the connector. > * GPIO 0 (Pin A GPIO) is connected to GPIO 12 of the SoC gpio > * controller > */ > #gpio-cells = <2>; > gpio-map = <0 0 &soc_gpio 12 0>; > gpio-map-mask = <0xf 0x0>; > gpio-map-pass-thru = <0x0 0xf>; > }; > > The connector pin A GPIO can be referenced using: > > <&connector1 0 GPIO_ACTIVE_HIGH> > > This implies that the overlay needs to know about exact label that > references the connector. This label can be different on a different board > and so applying the overlay could fail even if it is used to describe the > exact same addon board. Further more, a given base board can have several > connectors where the exact same addon board can be connected. In that case, > the same overlay cannot be used on both connector. Indeed, the connector > labels have to be different. > > The `export-symbols` node solves this issue. > > The idea of export-symbols is to have something similar to the global > `__symbols__` node but local to a specific node. Symbols listed in this > export-symbols are local and visible only when an overlay is applied on a > node having an export-symbols subnode. > > Note: `export-symbols` properties differ from __symbols__ since they are > phandles, not path references. This is much easier to work with in > overlays as described in [7]. > > Using export-symbols, our example becomes: > > soc_gpio: gpio-controller { > #gpio-cells = <2>; > }; > > connector1: connector1 { > /* > * Nexus node for the GPIO available on the connector. > * GPIO 0 (Pin A GPIO) is connected to GPIO 12 of the SoC gpio > * controller > */ > #gpio-cells = <2>; > gpio-map = <0 0 &soc_gpio 12 0>; > gpio-map-mask = <0xf 0x0>; > gpio-map-pass-thru = <0x0 0xf>; > > export-symbols { > connector = <&connector1>; > }; > }; > > With that export-symbols node, an overlay applied on connector1 node can > have the symbol named 'connector' resolved to connector1. Indeed, the > `export-symbols` node available at connector1 node is used when the overlay > is applied. If the overlay has an unresolved 'connector' symbol, it will be > resolved to connector1 thanks to export-symbols. > > Our overlay using the nexus node can contains: > > node { > foo-gpio = <&connector 0 GPIO_ACTIVE_HIGH>; > }; > > It used the GPIO 0 from the connector it is applied on. > > A board with two connectors can be described with: > > connector1: connector1 { > ... > export-symbols { > connector = <&connector1>; > }; > }; > > connector2: connector2 { > ... > export-symbols { > connector = <&connector2>; > }; > }; > > In that case, the same overlay with unresolved 'connector' symbol can be > applied on both connectors and the correct symbol resolution (connector1 > or connector2) will be done. How? I feel this gets hand-waved over but is the core issue you are trying to solve. Let's say I have the above, 2 of the same connector on a board, how do I apply my add-on overlay to one and not the other, or to both? I believe you have suggested maybe specifying the connector with a hint when applying it, so my question is why can't this "hint" just be the connector name without the export-symbols indirection? Maybe a concrete example could help me get the full picture here, say I want to do this ahead of time in U-Boot during boot (so I have basically just "fdtapply"). I know the name of the base DT and the name of the device overlay. What steps do I take here? Andrew > > Alternatives > ************* > > Some alternative approaches that were considered: > > 1. Using aliases. > > Currently, it is not possible to update aliases in device tree overlays. > I sent a patch a few weeks ago to add this support [4]. However, as was > outlined by Rob, this can break existing drivers that used the unused > indexes for devices not present in the aliases list. > > 2. Add support for phandles in `__symbols__` > > This has been discussed in the following patch series [5]. However, > since there is no way to distinguish between strings and phandles in > devicetree (everything is bytestring), the type guessing is awkward. > Also, the export-symbol solution is much more flexible than extending > the old `__symbols__` node. > > 3. Add support for path reference resolution to overlays > > An approach using `__symbols__` was proposed by Andrew Davis [6]. > However, currently, it is difficult to support path reference resolution > support to overlays [7]. This limitation makes it difficult to support > connector chaining (MikroBUS -> Grove -> Addon board), which is possible > in some connectors. > > Some other benefits to export-symbols > ************************************** > > 1. No need to enable generation of all symbols in base devicetree > Since the nodes used by connector are referenced by properties in > `export-symbols`, the symbols table entries for these nodes will be > generated, even if symbols generation is not enabled globally. This > can help save space, specially in constrained devices. > > 2. Enables scoping symbol resolution > Does not pollute the global symbols, and can be useful outside addon > board setups. > > Why add to specification? > ************************** > > I would like the ability to share the addon board overlays with > ZephyrRTOS, which also has boards that support MikroBUS (like BeagleConnect > Freedom [8]) and U-Boot. So it would make more sense if this node is part > of the specification instead of linux specific. > > [0]: https://lore.kernel.org/all/[email protected]/ > [1]: https://lore.kernel.org/all/[email protected]/ > [2]: https://lore.kernel.org/devicetree-compiler/[email protected]/T/#t > [3] https://github.com/devicetree-org/devicetree-specification/blob/v0.4/source/chapter2-devicetree-basics.rst#nexus-nodes-and-specifier-mapping > [4]: https://lore.kernel.org/all/[email protected]/T/#t > [5]: https://lore.kernel.org/devicetree-compiler/[email protected]/T/#mbbc181b0ef394b85b76b2024d7e209ebe70f7003 > [6]: https://lore.kernel.org/lkml/[email protected]/ > [7]: https://lore.kernel.org/devicetree-compiler/[email protected]/T/#m8259c8754f680b9da7b91f7b7dd89f10da91d8ed > [8]: https://www.beagleboard.org/boards/beagleconnect-freedom > [9]: https://lore.kernel.org/devicetree-spec/[email protected]/T/#mc339a0ae0c886ca46da0f7bb679518fa8b0b3007 > > Best Regards, > Ayush Singh > --- > source/chapter3-devicenodes.rst | 89 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 89 insertions(+) > > diff --git a/source/chapter3-devicenodes.rst b/source/chapter3-devicenodes.rst > index 8080321d6e60d6b1e86c81af86c6850246a0223b..c525eec7c5cd30a5ba933b4c0592c6a16cb14f6a 100644 > --- a/source/chapter3-devicenodes.rst > +++ b/source/chapter3-devicenodes.rst > @@ -988,3 +988,92 @@ each with their own on-chip L2 and a shared L3. > }; > }; > }; > + > +``*/export-symbols`` node > +------------------------- > +A devicetree node may have an export-symbols child node > +(`*/export-symbols`) that defines one of more export-symbol properties. > + > +Each property of the `export-symbols` node defines an alias local to it's > +parent. The property name specifies the alias name. The property value > +specifies the phandle to a node in the devicetree. For example, the > +property ``serial0 = <&main_uart0>`` defines ``serial0`` as the local alias > +to ``main_uart0``. > + > +Alias names shall be lowercase text strings of 1 to 31 characters from the > +following set of characters. > + > +.. tabularcolumns:: | c p{8cm} | > +.. table:: Valid characters for alias names > + > + ========= ================ > + Character Description > + ========= ================ > + 0-9 digit > + a-z lowercase letter > + \- dash > + ========= ================ > + > +An alias value is a phandle to a node in the devicetree. > + > +Resolution of nodes using `export-symbols` follows the following rules > +depending on the context: > + > +No target involved > +~~~~~~~~~~~~~~~~~~~ > +Properties of parent node use symbols from ``export-symbols``, but none of > +the subnodes will be able to use them. For example, the following code will > +resolve properly: > + > +.. code-block:: dts > + > + / { > + parent { > + led = <&local_gpio 0 GPIO_ACTIVE_HIGH>; > + > + export-symbols { > + local_gpio = <&gpio0>; > + }; > + }; > + } > + > +However, the code below is not valid: > + > +.. code-block:: dts > + > + / { > + parent { > + child { > + /* child node cannot access export-symbols */ > + led = <&local_gpio 0 GPIO_ACTIVE_HIGH>; > + }; > + > + export-symbols { > + local_gpio = <&gpio0>; > + }; > + }; > + } > + > +Target is used in the base devicetree or overlays > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > +Any node/subnode property is free to use symbols from ``export-symbols`` > +defined in the parent. To provide a concrete exampe, the following is > +valid: > + > +.. code-block:: dts > + > + / { > + parent { > + export-symbols { > + local_gpio = <&gpio0>; > + }; > + }; > + } > + > + &parent { > + led = <&local_gpio 0 GPIO_ACTIVE_HIGH>; > + > + child { > + led = <&local_gpio 0 GPIO_ACTIVE_HIGH>; > + }; > + }; > > --- > base-commit: 5688e1c0b961d2ca5a32e3b624a9f4a9b433184f > change-id: 20250225-export-symbols-3524f124cd93 > > Best regards,