Re: [PATCH v3] Add new `export-symbols` node

Ayush Singh <[email protected]> Wed, 30 Apr 2025 00:45:35 +0530
Newsgroups org.kernel.vger.devicetree-spec,org.kernel.vger.linux-devicetree
Message-ID <[email protected]>
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


Best Regards,

Ayush Singh