Re: [PATCH v3] Add new `export-symbols` node
Andrew Davis <[email protected]> Wed, 30 Apr 2025 13:56:33 -0500
| Newsgroups | org.kernel.vger.devicetree-spec,org.kernel.vger.linux-devicetree |
|---|---|
| Message-ID | <[email protected]> |
On 4/30/25 2:32 AM, Ayush Singh wrote: > On 4/30/25 01:21, Andrew Davis wrote: > >> On 4/29/25 2:15 PM, Ayush Singh wrote: >>> On 4/11/25 13:30, 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. >>>> >>>> Reviewed-by: Herve Codina <[email protected]> >>>> Reviewed-by: Luca Ceresoli <[email protected]> >>>> 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. >>>> >>>> Linux kernel already provides APIs to apply overlays at specific nodes >>>> [10], and I have a patch series to have similar functionality in >>>> fdtoverlay [11]. This is to allow writing overlays for addon-boards, >>>> that will be expected to be applied to the connector nodes, instead of >>>> on the global tree. >>>> >>>> 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 some resources like GPIO and PWM from the overlay. >>>> However, that still leaves things like pinmux, i2c adapter, etc. >>>> >>>> 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. This allows specifying the >>>> phandles to i2c adapter, pinmux, etc, per connector. Since the names >>>> used for these phandles for each connector can be standardized, it would >>>> allow having the same addon-board overaly work for connectors on >>>> different boards (or multiple connectors on the same board). >>>> >>>> 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 { >>>> GPIO_CONNECTOR = <&connector1>; >>>> PIN_33_GPIO_PINMUX = <&p1_33_gpio>; >>>> }; >>>> }; >>>> >>>> Our overlay can use thi >>>> >>>> leds { >>>> pinctrl-names = "default"; >>>> pinctrl-0 = <&PIN_33_GPIO_PINMUX>; >>>> >>>> led-1 { >>>> gpios = <&GPIO_CONNECTOR 33 GPIO_ACTIVE_HIGH>; >>>> }; >>>> }; >>>> >>>> It used the P1_33 pin in the connector it is applied on. >>>> >>>> A board with two connectors can be described with: >>>> >>>> connector1: connector1 { >>>> ... >>>> export-symbols { >>>> GPIO_CONNECTOR = <&connector1>; >>>> PIN_33_GPIO_PINMUX = <&p1_33_gpio>; >>>> }; >>>> }; >>>> >>>> connector2: connector2 { >>>> ... >>>> export-symbols { >>>> GPIO_CONNECTOR = <&connector2>; >>>> PIN_33_GPIO_PINMUX = <&p3_33_gpio>; >>>> }; >>>> }; >>>> >>>> In that case, the same overlay with unresolved `GPIO_CONNECTOR` and >>>> `PIN_33_GPIO_PINMUX` symbol can be applied on both connectors and the >>>> correct symbol resolution will be done. >>>> >>>> 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 >>>> [10]: https://docs.kernel.org/devicetree/kernel-api.html#c.of_overlay_fdt_apply >>>> [11]: https://lore.kernel.org/devicetree-compiler/[email protected]/T/#t >>>> >>>> Best Regards, >>>> Ayush Singh >>>> --- >>>> Changes in v3: >>>> - Add trailer >>>> - CC linux-devicetree >>>> - Link to v2: https://lore.kernel.org/r/[email protected] >>>> >>>> Changes in v2: >>>> - Improve examples. More focus on export-symbols and less on nexus nodes >>>> - Fix typo. >>>> - Link to v1: https://lore.kernel.org/r/[email protected] >>>> --- >>>> source/chapter3-devicenodes.rst | 89 +++++++++++++++++++++++++++++++++++++++++ >>>> 1 file changed, 89 insertions(+) >>>> >>>> diff --git a/source/chapter3-devicenodes.rst b/source/chapter3-devicenodes.rst >>>> index 8080321d6e60d6b1e86c81af86c6850246a0223b..2c3bbc2c81bacd71fcf3b389a31237344f995ba7 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 or 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, >>> >>> >>> I have a very basic pocketbeagle2 connector driver with overlay for techlab cape [0]. It only uses export-symbols for pinmuxes for now, but might provide an example of use outside of nexus nodes. >>> >>> >>> [0]: https://github.com/Ayush1325/linux/tree/b4/beagle-cape >>> >> >> You have proven my point here. You were only able to model the GPIO >> attached devices: buttons and LEDs. Nothing else of this cape was >> modeled, nor could it be modeled with this solution. > > > For i2c, I first need to implement the i2c bus extensions [0]. Something similar for SPI, UART, etc. Somewhat long list of things. > That is exactly the issue, I'd think I2C extensions would be the trivial case but even it is getting some (valid) push back, how do you intend to do the same for SPI, UART, etc.. Would take years even at the best rate. Any solution that requires modifying the schema for every type of peripheral node is a non-starter. > >> >> Your example fails to do even the most fundamental task: the overlay >> is still specific to just one host board. Go connect this cape to >> an original PocketBeagle and try to apply the overlay to its DTS.. > > > Once I make the connector node a gpio and pwm nexus node, it will not be specific to just one host board. But yes, the current one is like that. > > >> >> What you did with "export-symbols" in this example could have been >> done exactly the same with normal overlays. These "examples" keep >> showing "what" the "export-symbols" node does, not "why" it is >> needed or better than just normal __symbols__. >> >> Andrew > > > No, it cannot be. When using `__symbols__`, the changes are not contained to a single devicetree nodes. As you can see even in the current form of the overlay, any modifications happen inside the connector node. Nothing outside of the connector node is modified at runtime. > > I am not here to argue whether runtime global devicetree manipulation is an okay thing to do. I would be fine with it if upstream is okay with it. But neither sysfs based, nor configfs based patches for dynamic devicetree are being considered for that exact reason. > > I am working from the assumption that upstream will not accept a global devicetree manipulation solution. So for local node based solution, export-symbols are essential. If I misunderstood something in this very basic assumption, then feel free to correct me. > > Do note, that any solution cannot just stay as a static, apply using fdtoverlay kind of thing. It needs to allow for dynamic discovery using both EEPROM or something similar, and a fallback using sysfs or configfs. > Any static solution (works with just fdtoverlay) can be extended to the dynamic discovery case by simply doing the application of the overlay exactly the same way, but at runtime. The issue "global devicetree manipulation" seems to be around how unloading of the overlay would work, which is an unsolved problem for a lot of other reasons. Just to note here, I have no issue with export-symbols, I think it is a useful addition to the DT toolbox. All I'm trying to do here is understand what you plan to do with this new tool. Hence asking for a *complete* and *functional* example with a real add-on board, so I can see how many more tools will be needed after this one. Anyway seems like you are trying to consolidate the all the current discussions on this to one thread[0], so we can continue this over there. Thanks, Andrew [0] https://www.spinics.net/lists/kernel/msg5663574.html > > Best Regards, > > Ayush Singh > > > [0]: https://lore.kernel.org/devicetree-spec/[email protected]/T/#m5ae5b64b0e7fcae709127b99c8aa10fc28fb1ea8 >