Device tree representation of (hotplug) connectors: discussion at ELCE
Hello,
[this main was co-written by Hervé and Luca]
Hervé and I are working since 1+y to allow describing hot-pluggable add-ons and their connectors with device tree overlays. Our work is not very much progressing because discussions about device tree bindings has raised some issue that are not obvious to solve.
This e-mail is a report of the efforts we did last week during the Embedded Linux Conference Europe to try to address the currently blocking issues.
First, I gave a talk about the overall hotplug work, to provide a status update but also to clarify the goals and use cases. Slides are available at [2]. Goals include:
- decoupling base board and add-on, so an addon can have a single dtbo valid for any base board, and vice versa
- supporting main boards with multiple connectors where multiple instances of the same addon model can be connected independently
- allowing overlay insertion and removal at runtime (hotplug)
The first goal implies that addon overlays do not refer to anything (phandles) beyond the connector node.
The talk has attracted a lot of people. All seats in the 200+ room were taken, and when I asked who has a connector use case about 40-50 attendeed raised their hands. I also had several questions asked after the talk and in the hallway.
After the talk we had planned a discussion about the topic. Krzysztof Kozlowski was present in person (thanks!), while Ayush Singh and Wolfram Sang connected remotely. Jason Kridner (beagleboard.org) and Geert Uytterhoeven were present and actively constributing to the discussion. Unfortunately Rob Herring was not connected, but still we tried to make the best out of the discussion. So we focused on discussing the current proposals to go past the issues with our export-symbols proposal raised mainly by Rob.
Here is a summary of the ideas we have discussed, in order from simplest discussion (looking like not doable) to most complex (which look like doable).
---------------------------------------------------------------------
Idea #1: Label on __overlay__
Proposed by Rob in [0]
Quoted 7 lines
Couldn't we make something like this work:
connector: __overlay__ { node { foo-gpio = <&connector 0 GPIO_ACTIVE_HIGH>; }; };
This would be OK for simple cases but it only allows exporting one label, for the connector (i.e. the overlay target node). More than one label need to be referenced from the overlay for cases such as:
- pinmux, where each pinmux configuration is a node, and is defined in the pinmux node outside of the connector
- HDMI ddc-i2c property, for HDMI chips in the overlay which needs to point at an I2C adapter in the base tree
---------------------------------------------------------------------
Idea #2: add /export/ keyword to mark labels to be exported Proposed by Rob in [1]
The idea is to mark modes in the base tree that can be referenced by overlays:
Quoted 4 lines
/export/ label: node {
};And then
__symbols__can be only those exported labels (unless -@ is used).
This is an opt-in version of the "global" __symbols__ to limit the issues __symbols__ introduces. However it is not sufficient for connectors because it tells what can be exported but not on which connector. Also, overlays would need to refer to the nodes in the main tree, thus not decoupling mainboard and addon.
---------------------------------------------------------------------
Idea #3: label on empty (*) node
(*) until overlay applied
Proposed by Hervé at LPC2024 in a discussion with Krzysztof, later abandoned
This is based on Idea #1 but tries to make HDMI ddc-i2c work:
connector1: connector1 {
#gpio-cells = <2>;
gpio-map = <0 0 &soc_gpio 12 0>;
gpio-map-mask = <0xf 0x0>;
gpio-map-pass-thru = <0x0 0xf>;
i2c8: i2c-hdmi { [**]
i2c-parent = <&soc_i2c8>;
}
};connector: __overlay__ {
node {
foo-gpio = <&connector 0 GPIO_ACTIVE_HIGH>;
};
i2c_hdmi: i2c-hdmi {
//empty
};
hdmictrl@99876 {
ddc-i2c = <&i2c_hdmi>; };
};
This would leverage the i2c-bus-extension work (also under discussion [3]). Since for HDMI an I2C device is not added it would have a node (i2c-hdmi) that is empty in the overlay (but not in the base tree and thus not in the live tree after the overlay is applied). This empty node is needed to ensure we can have a label (i2c_hdmi) that can be referenced from elsewhere in the overlay (ddc-i2c).
However there are various issues with this approach:
- mainlin, it does not handle pinumxes nicely
- if the node that is overlayed by the empty node (i2c-hdmi) has a label in the base tree (line [**]), then the overlay-provided phandle ID would screw up the base-tree phandle ID
- in dtbo, the empty node (i2c-hdmi) has a property in the overlay (phandle) but the node exists in the base tree, thus the property would leak on removal
---------------------------------------------------------------------
Idea #4: resolving phandle errors by the connector driver Proposed by Rob in [1]
Quoted 4 lines
I'll throw out another idea. What if we make resolving phandle errors something that can be handled by the connector driver? The driver knows 'connector' resolves to the connector node it is applying the overlay to.
This idea looked promising, so we tried simulating the process with a dts/dtso example:
Base tree:
connector1 {
compatible = "myvendor,myconn";
#gpio-cells = <2>;
gpio-map = <0 0 &soc_gpio1 12 0>, <1 0 &soc_gpio3 42 0>;
gpio-map-mask = <0xf 0x0>;
gpio-map-pass-thru = <0x0 0xf>;
i2c-sensors {
compatible = "i2c-bus-extension";
i2c-parent = <&i2c@abcd0000>;
};
hdmi-ddc-adapter = <&soc_i2c8>;
// All pinctrls that addons may need
pin12-pinctrl-i2c = <&pin12_mode_i2c>;
pin1-pinctrl-gpio = <&pin1_mode_gpio>;
pin2-pinctrl-gpio = <&pin2_mode_gpio>;
};Overlay:
/ {
fragment@0 {
__overlay__ {
node {
foo-gpios = <&connector 0 GPIO_ACTIVE_HIGH>, <&connector 1 GPIO_ACTIVE_HIGH>;
};
i2c-sensors {
thm: thermal@15 {reg = <15>;...};
};
hdmictrl@12345678 {
ddc-i2c = <&ddc_adapter>; [*]
};
some_other_node {
pinctrl-0 = <&pin12_pinctrl_i2c>;
thermal = <&thm>; };
};
This is what would happen for the HDMI ddc-i2c at line [*]:
1. of_overlay_fdt_apply_new(..., resolve_dt_error_cb) is called; it is a variant of of_overlay_fdt_apply() (name to be defined!) that:
a. takes a function pointer to invoke the connector for resolving
unknown labels
b. does not even try to resolve phandles beyond the connector c. if target node has no phandle, creates one with next unused
number
2. resolver does not find 'ddc_adapter' label
3. before calling it a fatal error, resolver calls connector driver callback
4. connector driver callback knows the "ddc_adapter" string must be resolved using the "hdmi-ddc-adapter" property, returns soc_i2c8 phandle ID
connector driver callback in pseudocode:
resolve_dt_error_cb(conn, label)
{
switch (label) {
case "connector":
return conn->of_node;
case "ddc_adapter":
return resolve(conn->of_node, "hdmi-ddc-adapter");
case "pin12_pinctrl_i2c":
return resolve(conn->of_node, "pin12-pinctrl-i2c");
}
}We discussed some possible issues, such as: what if a label is actually found in the base tree and thus resolved? This is handled by point 1.b.
above: the OF core does not even try to resolve phandles beyond the connector, it would not make sense for connector anyway. In other words it only resolves local fixups, which are internal to the overlay, such as "thm" in the example above.
This looked like the most promising approach because it handles nicely HDMI DDC and pinmux and minimize pollution in the phandle ID space.
---------------------------------------------------------------------
So that was what we discussed in the meeting last Tuesday. We hope this will help in setting the current point and let the discussion move forward.
Anyone having taken part to the discussion is welcome to correct or add any info we may have missed.
Best regards,
Hervé and Luca
[0] https://lore.kernel.org/all/CAL_JsqLT3prYBcxnsUwAShULCLJScYoU29ta29RJLGyiNkCrTg@mail.gmail.com/
[1] https://lore.kernel.org/all/CAL_JsqJCbmMJWJnmr8FneKrW4pjvTcyEco94Ot32o2YtaVxRQQ@mail.gmail.com/
[2] https://sched.co/25Vrw
[3] https://lore.kernel.org/all/[email protected]/
Signature · 3 lines
Luca Ceresoli, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
Quoted 6 lines · Luca Ceresoli
Hello,
[this main was co-written by Hervé and Luca]
Hervé and I are working since 1+y to allow describing hot-pluggable add-ons and their connectors with device tree overlays. Our work is not
So.. I think this is a poor way of framing the question. Device tree overlays were, frankly, a quick hack to get some sort device tree variability happening. They were pretty easy to implement, but they have a bunch of limitations. Then, as such things so often are, they were used and overused.
IMO, a lot of the problems being encountered now are really those fundamental limitations of the overlay approach. Trying to address them "with device tree overlays" is constraining you to a poorly thought out approach, adding hacks on top of hacks.
I proposed a possible "connector" format years ago (which I still think could do with renewed consideration) as an *alternative to* device tree overlays, not as an extension of them.
Quoted 7 lines
very much progressing because discussions about device tree bindings has raised some issue that are not obvious to solve.
This e-mail is a report of the efforts we did last week during the Embedded Linux Conference Europe to try to address the currently blocking issues.
Quoted 6 lines
First, I gave a talk about the overall hotplug work, to provide a status update but also to clarify the goals and use cases. Slides are available at [2]. Goals include:
- decoupling base board and add-on, so an addon can have a single dtbo valid for any base board, and vice versa
Good goal. This one can be somewhat addressed within the dtbo format (e.g. the 'export-symbols' proposal'). However doing so leans into the limitations of the dtbo format, which I think won't serve you well.
Quoted 2 lines
- supporting main boards with multiple connectors where multiple instances of the same addon model can be connected independently
Such as right here. The basic overlay approach is really badly suited to this.
Quoted 1 line
- allowing overlay insertion and removal at runtime (hotplug)
Again, I think that's poor framing. You want to be able to insert and remove things into connectors. Thinking of that as inserting and removing overlays hotplug limits you to crappy solutions. The basic definition of overlay application is fundmentally lossy - making them removable requires a pile of ugly hacks. Better to look at an approach at a different semantic layer.
Quoted 34 lines
The first goal implies that addon overlays do not refer to anything (phandles) beyond the connector node.
The talk has attracted a lot of people. All seats in the 200+ room were taken, and when I asked who has a connector use case about 40-50 attendeed raised their hands. I also had several questions asked after the talk and in the hallway.
After the talk we had planned a discussion about the topic. Krzysztof Kozlowski was present in person (thanks!), while Ayush Singh and Wolfram Sang connected remotely. Jason Kridner (beagleboard.org) and Geert Uytterhoeven were present and actively constributing to the discussion. Unfortunately Rob Herring was not connected, but still we tried to make the best out of the discussion. So we focused on discussing the current proposals to go past the issues with our export-symbols proposal raised mainly by Rob.
Here is a summary of the ideas we have discussed, in order from simplest discussion (looking like not doable) to most complex (which look like doable).
---------------------------------------------------------------------
Idea #1: Label on
__overlay__
Proposed by Rob in [0]Quoted 7 lines
Couldn't we make something like this work:
connector: __overlay__ { node { foo-gpio = <&connector 0 GPIO_ACTIVE_HIGH>; }; };
Quoted 8 lines
This would be OK for simple cases but it only allows exporting one label, for the connector (i.e. the overlay target node). More than one label need to be referenced from the overlay for cases such as:
- pinmux, where each pinmux configuration is a node, and is defined in the pinmux node outside of the connector
- HDMI ddc-i2c property, for HDMI chips in the overlay which needs to point at an I2C adapter in the base tree
Even wiring up plain old interrupts could be hard with this approach. It's also not clear how it would be encoded in the dtb.
Quoted 11 lines
---------------------------------------------------------------------
Idea #2: add /export/ keyword to mark labels to be exported Proposed by Rob in [1]
The idea is to mark modes in the base tree that can be referenced by overlays:
Quoted 3 lines
/export/ label: node {
};
Quoted 7 lines
Quoted 1 line
And then
__symbols__can be only those exported labels (unless -@ is used).This is an opt-in version of the "global"
__symbols__to limit the issues__symbols__introduces. However it is not sufficient for connectors because it tells what can be exported but not on which connector. Also, overlays would need to refer to the nodes in the main tree, thus not decoupling mainboard and addon.
Sounds like a strictly worse version of export-symbols.
Quoted 20 lines
---------------------------------------------------------------------
Idea #3: label on empty (*) node
(*) until overlay applied
Proposed by Hervé at LPC2024 in a discussion with Krzysztof, later abandonedThis is based on Idea #1 but tries to make HDMI ddc-i2c work:
connector1: connector1 { #gpio-cells = <2>; gpio-map = <0 0 &soc_gpio 12 0>; gpio-map-mask = <0xf 0x0>; gpio-map-pass-thru = <0x0 0xf>; i2c8: i2c-hdmi { [**] i2c-parent = <&soc_i2c8>; } };
Quoted 11 lines
connector: __overlay__ {
node {
foo-gpio = <&connector 0 GPIO_ACTIVE_HIGH>;
};
i2c_hdmi: i2c-hdmi {
//empty
};
hdmictrl@99876 {
ddc-i2c = <&i2c_hdmi>;
};
};Having symbol / glue information that's local to a particular connector is, I think, the way to go. But again, I think encoding this in terms of overlays semantics is going to make it harder than it needs to be.
Quoted 91 lines
This would leverage the i2c-bus-extension work (also under discussion [3]). Since for HDMI an I2C device is not added it would have a node (i2c-hdmi) that is empty in the overlay (but not in the base tree and thus not in the live tree after the overlay is applied). This empty node is needed to ensure we can have a label (
i2c_hdmi) that can be referenced from elsewhere in the overlay (ddc-i2c).However there are various issues with this approach:
- mainlin, it does not handle pinumxes nicely
- if the node that is overlayed by the empty node (i2c-hdmi) has a label in the base tree (line [**]), then the overlay-provided phandle ID would screw up the base-tree phandle ID
- in dtbo, the empty node (i2c-hdmi) has a property in the overlay (phandle) but the node exists in the base tree, thus the property would leak on removal---------------------------------------------------------------------
Idea #4: resolving phandle errors by the connector driver Proposed by Rob in [1]
Quoted 4 lines
I'll throw out another idea. What if we make resolving phandle errors something that can be handled by the connector driver? The driver knows 'connector' resolves to the connector node it is applying the overlay to.
This idea looked promising, so we tried simulating the process with a dts/dtso example:
Base tree:
connector1 { compatible = "myvendor,myconn"; #gpio-cells = <2>; gpio-map = <0 0 &soc_gpio1 12 0>, <1 0 &soc_gpio3 42 0>; gpio-map-mask = <0xf 0x0>; gpio-map-pass-thru = <0x0 0xf>; i2c-sensors { compatible = "i2c-bus-extension"; i2c-parent = <&i2c@abcd0000>; }; hdmi-ddc-adapter = <&soc_i2c8>; // All pinctrls that addons may need pin12-pinctrl-i2c = <&pin12_mode_i2c>; pin1-pinctrl-gpio = <&pin1_mode_gpio>; pin2-pinctrl-gpio = <&pin2_mode_gpio>; };Overlay:
/ {
fragment@0 {__overlay__ { node { foo-gpios = <&connector 0 GPIO_ACTIVE_HIGH>, <&connector 1 GPIO_ACTIVE_HIGH>; }; i2c-sensors { thm: thermal@15 {reg = <15>;...}; }; hdmictrl@12345678 { ddc-i2c = <&ddc_adapter>; [*] }; some_other_node { pinctrl-0 = <&pin12_pinctrl_i2c>; thermal = <&thm>; }; };This is what would happen for the HDMI ddc-i2c at line [*]:
1.
of_overlay_fdt_apply_new(..., resolve_dt_error_cb)is called; it is a variant ofof_overlay_fdt_apply()(name to be defined!) that:
a. takes a function pointer to invoke the connector for resolving
unknown labels
b. does not even try to resolve phandles beyond the connector c. if target node has no phandle, creates one with next unused
number
2. resolver does not find 'ddc_adapter' label
3. before calling it a fatal error, resolver calls connector driver callback
4. connector driver callback knows the "ddc_adapter" string must be resolved using the "hdmi-ddc-adapter" property, returnssoc_i2c8phandle IDconnector driver callback in pseudocode:
Quoted 11 lines
resolve_dt_error_cb(conn, label)
{
switch (label) {
case "connector":
return conn->of_node;
case "ddc_adapter":
return resolve(conn->of_node, "hdmi-ddc-adapter");
case "pin12_pinctrl_i2c":
return resolve(conn->of_node, "pin12-pinctrl-i2c");
}
}The idea of putting logic into a connector driver makes sense. However, it's unclear to me where those strings its resolving are actually encoded in the dtb.
Quoted 7 lines
We discussed some possible issues, such as: what if a label is actually found in the base tree and thus resolved? This is handled by point 1.b.
above: the OF core does not even try to resolve phandles beyond the connector, it would not make sense for connector anyway. In other words it only resolves local fixups, which are internal to the overlay, such as "thm" in the example above.
Quoted 8 lines
This looked like the most promising approach because it handles nicely HDMI DDC and pinmux and minimize pollution in the phandle ID space.
---------------------------------------------------------------------
So that was what we discussed in the meeting last Tuesday. We hope this will help in setting the current point and let the discussion move forward.
Let me throw a few more ideas in the pot. None of these are total solutions, but I think they may make good components of solutions.
1) Connector local labels/symbols/aliases
This is not a new idea - both the export-symbols proposal and my ancient connector proposal had this in one form or another. I think something along these lines is almost essential. Things that plug into connectors almost always require references to several host board resources (interrupt controller, gpio, ...). In order to be pluggable on multiple host boards you want to refer to those symbolically. In order to support multiple instances of the same connector type, you need those symbols to refer to different things fordifferent connector instances.
Whhat I think is a mistake is trying to tie this too closely to the existing __symbols__ structure. Those have an ugly encoding that requires tortured processing in a way that's not natural for dtb handling. Plus they already kinda-sorta duplicate old-school aliases in an odd way.
You want some sort of string => node mapping on the connector side, and a way to mark portions of properties on the plugin side as being resolved to some string reference. But we can take the opportunity to design a better way of doing that than the ugly one we have now.
2) Extend dtb itself
A maor thing that makes current symbols and fixups ugly is the fact that they are encoded into properties in the device tree itself, despite being logically at a different semantic level. Obviously you *can* do that, but it's not natural. It would make more sense to add fixup tags into the dtb format itself.
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal really awkward. Here's an idea I had a while ago to allow plugins to be a single subtree, by extending what's allowed in the tree content:
Currently a node can only really have a presence on its immediate parent bus, as encoded in the 'reg' and 'ranges' properties. 'bus-reg' and 'bus-ranges' would extend that having a similar format to 'reg' and 'ranges' but adding a phandle for each entry saying which bus it lives on - somewhat similar to interrupt-map.
For example, here's an MMIO bus bridge of some sort, which has control registers on I2C:
mmio-bus@... {
#address-cells = < 2 >;
#size-cells = < 2 >;
bridge@XXXX {
ranges = <...>;
bus-reg = <&i2c0 0x407>
}
}
i2c0: i2c@... {
#address-cells = < 1 >;
#size-cells = < 0 >;
}In a sense this extends the device tree to a device DAG.
Obviously this does need changes at the OS device core level, but it gives you a lot of flexibility having done so.
4) You don't necessarily need to build a "full" device tree
Flattened device trees (as opposed to original IEEE1275 device trees)
- by design - allow certain information to be omitted. The most common example is that for introspectable buses, like PCI, it's normal to have the DT only include a node for the host bridge, with devices under it being discovered by their own bus specific methods. That's discovery is handled by the bus/bridge driver.
Connectors usually aren't introspectable, but it's still possible to use an approach like this where the connector driver's discovery method is "look at a different device tree". So, for example,
Board device tree:
/ {
compatible = "board-with-foo-connector";
. . .
mmio@... {
foo-connector@... {
compatible = "foo-connector";
ranges = < ... >;
}
}
}Foo device tree:
/ {
compatible = "foo-device";
foo-port-id = < 0x1234 >;
component@... {
reg = < ... >;
}
}Obviously a "foo device tree" would have different conventions than a board device tree. It wouldn't have /cpus, /memory, /chosen - but it could have its own "magic" nodes that make sense for the properties of the specific connector type.
Again, that would require work in the device core part of the OS. The bonus is that runtime addition and removal is now trivial. No hacking of the base device tree is needed, and so doesn't need to be reverted. The connector driver just adds/removes the reference to its own private tree.
This would, of course, need some way to refer to board resources (interrupt controller, gpio controller) etc. I think that can be assembled using some of the previous ideas, though.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Quoted 293 lines · David Gibson
Quoted 6 lines · Luca Ceresoli
Hello,
[this main was co-written by Hervé and Luca]
Hervé and I are working since 1+y to allow describing hot-pluggable add-ons and their connectors with device tree overlays. Our work is not
So.. I think this is a poor way of framing the question. Device tree overlays were, frankly, a quick hack to get some sort device tree variability happening. They were pretty easy to implement, but they have a bunch of limitations. Then, as such things so often are, they were used and overused.
IMO, a lot of the problems being encountered now are really those fundamental limitations of the overlay approach. Trying to address them "with device tree overlays" is constraining you to a poorly thought out approach, adding hacks on top of hacks.
I proposed a possible "connector" format years ago (which I still think could do with renewed consideration) as an *alternative to* device tree overlays, not as an extension of them.
Quoted 7 lines
very much progressing because discussions about device tree bindings has raised some issue that are not obvious to solve.
This e-mail is a report of the efforts we did last week during the Embedded Linux Conference Europe to try to address the currently blocking issues.
Quoted 6 lines
First, I gave a talk about the overall hotplug work, to provide a status update but also to clarify the goals and use cases. Slides are available at [2]. Goals include:
- decoupling base board and add-on, so an addon can have a single dtbo valid for any base board, and vice versa
Good goal. This one can be somewhat addressed within the dtbo format (e.g. the 'export-symbols' proposal'). However doing so leans into the limitations of the dtbo format, which I think won't serve you well.
Quoted 2 lines
- supporting main boards with multiple connectors where multiple instances of the same addon model can be connected independently
Such as right here. The basic overlay approach is really badly suited to this.
Quoted 1 line
- allowing overlay insertion and removal at runtime (hotplug)
Again, I think that's poor framing. You want to be able to insert and remove things into connectors. Thinking of that as inserting and removing overlays hotplug limits you to crappy solutions. The basic definition of overlay application is fundmentally lossy - making them removable requires a pile of ugly hacks. Better to look at an approach at a different semantic layer.
Quoted 33 lines
The first goal implies that addon overlays do not refer to anything (phandles) beyond the connector node.
The talk has attracted a lot of people. All seats in the 200+ room were taken, and when I asked who has a connector use case about 40-50 attendeed raised their hands. I also had several questions asked after the talk and in the hallway.
After the talk we had planned a discussion about the topic. Krzysztof Kozlowski was present in person (thanks!), while Ayush Singh and Wolfram Sang connected remotely. Jason Kridner (beagleboard.org) and Geert Uytterhoeven were present and actively constributing to the discussion. Unfortunately Rob Herring was not connected, but still we tried to make the best out of the discussion. So we focused on discussing the current proposals to go past the issues with our export-symbols proposal raised mainly by Rob.
Here is a summary of the ideas we have discussed, in order from simplest discussion (looking like not doable) to most complex (which look like doable).
---------------------------------------------------------------------
Idea #1: Label on
__overlay__
Proposed by Rob in [0]Quoted 7 lines
Couldn't we make something like this work:
connector: __overlay__ { node { foo-gpio = <&connector 0 GPIO_ACTIVE_HIGH>; }; };Quoted 8 lines
This would be OK for simple cases but it only allows exporting one label, for the connector (i.e. the overlay target node). More than one label need to be referenced from the overlay for cases such as:
- pinmux, where each pinmux configuration is a node, and is defined in the pinmux node outside of the connector
- HDMI ddc-i2c property, for HDMI chips in the overlay which needs to point at an I2C adapter in the base treeEven wiring up plain old interrupts could be hard with this approach. It's also not clear how it would be encoded in the dtb.
Quoted 11 lines
---------------------------------------------------------------------
Idea #2: add /export/ keyword to mark labels to be exported Proposed by Rob in [1]
The idea is to mark modes in the base tree that can be referenced by overlays:
Quoted 3 lines
/export/ label: node {
};Quoted 6 lines
Quoted 1 line
And then
__symbols__can be only those exported labels (unless -@ is used).This is an opt-in version of the "global"
__symbols__to limit the issues__symbols__introduces. However it is not sufficient for connectors because it tells what can be exported but not on which connector. Also, overlays would need to refer to the nodes in the main tree, thus not decoupling mainboard and addon.Sounds like a strictly worse version of export-symbols.
Quoted 20 lines
---------------------------------------------------------------------
Idea #3: label on empty (*) node
(*) until overlay applied
Proposed by Hervé at LPC2024 in a discussion with Krzysztof, later abandonedThis is based on Idea #1 but tries to make HDMI ddc-i2c work:
connector1: connector1 { #gpio-cells = <2>; gpio-map = <0 0 &soc_gpio 12 0>; gpio-map-mask = <0xf 0x0>; gpio-map-pass-thru = <0x0 0xf>; i2c8: i2c-hdmi { [**] i2c-parent = <&soc_i2c8>; } };Quoted 11 lines
connector: __overlay__ { node { foo-gpio = <&connector 0 GPIO_ACTIVE_HIGH>; }; i2c_hdmi: i2c-hdmi { //empty }; hdmictrl@99876 { ddc-i2c = <&i2c_hdmi>; }; };Having symbol / glue information that's local to a particular connector is, I think, the way to go. But again, I think encoding this in terms of overlays semantics is going to make it harder than it needs to be.
Quoted 90 lines
This would leverage the i2c-bus-extension work (also under discussion [3]). Since for HDMI an I2C device is not added it would have a node (i2c-hdmi) that is empty in the overlay (but not in the base tree and thus not in the live tree after the overlay is applied). This empty node is needed to ensure we can have a label (
i2c_hdmi) that can be referenced from elsewhere in the overlay (ddc-i2c).However there are various issues with this approach:
- mainlin, it does not handle pinumxes nicely
- if the node that is overlayed by the empty node (i2c-hdmi) has a label in the base tree (line [**]), then the overlay-provided phandle ID would screw up the base-tree phandle ID
- in dtbo, the empty node (i2c-hdmi) has a property in the overlay (phandle) but the node exists in the base tree, thus the property would leak on removal---------------------------------------------------------------------
Idea #4: resolving phandle errors by the connector driver Proposed by Rob in [1]
Quoted 4 lines
I'll throw out another idea. What if we make resolving phandle errors something that can be handled by the connector driver? The driver knows 'connector' resolves to the connector node it is applying the overlay to.
This idea looked promising, so we tried simulating the process with a dts/dtso example:
Base tree:
connector1 { compatible = "myvendor,myconn"; #gpio-cells = <2>; gpio-map = <0 0 &soc_gpio1 12 0>, <1 0 &soc_gpio3 42 0>; gpio-map-mask = <0xf 0x0>; gpio-map-pass-thru = <0x0 0xf>; i2c-sensors { compatible = "i2c-bus-extension"; i2c-parent = <&i2c@abcd0000>; }; hdmi-ddc-adapter = <&soc_i2c8>; // All pinctrls that addons may need pin12-pinctrl-i2c = <&pin12_mode_i2c>; pin1-pinctrl-gpio = <&pin1_mode_gpio>; pin2-pinctrl-gpio = <&pin2_mode_gpio>; };Overlay:
/ {
fragment@0 { __overlay__ { node { foo-gpios = <&connector 0 GPIO_ACTIVE_HIGH>, <&connector 1 GPIO_ACTIVE_HIGH>; }; i2c-sensors { thm: thermal@15 {reg = <15>;...}; }; hdmictrl@12345678 { ddc-i2c = <&ddc_adapter>; [*] }; some_other_node { pinctrl-0 = <&pin12_pinctrl_i2c>; thermal = <&thm>; }; };This is what would happen for the HDMI ddc-i2c at line [*]:
1.
of_overlay_fdt_apply_new(..., resolve_dt_error_cb)is called; it is a variant ofof_overlay_fdt_apply()(name to be defined!) that:
a. takes a function pointer to invoke the connector for resolving
unknown labels
b. does not even try to resolve phandles beyond the connector c. if target node has no phandle, creates one with next unused
number
2. resolver does not find 'ddc_adapter' label
3. before calling it a fatal error, resolver calls connector driver callback
4. connector driver callback knows the "ddc_adapter" string must be resolved using the "hdmi-ddc-adapter" property, returnssoc_i2c8phandle IDconnector driver callback in pseudocode:
Quoted 11 lines
resolve_dt_error_cb(conn, label) { switch (label) { case "connector": return conn->of_node; case "ddc_adapter": return resolve(conn->of_node, "hdmi-ddc-adapter"); case "pin12_pinctrl_i2c": return resolve(conn->of_node, "pin12-pinctrl-i2c"); } }The idea of putting logic into a connector driver makes sense. However, it's unclear to me where those strings its resolving are actually encoded in the dtb.
Quoted 7 lines
We discussed some possible issues, such as: what if a label is actually found in the base tree and thus resolved? This is handled by point 1.b.
above: the OF core does not even try to resolve phandles beyond the connector, it would not make sense for connector anyway. In other words it only resolves local fixups, which are internal to the overlay, such as "thm" in the example above.Quoted 8 lines
This looked like the most promising approach because it handles nicely HDMI DDC and pinmux and minimize pollution in the phandle ID space.
---------------------------------------------------------------------
So that was what we discussed in the meeting last Tuesday. We hope this will help in setting the current point and let the discussion move forward.
Let me throw a few more ideas in the pot. None of these are total solutions, but I think they may make good components of solutions.
1) Connector local labels/symbols/aliases
This is not a new idea - both the export-symbols proposal and my ancient connector proposal had this in one form or another. I think something along these lines is almost essential. Things that plug into connectors almost always require references to several host board resources (interrupt controller, gpio, ...). In order to be pluggable on multiple host boards you want to refer to those symbolically. In order to support multiple instances of the same connector type, you need those symbols to refer to different things fordifferent connector instances.
Whhat I think is a mistake is trying to tie this too closely to the existing
__symbols__structure. Those have an ugly encoding that requires tortured processing in a way that's not natural for dtb handling. Plus they already kinda-sorta duplicate old-school aliases in an odd way.
Quoted 4 lines
You want some sort of string => node mapping on the connector side, and a way to mark portions of properties on the plugin side as being resolved to some string reference. But we can take the opportunity to design a better way of doing that than the ugly one we have now.
Isn't export-symbols exactly this. We do take inspiration from __symbols__. However, in case of export-symbols, its string => phandle mapping (as opposed to string => string in __symbols__).
I suppose export-symbols could follow aliase conventions, but that still is a string => string mapping, which seems worse to me than a phandle (since phandle size is constant).
Quoted 8 lines
2) Extend dtb itself
A maor thing that makes current symbols and fixups ugly is the fact that they are encoded into properties in the device tree itself, despite being logically at a different semantic level. Obviously you *can* do that, but it's not natural. It would make more sense to add fixup tags into the dtb format itself.
Having something akin to fixup in dtb format itself would be nice.
Quoted 32 lines
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal really awkward. Here's an idea I had a while ago to allow plugins to be a single subtree, by extending what's allowed in the tree content:
Currently a node can only really have a presence on its immediate parent bus, as encoded in the 'reg' and 'ranges' properties. 'bus-reg' and 'bus-ranges' would extend that having a similar format to 'reg' and 'ranges' but adding a phandle for each entry saying which bus it lives on - somewhat similar to interrupt-map.
For example, here's an MMIO bus bridge of some sort, which has control registers on I2C:
mmio-bus@... { #address-cells = < 2 >; #size-cells = < 2 >; bridge@XXXX { ranges = <...>; bus-reg = <&i2c0 0x407> } } i2c0: i2c@... { #address-cells = < 1 >; #size-cells = < 0 >; }
Quoted 4 lines
In a sense this extends the device tree to a device DAG.
Obviously this does need changes at the OS device core level, but it gives you a lot of flexibility having done so.
There is an i2c-bus-extension [1] and spi-bus-extension proposal to do the same. But, if we can figure out a common way for all buses, that would be great.
[1]: https://lore.kernel.org/all/[email protected]/
[2]: https://lore.kernel.org/all/[email protected]/
Quoted 48 lines
4) You don't necessarily need to build a "full" device tree
Flattened device trees (as opposed to original IEEE1275 device trees)
- by design - allow certain information to be omitted. The most common example is that for introspectable buses, like PCI, it's normal to have the DT only include a node for the host bridge, with devices under it being discovered by their own bus specific methods. That's discovery is handled by the bus/bridge driver.Connectors usually aren't introspectable, but it's still possible to use an approach like this where the connector driver's discovery method is "look at a different device tree". So, for example,
Board device tree:
/ { compatible = "board-with-foo-connector"; . . . mmio@... { foo-connector@... { compatible = "foo-connector"; ranges = < ... >; } } }Foo device tree:
/ { compatible = "foo-device"; foo-port-id = < 0x1234 >; component@... { reg = < ... >; } }Obviously a "foo device tree" would have different conventions than a board device tree. It wouldn't have /cpus, /memory, /chosen - but it could have its own "magic" nodes that make sense for the properties of the specific connector type.
Again, that would require work in the device core part of the OS. The bonus is that runtime addition and removal is now trivial. No hacking of the base device tree is needed, and so doesn't need to be reverted. The connector driver just adds/removes the reference to its own private tree.
Quoted 4 lines
This would, of course, need some way to refer to board resources (interrupt controller, gpio controller) etc. I think that can be assembled using some of the previous ideas, though.
I would need to wrap my head around this a bit, specially in context of chaining connectors. It does seem like it will still require the points you mentioned above to be present in one form or another, i.e. some way to extend busses to different nodes/trees and connector (even a chained one) local symbols/aliases.
Best Regards,
Ayush Singh
Quoted 2 lines · Ayush Singh
Quoted 1 line · David Gibson
On Tue, Sep 02, 2025 at 10:57:10AM +0200, Luca Ceresoli wrote:
[snip]
Quoted 24 lines
Quoted 18 lines
1) Connector local labels/symbols/aliases
This is not a new idea - both the export-symbols proposal and my ancient connector proposal had this in one form or another. I think something along these lines is almost essential. Things that plug into connectors almost always require references to several host board resources (interrupt controller, gpio, ...). In order to be pluggable on multiple host boards you want to refer to those symbolically. In order to support multiple instances of the same connector type, you need those symbols to refer to different things fordifferent connector instances.
Whhat I think is a mistake is trying to tie this too closely to the existing
__symbols__structure. Those have an ugly encoding that requires tortured processing in a way that's not natural for dtb handling. Plus they already kinda-sorta duplicate old-school aliases in an odd way.Quoted 4 lines
You want some sort of string => node mapping on the connector side, and a way to mark portions of properties on the plugin side as being resolved to some string reference. But we can take the opportunity to design a better way of doing that than the ugly one we have now.
Quoted 3 lines
Isn't export-symbols exactly this. We do take inspiration from
__symbols__. However, in case of export-symbols, its string => phandle mapping (as opposed to string => string in__symbols__).
As far as the specific It kind of is, yes, and that aspect I like. What I'm not convinced by is how export-symbols is proposed to fit in with and be used by surrounding logic. export-symbols has been designed to fit in with the existing (ugly) overlay mechanism. I think that's putting the cart before the horse. Instead work out how to logically define connectors first - which will involve information equivalent to export-symbols - then work out how to update or replace the overlay mechanism to work with that.
Quoted 8 lines
I suppose export-symbols could follow aliase conventions, but that still is a string => string mapping, which seems worse to me than a phandle (since phandle size is constant).
Quoted 3 lines
2) Extend dtb itself
Quoted 7 lines
Quoted 5 lines
A maor thing that makes current symbols and fixups ugly is the fact that they are encoded into properties in the device tree itself, despite being logically at a different semantic level. Obviously you *can* do that, but it's not natural. It would make more sense to add fixup tags into the dtb format itself.
Having something akin to fixup in dtb format itself would be nice.
Yes, it would.
Quoted 31 lines
Quoted 31 lines
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal really awkward. Here's an idea I had a while ago to allow plugins to be a single subtree, by extending what's allowed in the tree content:
Currently a node can only really have a presence on its immediate parent bus, as encoded in the 'reg' and 'ranges' properties. 'bus-reg' and 'bus-ranges' would extend that having a similar format to 'reg' and 'ranges' but adding a phandle for each entry saying which bus it lives on - somewhat similar to interrupt-map.
For example, here's an MMIO bus bridge of some sort, which has control registers on I2C:
mmio-bus@... { #address-cells = < 2 >; #size-cells = < 2 >; bridge@XXXX { ranges = <...>; bus-reg = <&i2c0 0x407> } } i2c0: i2c@... { #address-cells = < 1 >; #size-cells = < 0 >; }
Quoted 8 lines
Quoted 4 lines
In a sense this extends the device tree to a device DAG.
Obviously this does need changes at the OS device core level, but it gives you a lot of flexibility having done so.
There is an i2c-bus-extension [1] and spi-bus-extension proposal to do the same. But, if we can figure out a common way for all buses, that would be great.
Heh, right. That reinforces my thought that this could be a good idea.
[Btw, the theoretically correct IEEE1275 way to do this is change
addressing across the whole tree. e.g. set #address-cells = <3>, with the first cell being, say, 0 for mmio, 1 for i2c, 2 for SPI, then the remaining cells are the address within that bus. So, this sort of thing is technically possible in old-school OF trees. That would become pretty unmanageable though. The idea of bus-reg is to encode the same information in a less awkward way]
Quoted 57 lines
[1]:
https://lore.kernel.org/all/[email protected]/[2]: https://lore.kernel.org/all/[email protected]/
Quoted 47 lines
4) You don't necessarily need to build a "full" device tree
Flattened device trees (as opposed to original IEEE1275 device trees)
- by design - allow certain information to be omitted. The most common example is that for introspectable buses, like PCI, it's normal to have the DT only include a node for the host bridge, with devices under it being discovered by their own bus specific methods. That's discovery is handled by the bus/bridge driver.Connectors usually aren't introspectable, but it's still possible to use an approach like this where the connector driver's discovery method is "look at a different device tree". So, for example,
Board device tree:
/ { compatible = "board-with-foo-connector"; . . . mmio@... { foo-connector@... { compatible = "foo-connector"; ranges = < ... >; } } }Foo device tree:
/ { compatible = "foo-device"; foo-port-id = < 0x1234 >; component@... { reg = < ... >; } }Obviously a "foo device tree" would have different conventions than a board device tree. It wouldn't have /cpus, /memory, /chosen - but it could have its own "magic" nodes that make sense for the properties of the specific connector type.
Again, that would require work in the device core part of the OS. The bonus is that runtime addition and removal is now trivial. No hacking of the base device tree is needed, and so doesn't need to be reverted. The connector driver just adds/removes the reference to its own private tree.
Quoted 3 lines
This would, of course, need some way to refer to board resources (interrupt controller, gpio controller) etc. I think that can be assembled using some of the previous ideas, though.
Quoted 5 lines
I would need to wrap my head around this a bit, specially in context of chaining connectors. It does seem like it will still require the points you mentioned above to be present in one form or another, i.e. some way to extend busses to different nodes/trees and connector (even a chained one) local symbols/aliases.
Yes, it would still require those mappings. I don't think chained connectors introduce a lot of extra complication. An intermediate connector would need to be able to "re-export" things it got from its parent connector to its child connector(s) - renaming them if necessary.
I think those two elements would be enough to make something that's useful in at least a few cases. However, the pretty common case of a connector with pins from multiple different parent buses would need bus-reg or something similar. Or else the nasty multiplexed encoding described above.
I say, "nasty" and in many cases it would be, but I think there may be some cases where that approach does make sense: e.g. a connector that has several logically separate address spaces but which always travel together and are typically handled by a common bridge device. PCI is a case of this, if you squint - a host bridge provides a config space bus, and an MMIO bus and a PIO bus. Also sometimes some sort of interrupt controller / interrupt routing, complicated by the fact that there are several different models for that across PCI and PCI-E.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David,
Quoted 7 lines · David Gibson
Quoted 5 lines · Ayush Singh
I would need to wrap my head around this a bit, specially in context of chaining connectors. It does seem like it will still require the points you mentioned above to be present in one form or another, i.e. some way to extend busses to different nodes/trees and connector (even a chained one) local symbols/aliases.
Quoted 5 lines
Yes, it would still require those mappings. I don't think chained connectors introduce a lot of extra complication. An intermediate connector would need to be able to "re-export" things it got from its parent connector to its child connector(s) - renaming them if necessary.
I don't expect chained connectors to be complicated. Boards using multiple-connectors may be more difficult, e.g.
https://1bitsquared.de/products/pmod-hyperram
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Quoted 16 lines · Geert Uytterhoeven
Hi David,
Quoted 7 lines · David Gibson
Quoted 5 lines · Ayush Singh
I would need to wrap my head around this a bit, specially in context of chaining connectors. It does seem like it will still require the points you mentioned above to be present in one form or another, i.e. some way to extend busses to different nodes/trees and connector (even a chained one) local symbols/aliases.
Quoted 5 lines
Yes, it would still require those mappings. I don't think chained connectors introduce a lot of extra complication. An intermediate connector would need to be able to "re-export" things it got from its parent connector to its child connector(s) - renaming them if necessary.
Quoted 3 lines
I don't expect chained connectors to be complicated. Boards using multiple-connectors may be more difficult, e.g.
https://1bitsquared.de/products/pmod-hyperram
Ah.. from the link, I'm gathering you mean a peripheral which plugs into multiple connectors on a parent board, rather than a board which supplies multiple connectors.
That is a case I hadn't considered, which does complicate things further. I think the main thing that would need to be tackled here is that the resources would need to be renamable / namespaced on the plugin side as well as the parent board side.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David,
Quoted 6 lines · On Mon, 8 Sep 2025 14:36:06 +1000 David Gibson <[email protected]>…
Quoted 2 lines · Ayush Singh
Quoted 1 line · David Gibson
On Tue, Sep 02, 2025 at 10:57:10AM +0200, Luca Ceresoli wrote:
[snip]
Quoted 2 lines
Quoted 2 lines
1) Connector local labels/symbols/aliases
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
This is not a new idea - both the export-symbols proposal and my ancient connector proposal had this in one form or another. I think something along these lines is almost essential. Things that plug into connectors almost always require references to several host board resources (interrupt controller, gpio, ...). In order to be pluggable on multiple host boards you want to refer to those symbolically. In order to support multiple instances of the same connector type, you need those symbols to refer to different things fordifferent connector instances.
Some of the resources can be "translated" using a nexus node. It works for interrupt, gpio, pwm, ...
I fact, it should work for all references that use a phandle with a resource number. I mean any reference in the form 'ref = <&ctrl 123>' to reference the resource 123 of the controller.
From the addon, &ctrl need to be resolved. Using a nexus node at connector level this becomes "ref = <&connector 10>;" and considering the connector itself in the base tree as a nexus node allows to perform the translation.
connector {
gpio-map = <10 &ctrl 123>;};
but this don't work for a reference that uses only a phandle without any number (pinctrl for instance) or for busses where devices need to be added.
For busses where devices could be added by the add-on, bus extensions were introduced (i2c-bus-extension).
In any cases, some symbols need to be referenced from the addon.
Quoted 17 lines
Quoted 13 lines
Quoted 11 lines
Whhat I think is a mistake is trying to tie this too closely to the existing
__symbols__structure. Those have an ugly encoding that requires tortured processing in a way that's not natural for dtb handling. Plus they already kinda-sorta duplicate old-school aliases in an odd way.You want some sort of string => node mapping on the connector side, and a way to mark portions of properties on the plugin side as being resolved to some string reference. But we can take the opportunity to design a better way of doing that than the ugly one we have now.
Quoted 3 lines
Isn't export-symbols exactly this. We do take inspiration from
__symbols__. However, in case of export-symbols, its string => phandle mapping (as opposed to string => string in__symbols__).
Quoted 8 lines
As far as the specific It kind of is, yes, and that aspect I like. What I'm not convinced by is how export-symbols is proposed to fit in with and be used by surrounding logic. export-symbols has been designed to fit in with the existing (ugly) overlay mechanism. I think that's putting the cart before the horse. Instead work out how to logically define connectors first - which will involve information equivalent to export-symbols - then work out how to update or replace the overlay mechanism to work with that.
I think that a connector is something with a bunch of resources provided by the board where the connector is soldered. Those resources are wired to the connector and defined by the connector pinout.
3v3 ------- Pin 0
i2c_scl ------- Pin 1
i2c_sda ------- Pin 2
gpio A ------- Pin 3
gpio B ------- Pin 4
gnd ------- Pin 5IMHO, this need to be described and defined in the base board and an addon can only reference resources wired and described by the connector node.
Now, questions are:
- 1) How to describe a connector?
- 2) How to reference resources provided at connector level from an add-on?
Our current approach was:
---- base board DT ----
connector0 {
gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */
<1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */
i2c-one {
compatible = "i2c-bus-extension";
i2c-parent = <i2c5>; /* i2c-one wired to i2c5 controller */
};
i2c-two {
compatible = "i2c-bus-extension";
i2c-parent = <i2c6>; /* i2c-two wired to i2c6 controller */
};
/*
* From the addon we need to reference:
* - The connector itself,
* - Maybe some pinctrl related to signals wired to the connector,
* - In some cases the i2c bus (HDMI, ddc-i2c-bus = <&i2c-two>;)
*
* This was solved introducing the controversial export-symbols node.
*/};
---- addon board DT ----
{
some-node {
compatible = "foo,bar";
reset-gpios = <&connector 0>; /* gpio A used as a reset gpio */
ddc-i2c-bus = <&i2c-two>;
}
i2c-one {
eeprom@10 {
compatible = "baz,eeprom"
reg = 10;
};
};};
The addon board DT can only be applied at a connector node. It described the addon board connected to this connector.
Quoted 15 lines
Quoted 15 lines
I suppose export-symbols could follow aliase conventions, but that still is a string => string mapping, which seems worse to me than a phandle (since phandle size is constant).
Quoted 8 lines
2) Extend dtb itself
A maor thing that makes current symbols and fixups ugly is the fact that they are encoded into properties in the device tree itself, despite being logically at a different semantic level. Obviously you *can* do that, but it's not natural. It would make more sense to add fixup tags into the dtb format itself.
Quoted 3 lines
Quoted 1 line
Having something akin to fixup in dtb format itself would be nice.
Yes, it would.
What could be the modification expected at dtb to support the connector use case?
Also what could be the modification expected at dts to described the connector?
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal
It can be a single subtree if decoupling is present at connector node available in the base device tree.
All resources wired to the connector should be described in the connector node A add-on board should only see resources provided and described at the connector node or translated by something (nexus, export-symbols) present in the connector node.
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
really awkward. Here's an idea I had a while ago to allow plugins to be a single subtree, by extending what's allowed in the tree content:
Currently a node can only really have a presence on its immediate parent bus, as encoded in the 'reg' and 'ranges' properties. 'bus-reg' and 'bus-ranges' would extend that having a similar format to 'reg' and 'ranges' but adding a phandle for each entry saying which bus it lives on - somewhat similar to interrupt-map.
For example, here's an MMIO bus bridge of some sort, which has control registers on I2C:
mmio-bus@... { #address-cells = < 2 >; #size-cells = < 2 >; bridge@XXXX { ranges = <...>; bus-reg = <&i2c0 0x407> } } i2c0: i2c@... { #address-cells = < 1 >; #size-cells = < 0 >; }
Quoted 8 lines
Quoted 8 lines
Quoted 4 lines
In a sense this extends the device tree to a device DAG.
Obviously this does need changes at the OS device core level, but it gives you a lot of flexibility having done so.
There is an i2c-bus-extension [1] and spi-bus-extension proposal to do the same. But, if we can figure out a common way for all buses, that would be great.
Exactly, this is the purpose of bus extensions.
Also, I don't thing that the 'ranges' property should be used for that purpose. The 'ranges' property is used to translate addresses from child addresses space to parent addresses space.
For instance, in case of i2c, where is the address translation?
The address of a child (device) is its I2C address. This address is device in its datasheet. There is no reason to have this address depending on the I2C bus this child is connected to.
In your example, the bridge@XXXX is not related to any hardware components. If is allows to physically perform I2C transaction from a MMIO device connected to MMIO bus, this is a traduction I2C controller with a bunch of registers to configure an perform I2C transactions.
In that case, this "bridge" looks like all I2C we already support in the kernel.
Having the additional indirection with the "bridge" between the MMIO bus and the i2c@... node seems not a hardware representation of the system.
Did I miss something?
Quoted 4 lines
Heh, right. That reinforces my thought that this could be a good idea.
Quoted 39 lines
[Btw, the theoretically correct IEEE1275 way to do this is change
addressing across the whole tree. e.g. set #address-cells = <3>, with the first cell being, say, 0 for mmio, 1 for i2c, 2 for SPI, then the remaining cells are the address within that bus. So, this sort of thing is technically possible in old-school OF trees. That would become pretty unmanageable though. The idea of bus-reg is to encode the same information in a less awkward way]Quoted 31 lines
[1]:
https://lore.kernel.org/all/[email protected]/[2]: https://lore.kernel.org/all/[email protected]/
Quoted 25 lines
4) You don't necessarily need to build a "full" device tree
Flattened device trees (as opposed to original IEEE1275 device trees)
- by design - allow certain information to be omitted. The most common example is that for introspectable buses, like PCI, it's normal to have the DT only include a node for the host bridge, with devices under it being discovered by their own bus specific methods. That's discovery is handled by the bus/bridge driver.Connectors usually aren't introspectable, but it's still possible to use an approach like this where the connector driver's discovery method is "look at a different device tree". So, for example,
Board device tree:
/ { compatible = "board-with-foo-connector"; . . . mmio@... { foo-connector@... { compatible = "foo-connector"; ranges = < ... >; } } }
I would expect a description of resources wired to the connector available at the foo-connector node.
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Foo device tree:
/ { compatible = "foo-device"; foo-port-id = < 0x1234 >; component@... { reg = < ... >; } }
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Obviously a "foo device tree" would have different conventions than a board device tree. It wouldn't have /cpus, /memory, /chosen - but it could have its own "magic" nodes that make sense for the properties of the specific connector type.
I agree with the fact that /cpus, /memory, ... wouldn't be present at this node.
Can you provide an example of the "magic" node and what do you have in mind to store this information in DTB?
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Again, that would require work in the device core part of the OS. The bonus is that runtime addition and removal is now trivial. No hacking of the base device tree is needed, and so doesn't need to be reverted. The connector driver just adds/removes the reference to its own private tree.
Here also, I don't see exactly what you have in mind. Can you provide some details and example?
Quoted 23 lines
Quoted 10 lines
Quoted 4 lines
This would, of course, need some way to refer to board resources (interrupt controller, gpio controller) etc. I think that can be assembled using some of the previous ideas, though.
I would need to wrap my head around this a bit, specially in context of chaining connectors. It does seem like it will still require the points you mentioned above to be present in one form or another, i.e. some way to extend busses to different nodes/trees and connector (even a chained one) local symbols/aliases.
Yes, it would still require those mappings. I don't think chained connectors introduce a lot of extra complication. An intermediate connector would need to be able to "re-export" things it got from its parent connector to its child connector(s) - renaming them if necessary.
I think those two elements would be enough to make something that's useful in at least a few cases. However, the pretty common case of a connector with pins from multiple different parent buses would need bus-reg or something similar. Or else the nasty multiplexed encoding described above.
Quoted 9 lines
I say, "nasty" and in many cases it would be, but I think there may be some cases where that approach does make sense: e.g. a connector that has several logically separate address spaces but which always travel together and are typically handled by a common bridge device. PCI is a case of this, if you squint - a host bridge provides a config space bus, and an MMIO bus and a PIO bus. Also sometimes some sort of interrupt controller / interrupt routing, complicated by the fact that there are several different models for that across PCI and PCI-E.
To move forward on the topic, some concrete example would help to understand how to describe link, how the information is stored in DTB.
This would help us in moving in the right direction.
If the issue with export-symbols is having it described as a DTS node, this could be changed with a new DTS keyword.
/export/ <symbol_name_to_resolve> <resolved_symbol_name>
- <symbol_name_tp_resolved>: Symbol name seen by a user
- <resolved_symbol_name>: Symbol used once resolved.
<resolved_symbol_name> can be restricted to phandle values.
Mutiple /export/ can be available inside a node in order to give a list of exported symbols.
For instance with the connector example I previously mentioned. We can replace the export-symbols node by the following:
---- base board DT ----
conn0: connector0 {
gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */
<1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */
i2c_one: i2c-one {
compatible = "i2c-bus-extension";
i2c-parent = <i2c5>; /* i2c wired to i2c5 controller */
};
i2c_two: i2c-two {
compatible = "i2c-bus-extension";
i2c-parent = <i2c6>; /* i2c wired to i2c6 controller */
};
/export/ connector &conn0
/export/ i2cA &i2c_one
/export/ i2cB &i2c_two};
A reference to connector (&connector) from the addon will be resolve to a reference to &conn0 (phandle of the connector0 node.
---- addon board DT, applied at connector0 node ----
{
some-node {
compatible = "foo,bar";
reset-gpios = <&connector 0>; /* gpioA used as a reset gpio */
ddc-i2c-bus = <&i2cB> /* Resolved thanks to /export/ */
}
i2c-one {
/*
* A device added on the i2c-one bus wire to the connector.
* /export/ not involved. i2c-one is a node (bus extension) available
* in the DT node where this addon board DT is applied.
*
*/
eeprom@10 {
compatible = "baz,eeprom"
reg = 10;
};
};};
Now, what is expected in term of DTB format?
I think we need:
- Base DT: List of exported symbols per nodes (/export/)
- Addon DT: List of unresolved symbols and their location
- Addon DT: A way to avoid collision in phandle values
Best regards,
Hervé
Quoted 21 lines · Herve Codina
Hi David,
Quoted 6 lines · On Mon, 8 Sep 2025 14:36:06 +1000 David Gibson <[email protected]>…
Quoted 2 lines · Ayush Singh
Quoted 1 line · David Gibson
On Tue, Sep 02, 2025 at 10:57:10AM +0200, Luca Ceresoli wrote:
[snip]
Quoted 2 lines
Quoted 2 lines
1) Connector local labels/symbols/aliases
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
This is not a new idea - both the export-symbols proposal and my ancient connector proposal had this in one form or another. I think something along these lines is almost essential. Things that plug into connectors almost always require references to several host board resources (interrupt controller, gpio, ...). In order to be pluggable on multiple host boards you want to refer to those symbolically. In order to support multiple instances of the same connector type, you need those symbols to refer to different things fordifferent connector instances.
Quoted 2 lines
Some of the resources can be "translated" using a nexus node. It works for interrupt, gpio, pwm, ...
Yes, I expect that will be necessary.
Quoted 3 lines
I fact, it should work for all references that use a phandle with a resource number. I mean any reference in the form 'ref = <&ctrl 123>' to reference the resource 123 of the controller.
Well, as long as they have a way of defining a nexus / map. That's true of interrupts of course, but I'm not really familiar with the more modern instances.
Quoted 2 lines
From the addon, &ctrl need to be resolved. Using a nexus node at connector level this becomes "ref = <&connector 10>;" and considering the connector itself in the
Right, this requires at least 'connector' to be resolvable as an external resource. If that's possible, I'm not sure that allowing multiple symbols to be resolved to the base tree is notably more complex.
Quoted 7 lines
base tree as a nexus node allows to perform the translation.
connector { gpio-map = <10 &ctrl 123>;};
but this don't work for a reference that uses only a phandle without any number (pinctrl for instance) or for busses where devices need to be added.
That might be true in practice, but there's nothing inherently true about this - it just depends on what the bindings define in terms of nexus / remapping options.
Quoted 2 lines
For busses where devices could be added by the add-on, bus extensions were introduced (i2c-bus-extension).
I think bus-reg is a more natural way to do this for any bus without needing to set up bindings for each new bus type.
Quoted 1 line
In any cases, some symbols need to be referenced from the addon.
Well, certain base tree nodes need to be referred to by the addon, so "symbols" in some sense. That doesn't necessarily have to be done by the existing symbols mechanism.
Quoted 36 lines
Quoted 16 lines
Quoted 12 lines
Quoted 10 lines
Whhat I think is a mistake is trying to tie this too closely to the existing
__symbols__structure. Those have an ugly encoding that requires tortured processing in a way that's not natural for dtb handling. Plus they already kinda-sorta duplicate old-school aliases in an odd way.You want some sort of string => node mapping on the connector side, and a way to mark portions of properties on the plugin side as being resolved to some string reference. But we can take the opportunity to design a better way of doing that than the ugly one we have now.
Quoted 3 lines
Isn't export-symbols exactly this. We do take inspiration from
__symbols__. However, in case of export-symbols, its string => phandle mapping (as opposed to string => string in__symbols__).Quoted 8 lines
As far as the specific It kind of is, yes, and that aspect I like. What I'm not convinced by is how export-symbols is proposed to fit in with and be used by surrounding logic. export-symbols has been designed to fit in with the existing (ugly) overlay mechanism. I think that's putting the cart before the horse. Instead work out how to logically define connectors first - which will involve information equivalent to export-symbols - then work out how to update or replace the overlay mechanism to work with that.
I think that a connector is something with a bunch of resources provided by the board where the connector is soldered. Those resources are wired to the connector and defined by the connector pinout.
3v3 ------- Pin 0 i2c_scl ------- Pin 1 i2c_sda ------- Pin 2 gpio A ------- Pin 3 gpio B ------- Pin 4 gnd ------- Pin 5
Quoted 2 lines
IMHO, this need to be described and defined in the base board and an addon can only reference resources wired and described by the connector node.
Yes, that's exactly what I'm proposing too.
Quoted 3 lines
Now, questions are:
- 1) How to describe a connector?
- 2) How to reference resources provided at connector level from an add-on?
Right.
Quoted 15 lines
Our current approach was:
---- base board DT ----connector0 { gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */ <1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */ i2c-one { compatible = "i2c-bus-extension"; i2c-parent = <i2c5>; /* i2c-one wired to i2c5 controller */ }; i2c-two { compatible = "i2c-bus-extension"; i2c-parent = <i2c6>; /* i2c-two wired to i2c6 controller */ };
Quoted 8 lines
/*
* From the addon we need to reference:
* - The connector itself,
* - Maybe some pinctrl related to signals wired to the connector,
* - In some cases the i2c bus (HDMI, ddc-i2c-bus = <&i2c-two>;)
*
* This was solved introducing the controversial export-symbols node.
*/I think the type of connector should also be named on both sides (with 'compatible' or something like it).
Quoted 16 lines
};---- addon board DT ----
{ some-node { compatible = "foo,bar"; reset-gpios = <&connector 0>; /* gpio A used as a reset gpio */ ddc-i2c-bus = <&i2c-two>; } i2c-one { eeprom@10 { compatible = "baz,eeprom" reg = 10; }; };
Quoted 3 lines
};
The addon board DT can only be applied at a connector node.
Right. This is not how overlays work now. By the nature of how they're built they apply global updates to the base tree. That means we need to spec a new way of describing addons that *is* restricted to a particular connector slot (or slots, as Geert points out). Since we have that opportunity, we should _not_ try to make it a minimal extension to existing overlay format, but define a new and better encoding, designed to meet the problems you're looking to address.
Quoted 17 lines
It described the addon board connected to this connector.
Quoted 15 lines
Quoted 15 lines
I suppose export-symbols could follow aliase conventions, but that still is a string => string mapping, which seems worse to me than a phandle (since phandle size is constant).
Quoted 8 lines
2) Extend dtb itself
A maor thing that makes current symbols and fixups ugly is the fact that they are encoded into properties in the device tree itself, despite being logically at a different semantic level. Obviously you *can* do that, but it's not natural. It would make more sense to add fixup tags into the dtb format itself.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Having something akin to fixup in dtb format itself would be nice.
Yes, it would.
What could be the modification expected at dtb to support the connector use case?
I don't entirely understand the question. It kind of depends what's needed. But certainly FDT_REF_PHANDLE and/or FDT_REF_PATH tags seem reasonable to me. A new symbols/aliases/whatever section in the dtb (separate from the structure block) could also be considered.
Quoted 2 lines
Also what could be the modification expected at dts to described the connector?
One thing I'm hoping is that the new structure can be defined in such a way that not much dts extension is needed.
Quoted 9 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal
It can be a single subtree if decoupling is present at connector node available in the base device tree.
Right - allowing that decoupling is exactly what I'm proposing bus-reg for. Note that the case of an addon that plugs into multiple connectors that Geert pointed out complicates this again.
Quoted 4 lines
All resources wired to the connector should be described in the connector node A add-on board should only see resources provided and described at the connector node or translated by something (nexus, export-symbols) present in the connector node.
Agreed.
Quoted 27 lines
Quoted 27 lines
Quoted 27 lines
Quoted 27 lines
really awkward. Here's an idea I had a while ago to allow plugins to be a single subtree, by extending what's allowed in the tree content:
Currently a node can only really have a presence on its immediate parent bus, as encoded in the 'reg' and 'ranges' properties. 'bus-reg' and 'bus-ranges' would extend that having a similar format to 'reg' and 'ranges' but adding a phandle for each entry saying which bus it lives on - somewhat similar to interrupt-map.
For example, here's an MMIO bus bridge of some sort, which has control registers on I2C:
mmio-bus@... { #address-cells = < 2 >; #size-cells = < 2 >; bridge@XXXX { ranges = <...>; bus-reg = <&i2c0 0x407> } } i2c0: i2c@... { #address-cells = < 1 >; #size-cells = < 0 >; }In a sense this extends the device tree to a device DAG.
Quoted 8 lines
Quoted 6 lines
Quoted 6 lines
Quoted 2 lines
Obviously this does need changes at the OS device core level, but it gives you a lot of flexibility having done so.
There is an i2c-bus-extension [1] and spi-bus-extension proposal to do the same. But, if we can figure out a common way for all buses, that would be great.
Exactly, this is the purpose of bus extensions.
Right, but redefining it for each bus type seems silly.
Quoted 3 lines
Also, I don't thing that the 'ranges' property should be used for that purpose. The 'ranges' property is used to translate addresses from child addresses space to parent addresses space.
The rationale for bus-ranges is that the add-on board could re-expose one of the buses on the connector (say MMIO for simplicity) to several chips physically included on the addon board. We don't want those sub-chips to need different device nodes depending on whether they're on an addon board or wired directly onto a main board. bus-ranges would allow the root of the connector to create a subtree in which regular MMIO (or whatever) devices can be described, and then routed via the connector onto the bus on the main board.
Quoted 1 line
For instance, in case of i2c, where is the address translation?
I think i2c multiplexers can sometimes do that. But in any case, ranges can be used for 1:1 translation as well.
Quoted 3 lines
The address of a child (device) is its I2C address. This address is device in its datasheet. There is no reason to have this address depending on the I2C bus this child is connected to.
Maybe not for I2C, but other buses can certainly allow translation, so the flexibility is needed.
Quoted 1 line
In your example, the bridge@XXXX is not related to any hardware components.
I'm not sure what you mean by that.
Quoted 3 lines
If is allows to physically perform I2C transaction from a MMIO device connected to MMIO bus, this is a traduction I2C controller with a bunch of registers to configure an perform I2C transactions.
Yes, absolutely. The i2c in bus-reg there is not supposed to indicate that the bridge is used to access i2c devices. Rather it's saying that the bridge itself has configuration registers accessible via i2c.
If a device does have its own i2c bus hanging off, then as you say there should not be a 'ranges' property. It would have its own i2c controller driver.
bus-ranges could be used when a connector has pins on multiple MMIO buses, and an addon could have sub-devices on either one of them.
Note that bus-ranges translated between i2c buses isn't theoretically
impossible: that would represent a case with some sort of I2C "relay" device that forwards I2C commands from one side to the other altering the address on the way. I don't know if such devices exist in practice, but they're certainly theoretically possible (and could be used, e.g. for allowing 10-bit I2C devices to be accessed from an old 7-bit I2C bus).
Quoted 6 lines
In that case, this "bridge" looks like all I2C we already support in the kernel.
Having the additional indirection with the "bridge" between the MMIO bus and the i2c@... node seems not a hardware representation of the system.Did I miss something?
I think so. That's representing the bridge itself being configured via I2C, not allowing I2C access to devices _on_ the bus.
Quoted 43 lines
Quoted 42 lines
Heh, right. That reinforces my thought that this could be a good idea.
[Btw, the theoretically correct IEEE1275 way to do this is change
addressing across the whole tree. e.g. set #address-cells = <3>, with the first cell being, say, 0 for mmio, 1 for i2c, 2 for SPI, then the remaining cells are the address within that bus. So, this sort of thing is technically possible in old-school OF trees. That would become pretty unmanageable though. The idea of bus-reg is to encode the same information in a less awkward way]Quoted 31 lines
[1]:
https://lore.kernel.org/all/[email protected]/[2]: https://lore.kernel.org/all/[email protected]/
Quoted 25 lines
4) You don't necessarily need to build a "full" device tree
Flattened device trees (as opposed to original IEEE1275 device trees)
- by design - allow certain information to be omitted. The most common example is that for introspectable buses, like PCI, it's normal to have the DT only include a node for the host bridge, with devices under it being discovered by their own bus specific methods. That's discovery is handled by the bus/bridge driver.Connectors usually aren't introspectable, but it's still possible to use an approach like this where the connector driver's discovery method is "look at a different device tree". So, for example,
Board device tree:
/ { compatible = "board-with-foo-connector"; . . . mmio@... { foo-connector@... { compatible = "foo-connector"; ranges = < ... >; } } }
Quoted 2 lines
I would expect a description of resources wired to the connector available at the foo-connector node.
Possibly yes. Here I was assuming a case where the resources presented by a "foo-connector" are fixed and described in a foo-connector binding. But an approach which explicitly describes the exposed resources could certainly have advantages.
Quoted 16 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Foo device tree:
/ { compatible = "foo-device"; foo-port-id = < 0x1234 >; component@... { reg = < ... >; } }Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Obviously a "foo device tree" would have different conventions than a board device tree. It wouldn't have /cpus, /memory, /chosen - but it could have its own "magic" nodes that make sense for the properties of the specific connector type.
Quoted 5 lines
I agree with the fact that /cpus, /memory, ... wouldn't be present at this node.
Can you provide an example of the "magic" node and what do you have in mind to store this information in DTB?
One obvious one is somewhere to store a mapping / renaming of resources for local use on the connector. Another might be for metadata, like an ID code, if this connector type supports it.
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Again, that would require work in the device core part of the OS. The bonus is that runtime addition and removal is now trivial. No hacking of the base device tree is needed, and so doesn't need to be reverted. The connector driver just adds/removes the reference to its own private tree.
Here also, I don't see exactly what you have in mind. Can you provide some details and example?
What I'm suggesting is that the "main" DT managed by the kernel would never include devices from the addon board. Instead the connector driver would locally a store a different device tree representing just the things under the connector. It would present a bus to the kernel device core that would "discover" devices on the bus based on that local device tree.
Quoted 37 lines
Quoted 22 lines
Quoted 9 lines
Quoted 3 lines
This would, of course, need some way to refer to board resources (interrupt controller, gpio controller) etc. I think that can be assembled using some of the previous ideas, though.
I would need to wrap my head around this a bit, specially in context of chaining connectors. It does seem like it will still require the points you mentioned above to be present in one form or another, i.e. some way to extend busses to different nodes/trees and connector (even a chained one) local symbols/aliases.
Yes, it would still require those mappings. I don't think chained connectors introduce a lot of extra complication. An intermediate connector would need to be able to "re-export" things it got from its parent connector to its child connector(s) - renaming them if necessary.
I think those two elements would be enough to make something that's useful in at least a few cases. However, the pretty common case of a connector with pins from multiple different parent buses would need bus-reg or something similar. Or else the nasty multiplexed encoding described above.
Quoted 8 lines
I say, "nasty" and in many cases it would be, but I think there may be some cases where that approach does make sense: e.g. a connector that has several logically separate address spaces but which always travel together and are typically handled by a common bridge device. PCI is a case of this, if you squint - a host bridge provides a config space bus, and an MMIO bus and a PIO bus. Also sometimes some sort of interrupt controller / interrupt routing, complicated by the fact that there are several different models for that across PCI and PCI-E.
To move forward on the topic, some concrete example would help to understand how to describe link, how the information is stored in DTB.
This would help us in moving in the right direction.
Quoted 6 lines
If the issue with export-symbols is having it described as a DTS node, this could be changed with a new DTS keyword.
/export/ <
symbol_name_to_resolve> <resolved_symbol_name>
- <symbol_name_tp_resolved>: Symbol name seen by a user
- <resolved_symbol_name>: Symbol used once resolved.
I might have some quibbles with the details, but I'd be open to something like that.
Quoted 1 line
<
resolved_symbol_name> can be restricted to phandle values.
Because we're operating at the dts level here, whether it's a phandle is not actually relevant. We can treat this as a dts label name (or optionally path) - how that's encoded in the dtb we get to choose. A phandle is the most obvious approach.
Quoted 2 lines
Mutiple /export/ can be available inside a node in order to give a list of exported symbols.
Sure.
Quoted 11 lines
For instance with the connector example I previously mentioned. We can replace the export-symbols node by the following:
---- base board DT ----
conn0: connector0 { gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */ <1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */ i2c_one: i2c-one { compatible = "i2c-bus-extension"; i2c-parent = <i2c5>; /* i2c wired to i2c5 controller */
I think bus-reg or bus-ranges is a more natural way to do this than per-bus bindings, but that's not particularly relevant to the rest of the proposal.
Quoted 10 lines
};
i2c_two: i2c-two {
compatible = "i2c-bus-extension";
i2c-parent = <i2c6>; /* i2c wired to i2c6 controller */
};
/export/ connector &conn0
/export/ i2cA &i2c_one
/export/ i2cB &i2c_twoSince dtc is explicitly aware of this, we could even allow relative paths here, say
/export/ connector &.;
Quoted 4 lines
};A reference to connector (&connector) from the addon will be resolve to a reference to &conn0 (phandle of the connector0 node.
To handle the addon with multiple connectors we might want an (optional) remapping / renaming on the addon side as well. Or maybe simpler, we could allow namespacing the references on the addon side.
Quoted 22 lines
---- addon board DT, applied at connector0 node ----
{ some-node { compatible = "foo,bar"; reset-gpios = <&connector 0>; /* gpioA used as a reset gpio */ ddc-i2c-bus = <&i2cB> /* Resolved thanks to /export/ */ } i2c-one { /* * A device added on the i2c-one bus wire to the connector. * /export/ not involved. i2c-one is a node (bus extension) available * in the DT node where this addon board DT is applied. * */ eeprom@10 { compatible = "baz,eeprom" reg = 10; }; };
Quoted 8 lines
};
Now, what is expected in term of DTB format?
I think we need:
- Base DT: List of exported symbols per nodes (/export/)
Yes. I'm not necessarily opposed to encoding this as a regular property (basically, 'exported-symbols'). It's more the fixup information that is horrible as regular properties. Connectors should also probably have a property marking them *as* a connector and giving the type.
If we didn't want a regular property we could encode this as an FDT_EXPORT tag. These would go after FDT_BEGIN_NODE, before FDT_PROP and each include a (local-name, phandle) tuple. local-name could be a string table reference.
Quoted 1 line
- Addon DT: List of unresolved symbols and their location
Not sure we need this as a singular list, see below.
Quoted 1 line
- Addon DT: A way to avoid collision in phandle values
I'd suggest maybe three new tags for this, these would appear immediately after the FDT_PROP tag to which they're relevant.
FDT_REF_PHANDLE (offset, name)
This would replace the 4 bytes at offset in the previous property with the phandle of the node referred to by name (which must match something in the connector's exported list).
FDT_REF_PATH (offset, name)
Similar but would insert the full path name of the referenced node in the property.
FDT_REF_LOCAL (offset)
This indicates that that offset in the property contains a phandle value pointing to something within the addon - when we adjust addon phandles to avoid collisions, it needs to be updated too.
The addon should also include information on the type of connector(s) it wants to plug into. That should be a stringlist, like 'compatible', to allow for backwards compatible future extensions.
Or... allowing for addons plugging into multiple connectors, possibly each of those names needs to be extended to (connector, name). connector would be either a name or index saying which connector we're referring to (numbering/naming controlled by the addon) with name being the name of the symbol within that connector (naming controlled by the base board / connector type).
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David,
On Tue, 9 Sep 2025 15:09:18 +1000
David Gibson <[email protected]> wrote:
...
Quoted 46 lines
Quoted 11 lines
I think that a connector is something with a bunch of resources provided by the board where the connector is soldered. Those resources are wired to the connector and defined by the connector pinout.
3v3 ------- Pin 0 i2c_scl ------- Pin 1 i2c_sda ------- Pin 2 gpio A ------- Pin 3 gpio B ------- Pin 4 gnd ------- Pin 5Quoted 2 lines
IMHO, this need to be described and defined in the base board and an addon can only reference resources wired and described by the connector node.
Yes, that's exactly what I'm proposing too.
Quoted 3 lines
Now, questions are:
- 1) How to describe a connector?
- 2) How to reference resources provided at connector level from an add-on?Right.
Quoted 15 lines
Our current approach was:
---- base board DT ----connector0 { gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */ <1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */ i2c-one { compatible = "i2c-bus-extension"; i2c-parent = <i2c5>; /* i2c-one wired to i2c5 controller */ }; i2c-two { compatible = "i2c-bus-extension"; i2c-parent = <i2c6>; /* i2c-two wired to i2c6 controller */ };Quoted 8 lines
/* * From the addon we need to reference: * - The connector itself, * - Maybe some pinctrl related to signals wired to the connector, * - In some cases the i2c bus (HDMI, ddc-i2c-bus = <&i2c-two>;) * * This was solved introducing the controversial export-symbols node. */
Quoted 2 lines
I think the type of connector should also be named on both sides (with 'compatible' or something like it).
It makes sense.
Quoted 21 lines
Quoted 17 lines
};---- addon board DT ----
{ some-node { compatible = "foo,bar"; reset-gpios = <&connector 0>; /* gpio A used as a reset gpio */ ddc-i2c-bus = <&i2c-two>; } i2c-one { eeprom@10 { compatible = "baz,eeprom" reg = 10; }; };Quoted 3 lines
};
The addon board DT can only be applied at a connector node.
Quoted 7 lines
Right. This is not how overlays work now. By the nature of how they're built they apply global updates to the base tree. That means we need to spec a new way of describing addons that *is* restricted to a particular connector slot (or slots, as Geert points out). Since we have that opportunity, we should _not_ try to make it a minimal extension to existing overlay format, but define a new and better encoding, designed to meet the problems you're looking to address.
On the kernel side, overlays can be applied at a specific node. The node is chosen when the overlay is apply.
https://elixir.bootlin.com/linux/v6.16/source/drivers/of/overlay.c#L970
This allows to apply an overlay to a specific node without any modification of the overlay dtb (dtbo).
Ajush proposed an update to support this feature in fdtoverlay
https://lore.kernel.org/all/[email protected]/
...
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal
Quoted 6 lines
Quoted 2 lines
It can be a single subtree if decoupling is present at connector node available in the base device tree.
Right - allowing that decoupling is exactly what I'm proposing bus-reg for. Note that the case of an addon that plugs into multiple connectors that Geert pointed out complicates this again.
Geert's use case needs to be clarified.
Suppose a base board with 2 connectors:
- connA
- connB
Case 1: Addons are independant
+--------+
connA <----> | AddonA |
+--------+
+--------+
connB <---------------->| AddonB |
+--------+With addonA and B two addon board each connected at one connector without any relationship between addon A and B
Case 2: Only one Addons using ressources from both connector
+------+
connA <-----> |Addon |
| |
connB <-----> | |
+------+The addon is connected to both connector and uses ressources from connA and connB in a dependent manner.
The Case 2 can be solved using a connector that described both connA and connB. Having the split connA and connB is a mechanical point of view.
Also adding and Addon on only one part (connA for instance) should not be an issue if the connector describe both parts.
but well, here again I can miss something.
Geert, can you provide details?
...
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
There is an i2c-bus-extension [1] and spi-bus-extension proposal to do the same. But, if we can figure out a common way for all buses, that would be great.
Exactly, this is the purpose of bus extensions.
Right, but redefining it for each bus type seems silly.
Nexus node properties are re-defined for each kind of resources (interrupt, gpio, pwm, ...).
Why not for bus extensions.
Also I am pretty sure that some bus extension will need to define some properties specific to the bus related to the extension.
Quoted 5 lines
Quoted 4 lines
Also, I don't thing that the 'ranges' property should be used for that purpose. The 'ranges' property is used to translate addresses from child addresses space to parent addresses space.
Quoted 8 lines
The rationale for bus-ranges is that the add-on board could re-expose one of the buses on the connector (say MMIO for simplicity) to several chips physically included on the addon board. We don't want those sub-chips to need different device nodes depending on whether they're on an addon board or wired directly onto a main board. bus-ranges would allow the root of the connector to create a subtree in which regular MMIO (or whatever) devices can be described, and then routed via the connector onto the bus on the main board.
bus extensions supports this feature without bus-regs nor bus-ranges.
A bus extension ended by a sub node in the connector node. Applying the addon DT at the connector node allow the addon to had subnode to the extension node.
Quoted 5 lines
Quoted 2 lines
For instance, in case of i2c, where is the address translation?
I think i2c multiplexers can sometimes do that. But in any case, ranges can be used for 1:1 translation as well.
i2c multiplexers are physical devices performing some internal logic. They are real bridges and route an upstream i2c bus to downstream i2c busses.
They are handled by a specific driver.
Quoted 11 lines
Quoted 4 lines
The address of a child (device) is its I2C address. This address is device in its datasheet. There is no reason to have this address depending on the I2C bus this child is connected to.
Maybe not for I2C, but other buses can certainly allow translation, so the flexibility is needed.
Quoted 1 line
In your example, the bridge@XXXX is not related to any hardware components.
I'm not sure what you mean by that.
We have just wires from a controller to a connector. No bridges nor other devices between the controller and the connector.
The controller is described in the base device tree, the connector is described in the base device tree and the physical links between the controller and the connector are wires on PCB.
If a physical device is present between the controller and the connector such as a i2c mux, this physical device is allready described in the base DT.
In that case, your "bridge" will be betweeh the i2c mux and the connector.
In the extension bus case, the extension bus is between the i2c mux and the connector.
Quoted 29 lines
Quoted 4 lines
If is allows to physically perform I2C transaction from a MMIO device connected to MMIO bus, this is a traduction I2C controller with a bunch of registers to configure an perform I2C transactions.
Yes, absolutely. The i2c in bus-reg there is not supposed to indicate that the bridge is used to access i2c devices. Rather it's saying that the bridge itself has configuration registers accessible via i2c.
If a device does have its own i2c bus hanging off, then as you say there should not be a 'ranges' property. It would have its own i2c controller driver.
bus-ranges could be used when a connector has pins on multiple MMIO buses, and an addon could have sub-devices on either one of them.
Note that bus-ranges translated between i2c buses isn't theoretically
impossible: that would represent a case with some sort of I2C "relay" device that forwards I2C commands from one side to the other altering the address on the way. I don't know if such devices exist in practice, but they're certainly theoretically possible (and could be used, e.g. for allowing 10-bit I2C devices to be accessed from an old 7-bit I2C bus).Quoted 5 lines
In that case, this "bridge" looks like all I2C we already support in the kernel.
Having the additional indirection with the "bridge" between the MMIO bus and the i2c@... node seems not a hardware representation of the system.
Quoted 4 lines
Quoted 1 line
Did I miss something?
I think so. That's representing the bridge itself being configured via I2C, not allowing I2C access to devices _on_ the bus.
If I understand correctly the addon board can configure the bridge available on the base board.
How do you describe that when you have everything soldered on a base board and described in a base DT?
I think that the description should be the same with when some devices are soldered on an addon board connected to a connector.
The only difference should be the location of the nodes. Indeed, those devices, on the addon board, behid the connector, should be described as subnodes of the connector.
Extension bus is exactly for that purpose.
...
Quoted 69 lines
Quoted 26 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
4) You don't necessarily need to build a "full" device tree
Flattened device trees (as opposed to original IEEE1275 device trees)
- by design - allow certain information to be omitted. The most common example is that for introspectable buses, like PCI, it's normal to have the DT only include a node for the host bridge, with devices under it being discovered by their own bus specific methods. That's discovery is handled by the bus/bridge driver.Connectors usually aren't introspectable, but it's still possible to use an approach like this where the connector driver's discovery method is "look at a different device tree". So, for example,
Board device tree:
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
/ { compatible = "board-with-foo-connector"; . . . mmio@... { foo-connector@... { compatible = "foo-connector"; ranges = < ... >; } } }Quoted 2 lines
I would expect a description of resources wired to the connector available at the foo-connector node.
Possibly yes. Here I was assuming a case where the resources presented by a "foo-connector" are fixed and described in a foo-connector binding. But an approach which explicitly describes the exposed resources could certainly have advantages.
Quoted 16 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Foo device tree:
/ { compatible = "foo-device"; foo-port-id = < 0x1234 >; component@... { reg = < ... >; } }Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Obviously a "foo device tree" would have different conventions than a board device tree. It wouldn't have /cpus, /memory, /chosen - but it could have its own "magic" nodes that make sense for the properties of the specific connector type.
Quoted 5 lines
I agree with the fact that /cpus, /memory, ... wouldn't be present at this node.
Can you provide an example of the "magic" node and what do you have in mind to store this information in DTB?
One obvious one is somewhere to store a mapping / renaming of resources for local use on the connector. Another might be for metadata, like an ID code, if this connector type supports it.
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Again, that would require work in the device core part of the OS. The bonus is that runtime addition and removal is now trivial. No hacking of the base device tree is needed, and so doesn't need to be reverted. The connector driver just adds/removes the reference to its own private tree.
Here also, I don't see exactly what you have in mind. Can you provide some details and example?
Quoted 6 lines
What I'm suggesting is that the "main" DT managed by the kernel would never include devices from the addon board. Instead the connector driver would locally a store a different device tree representing just the things under the connector. It would present a bus to the kernel device core that would "discover" devices on the bus based on that local device tree.
We agree with that and this is what we have proposed with our connector binding.
The main DT has to provide (describe) busses that can be used by the addon (adding devices to those busses).
Our binding with bus extension fulfills this requirement.
Quoted 41 lines
Quoted 41 lines
Quoted 23 lines
Quoted 10 lines
Quoted 4 lines
This would, of course, need some way to refer to board resources (interrupt controller, gpio controller) etc. I think that can be assembled using some of the previous ideas, though.
I would need to wrap my head around this a bit, specially in context of chaining connectors. It does seem like it will still require the points you mentioned above to be present in one form or another, i.e. some way to extend busses to different nodes/trees and connector (even a chained one) local symbols/aliases.
Yes, it would still require those mappings. I don't think chained connectors introduce a lot of extra complication. An intermediate connector would need to be able to "re-export" things it got from its parent connector to its child connector(s) - renaming them if necessary.
I think those two elements would be enough to make something that's useful in at least a few cases. However, the pretty common case of a connector with pins from multiple different parent buses would need bus-reg or something similar. Or else the nasty multiplexed encoding described above.
Quoted 8 lines
I say, "nasty" and in many cases it would be, but I think there may be some cases where that approach does make sense: e.g. a connector that has several logically separate address spaces but which always travel together and are typically handled by a common bridge device. PCI is a case of this, if you squint - a host bridge provides a config space bus, and an MMIO bus and a PIO bus. Also sometimes some sort of interrupt controller / interrupt routing, complicated by the fact that there are several different models for that across PCI and PCI-E.
To move forward on the topic, some concrete example would help to understand how to describe link, how the information is stored in DTB.
This would help us in moving in the right direction.
If the issue with export-symbols is having it described as a DTS node, this could be changed with a new DTS keyword.
Quoted 6 lines
Quoted 3 lines
/export/ <
symbol_name_to_resolve> <resolved_symbol_name>
- <symbol_name_tp_resolved>: Symbol name seen by a user
- <resolved_symbol_name>: Symbol used once resolved.I might have some quibbles with the details, but I'd be open to something like that.
Ok
Quoted 36 lines
Quoted 2 lines
<
resolved_symbol_name> can be restricted to phandle values.Because we're operating at the dts level here, whether it's a phandle is not actually relevant. We can treat this as a dts label name (or optionally path) - how that's encoded in the dtb we get to choose. A phandle is the most obvious approach.
Quoted 2 lines
Mutiple /export/ can be available inside a node in order to give a list of exported symbols.
Sure.
Quoted 11 lines
For instance with the connector example I previously mentioned. We can replace the export-symbols node by the following:
---- base board DT ----
conn0: connector0 { gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */ <1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */ i2c_one: i2c-one { compatible = "i2c-bus-extension"; i2c-parent = <i2c5>; /* i2c wired to i2c5 controller */I think bus-reg or bus-ranges is a more natural way to do this than per-bus bindings, but that's not particularly relevant to the rest of the proposal.
Quoted 7 lines
}; i2c_two: i2c-two { compatible = "i2c-bus-extension"; i2c-parent = <i2c6>; /* i2c wired to i2c6 controller */ };
Quoted 7 lines
Quoted 3 lines
/export/ connector &conn0 /export/ i2cA &i2c_one /export/ i2cB &i2c_twoSince dtc is explicitly aware of this, we could even allow relative paths here, say
/export/ connector &.;
Indeed, good point.
Quoted 10 lines
Quoted 6 lines
};A reference to connector (&connector) from the addon will be resolve to a reference to &conn0 (phandle of the connector0 node.
To handle the addon with multiple connectors we might want an (optional) remapping / renaming on the addon side as well. Or maybe simpler, we could allow namespacing the references on the addon side.
I think you talk about the Geert use case.
Geert, an example should be welcome.
The plan was to apply the DT related to an addon at a connector node. Maybe this will not fit well with Geert's use case but to know if it fits or not and to find the best way to handle this use case, an example is needed.
Quoted 30 lines
Quoted 29 lines
---- addon board DT, applied at connector0 node ----
{ some-node { compatible = "foo,bar"; reset-gpios = <&connector 0>; /* gpioA used as a reset gpio */ ddc-i2c-bus = <&i2cB> /* Resolved thanks to /export/ */ } i2c-one { /* * A device added on the i2c-one bus wire to the connector. * /export/ not involved. i2c-one is a node (bus extension) available * in the DT node where this addon board DT is applied. * */ eeprom@10 { compatible = "baz,eeprom" reg = 10; }; };};
Now, what is expected in term of DTB format?
I think we need:
Quoted 7 lines
Quoted 1 line
- Base DT: List of exported symbols per nodes (/export/)
Yes. I'm not necessarily opposed to encoding this as a regular property (basically, 'exported-symbols'). It's more the fixup information that is horrible as regular properties. Connectors should also probably have a property marking them *as* a connector and giving the type.
I thought that exported-symbols (or export-symbols) node was a no go.
With our proposal, nothing change in current __symbols__, __fixup__ and __local_fixup__ implementation.
We just add the export-symbols item in current resolution process.
Even if a new DTB format landed, we should support already existing format.
Quoted 23 lines
If we didn't want a regular property we could encode this as an
FDT_EXPORTtag. These would go afterFDT_BEGIN_NODE, beforeFDT_PROPand each include a (local-name, phandle) tuple. local-name could be a string table reference.Quoted 1 line
- Addon DT: List of unresolved symbols and their location
Not sure we need this as a singular list, see below.
Quoted 1 line
- Addon DT: A way to avoid collision in phandle values
I'd suggest maybe three new tags for this, these would appear immediately after the
FDT_PROPtag to which they're relevant.
FDT_REF_PHANDLE(offset, name)This would replace the 4 bytes at
offsetin the previous property with the phandle of the node referred to byname(which must match something in the connector's exported list).
FDT_REF_PATH(offset, name)
Quoted 8 lines
Similar but would insert the full path name of the referenced node in the property.
FDT_REF_LOCAL (offset)This indicates that that offset in the property contains a phandle value pointing to something within the addon - when we adjust addon phandles to avoid collisions, it needs to be updated too.
Ok for FDT_REF_PHANDLE(), FDT_REF_PATH() and FDT_REF_LOCAL().
They replace __fixups__ and __local_fixups__ but we need also something to replace __symbols__ and the "export-symbols"
Solution 1:
A new section is needed.
we have dt_struct and dt_strings. dt_symbols could be this new section.
In this section we have table(s) of exported symbols. In term of information, I think we need:
- The symbol name
- The node exporting the symbol (path)
- The symbol source:
- node referenced by the symbol (path)
- phandle referenced by the symbol
- original name for symbol remapping
Solution 2:
At nodes exporting symbols we could had:
- FDT_EXPORT_PHANDLE(name, phandle)
with name, the exported symbol name and phandle, the phandle value.
- FDT_EXPORT_PATH(name, path)
with name, the exported symbol name and path, the path to exported object
- FDT_EXPORT_REMAP(name, orig_name)
with name, the exported symbol name and orig_name, the original symbol name remapped to the exported symbol name.
Quoted 4 lines
The addon should also include information on the type of connector(s) it wants to plug into. That should be a stringlist, like 'compatible', to allow for backwards compatible future extensions.
This information (if needed) is used by the driver applying the connector. I don't think if should be involved in the symbol resolution mechanism.
From the symbol resolution point of view, we have:
- A base DT,
- A specific node in the base DT where the addon should be added
- The addon DT.
With this 3 inputs, the symbol resolution should do its work. It should not check any compatible strings values.
Quoted 9 lines
Or... allowing for addons plugging into multiple connectors, possibly each of those
names needs to be extended to (connector, name).connectorwould be either a name or index saying which connector we're referring to (numbering/naming controlled by the addon) with name being the name of the symbol within that connector (naming controlled by the base board / connector type).
Best regards,
Hervé
Signature · 3 lines
Hervé Codina, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
Hi Hervé,
Quoted 48 lines · Herve Codina
Quoted 46 lines · On Tue, 9 Sep 2025 15:09:18 +1000 David Gibson <[email protected]>…
Quoted 11 lines
I think that a connector is something with a bunch of resources provided by the board where the connector is soldered. Those resources are wired to the connector and defined by the connector pinout.
3v3 ------- Pin 0 i2c_scl ------- Pin 1 i2c_sda ------- Pin 2 gpio A ------- Pin 3 gpio B ------- Pin 4 gnd ------- Pin 5Quoted 2 lines
IMHO, this need to be described and defined in the base board and an addon can only reference resources wired and described by the connector node.
Yes, that's exactly what I'm proposing too.
Quoted 3 lines
Now, questions are:
- 1) How to describe a connector?
- 2) How to reference resources provided at connector level from an add-on?Right.
Quoted 23 lines
Our current approach was:
---- base board DT ----connector0 { gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */ <1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */ i2c-one { compatible = "i2c-bus-extension"; i2c-parent = <i2c5>; /* i2c-one wired to i2c5 controller */ }; i2c-two { compatible = "i2c-bus-extension"; i2c-parent = <i2c6>; /* i2c-two wired to i2c6 controller */ }; /* * From the addon we need to reference: * - The connector itself, * - Maybe some pinctrl related to signals wired to the connector, * - In some cases the i2c bus (HDMI, ddc-i2c-bus = <&i2c-two>;) * * This was solved introducing the controversial export-symbols node. */
Quoted 4 lines
Quoted 2 lines
I think the type of connector should also be named on both sides (with 'compatible' or something like it).
It makes sense.
Probably we also want header files under <dt/bindings/...> that define the (sole) symbols that are provided by a connector, and can be consumed by an attached board? Cfr. C header files defining an API. In case of multiple connectors (esp. of the same type), we need to specify a prefix before including the header file (see also namespacing below).
Quoted 30 lines
Quoted 22 lines
Quoted 18 lines
};---- addon board DT ----
{ some-node { compatible = "foo,bar"; reset-gpios = <&connector 0>; /* gpio A used as a reset gpio */ ddc-i2c-bus = <&i2c-two>; } i2c-one { eeprom@10 { compatible = "baz,eeprom" reg = 10; }; };Quoted 3 lines
};
The addon board DT can only be applied at a connector node.
Quoted 7 lines
Right. This is not how overlays work now. By the nature of how they're built they apply global updates to the base tree. That means we need to spec a new way of describing addons that *is* restricted to a particular connector slot (or slots, as Geert points out). Since we have that opportunity, we should _not_ try to make it a minimal extension to existing overlay format, but define a new and better encoding, designed to meet the problems you're looking to address.
Quoted 6 lines
On the kernel side, overlays can be applied at a specific node. The node is chosen when the overlay is apply.
https://elixir.bootlin.com/linux/v6.16/source/drivers/of/overlay.c#L970This allows to apply an overlay to a specific node without any modification of the overlay dtb (dtbo).
Which currently supports a single node/connector.
Quoted 43 lines
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal
Quoted 6 lines
Quoted 2 lines
It can be a single subtree if decoupling is present at connector node available in the base device tree.
Right - allowing that decoupling is exactly what I'm proposing bus-reg for. Note that the case of an addon that plugs into multiple connectors that Geert pointed out complicates this again.
Geert's use case needs to be clarified.
Suppose a base board with 2 connectors:
- connA
- connBCase 1: Addons are independant
+--------+ connA <----> | AddonA | +--------+ +--------+ connB <---------------->| AddonB | +--------+With addonA and B two addon board each connected at one connector without any relationship between addon A and B
Case 2: Only one Addons using ressources from both connector
+------+ connA <-----> |Addon | | | connB <-----> | | +------+The addon is connected to both connector and uses ressources from connA and connB in a dependent manner.
Quoted 8 lines
The Case 2 can be solved using a connector that described both connA and connB. Having the split connA and connB is a mechanical point of view.
Also adding and Addon on only one part (connA for instance) should not be an issue if the connector describe both parts.
but well, here again I can miss something.
Geert, can you provide details?
I think the above describes it well, thanks!
However, I am not so fond of having to describe yet another connector that contains connA and connB. E.g. a base board with 6 PMOD connectors would need to describe 30 combinations...
Quoted 7 lines
Quoted 6 lines
Quoted 2 lines
A reference to connector (&connector) from the addon will be resolve to a reference to &conn0 (phandle of the connector0 node.
To handle the addon with multiple connectors we might want an (optional) remapping / renaming on the addon side as well. Or maybe simpler, we could allow namespacing the references on the addon side.
Quoted 7 lines
I think you talk about the Geert use case.
Geert, an example should be welcome.The plan was to apply the DT related to an addon at a connector node. Maybe this will not fit well with Geert's use case but to know if it fits or not and to find the best way to handle this use case, an example is needed.
A PMOD Type 2A (expanded SPI) connector provides SPI and 4 GPIOS. A PMOD Type 6A (expanded I2C) connector provides I2C and 4 GPIOS. Hence a plug-in board that needs SPI, I2C, and a few GPIOs, would need to plug into two PMOD connectors.
Or:
A PMOD Type 1A (expanded GPIO) connector provides 8 GPIOS. Hence a non-multiplexed dual 7-segment LED display plug-in board needs 14 or 16 GPIOS, and thus would plug into two PMOD connectors.
To plug into two connectors, a mapping needs to provided between two connectors on base and add-on board.
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Quoted 51 lines · Geert Uytterhoeven
Hi Hervé,
Quoted 48 lines · Herve Codina
Quoted 46 lines · On Tue, 9 Sep 2025 15:09:18 +1000 David Gibson <[email protected]>…
Quoted 11 lines
I think that a connector is something with a bunch of resources provided by the board where the connector is soldered. Those resources are wired to the connector and defined by the connector pinout.
3v3 ------- Pin 0 i2c_scl ------- Pin 1 i2c_sda ------- Pin 2 gpio A ------- Pin 3 gpio B ------- Pin 4 gnd ------- Pin 5Quoted 2 lines
IMHO, this need to be described and defined in the base board and an addon can only reference resources wired and described by the connector node.
Yes, that's exactly what I'm proposing too.
Quoted 3 lines
Now, questions are:
- 1) How to describe a connector?
- 2) How to reference resources provided at connector level from an add-on?Right.
Quoted 23 lines
Our current approach was:
---- base board DT ----connector0 { gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */ <1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */ i2c-one { compatible = "i2c-bus-extension"; i2c-parent = <i2c5>; /* i2c-one wired to i2c5 controller */ }; i2c-two { compatible = "i2c-bus-extension"; i2c-parent = <i2c6>; /* i2c-two wired to i2c6 controller */ }; /* * From the addon we need to reference: * - The connector itself, * - Maybe some pinctrl related to signals wired to the connector, * - In some cases the i2c bus (HDMI, ddc-i2c-bus = <&i2c-two>;) * * This was solved introducing the controversial export-symbols node. */
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
I think the type of connector should also be named on both sides (with 'compatible' or something like it).
It makes sense.
Probably we also want header files under <dt/bindings/...> that define the (sole) symbols that are provided by a connector, and can be consumed
Yes. Connector types should have their own bindings, describing which symbols are available to things that plug into it.
Quoted 93 lines
by an attached board? Cfr. C header files defining an API. In case of multiple connectors (esp. of the same type), we need to specify a prefix before including the header file (see also namespacing below).
Quoted 30 lines
Quoted 22 lines
Quoted 18 lines
};---- addon board DT ----
{ some-node { compatible = "foo,bar"; reset-gpios = <&connector 0>; /* gpio A used as a reset gpio */ ddc-i2c-bus = <&i2c-two>; } i2c-one { eeprom@10 { compatible = "baz,eeprom" reg = 10; }; };Quoted 3 lines
};
The addon board DT can only be applied at a connector node.
Quoted 7 lines
Right. This is not how overlays work now. By the nature of how they're built they apply global updates to the base tree. That means we need to spec a new way of describing addons that *is* restricted to a particular connector slot (or slots, as Geert points out). Since we have that opportunity, we should _not_ try to make it a minimal extension to existing overlay format, but define a new and better encoding, designed to meet the problems you're looking to address.
Quoted 6 lines
On the kernel side, overlays can be applied at a specific node. The node is chosen when the overlay is apply.
https://elixir.bootlin.com/linux/v6.16/source/drivers/of/overlay.c#L970This allows to apply an overlay to a specific node without any modification of the overlay dtb (dtbo).
Which currently supports a single node/connector.
Quoted 49 lines
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal
Quoted 6 lines
Quoted 2 lines
It can be a single subtree if decoupling is present at connector node available in the base device tree.
Right - allowing that decoupling is exactly what I'm proposing bus-reg for. Note that the case of an addon that plugs into multiple connectors that Geert pointed out complicates this again.
Geert's use case needs to be clarified.
Suppose a base board with 2 connectors:
- connA
- connBCase 1: Addons are independant
+--------+ connA <----> | AddonA | +--------+ +--------+ connB <---------------->| AddonB | +--------+With addonA and B two addon board each connected at one connector without any relationship between addon A and B
Case 2: Only one Addons using ressources from both connector
+------+ connA <-----> |Addon | | | connB <-----> | | +------+The addon is connected to both connector and uses ressources from connA and connB in a dependent manner.
The Case 2 can be solved using a connector that described both connA and connB. Having the split connA and connB is a mechanical point of view.
Also adding and Addon on only one part (connA for instance) should not be an issue if the connector describe both parts.
Quoted 8 lines
Quoted 2 lines
but well, here again I can miss something.
Geert, can you provide details?I think the above describes it well, thanks!
However, I am not so fond of having to describe yet another connector that contains connA and connB. E.g. a base board with 6 PMOD connectors would need to describe 30 combinations...
And it would mean that the OS can't easily reason about which connector slots are currently occupied.
Quoted 39 lines
Quoted 7 lines
Quoted 6 lines
Quoted 2 lines
A reference to connector (&connector) from the addon will be resolve to a reference to &conn0 (phandle of the connector0 node.
To handle the addon with multiple connectors we might want an (optional) remapping / renaming on the addon side as well. Or maybe simpler, we could allow namespacing the references on the addon side.
Quoted 7 lines
I think you talk about the Geert use case.
Geert, an example should be welcome.The plan was to apply the DT related to an addon at a connector node. Maybe this will not fit well with Geert's use case but to know if it fits or not and to find the best way to handle this use case, an example is needed.
A PMOD Type 2A (expanded SPI) connector provides SPI and 4 GPIOS. A PMOD Type 6A (expanded I2C) connector provides I2C and 4 GPIOS. Hence a plug-in board that needs SPI, I2C, and a few GPIOs, would need to plug into two PMOD connectors.
Or:
A PMOD Type 1A (expanded GPIO) connector provides 8 GPIOS. Hence a non-multiplexed dual 7-segment LED display plug-in board needs 14 or 16 GPIOS, and thus would plug into two PMOD connectors.To plug into two connectors, a mapping needs to provided between two connectors on base and add-on board.
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David, Geert,
On Wed, 10 Sep 2025 14:36:46 +1000
David Gibson <[email protected]> wrote:
...
Quoted 6 lines
Quoted 6 lines
A PMOD Type 2A (expanded SPI) connector provides SPI and 4 GPIOS. A PMOD Type 6A (expanded I2C) connector provides I2C and 4 GPIOS. Hence a plug-in board that needs SPI, I2C, and a few GPIOs, would need to plug into two PMOD connectors.
Quoted 8 lines
Quoted 8 lines
Or:
A PMOD Type 1A (expanded GPIO) connector provides 8 GPIOS. Hence a non-multiplexed dual 7-segment LED display plug-in board needs 14 or 16 GPIOS, and thus would plug into two PMOD connectors.To plug into two connectors, a mapping needs to provided between two connectors on base and add-on board.
Base on this, let me draft some ideas to have some basis to move forward.
Suppose:
- A base board with:
2x PMOD Type 2A (SPI + 4 GPIOS)
1x PMOD Type 6A (I2C + 4 GPIOS)
3x PMOD Type 1A ( 8 GPIOS)
- An addon board which needs:
- 1x PMOD type 2A
- 2x PMOD type 1A
Hardware connection:
base board addon board
PMOD 2A #0 +------+ PMOD 2A
PMOD 2A #1
PMOD 6A
PMOD 1A #0
PMOD 1A #1 +------+ PMOD 1A I
PMOD 1A #2 +------+ PMOD 1A IIThe base board 'PMOD 1A #0' is not connected to the addon board. The addon board uses the base board PMOD 1A #1 and #2.
The base board DT:
pmods {
compatible = "pmods";
pmod_2a_0: pmod-2a-0 {
compatible = "pmod-2a"
/* Describe 4 gpios connected to this connector */
gpio-map = < 0 &gpio 10>,
...
< 3 &gpio 43>;
/* Describe the bus connected to this connector */
spi_bus_2a_0: spi-bus {
compatible = "spi-bus-extension";
spi-parent = <&spi2>;
};
/* Export symbols related to this connector */
export-symbols {
pmod-2a = <&pmod_2a_0>;
spi = <&spi_bus_2a_0>;
...
};
};
pmod_2a_1: pmod-2a-1 {
compatible = "pmod-2a"
/* Describe 4 gpios connected to this connector */
gpio-map = ...
/* Describe the bus connected to this connector */
spi_bus_2a_1: spi-bus { ... };
/* Export symbols related to this connector */
export-symbols {
pmod_2a = <&pmod_2a_1>;
spi = <&spi_bus_2a_1>;
...
};
};
pmod_6a: pmod-6a {
compatible = "pmod-6a";
...
export-symbols {
pmod_6a = <&pmod_6a>;
...
};
};
pmod_1a_0: pmod-1a-0 {
compatible = "pmod-1a"
/* Describe 8 gpios connected to this connector */
gpio-map = < 0 &gpio 16>,
...
< 7 &gpio 33>;
export-symbols {
pmod_1a = <&pmod_1a_0>;
gpio0_muxed_as_gpio = <&pin_mux_xxxx>;
gpio1_muxed_as_gpio = <&pin_mux_yyyy>;
gpio2_muxed_as_gpio = <&pin_mux_zzzz>;
};
};
pmod_1a_1: pmod-1a-1 {
compatible = "pmod-1a"
/* Describe 8 gpios connected to this connector */
...
export-symbols {
pmod_1a = <&pmod_1a_1>;
};
};
pmod_1a_2: pmod-1a-2 {
compatible = "pmod-1a"
/* Describe 8 gpios connected to this connector */
...
export-symbols {
pmod_1a = <&pmod_1a_2>;
};
};
};-- Question 1: How to describe resources needed by the addon
On the addon side, we need to tell that we need 1 PMOD 2A and 2 PMODs 1A (named i and ii).
Proposal supposing that this description will be applied at base board pmods node (the one grouping pmod connectors):
\{ or ??? corresponding to the entry point of the addon
import-symbols {
pmod_2a = "pmod_2a";
pmod_1a_i = "pmod_1a";
pmod_1a_ii = "pmod_1a";};
&pmod_2a {
spi-bus {
regulator@0 {
compatible "gpio-regulator";
pinctrl-0 = <&pmod_1a_i.gpio2_muxed_as_gpio>;
enable-gpios = <&pmod_1a_i 2>; /* Use GPIO #2 available on PMOD 1A I */
};
... };
};
Import-symbols asked for symbols with local name and type (compatible string ?). for instance 'pmod_1a_i = "pmod_2a";' means:
Hey I refernce localy 'pmod_1a_i' but I don't define it and so 'pmod_1a_i' should be remapped to a symbol, probably a node of my expected type "pmod_2a".
Also, we can node the syntax:
&pmod_1a_i.gpio2_muxed_as_gpio
meaning I use the symbols gpio2_muxed_as_gpio provided by pmod_1a_i (namespace). In other word, to have the addon DT successfully applied,
the node remapped to 'pmod_1a_i' has to export the symbol 'gpio2_muxed_as_gpio'.
--- Question 2: how to perform the mapping between pmods available on the
base board and pmods needed by the addon board.
The addon board describes what it is expected:
import-symbols {
pmod_2a = "pmod_2a";
pmod_1a_i = "pmod_1a";
pmod_1a_ii = "pmod_1a";};
Based on compatible string:
pmod_2a expected by the addon can be remapped to the node pmod-2a-0 or pmod-2a-1 described in the base board.
pmod_1a_i and pmod_1a_ii expected by the addon can be remapped to pmod-1a-0, pmod-1a-1, pmod-1a-2.
We need some more information to set correct mapping
pmod_2a <---> pmod-2a-0
pmod_1a_i <---> pmod-1a-1
pmod_1a_ii <---> pmod-1a-2 Can we imagine that this mapping is set by the compatible "pmods" driver base on some specific external information.
- Read info from addon to have some more hardware connection details (not sure it is relavant with PMODs connector)
- Expect this information from user-space ?
- Any other ideas ?
Best regards,
Hervé
Hello,
Quoted 170 lines · On Thu, 11 Sep 2025 12:11:03 +0200 Herve Codina <[email protected]>…
Hi David, Geert,
On Wed, 10 Sep 2025 14:36:46 +1000
David Gibson <[email protected]> wrote:...
Quoted 6 lines
Quoted 6 lines
A PMOD Type 2A (expanded SPI) connector provides SPI and 4 GPIOS. A PMOD Type 6A (expanded I2C) connector provides I2C and 4 GPIOS. Hence a plug-in board that needs SPI, I2C, and a few GPIOs, would need to plug into two PMOD connectors.
Quoted 8 lines
Quoted 8 lines
Or:
A PMOD Type 1A (expanded GPIO) connector provides 8 GPIOS. Hence a non-multiplexed dual 7-segment LED display plug-in board needs 14 or 16 GPIOS, and thus would plug into two PMOD connectors.To plug into two connectors, a mapping needs to provided between two connectors on base and add-on board.
Base on this, let me draft some ideas to have some basis to move forward.
Suppose:
- A base board with:
2x PMOD Type 2A (SPI + 4 GPIOS)
1x PMOD Type 6A (I2C + 4 GPIOS)
3x PMOD Type 1A ( 8 GPIOS)- An addon board which needs:
- 1x PMOD type 2A
- 2x PMOD type 1AHardware connection:
base board addon boardPMOD 2A #0 +------+ PMOD 2A PMOD 2A #1 PMOD 6A PMOD 1A #0 PMOD 1A #1 +------+ PMOD 1A I PMOD 1A #2 +------+ PMOD 1A IIThe base board 'PMOD 1A #0' is not connected to the addon board. The addon board uses the base board PMOD 1A #1 and #2.
The base board DT:
pmods { compatible = "pmods"; pmod_2a_0: pmod-2a-0 { compatible = "pmod-2a" /* Describe 4 gpios connected to this connector */ gpio-map = < 0 &gpio 10>, ... < 3 &gpio 43>; /* Describe the bus connected to this connector */ spi_bus_2a_0: spi-bus { compatible = "spi-bus-extension"; spi-parent = <&spi2>; }; /* Export symbols related to this connector */ export-symbols { pmod-2a = <&pmod_2a_0>; spi = <&spi_bus_2a_0>; ... }; }; pmod_2a_1: pmod-2a-1 { compatible = "pmod-2a" /* Describe 4 gpios connected to this connector */ gpio-map = ... /* Describe the bus connected to this connector */ spi_bus_2a_1: spi-bus { ... }; /* Export symbols related to this connector */ export-symbols { pmod_2a = <&pmod_2a_1>; spi = <&spi_bus_2a_1>; ... }; }; pmod_6a: pmod-6a { compatible = "pmod-6a"; ... export-symbols { pmod_6a = <&pmod_6a>; ... }; }; pmod_1a_0: pmod-1a-0 { compatible = "pmod-1a" /* Describe 8 gpios connected to this connector */ gpio-map = < 0 &gpio 16>, ... < 7 &gpio 33>; export-symbols { pmod_1a = <&pmod_1a_0>; gpio0_muxed_as_gpio = <&pin_mux_xxxx>; gpio1_muxed_as_gpio = <&pin_mux_yyyy>; gpio2_muxed_as_gpio = <&pin_mux_zzzz>; }; }; pmod_1a_1: pmod-1a-1 { compatible = "pmod-1a" /* Describe 8 gpios connected to this connector */ ... export-symbols { pmod_1a = <&pmod_1a_1>; }; }; pmod_1a_2: pmod-1a-2 { compatible = "pmod-1a" /* Describe 8 gpios connected to this connector */ ... export-symbols { pmod_1a = <&pmod_1a_2>; }; }; };-- Question 1: How to describe resources needed by the addon
On the addon side, we need to tell that we need 1 PMOD 2A and 2 PMODs 1A (named i and ii).
Proposal supposing that this description will be applied at base board pmods node (the one grouping pmod connectors):
\{ or ??? corresponding to the entry point of the addon
import-symbols { pmod_2a = "pmod_2a"; pmod_1a_i = "pmod_1a"; pmod_1a_ii = "pmod_1a";};
&pmod_2a { spi-bus { regulator@0 { compatible "gpio-regulator"; pinctrl-0 = <&pmod_1a_i.gpio2_muxed_as_gpio>; enable-gpios = <&pmod_1a_i 2>; /* Use GPIO #2 available on PMOD 1A I */ }; ... }; };Import-symbols asked for symbols with local name and type (compatible string ?). for instance '
pmod_1a_i= "pmod_2a";' means:
Hey I refernce localy 'pmod_1a_i' but I don't define it and so 'pmod_1a_i' should be remapped to a symbol, probably a node of my expected type "pmod_2a".
Quoted 6 lines
Also, we can node the syntax:
&pmod_1a_i.gpio2_muxed_as_gpiomeaning I use the symbols
gpio2_muxed_as_gpioprovided bypmod_1a_i(namespace). In other word, to have the addon DT successfully applied,
the node remapped to 'pmod_1a_i' has to export the symbol 'gpio2_muxed_as_gpio'.
Thanks for taking time to prepare a complete example. I think this example is very effective as it exposes perhaps all the features we are discussing.
I consider it pseudocode, i.e. the syntax may not be OK, but that's not too relevant at this point of the discussion. But as far as I can say it has the right information at the right place, and IMO that's what we need to iron out in the first place.
Quoted 22 lines
--- Question 2: how to perform the mapping between pmods available on the
base board and pmods needed by the addon board.The addon board describes what it is expected:
import-symbols { pmod_2a = "pmod_2a"; pmod_1a_i = "pmod_1a"; pmod_1a_ii = "pmod_1a";};
Based on compatible string:
pmod_2aexpected by the addon can be remapped to the node pmod-2a-0 or pmod-2a-1 described in the base board.
pmod_1a_iandpmod_1a_iiexpected by the addon can be remapped to pmod-1a-0, pmod-1a-1, pmod-1a-2.We need some more information to set correct mapping
pmod_2a <---> pmod-2a-0 pmod_1a_i <---> pmod-1a-1 pmod_1a_ii <---> pmod-1a-2
Quoted 8 lines
Can we imagine that this mapping is set by the compatible "pmods" driver base on some specific external information.
- Read info from addon to have some more hardware connection details (not sure it is relavant with PMODs connector)- Expect this information from user-space ?
- Any other ideas ?
I'd say the only possible answer to question 2 is "this is specific to each connector type and thus to each connector driver".
As you just described in [0], some connector types have model discovery capabilities so the driver can do on its own. In principle this might apply to addons using multiple connectors.
However for PMODs AFAIK there is no discovery at all, so the driver must be instructed by the user.
[0] https://lore.kernel.org/all/[email protected]/
Signature · 3 lines
Luca Ceresoli, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
Quoted 87 lines · Herve Codina
Hi David,
On Tue, 9 Sep 2025 15:09:18 +1000
David Gibson <[email protected]> wrote:...
Quoted 46 lines
Quoted 11 lines
I think that a connector is something with a bunch of resources provided by the board where the connector is soldered. Those resources are wired to the connector and defined by the connector pinout.
3v3 ------- Pin 0 i2c_scl ------- Pin 1 i2c_sda ------- Pin 2 gpio A ------- Pin 3 gpio B ------- Pin 4 gnd ------- Pin 5Quoted 2 lines
IMHO, this need to be described and defined in the base board and an addon can only reference resources wired and described by the connector node.
Yes, that's exactly what I'm proposing too.
Quoted 3 lines
Now, questions are:
- 1) How to describe a connector?
- 2) How to reference resources provided at connector level from an add-on?Right.
Quoted 15 lines
Our current approach was:
---- base board DT ----connector0 { gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */ <1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */ i2c-one { compatible = "i2c-bus-extension"; i2c-parent = <i2c5>; /* i2c-one wired to i2c5 controller */ }; i2c-two { compatible = "i2c-bus-extension"; i2c-parent = <i2c6>; /* i2c-two wired to i2c6 controller */ };Quoted 8 lines
/* * From the addon we need to reference: * - The connector itself, * - Maybe some pinctrl related to signals wired to the connector, * - In some cases the i2c bus (HDMI, ddc-i2c-bus = <&i2c-two>;) * * This was solved introducing the controversial export-symbols node. */Quoted 2 lines
I think the type of connector should also be named on both sides (with 'compatible' or something like it).
It makes sense.
Quoted 21 lines
Quoted 17 lines
};---- addon board DT ----
{ some-node { compatible = "foo,bar"; reset-gpios = <&connector 0>; /* gpio A used as a reset gpio */ ddc-i2c-bus = <&i2c-two>; } i2c-one { eeprom@10 { compatible = "baz,eeprom" reg = 10; }; };Quoted 3 lines
};
The addon board DT can only be applied at a connector node.
Quoted 7 lines
Right. This is not how overlays work now. By the nature of how they're built they apply global updates to the base tree. That means we need to spec a new way of describing addons that *is* restricted to a particular connector slot (or slots, as Geert points out). Since we have that opportunity, we should _not_ try to make it a minimal extension to existing overlay format, but define a new and better encoding, designed to meet the problems you're looking to address.
Quoted 3 lines
On the kernel side, overlays can be applied at a specific node. The node is chosen when the overlay is apply.
https://elixir.bootlin.com/linux/v6.16/source/drivers/of/overlay.c#L970
Huh, I wasn't aware that had already been merged.
Quoted 5 lines
This allows to apply an overlay to a specific node without any modification of the overlay dtb (dtbo).
Ajush proposed an update to support this feature in fdtoverlay
https://lore.kernel.org/all/[email protected]/
Yes, and I've been disinclined to merge it because I think extending overlays in this way, without a more wide-ranging redesign, is not a great idea.
Quoted 33 lines
...
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal
Quoted 6 lines
Quoted 2 lines
It can be a single subtree if decoupling is present at connector node available in the base device tree.
Right - allowing that decoupling is exactly what I'm proposing bus-reg for. Note that the case of an addon that plugs into multiple connectors that Geert pointed out complicates this again.
Geert's use case needs to be clarified.
Suppose a base board with 2 connectors:
- connA
- connBCase 1: Addons are independant
+--------+ connA <----> | AddonA | +--------+ +--------+ connB <---------------->| AddonB | +--------+With addonA and B two addon board each connected at one connector without any relationship between addon A and B
Quoted 7 lines
Case 2: Only one Addons using ressources from both connector
+------+ connA <-----> |Addon | | | connB <-----> | | +------+
Case 2 is what I'm talking about. Case 1 is the easy one.
Quoted 6 lines
The addon is connected to both connector and uses ressources from connA and connB in a dependent manner.
The Case 2 can be solved using a connector that described both connA and connB. Having the split connA and connB is a mechanical point of view.
I don't think that's a good solution, because it means you have to make that decision at the board layer. If I understand his case correctly, you have a board where you could do either case 1 or case 2 at runtime. We'd want the differences between these cases to only be reflected on the addon device tree, not the base board device tree.
Quoted 13 lines
Also adding and Addon on only one part (connA for instance) should not be an issue if the connector describe both parts.
but well, here again I can miss something.
Geert, can you provide details?...
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Quoted 4 lines
There is an i2c-bus-extension [1] and spi-bus-extension proposal to do the same. But, if we can figure out a common way for all buses, that would be great.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Exactly, this is the purpose of bus extensions.
Right, but redefining it for each bus type seems silly.
Nexus node properties are re-defined for each kind of resources (interrupt, gpio, pwm, ...).
Yes, for historical reasons. In IEE1275 days, interrupts was basically the only thing that worked this way. gpio and pwm were added much later using interrupts as a model. If we were designing from scratch having a common way of defining a nexus would make sense too.
Quoted 1 line
Why not for bus extensions.
So that we don't need to keep defining new bindings for it.
Quoted 2 lines
Also I am pretty sure that some bus extension will need to define some properties specific to the bus related to the extension.
Maybe, but then only those buses that specifically need it need the extra binding.
Quoted 13 lines
Quoted 4 lines
Quoted 3 lines
Also, I don't thing that the 'ranges' property should be used for that purpose. The 'ranges' property is used to translate addresses from child addresses space to parent addresses space.
Quoted 8 lines
The rationale for bus-ranges is that the add-on board could re-expose one of the buses on the connector (say MMIO for simplicity) to several chips physically included on the addon board. We don't want those sub-chips to need different device nodes depending on whether they're on an addon board or wired directly onto a main board. bus-ranges would allow the root of the connector to create a subtree in which regular MMIO (or whatever) devices can be described, and then routed via the connector onto the bus on the main board.
Quoted 1 line
bus extensions supports this feature without bus-regs nor bus-ranges.
bus-reg & bus-ranges allow it for any bus without having to create a new binding.
Quoted 3 lines
A bus extension ended by a sub node in the connector node. Applying the addon DT at the connector node allow the addon to had subnode to the extension node.
I don't really understand what point you're making here.
Quoted 10 lines
Quoted 6 lines
Quoted 3 lines
For instance, in case of i2c, where is the address translation?
I think i2c multiplexers can sometimes do that. But in any case, ranges can be used for 1:1 translation as well.
i2c multiplexers are physical devices performing some internal logic. They are real bridges and route an upstream i2c bus to downstream i2c busses.
Yes... and bus-ranges could encode exactly that. It just means that the downstream bus doesn't have to be physically located in the tree below the upstream bus.
Or, you can use a node with an identity mapping bus-ranges to allow bus extension without translation - just as as sometimes done for transparent MMIO bridges.
Quoted 10 lines
They are handled by a specific driver.
Quoted 8 lines
Quoted 4 lines
The address of a child (device) is its I2C address. This address is device in its datasheet. There is no reason to have this address depending on the I2C bus this child is connected to.
Maybe not for I2C, but other buses can certainly allow translation, so the flexibility is needed.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
In your example, the bridge@XXXX is not related to any hardware components.
I'm not sure what you mean by that.
We have just wires from a controller to a connector. No bridges nor other devices between the controller and the connector.
Wires are a hardware component. Not a very interesting one, but a device tree node doesn't have to represent active logic.
Quoted 11 lines
The controller is described in the base device tree, the connector is described in the base device tree and the physical links between the controller and the connector are wires on PCB.
If a physical device is present between the controller and the connector such as a i2c mux, this physical device is allready described in the base DT.
In that case, your "bridge" will be betweeh the i2c mux and the connector.
In the extension bus case, the extension bus is between the i2c mux and the connector.
Yes... and, so?
Quoted 28 lines
Quoted 28 lines
Quoted 3 lines
If is allows to physically perform I2C transaction from a MMIO device connected to MMIO bus, this is a traduction I2C controller with a bunch of registers to configure an perform I2C transactions.
Yes, absolutely. The i2c in bus-reg there is not supposed to indicate that the bridge is used to access i2c devices. Rather it's saying that the bridge itself has configuration registers accessible via i2c.
If a device does have its own i2c bus hanging off, then as you say there should not be a 'ranges' property. It would have its own i2c controller driver.
bus-ranges could be used when a connector has pins on multiple MMIO buses, and an addon could have sub-devices on either one of them.
Note that bus-ranges translated between i2c buses isn't theoretically
impossible: that would represent a case with some sort of I2C "relay" device that forwards I2C commands from one side to the other altering the address on the way. I don't know if such devices exist in practice, but they're certainly theoretically possible (and could be used, e.g. for allowing 10-bit I2C devices to be accessed from an old 7-bit I2C bus).Quoted 5 lines
In that case, this "bridge" looks like all I2C we already support in the kernel.
Having the additional indirection with the "bridge" between the MMIO bus and the i2c@... node seems not a hardware representation of the system.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Did I miss something?
I think so. That's representing the bridge itself being configured via I2C, not allowing I2C access to devices _on_ the bus.
If I understand correctly the addon board can configure the bridge available on the base board.
In this particular example there isn't (necessarily) an addon in play. I'm just giving an example of a plausible device that has a presence on two upstream buses - MMIO for the data path, and I2C for the control path. There's not a natural way to represent that with regular 'reg' and 'ranges'.
I'm saying that the *OS* can configure the bridge via I2C, nothing about the hardware (addon or otherwise) configuring the bridge.
Quoted 90 lines
How do you describe that when you have everything soldered on a base board and described in a base DT?
I think that the description should be the same with when some devices are soldered on an addon board connected to a connector.
The only difference should be the location of the nodes. Indeed, those devices, on the addon board, behid the connector, should be described as subnodes of the connector.
Extension bus is exactly for that purpose.
...
Quoted 69 lines
Quoted 26 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
4) You don't necessarily need to build a "full" device tree
Flattened device trees (as opposed to original IEEE1275 device trees)
- by design - allow certain information to be omitted. The most common example is that for introspectable buses, like PCI, it's normal to have the DT only include a node for the host bridge, with devices under it being discovered by their own bus specific methods. That's discovery is handled by the bus/bridge driver.Connectors usually aren't introspectable, but it's still possible to use an approach like this where the connector driver's discovery method is "look at a different device tree". So, for example,
Board device tree:
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
/ { compatible = "board-with-foo-connector"; . . . mmio@... { foo-connector@... { compatible = "foo-connector"; ranges = < ... >; } } }Quoted 2 lines
I would expect a description of resources wired to the connector available at the foo-connector node.
Possibly yes. Here I was assuming a case where the resources presented by a "foo-connector" are fixed and described in a foo-connector binding. But an approach which explicitly describes the exposed resources could certainly have advantages.
Quoted 16 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Foo device tree:
/ { compatible = "foo-device"; foo-port-id = < 0x1234 >; component@... { reg = < ... >; } }Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Obviously a "foo device tree" would have different conventions than a board device tree. It wouldn't have /cpus, /memory, /chosen - but it could have its own "magic" nodes that make sense for the properties of the specific connector type.
Quoted 5 lines
I agree with the fact that /cpus, /memory, ... wouldn't be present at this node.
Can you provide an example of the "magic" node and what do you have in mind to store this information in DTB?
One obvious one is somewhere to store a mapping / renaming of resources for local use on the connector. Another might be for metadata, like an ID code, if this connector type supports it.
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Again, that would require work in the device core part of the OS. The bonus is that runtime addition and removal is now trivial. No hacking of the base device tree is needed, and so doesn't need to be reverted. The connector driver just adds/removes the reference to its own private tree.
Here also, I don't see exactly what you have in mind. Can you provide some details and example?
Quoted 6 lines
What I'm suggesting is that the "main" DT managed by the kernel would never include devices from the addon board. Instead the connector driver would locally a store a different device tree representing just the things under the connector. It would present a bus to the kernel device core that would "discover" devices on the bus based on that local device tree.
Quoted 6 lines
We agree with that and this is what we have proposed with our connector binding.
The main DT has to provide (describe) busses that can be used by the addon (adding devices to those busses).Our binding with bus extension fulfills this requirement.
Right, but I'm saying even for the OS's runtime copy of the device tree the addon device would not be (directly) included. I'm not saying that's the only way or the best way to do it, just that I think it should be considered. It makes runtime device discovery more complex - not just one DT must be traversed, but possibly several depending on connector drivers. However, the plus side is that the core DT management doesn't ever need to deal with hotplug or hot remove.
Quoted 146 lines
Quoted 40 lines
Quoted 40 lines
Quoted 22 lines
Quoted 9 lines
Quoted 3 lines
This would, of course, need some way to refer to board resources (interrupt controller, gpio controller) etc. I think that can be assembled using some of the previous ideas, though.
I would need to wrap my head around this a bit, specially in context of chaining connectors. It does seem like it will still require the points you mentioned above to be present in one form or another, i.e. some way to extend busses to different nodes/trees and connector (even a chained one) local symbols/aliases.
Yes, it would still require those mappings. I don't think chained connectors introduce a lot of extra complication. An intermediate connector would need to be able to "re-export" things it got from its parent connector to its child connector(s) - renaming them if necessary.
I think those two elements would be enough to make something that's useful in at least a few cases. However, the pretty common case of a connector with pins from multiple different parent buses would need bus-reg or something similar. Or else the nasty multiplexed encoding described above.
Quoted 8 lines
I say, "nasty" and in many cases it would be, but I think there may be some cases where that approach does make sense: e.g. a connector that has several logically separate address spaces but which always travel together and are typically handled by a common bridge device. PCI is a case of this, if you squint - a host bridge provides a config space bus, and an MMIO bus and a PIO bus. Also sometimes some sort of interrupt controller / interrupt routing, complicated by the fact that there are several different models for that across PCI and PCI-E.
To move forward on the topic, some concrete example would help to understand how to describe link, how the information is stored in DTB.
This would help us in moving in the right direction.
If the issue with export-symbols is having it described as a DTS node, this could be changed with a new DTS keyword.
Quoted 6 lines
Quoted 3 lines
/export/ <
symbol_name_to_resolve> <resolved_symbol_name>
- <symbol_name_tp_resolved>: Symbol name seen by a user
- <resolved_symbol_name>: Symbol used once resolved.I might have some quibbles with the details, but I'd be open to something like that.
Ok
Quoted 36 lines
Quoted 2 lines
<
resolved_symbol_name> can be restricted to phandle values.Because we're operating at the dts level here, whether it's a phandle is not actually relevant. We can treat this as a dts label name (or optionally path) - how that's encoded in the dtb we get to choose. A phandle is the most obvious approach.
Quoted 2 lines
Mutiple /export/ can be available inside a node in order to give a list of exported symbols.
Sure.
Quoted 11 lines
For instance with the connector example I previously mentioned. We can replace the export-symbols node by the following:
---- base board DT ----
conn0: connector0 { gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */ <1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */ i2c_one: i2c-one { compatible = "i2c-bus-extension"; i2c-parent = <i2c5>; /* i2c wired to i2c5 controller */I think bus-reg or bus-ranges is a more natural way to do this than per-bus bindings, but that's not particularly relevant to the rest of the proposal.
Quoted 7 lines
}; i2c_two: i2c-two { compatible = "i2c-bus-extension"; i2c-parent = <i2c6>; /* i2c wired to i2c6 controller */ };Quoted 7 lines
Quoted 3 lines
/export/ connector &conn0 /export/ i2cA &i2c_one /export/ i2cB &i2c_twoSince dtc is explicitly aware of this, we could even allow relative paths here, say
/export/ connector &.;Indeed, good point.
Quoted 10 lines
Quoted 6 lines
};A reference to connector (&connector) from the addon will be resolve to a reference to &conn0 (phandle of the connector0 node.
To handle the addon with multiple connectors we might want an (optional) remapping / renaming on the addon side as well. Or maybe simpler, we could allow namespacing the references on the addon side.
I think you talk about the Geert use case.
Geert, an example should be welcome.The plan was to apply the DT related to an addon at a connector node. Maybe this will not fit well with Geert's use case but to know if it fits or not and to find the best way to handle this use case, an example is needed.
Quoted 32 lines
Quoted 31 lines
---- addon board DT, applied at connector0 node ----
{ some-node { compatible = "foo,bar"; reset-gpios = <&connector 0>; /* gpioA used as a reset gpio */ ddc-i2c-bus = <&i2cB> /* Resolved thanks to /export/ */ } i2c-one { /* * A device added on the i2c-one bus wire to the connector. * /export/ not involved. i2c-one is a node (bus extension) available * in the DT node where this addon board DT is applied. * */ eeprom@10 { compatible = "baz,eeprom" reg = 10; }; };};
Now, what is expected in term of DTB format?
I think we need:
- Base DT: List of exported symbols per nodes (/export/)
Quoted 7 lines
Quoted 5 lines
Yes. I'm not necessarily opposed to encoding this as a regular property (basically, 'exported-symbols'). It's more the fixup information that is horrible as regular properties. Connectors should also probably have a property marking them *as* a connector and giving the type.
I thought that exported-symbols (or export-symbols) node was a no go.
I'm not against 'export-symbols' itself. I'm just against implementing it purely to stretch existing overlay mechanisms to do things they were never really meant to, without considering the end to end design.
Quoted 6 lines
With our proposal, nothing change in current
__symbols__,__fixup__and__local_fixup__implementation.We just add the export-symbols item in current resolution process.
Even if a new DTB format landed, we should support already existing format.
"Support" in what sense? Still allow, obviously, but I don't think it's necessary to squeeze new features into an old format.
Quoted 33 lines
Quoted 22 lines
If we didn't want a regular property we could encode this as an
FDT_EXPORTtag. These would go afterFDT_BEGIN_NODE, beforeFDT_PROPand each include a (local-name, phandle) tuple. local-name could be a string table reference.Quoted 1 line
- Addon DT: List of unresolved symbols and their location
Not sure we need this as a singular list, see below.
Quoted 1 line
- Addon DT: A way to avoid collision in phandle values
I'd suggest maybe three new tags for this, these would appear immediately after the
FDT_PROPtag to which they're relevant.
FDT_REF_PHANDLE(offset, name)This would replace the 4 bytes at
offsetin the previous property with the phandle of the node referred to byname(which must match something in the connector's exported list).
FDT_REF_PATH(offset, name)Quoted 8 lines
Similar but would insert the full path name of the referenced node in the property.
FDT_REF_LOCAL (offset)This indicates that that offset in the property contains a phandle value pointing to something within the addon - when we adjust addon phandles to avoid collisions, it needs to be updated too.
Ok for
FDT_REF_PHANDLE(),FDT_REF_PATH()andFDT_REF_LOCAL().
Quoted 7 lines
They replace
__fixups__and__local_fixups__but we need also something to replace__symbols__and the "export-symbols"Solution 1:
A new section is needed.
we havedt_structanddt_strings.dt_symbolscould be this new section.
I think we want to heavily discourage / deprecate use of global symbols like we have now, in favour of local symbols (export-symbols or something like it). So I don't think adding a new section for global symbols is a good idea.
Quoted 15 lines
In this section we have table(s) of exported symbols. In term of information, I think we need:
- The symbol name
- The node exporting the symbol (path)
- The symbol source:
- node referenced by the symbol (path)
- phandle referenced by the symbol
- original name for symbol remappingSolution 2:
At nodes exporting symbols we could had:
-FDT_EXPORT_PHANDLE(name, phandle)
with name, the exported symbol name and phandle, the phandle value.
Quoted 7 lines
-
FDT_EXPORT_PATH(name, path)
with name, the exported symbol name and path, the path to exported object-
FDT_EXPORT_REMAP(name, orig_name)
with name, the exported symbol name andorig_name, the original symbol name remapped to the exported symbol name.
I think we only need one of these (probably _PHANDLE). We could allow the other variants in source, but it should be strightforward to compile them all to the same thing.
Quoted 6 lines
Quoted 3 lines
The addon should also include information on the type of connector(s) it wants to plug into. That should be a stringlist, like 'compatible', to allow for backwards compatible future extensions.
This information (if needed) is used by the driver applying the connector. I don't think if should be involved in the symbol resolution mechanism.
Maybe, but it's still information that should be there.
Quoted 3 lines
From the symbol resolution point of view, we have:
- A base DT,
- A specific node in the base DT where the addon should be added
Not necessarily just one for Case 2 above.
Quoted 4 lines
- The addon DT.
With this 3 inputs, the symbol resolution should do its work. It should not check any compatible strings values.
Hmm. Why not? It's not strictly necessary to the process, I agree, but seems like it could be a useful sanity check.
Quoted 19 lines
Quoted 10 lines
Or... allowing for addons plugging into multiple connectors, possibly each of those
names needs to be extended to (connector, name).connectorwould be either a name or index saying which connector we're referring to (numbering/naming controlled by the addon) with name being the name of the symbol within that connector (naming controlled by the base board / connector type).Best regards,
HervéSignature · 3 lines
Hervé Codina, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David,
Quoted 151 lines · On Wed, 10 Sep 2025 14:33:45 +1000 David Gibson <[email protected]>…
Quoted 87 lines · Herve Codina
Hi David,
On Tue, 9 Sep 2025 15:09:18 +1000
David Gibson <[email protected]> wrote:...
Quoted 46 lines
Quoted 11 lines
I think that a connector is something with a bunch of resources provided by the board where the connector is soldered. Those resources are wired to the connector and defined by the connector pinout.
3v3 ------- Pin 0 i2c_scl ------- Pin 1 i2c_sda ------- Pin 2 gpio A ------- Pin 3 gpio B ------- Pin 4 gnd ------- Pin 5Quoted 2 lines
IMHO, this need to be described and defined in the base board and an addon can only reference resources wired and described by the connector node.
Yes, that's exactly what I'm proposing too.
Quoted 3 lines
Now, questions are:
- 1) How to describe a connector?
- 2) How to reference resources provided at connector level from an add-on?Right.
Quoted 15 lines
Our current approach was:
---- base board DT ----connector0 { gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */ <1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */ i2c-one { compatible = "i2c-bus-extension"; i2c-parent = <i2c5>; /* i2c-one wired to i2c5 controller */ }; i2c-two { compatible = "i2c-bus-extension"; i2c-parent = <i2c6>; /* i2c-two wired to i2c6 controller */ };Quoted 8 lines
/* * From the addon we need to reference: * - The connector itself, * - Maybe some pinctrl related to signals wired to the connector, * - In some cases the i2c bus (HDMI, ddc-i2c-bus = <&i2c-two>;) * * This was solved introducing the controversial export-symbols node. */Quoted 2 lines
I think the type of connector should also be named on both sides (with 'compatible' or something like it).
It makes sense.
Quoted 21 lines
Quoted 17 lines
};---- addon board DT ----
{ some-node { compatible = "foo,bar"; reset-gpios = <&connector 0>; /* gpio A used as a reset gpio */ ddc-i2c-bus = <&i2c-two>; } i2c-one { eeprom@10 { compatible = "baz,eeprom" reg = 10; }; };Quoted 3 lines
};
The addon board DT can only be applied at a connector node.
Quoted 7 lines
Right. This is not how overlays work now. By the nature of how they're built they apply global updates to the base tree. That means we need to spec a new way of describing addons that *is* restricted to a particular connector slot (or slots, as Geert points out). Since we have that opportunity, we should _not_ try to make it a minimal extension to existing overlay format, but define a new and better encoding, designed to meet the problems you're looking to address.
Quoted 3 lines
On the kernel side, overlays can be applied at a specific node. The node is chosen when the overlay is apply.
https://elixir.bootlin.com/linux/v6.16/source/drivers/of/overlay.c#L970Huh, I wasn't aware that had already been merged.
Quoted 5 lines
This allows to apply an overlay to a specific node without any modification of the overlay dtb (dtbo).
Ajush proposed an update to support this feature in fdtoverlay
https://lore.kernel.org/all/[email protected]/Yes, and I've been disinclined to merge it because I think extending overlays in this way, without a more wide-ranging redesign, is not a great idea.
Quoted 33 lines
...
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal
Quoted 6 lines
Quoted 2 lines
It can be a single subtree if decoupling is present at connector node available in the base device tree.
Right - allowing that decoupling is exactly what I'm proposing bus-reg for. Note that the case of an addon that plugs into multiple connectors that Geert pointed out complicates this again.
Geert's use case needs to be clarified.
Suppose a base board with 2 connectors:
- connA
- connBCase 1: Addons are independant
+--------+ connA <----> | AddonA | +--------+ +--------+ connB <---------------->| AddonB | +--------+With addonA and B two addon board each connected at one connector without any relationship between addon A and B
Quoted 7 lines
Case 2: Only one Addons using ressources from both connector
+------+ connA <-----> |Addon | | | connB <-----> | | +------+Case 2 is what I'm talking about. Case 1 is the easy one.
Quoted 4 lines
The addon is connected to both connector and uses ressources from connA and connB in a dependent manner.
Quoted 8 lines
Quoted 2 lines
The Case 2 can be solved using a connector that described both connA and connB. Having the split connA and connB is a mechanical point of view.
I don't think that's a good solution, because it means you have to make that decision at the board layer. If I understand his case correctly, you have a board where you could do either case 1 or case 2 at runtime. We'd want the differences between these cases to only be reflected on the addon device tree, not the base board device tree.
Based on my understanding of Geer's use-case, I think decision at base board level will be needed.
base board addon board
connA +--------+conn1
connB +--------+conn2
connC +
Or
base board addon board
connA +--------+conn1
connB + ,---+conn2
connC +---'
Or any other combination that would match.
From the addon board point of view, the only think we can say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".
Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
Quoted 52 lines
Quoted 14 lines
Also adding and Addon on only one part (connA for instance) should not be an issue if the connector describe both parts.
but well, here again I can miss something.
Geert, can you provide details?...
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Quoted 4 lines
There is an i2c-bus-extension [1] and spi-bus-extension proposal to do the same. But, if we can figure out a common way for all buses, that would be great.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Exactly, this is the purpose of bus extensions.
Right, but redefining it for each bus type seems silly.
Nexus node properties are re-defined for each kind of resources (interrupt, gpio, pwm, ...).
Yes, for historical reasons. In IEE1275 days, interrupts was basically the only thing that worked this way. gpio and pwm were added much later using interrupts as a model. If we were designing from scratch having a common way of defining a nexus would make sense too.
Quoted 1 line
Why not for bus extensions.
So that we don't need to keep defining new bindings for it.
Quoted 2 lines
Also I am pretty sure that some bus extension will need to define some properties specific to the bus related to the extension.
Maybe, but then only those buses that specifically need it need the extra binding.
Quoted 13 lines
Quoted 4 lines
Quoted 3 lines
Also, I don't thing that the 'ranges' property should be used for that purpose. The 'ranges' property is used to translate addresses from child addresses space to parent addresses space.
Quoted 8 lines
The rationale for bus-ranges is that the add-on board could re-expose one of the buses on the connector (say MMIO for simplicity) to several chips physically included on the addon board. We don't want those sub-chips to need different device nodes depending on whether they're on an addon board or wired directly onto a main board. bus-ranges would allow the root of the connector to create a subtree in which regular MMIO (or whatever) devices can be described, and then routed via the connector onto the bus on the main board.
Quoted 1 line
bus extensions supports this feature without bus-regs nor bus-ranges.
Quoted 8 lines
bus-reg & bus-ranges allow it for any bus without having to create a new binding.
Quoted 3 lines
A bus extension ended by a sub node in the connector node. Applying the addon DT at the connector node allow the addon to had subnode to the extension node.
I don't really understand what point you're making here.
Hardware:
+------------------+ +----------------------+ | base board | | addon board | | +------+ | | | | | i2c0 | +-----------+ +------------+ | | | +----+ connector +----+ eeprom @10 | | | | | +-----------+ +------------+ | | +------+ | | | +------------------+ +----------------------+
base board DT:
connector {
i2c-ctrl {
compatible = "i2c-bus-extension";
i2c-parent = <&i2c0>;
};
};addon board DT:
i2c-ctrl {
eeprom@10 {
compatible = "foo,eeprom";
reg = <10>;
};
};Once addon board DT is applied at the base board connector node, the full DT is:
connector {
i2c-ctrl {
compatible = "i2c-bus-extension";
i2c-parent = <&i2c0>;
eeprom@10 {
compatible = "foo,eeprom";
reg = <10>;
};
};
};I probably didn't understand the bus-reg and bus-range usage.
In order to clarify my understanding, using the same hardware example above, can you provide an example of description using bus-reg & bus-ranges?
Best regards,
Hervé
Signature · 3 lines
Hervé Codina, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
Hi Hervé,
Quoted 58 lines · Herve Codina
Quoted 30 lines · On Wed, 10 Sep 2025 14:33:45 +1000 David Gibson <[email protected]>…
Quoted 15 lines · Herve Codina
Suppose a base board with 2 connectors:
- connA
- connBCase 1: Addons are independant
+--------+ connA <----> | AddonA | +--------+ +--------+ connB <---------------->| AddonB | +--------+With addonA and B two addon board each connected at one connector without any relationship between addon A and B
Quoted 7 lines
Case 2: Only one Addons using ressources from both connector
+------+ connA <-----> |Addon | | | connB <-----> | | +------+Case 2 is what I'm talking about. Case 1 is the easy one.
Quoted 4 lines
The addon is connected to both connector and uses ressources from connA and connB in a dependent manner.
Quoted 8 lines
Quoted 2 lines
The Case 2 can be solved using a connector that described both connA and connB. Having the split connA and connB is a mechanical point of view.
I don't think that's a good solution, because it means you have to make that decision at the board layer. If I understand his case correctly, you have a board where you could do either case 1 or case 2 at runtime. We'd want the differences between these cases to only be reflected on the addon device tree, not the base board device tree.
Based on my understanding of Geer's use-case, I think decision at base board level will be needed.
base board addon board
connA +--------+conn1
connB +--------+conn2
connC +Or
base board addon board
connA +--------+conn1
connB + ,---+conn2
connC +---'Or any other combination that would match.
Quoted 7 lines
From the addon board point of view, the only think we can say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".
Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
Correct.
Quoted 7 lines
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
All these choices and decisions apply to single-connector add-on boards, too.
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Hi Geert,
Quoted 76 lines · On Thu, 11 Sep 2025 10:54:02 +0200 Geert Uytterhoeven <[email protected]>…
Hi Hervé,
Quoted 58 lines · Herve Codina
Quoted 30 lines · On Wed, 10 Sep 2025 14:33:45 +1000 David Gibson <[email protected]>…
Quoted 15 lines · Herve Codina
Suppose a base board with 2 connectors:
- connA
- connBCase 1: Addons are independant
+--------+ connA <----> | AddonA | +--------+ +--------+ connB <---------------->| AddonB | +--------+With addonA and B two addon board each connected at one connector without any relationship between addon A and B
Quoted 7 lines
Case 2: Only one Addons using ressources from both connector
+------+ connA <-----> |Addon | | | connB <-----> | | +------+Case 2 is what I'm talking about. Case 1 is the easy one.
Quoted 4 lines
The addon is connected to both connector and uses ressources from connA and connB in a dependent manner.
Quoted 8 lines
Quoted 2 lines
The Case 2 can be solved using a connector that described both connA and connB. Having the split connA and connB is a mechanical point of view.
I don't think that's a good solution, because it means you have to make that decision at the board layer. If I understand his case correctly, you have a board where you could do either case 1 or case 2 at runtime. We'd want the differences between these cases to only be reflected on the addon device tree, not the base board device tree.
Based on my understanding of Geer's use-case, I think decision at base board level will be needed.
base board addon board
connA +--------+conn1
connB +--------+conn2
connC +Or
base board addon board
connA +--------+conn1
connB + ,---+conn2
connC +---'Or any other combination that would match.
Quoted 7 lines
From the addon board point of view, the only think we can say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".
Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
Correct.
Quoted 5 lines
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
Quoted 5 lines
Quoted 2 lines
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
All these choices and decisions apply to single-connector add-on boards, too.
Yes, in our use case (me and Luca), each addon has an eeprom, wired exactly the same on all supported addon, which allows to known the exact addon. Also addon insertions and removals are detected using some gpios wired to the connector.
Based on that our specific driver handling our specific connector perform the following operations on addon insertion detection:
- load a first addon DT to have access to the eeprom
- Read the eeprom to determine the addon type
- load the DT matching with the addon type
This part is of course connector type specific. I mean having an eeprom with some encoded addon type values and hotplug detection with gpio is a part of the contract between the board and the addon (part of connector specification).
Best regards,
Hervé
Quoted 91 lines · Herve Codina
Hi Geert,
Quoted 67 lines · On Thu, 11 Sep 2025 10:54:02 +0200 Geert Uytterhoeven <[email protected]>…
Hi Hervé,
Quoted 55 lines · Herve Codina
Quoted 29 lines · On Wed, 10 Sep 2025 14:33:45 +1000 David Gibson <[email protected]>…
Quoted 15 lines · Herve Codina
Suppose a base board with 2 connectors:
- connA
- connBCase 1: Addons are independant
+--------+ connA <----> | AddonA | +--------+ +--------+ connB <---------------->| AddonB | +--------+With addonA and B two addon board each connected at one connector without any relationship between addon A and B
Quoted 7 lines
Case 2: Only one Addons using ressources from both connector
+------+ connA <-----> |Addon | | | connB <-----> | | +------+Case 2 is what I'm talking about. Case 1 is the easy one.
Quoted 4 lines
The addon is connected to both connector and uses ressources from connA and connB in a dependent manner.
Quoted 7 lines
Quoted 2 lines
The Case 2 can be solved using a connector that described both connA and connB. Having the split connA and connB is a mechanical point of view.
I don't think that's a good solution, because it means you have to make that decision at the board layer. If I understand his case correctly, you have a board where you could do either case 1 or case 2 at runtime. We'd want the differences between these cases to only be reflected on the addon device tree, not the base board device tree.
Based on my understanding of Geer's use-case, I think decision at base board level will be needed.
base board addon board
connA +--------+conn1
connB +--------+conn2
connC +Or
base board addon board
connA +--------+conn1
connB + ,---+conn2
connC +---'Or any other combination that would match.
Quoted 7 lines
From the addon board point of view, the only think we can
say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
Correct.
Quoted 9 lines
Quoted 7 lines
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
All these choices and decisions apply to single-connector add-on boards, too.
Yes, in our use case (me and Luca), each addon has an eeprom, wired exactly the same on all supported addon, which allows to known the exact addon. Also addon insertions and removals are detected using some gpios wired to the connector.
Based on that our specific driver handling our specific connector perform the following operations on addon insertion detection:
- load a first addon DT to have access to the eeprom
- Read the eeprom to determine the addon type
- load the DT matching with the addon type
Quoted 7 lines
This part is of course connector type specific. I mean having an eeprom with some encoded addon type values and hotplug detection with gpio is a part of the contract between the board and the addon (part of connector specification).
Best regards,
Hervé
My usecase is a bit more complicated, since I am trying to model all the available headers on BeagleBoard.org sbcs (particularly PocketBeagle 2 initially) as connectors. However, that still ends up being a single connector which can have multiple addon-boards simultaneously instead of the other way around.
Best Regards,
Ayush Singh
Hi Ayush,
Quoted 100 lines · On Thu, 11 Sep 2025 17:45:17 +0530 Ayush Singh <[email protected]> wrote:
Quoted 91 lines · Herve Codina
Hi Geert,
Quoted 67 lines · On Thu, 11 Sep 2025 10:54:02 +0200 Geert Uytterhoeven <[email protected]>…
Hi Hervé,
Quoted 55 lines · Herve Codina
Quoted 29 lines · On Wed, 10 Sep 2025 14:33:45 +1000 David Gibson <[email protected]>…
Quoted 15 lines · Herve Codina
Suppose a base board with 2 connectors:
- connA
- connBCase 1: Addons are independant
+--------+ connA <----> | AddonA | +--------+ +--------+ connB <---------------->| AddonB | +--------+With addonA and B two addon board each connected at one connector without any relationship between addon A and B
Quoted 7 lines
Case 2: Only one Addons using ressources from both connector
+------+ connA <-----> |Addon | | | connB <-----> | | +------+Case 2 is what I'm talking about. Case 1 is the easy one.
Quoted 4 lines
The addon is connected to both connector and uses ressources from connA and connB in a dependent manner.
Quoted 7 lines
Quoted 2 lines
The Case 2 can be solved using a connector that described both connA and connB. Having the split connA and connB is a mechanical point of view.
I don't think that's a good solution, because it means you have to make that decision at the board layer. If I understand his case correctly, you have a board where you could do either case 1 or case 2 at runtime. We'd want the differences between these cases to only be reflected on the addon device tree, not the base board device tree.
Based on my understanding of Geer's use-case, I think decision at base board level will be needed.
base board addon board
connA +--------+conn1
connB +--------+conn2
connC +Or
base board addon board
connA +--------+conn1
connB + ,---+conn2
connC +---'Or any other combination that would match.
Quoted 7 lines
From the addon board point of view, the only think we can
say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
Correct.
Quoted 9 lines
Quoted 7 lines
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
All these choices and decisions apply to single-connector add-on boards, too.
Yes, in our use case (me and Luca), each addon has an eeprom, wired exactly the same on all supported addon, which allows to known the exact addon. Also addon insertions and removals are detected using some gpios wired to the connector.
Based on that our specific driver handling our specific connector perform the following operations on addon insertion detection:
- load a first addon DT to have access to the eeprom
- Read the eeprom to determine the addon type
- load the DT matching with the addon typeQuoted 7 lines
This part is of course connector type specific. I mean having an eeprom with some encoded addon type values and hotplug detection with gpio is a part of the contract between the board and the addon (part of connector specification).
Best regards,
Hervé
Quoted 6 lines
My usecase is a bit more complicated, since I am trying to model all the available headers on BeagleBoard.org sbcs (particularly PocketBeagle 2 initially) as connectors. However, that still ends up being a single connector which can have multiple addon-boards simultaneously instead of the other way around.
In that case, a connector cannot have the state "free" or "used" handled globally by a core part.
IMHO, each connector drivers should handle this kind of state if relevant. I mean, in case of "pmods" compatible driver having this state per PMOD connector could make sense whereas in "beagle-connector" it doesn't.
Also, on my side, with my 2-step DT loading, the first loading should not consider the connector as 'used'.
All of that is implied by the "contract" between the board and the addon. It is connector specific and so should be handled by the specific connector driver itself.
Best regards,
Hervé
Hi Hervé,
Quoted 35 lines · Herve Codina
Quoted 27 lines · On Thu, 11 Sep 2025 17:45:17 +0530 Ayush Singh <[email protected]> wrote:
Quoted 22 lines · Herve Codina
Quoted 10 lines · On Thu, 11 Sep 2025 10:54:02 +0200 Geert Uytterhoeven <[email protected]>…
Quoted 7 lines · Herve Codina
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
All these choices and decisions apply to single-connector add-on boards, too.
Yes, in our use case (me and Luca), each addon has an eeprom, wired exactly the same on all supported addon, which allows to known the exact addon. Also addon insertions and removals are detected using some gpios wired to the connector.
Based on that our specific driver handling our specific connector perform the following operations on addon insertion detection:
- load a first addon DT to have access to the eeprom
- Read the eeprom to determine the addon type
- load the DT matching with the addon typeQuoted 3 lines
This part is of course connector type specific. I mean having an eeprom with some encoded addon type values and hotplug detection with gpio is a part of the contract between the board and the addon (part of connector specification).
Quoted 5 lines
My usecase is a bit more complicated, since I am trying to model all the available headers on BeagleBoard.org sbcs (particularly PocketBeagle 2 initially) as connectors. However, that still ends up being a single connector which can have multiple addon-boards simultaneously instead of the other way around.
Quoted 6 lines
In that case, a connector cannot have the state "free" or "used" handled globally by a core part.
IMHO, each connector drivers should handle this kind of state if relevant. I mean, in case of "pmods" compatible driver having this state per PMOD connector could make sense whereas in "beagle-connector" it doesn't.
It depends on whether the add-on board has stacking headers, or not ;-)
Quoted 6 lines
Also, on my side, with my 2-step DT loading, the first loading should not consider the connector as 'used'.
All of that is implied by the "contract" between the board and the addon. It is connector specific and so should be handled by the specific connector driver itself.
Since stacking boards is a fairly common use case (beagle, rpi), perhaps it makes sense to have a simple method to re-export / forward a connector? The alternative would be to re-describe and re-export everything.
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Quoted 50 lines · On Thu, 11 Sep 2025 15:08:33 +0200 Geert Uytterhoeven <[email protected]>…
Hi Hervé,
Quoted 35 lines · Herve Codina
Quoted 27 lines · On Thu, 11 Sep 2025 17:45:17 +0530 Ayush Singh <[email protected]> wrote:
Quoted 22 lines · Herve Codina
Quoted 10 lines · On Thu, 11 Sep 2025 10:54:02 +0200 Geert Uytterhoeven <[email protected]>…
Quoted 7 lines · Herve Codina
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
All these choices and decisions apply to single-connector add-on boards, too.
Yes, in our use case (me and Luca), each addon has an eeprom, wired exactly the same on all supported addon, which allows to known the exact addon. Also addon insertions and removals are detected using some gpios wired to the connector.
Based on that our specific driver handling our specific connector perform the following operations on addon insertion detection:
- load a first addon DT to have access to the eeprom
- Read the eeprom to determine the addon type
- load the DT matching with the addon typeQuoted 3 lines
This part is of course connector type specific. I mean having an eeprom with some encoded addon type values and hotplug detection with gpio is a part of the contract between the board and the addon (part of connector specification).
Quoted 5 lines
My usecase is a bit more complicated, since I am trying to model all the available headers on BeagleBoard.org sbcs (particularly PocketBeagle 2 initially) as connectors. However, that still ends up being a single connector which can have multiple addon-boards simultaneously instead of the other way around.
Quoted 6 lines
In that case, a connector cannot have the state "free" or "used" handled globally by a core part.
IMHO, each connector drivers should handle this kind of state if relevant. I mean, in case of "pmods" compatible driver having this state per PMOD connector could make sense whereas in "beagle-connector" it doesn't.
It depends on whether the add-on board has stacking headers, or not ;-)
Quoted 3 lines
Also, on my side, with my 2-step DT loading, the first loading should not consider the connector as 'used'.
Quoted 7 lines
Quoted 3 lines
All of that is implied by the "contract" between the board and the addon. It is connector specific and so should be handled by the specific connector driver itself.
Since stacking boards is a fairly common use case (beagle, rpi), perhaps it makes sense to have a simple method to re-export / forward a connector? The alternative would be to re-describe and re-export everything.
You re-apply an addon DT on the same connector. You should see the exact same symbols without re-exporting anything.
I think that you have to re-export stuff only if, on the addon board itself, you wire some pins from one connector to an other one.
+-----------------------------+
| Addon board |
+---------+ +--------+
+ conn A +-------------------+ conn B +
+ +--, +--------+ +--------+
+---------+ '--+ device | |
| +--------+ |
+-----------------------------+Here the resource available at conn A directly wired to conn B should be re-exported in order to allow another addon connected to conn B to use this signal.
Multiple addons with conn A connector stacked should see all symbols exported from the based board related to conn A.
Best regards,
Hervé
Quoted 173 lines · Herve Codina
Hi David,
Quoted 151 lines · On Wed, 10 Sep 2025 14:33:45 +1000 David Gibson <[email protected]>…
Quoted 87 lines · Herve Codina
Hi David,
On Tue, 9 Sep 2025 15:09:18 +1000
David Gibson <[email protected]> wrote:...
Quoted 46 lines
Quoted 11 lines
I think that a connector is something with a bunch of resources provided by the board where the connector is soldered. Those resources are wired to the connector and defined by the connector pinout.
3v3 ------- Pin 0 i2c_scl ------- Pin 1 i2c_sda ------- Pin 2 gpio A ------- Pin 3 gpio B ------- Pin 4 gnd ------- Pin 5Quoted 2 lines
IMHO, this need to be described and defined in the base board and an addon can only reference resources wired and described by the connector node.
Yes, that's exactly what I'm proposing too.
Quoted 3 lines
Now, questions are:
- 1) How to describe a connector?
- 2) How to reference resources provided at connector level from an add-on?Right.
Quoted 15 lines
Our current approach was:
---- base board DT ----connector0 { gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */ <1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */ i2c-one { compatible = "i2c-bus-extension"; i2c-parent = <i2c5>; /* i2c-one wired to i2c5 controller */ }; i2c-two { compatible = "i2c-bus-extension"; i2c-parent = <i2c6>; /* i2c-two wired to i2c6 controller */ };Quoted 8 lines
/* * From the addon we need to reference: * - The connector itself, * - Maybe some pinctrl related to signals wired to the connector, * - In some cases the i2c bus (HDMI, ddc-i2c-bus = <&i2c-two>;) * * This was solved introducing the controversial export-symbols node. */Quoted 2 lines
I think the type of connector should also be named on both sides (with 'compatible' or something like it).
It makes sense.
Quoted 21 lines
Quoted 17 lines
};---- addon board DT ----
{ some-node { compatible = "foo,bar"; reset-gpios = <&connector 0>; /* gpio A used as a reset gpio */ ddc-i2c-bus = <&i2c-two>; } i2c-one { eeprom@10 { compatible = "baz,eeprom" reg = 10; }; };Quoted 3 lines
};
The addon board DT can only be applied at a connector node.
Quoted 7 lines
Right. This is not how overlays work now. By the nature of how they're built they apply global updates to the base tree. That means we need to spec a new way of describing addons that *is* restricted to a particular connector slot (or slots, as Geert points out). Since we have that opportunity, we should _not_ try to make it a minimal extension to existing overlay format, but define a new and better encoding, designed to meet the problems you're looking to address.
Quoted 3 lines
On the kernel side, overlays can be applied at a specific node. The node is chosen when the overlay is apply.
https://elixir.bootlin.com/linux/v6.16/source/drivers/of/overlay.c#L970Huh, I wasn't aware that had already been merged.
Quoted 5 lines
This allows to apply an overlay to a specific node without any modification of the overlay dtb (dtbo).
Ajush proposed an update to support this feature in fdtoverlay
https://lore.kernel.org/all/[email protected]/Yes, and I've been disinclined to merge it because I think extending overlays in this way, without a more wide-ranging redesign, is not a great idea.
Quoted 33 lines
...
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal
Quoted 6 lines
Quoted 2 lines
It can be a single subtree if decoupling is present at connector node available in the base device tree.
Right - allowing that decoupling is exactly what I'm proposing bus-reg for. Note that the case of an addon that plugs into multiple connectors that Geert pointed out complicates this again.
Geert's use case needs to be clarified.
Suppose a base board with 2 connectors:
- connA
- connBCase 1: Addons are independant
+--------+ connA <----> | AddonA | +--------+ +--------+ connB <---------------->| AddonB | +--------+With addonA and B two addon board each connected at one connector without any relationship between addon A and B
Quoted 7 lines
Case 2: Only one Addons using ressources from both connector
+------+ connA <-----> |Addon | | | connB <-----> | | +------+Case 2 is what I'm talking about. Case 1 is the easy one.
Quoted 4 lines
The addon is connected to both connector and uses ressources from connA and connB in a dependent manner.
Quoted 8 lines
Quoted 2 lines
The Case 2 can be solved using a connector that described both connA and connB. Having the split connA and connB is a mechanical point of view.
I don't think that's a good solution, because it means you have to make that decision at the board layer. If I understand his case correctly, you have a board where you could do either case 1 or case 2 at runtime. We'd want the differences between these cases to only be reflected on the addon device tree, not the base board device tree.
Based on my understanding of Geer's use-case, I think decision at base board level will be needed.
base board addon board
connA +--------+conn1
connB +--------+conn2
connC +
Quoted 6 lines
Or
base board addon board
connA +--------+conn1
connB + ,---+conn2
connC +---'
I'm not sure what you mean by a decision at the base board level. I certainly don't think this should be in the base DT. I'd see this as a runtime parameter needed when you apply/insert/activate the addon. That's not really any different from addons with a single connector. To allow for base boards with multiple instances of that connector you'd need to specify at insert time which instance you're attaching to.
That information could be supplied by the user, or in the case of connectors that can be probed in some way (e.g. an EEPROM) the connector driver could supply the information.
Which does make me think, considering this case says to me that conceptualizing the choice of where to plug an addon as "subnode in the base tree it goes under" is not a good idea. That's not really going to work for a multiple connector addon.
So, we can specify where an addon goes by which "connector" it attaches to. That connector would have an explicit entry in the base tree, but it could reference multiple places to add nodes within that base tree. Which means thinking about it that way, we might not need 'bus-reg' / 'bus-ranges' after all, and in some cases maybe not bus extensions either.
Adding nodes in multiple places makes removal a bunch more complicated (although it's still much better than overlays being able to modify *anywhere*).
Quoted 5 lines
Or any other combination that would match.
From the addon board point of view, the only think we can say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".
Agreed.
Quoted 8 lines
Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
Agreed.
Quoted 2 lines
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
Yes. Although if the addons have an EEPROM, or some other sort of ID register, it may be possible for some connector drivers to probe this.
Quoted 100 lines
Quoted 51 lines
Quoted 13 lines
Also adding and Addon on only one part (connA for instance) should not be an issue if the connector describe both parts.
but well, here again I can miss something.
Geert, can you provide details?...
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Quoted 4 lines
There is an i2c-bus-extension [1] and spi-bus-extension proposal to do the same. But, if we can figure out a common way for all buses, that would be great.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Exactly, this is the purpose of bus extensions.
Right, but redefining it for each bus type seems silly.
Nexus node properties are re-defined for each kind of resources (interrupt, gpio, pwm, ...).
Yes, for historical reasons. In IEE1275 days, interrupts was basically the only thing that worked this way. gpio and pwm were added much later using interrupts as a model. If we were designing from scratch having a common way of defining a nexus would make sense too.
Quoted 1 line
Why not for bus extensions.
So that we don't need to keep defining new bindings for it.
Quoted 2 lines
Also I am pretty sure that some bus extension will need to define some properties specific to the bus related to the extension.
Maybe, but then only those buses that specifically need it need the extra binding.
Quoted 13 lines
Quoted 4 lines
Quoted 3 lines
Also, I don't thing that the 'ranges' property should be used for that purpose. The 'ranges' property is used to translate addresses from child addresses space to parent addresses space.
Quoted 8 lines
The rationale for bus-ranges is that the add-on board could re-expose one of the buses on the connector (say MMIO for simplicity) to several chips physically included on the addon board. We don't want those sub-chips to need different device nodes depending on whether they're on an addon board or wired directly onto a main board. bus-ranges would allow the root of the connector to create a subtree in which regular MMIO (or whatever) devices can be described, and then routed via the connector onto the bus on the main board.
Quoted 1 line
bus extensions supports this feature without bus-regs nor bus-ranges.
Quoted 8 lines
bus-reg & bus-ranges allow it for any bus without having to create a new binding.
Quoted 3 lines
A bus extension ended by a sub node in the connector node. Applying the addon DT at the connector node allow the addon to had subnode to the extension node.
I don't really understand what point you're making here.
Hardware:
+------------------+ +----------------------+ | base board | | addon board | | +------+ | | | | | i2c0 | +-----------+ +------------+ | | | +----+ connector +----+ eeprom @10 | | | | | +-----------+ +------------+ | | +------+ | | | +------------------+ +----------------------+base board DT:
connector { i2c-ctrl { compatible = "i2c-bus-extension"; i2c-parent = <&i2c0>; }; };addon board DT:
i2c-ctrl { eeprom@10 { compatible = "foo,eeprom"; reg = <10>; }; };Once addon board DT is applied at the base board connector node, the full DT is:
connector { i2c-ctrl { compatible = "i2c-bus-extension"; i2c-parent = <&i2c0>; eeprom@10 { compatible = "foo,eeprom"; reg = <10>; }; }; };
Quoted 4 lines
I probably didn't understand the bus-reg and bus-range usage.
In order to clarify my understanding, using the same hardware example above, can you provide an example of description using bus-reg & bus-ranges?
Thoughts above suggest a different direction, but here's what I was thinking before:
base board:
connector {
/export/ "i2c" &i2c0;
};addon:
eeprom@10 {
compatible = "foo,eeprom";
bus-reg = <&i2c 0x10>;
}Or, if the addon had multiple i2c devices, maybe something like:
board-i2c {
compatible = "i2c-simple-bridge";
bus-ranges = <&i2c 0 0x3ff>; /* Whole addr space */
eeprom@10 {
compatible = "foo,eeprom";
reg = <0x10>;
}
widget@20 {
compatible = "vendor,widget";
reg = <0x20>;
}
}Writing that, I realise I2C introduces some complications for this. Because it has #size-cells = <0>, ranges doesn't really work (without listing every single address to be translated). Likewise, because we always need the parent bus phandle, we can't use the trick of an empty 'ranges' to mean an identity mapping.
We could invent encodings to address those, but given the addon with multiple connectors case provides another incentive for a single connector to allow adding nodes in multiple (but strictly enumerated) places in the base device tree provides a better approach.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David,
+CC Wolfram
Quoted 227 lines · On Mon, 15 Sep 2025 14:51:41 +1000 David Gibson <[email protected]>…
Quoted 173 lines · Herve Codina
Hi David,
Quoted 151 lines · On Wed, 10 Sep 2025 14:33:45 +1000 David Gibson <[email protected]>…
Quoted 87 lines · Herve Codina
Hi David,
On Tue, 9 Sep 2025 15:09:18 +1000
David Gibson <[email protected]> wrote:...
Quoted 46 lines
Quoted 11 lines
I think that a connector is something with a bunch of resources provided by the board where the connector is soldered. Those resources are wired to the connector and defined by the connector pinout.
3v3 ------- Pin 0 i2c_scl ------- Pin 1 i2c_sda ------- Pin 2 gpio A ------- Pin 3 gpio B ------- Pin 4 gnd ------- Pin 5Quoted 2 lines
IMHO, this need to be described and defined in the base board and an addon can only reference resources wired and described by the connector node.
Yes, that's exactly what I'm proposing too.
Quoted 3 lines
Now, questions are:
- 1) How to describe a connector?
- 2) How to reference resources provided at connector level from an add-on?Right.
Quoted 15 lines
Our current approach was:
---- base board DT ----connector0 { gpio-map = <0 &gpio0 12>, /* gpio A wired to gpio 12 of gpio0 controller */ <1 &gpio2 10; /* gpio B wired to gpio 10 of gpio2 controller */ i2c-one { compatible = "i2c-bus-extension"; i2c-parent = <i2c5>; /* i2c-one wired to i2c5 controller */ }; i2c-two { compatible = "i2c-bus-extension"; i2c-parent = <i2c6>; /* i2c-two wired to i2c6 controller */ };Quoted 8 lines
/* * From the addon we need to reference: * - The connector itself, * - Maybe some pinctrl related to signals wired to the connector, * - In some cases the i2c bus (HDMI, ddc-i2c-bus = <&i2c-two>;) * * This was solved introducing the controversial export-symbols node. */Quoted 2 lines
I think the type of connector should also be named on both sides (with 'compatible' or something like it).
It makes sense.
Quoted 21 lines
Quoted 17 lines
};---- addon board DT ----
{ some-node { compatible = "foo,bar"; reset-gpios = <&connector 0>; /* gpio A used as a reset gpio */ ddc-i2c-bus = <&i2c-two>; } i2c-one { eeprom@10 { compatible = "baz,eeprom" reg = 10; }; };Quoted 3 lines
};
The addon board DT can only be applied at a connector node.
Quoted 7 lines
Right. This is not how overlays work now. By the nature of how they're built they apply global updates to the base tree. That means we need to spec a new way of describing addons that *is* restricted to a particular connector slot (or slots, as Geert points out). Since we have that opportunity, we should _not_ try to make it a minimal extension to existing overlay format, but define a new and better encoding, designed to meet the problems you're looking to address.
Quoted 3 lines
On the kernel side, overlays can be applied at a specific node. The node is chosen when the overlay is apply.
https://elixir.bootlin.com/linux/v6.16/source/drivers/of/overlay.c#L970Huh, I wasn't aware that had already been merged.
Quoted 5 lines
This allows to apply an overlay to a specific node without any modification of the overlay dtb (dtbo).
Ajush proposed an update to support this feature in fdtoverlay
https://lore.kernel.org/all/[email protected]/Yes, and I've been disinclined to merge it because I think extending overlays in this way, without a more wide-ranging redesign, is not a great idea.
Quoted 33 lines
...
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
3) bus-reg / bus-ranges
One thing that makes connector plugins a bit awkward is that they often need to add things to multiple buses on the host system (MMIO & i2c for a simple case). This means that once resolved the plugin isn't neatly a single subtree. That's one factor making removal
Quoted 6 lines
Quoted 2 lines
It can be a single subtree if decoupling is present at connector node available in the base device tree.
Right - allowing that decoupling is exactly what I'm proposing bus-reg for. Note that the case of an addon that plugs into multiple connectors that Geert pointed out complicates this again.
Geert's use case needs to be clarified.
Suppose a base board with 2 connectors:
- connA
- connBCase 1: Addons are independant
+--------+ connA <----> | AddonA | +--------+ +--------+ connB <---------------->| AddonB | +--------+With addonA and B two addon board each connected at one connector without any relationship between addon A and B
Quoted 7 lines
Case 2: Only one Addons using ressources from both connector
+------+ connA <-----> |Addon | | | connB <-----> | | +------+Case 2 is what I'm talking about. Case 1 is the easy one.
Quoted 4 lines
The addon is connected to both connector and uses ressources from connA and connB in a dependent manner.
Quoted 8 lines
Quoted 2 lines
The Case 2 can be solved using a connector that described both connA and connB. Having the split connA and connB is a mechanical point of view.
I don't think that's a good solution, because it means you have to make that decision at the board layer. If I understand his case correctly, you have a board where you could do either case 1 or case 2 at runtime. We'd want the differences between these cases to only be reflected on the addon device tree, not the base board device tree.
Based on my understanding of Geer's use-case, I think decision at base board level will be needed.
base board addon board
connA +--------+conn1
connB +--------+conn2
connC +Quoted 6 lines
Or
base board addon board
connA +--------+conn1
connB + ,---+conn2
connC +---'I'm not sure what you mean by a decision at the base board level. I certainly don't think this should be in the base DT. I'd see this as a runtime parameter needed when you apply/insert/activate the addon. That's not really any different from addons with a single connector. To allow for base boards with multiple instances of that connector you'd need to specify at insert time which instance you're attaching to.
That information could be supplied by the user, or in the case of connectors that can be probed in some way (e.g. an EEPROM) the connector driver could supply the information.
Which does make me think, considering this case says to me that conceptualizing the choice of where to plug an addon as "subnode in the base tree it goes under" is not a good idea. That's not really going to work for a multiple connector addon.
So, we can specify where an addon goes by which "connector" it attaches to. That connector would have an explicit entry in the base tree, but it could reference multiple places to add nodes within that base tree. Which means thinking about it that way, we might not need 'bus-reg' / 'bus-ranges' after all, and in some cases maybe not bus extensions either.
Adding nodes in multiple places makes removal a bunch more complicated (although it's still much better than overlays being able to modify *anywhere*).
Quoted 5 lines
Or any other combination that would match.
From the addon board point of view, the only think we can say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".
Agreed.
Quoted 8 lines
Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
Quoted 7 lines
Agreed.
Quoted 2 lines
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
Yes. Although if the addons have an EEPROM, or some other sort of ID register, it may be possible for some connector drivers to probe this.
Right, I think we agree that a driver is needed to help in the mapping at least when multiple connectors are involved.
Quoted 142 lines
Quoted 101 lines
Quoted 52 lines
Quoted 14 lines
Also adding and Addon on only one part (connA for instance) should not be an issue if the connector describe both parts.
but well, here again I can miss something.
Geert, can you provide details?...
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Quoted 4 lines
There is an i2c-bus-extension [1] and spi-bus-extension proposal to do the same. But, if we can figure out a common way for all buses, that would be great.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Exactly, this is the purpose of bus extensions.
Right, but redefining it for each bus type seems silly.
Nexus node properties are re-defined for each kind of resources (interrupt, gpio, pwm, ...).
Yes, for historical reasons. In IEE1275 days, interrupts was basically the only thing that worked this way. gpio and pwm were added much later using interrupts as a model. If we were designing from scratch having a common way of defining a nexus would make sense too.
Quoted 1 line
Why not for bus extensions.
So that we don't need to keep defining new bindings for it.
Quoted 2 lines
Also I am pretty sure that some bus extension will need to define some properties specific to the bus related to the extension.
Maybe, but then only those buses that specifically need it need the extra binding.
Quoted 13 lines
Quoted 4 lines
Quoted 3 lines
Also, I don't thing that the 'ranges' property should be used for that purpose. The 'ranges' property is used to translate addresses from child addresses space to parent addresses space.
Quoted 8 lines
The rationale for bus-ranges is that the add-on board could re-expose one of the buses on the connector (say MMIO for simplicity) to several chips physically included on the addon board. We don't want those sub-chips to need different device nodes depending on whether they're on an addon board or wired directly onto a main board. bus-ranges would allow the root of the connector to create a subtree in which regular MMIO (or whatever) devices can be described, and then routed via the connector onto the bus on the main board.
Quoted 1 line
bus extensions supports this feature without bus-regs nor bus-ranges.
Quoted 8 lines
bus-reg & bus-ranges allow it for any bus without having to create a new binding.
Quoted 3 lines
A bus extension ended by a sub node in the connector node. Applying the addon DT at the connector node allow the addon to had subnode to the extension node.
I don't really understand what point you're making here.
Hardware:
+------------------+ +----------------------+ | base board | | addon board | | +------+ | | | | | i2c0 | +-----------+ +------------+ | | | +----+ connector +----+ eeprom @10 | | | | | +-----------+ +------------+ | | +------+ | | | +------------------+ +----------------------+base board DT:
connector { i2c-ctrl { compatible = "i2c-bus-extension"; i2c-parent = <&i2c0>; }; };addon board DT:
i2c-ctrl { eeprom@10 { compatible = "foo,eeprom"; reg = <10>; }; };Once addon board DT is applied at the base board connector node, the full DT is:
connector { i2c-ctrl { compatible = "i2c-bus-extension"; i2c-parent = <&i2c0>; eeprom@10 { compatible = "foo,eeprom"; reg = <10>; }; }; };Quoted 4 lines
I probably didn't understand the bus-reg and bus-range usage.
In order to clarify my understanding, using the same hardware example above, can you provide an example of description using bus-reg & bus-ranges?Thoughts above suggest a different direction, but here's what I was thinking before:
base board:
connector { /export/ "i2c" &i2c0; };addon:
eeprom@10 { compatible = "foo,eeprom"; bus-reg = <&i2c 0x10>; }Or, if the addon had multiple i2c devices, maybe something like:
board-i2c { compatible = "i2c-simple-bridge"; bus-ranges = <&i2c 0 0x3ff>; /* Whole addr space */ eeprom@10 { compatible = "foo,eeprom"; reg = <0x10>; } widget@20 { compatible = "vendor,widget"; reg = <0x20>; } }Writing that, I realise I2C introduces some complications for this. Because it has #size-cells = <0>, ranges doesn't really work (without listing every single address to be translated). Likewise, because we always need the parent bus phandle, we can't use the trick of an empty 'ranges' to mean an identity mapping.
Quoted 5 lines
We could invent encodings to address those, but given the addon with multiple connectors case provides another incentive for a single connector to allow adding nodes in multiple (but strictly enumerated) places in the base device tree provides a better approach.
and the "place in base device tree" is the goal of the extension bus.
The strict enumeration of nodes enumerated is done by two means:
- extension busses at connector level
Those extensions are described as connector sub-nodes.
The addon DT can only add nodes in those sub-nodes to describe devices connected to the relared extension bus.
- export symbols
An addon DT can only use symbols exported to reference symbols outside the addon DT itself.
Can I assume that bus extensions we proposed (i2c-bus-extension and spi-bus-extension) could be a correct solution ?
Best regards,
Hervé
Hi Hervé,
Quoted 20 lines · Herve Codina
Quoted 18 lines · On Mon, 15 Sep 2025 14:51:41 +1000 David Gibson <[email protected]>…
Quoted 3 lines · Herve Codina
From the addon board point of view, the only think we can say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".
Agreed.
Quoted 8 lines
Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
Agreed.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
Yes. Although if the addons have an EEPROM, or some other sort of ID register, it may be possible for some connector drivers to probe this.
Right, I think we agree that a driver is needed to help in the mapping at least when multiple connectors are involved.
I agree you need a driver to read an ID EEPROM.
But why would you need a driver if no ID EEPROM is involved? If the connector types on base board and add-on match, it should work.
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Quoted 27 lines · Geert Uytterhoeven
Hi Hervé,
Quoted 16 lines · Herve Codina
Quoted 14 lines · On Mon, 15 Sep 2025 14:51:41 +1000 David Gibson <[email protected]>…
Quoted 3 lines · Herve Codina
From the addon board point of view, the only think we can
say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".Agreed.
Quoted 8 lines
Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
Quoted 8 lines
Quoted 6 lines
Agreed.
Quoted 2 lines
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
Yes. Although if the addons have an EEPROM, or some other sort of ID register, it may be possible for some connector drivers to probe this.
Right, I think we agree that a driver is needed to help in the mapping at least when multiple connectors are involved.
Quoted 8 lines
I agree you need a driver to read an ID EEPROM.
But why would you need a driver if no ID EEPROM is involved? If the connector types on base board and add-on match, it should work.Gr{oetje,eeting}s,
Geert
How would a connector be disabled in such a setup? I guess maybe status property can be used while applying overlay to check if the connector is enabled. But maybe that goes outside the scope of fdtoverlay?
Also, I would assume that most such connectors would want to provide some kind of configfs based API to add/remove addon boards.
Best Regards,
Ayush Singh
Hi Ayush,
Quoted 27 lines · Ayush Singh
Quoted 25 lines · Geert Uytterhoeven
Quoted 24 lines · Herve Codina
Quoted 14 lines · On Mon, 15 Sep 2025 14:51:41 +1000 David Gibson <[email protected]>…
Quoted 3 lines · Herve Codina
From the addon board point of view, the only think we can
say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".Agreed.
Quoted 8 lines
Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
Quoted 6 lines
Agreed.
Quoted 2 lines
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
Yes. Although if the addons have an EEPROM, or some other sort of ID register, it may be possible for some connector drivers to probe this.
Right, I think we agree that a driver is needed to help in the mapping at least when multiple connectors are involved.
Quoted 7 lines
Quoted 3 lines
I agree you need a driver to read an ID EEPROM.
But why would you need a driver if no ID EEPROM is involved? If the connector types on base board and add-on match, it should work.How would a connector be disabled in such a setup? I guess maybe status property can be used while applying overlay to check if the connector is enabled. But maybe that goes outside the scope of fdtoverlay?
Why would you want to disable a connector?
Quoted 2 lines
Also, I would assume that most such connectors would want to provide some kind of configfs based API to add/remove addon boards.
Yes, we need some way to configure add-on board add/remove, and on which connector(s).
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Hi Geert,
Quoted 43 lines · On Tue, 16 Sep 2025 15:34:52 +0200 Geert Uytterhoeven <[email protected]>…
Hi Ayush,
Quoted 27 lines · Ayush Singh
Quoted 25 lines · Geert Uytterhoeven
Quoted 24 lines · Herve Codina
Quoted 14 lines · On Mon, 15 Sep 2025 14:51:41 +1000 David Gibson <[email protected]>…
Quoted 3 lines · Herve Codina
From the addon board point of view, the only think we can
say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".Agreed.
Quoted 8 lines
Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
Quoted 6 lines
Agreed.
Quoted 2 lines
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
Yes. Although if the addons have an EEPROM, or some other sort of ID register, it may be possible for some connector drivers to probe this.
Right, I think we agree that a driver is needed to help in the mapping at least when multiple connectors are involved.
Quoted 7 lines
Quoted 3 lines
I agree you need a driver to read an ID EEPROM.
But why would you need a driver if no ID EEPROM is involved? If the connector types on base board and add-on match, it should work.How would a connector be disabled in such a setup? I guess maybe status property can be used while applying overlay to check if the connector is enabled. But maybe that goes outside the scope of fdtoverlay?
Why would you want to disable a connector?
Quoted 2 lines
Also, I would assume that most such connectors would want to provide some kind of configfs based API to add/remove addon boards.
Quoted 7 lines
Yes, we need some way to configure add-on board add/remove, and on which connector(s).
Gr{oetje,eeting}s,
Geert
Having drivers for connectors is an expectation from Rob:
https://lore.kernel.org/all/CAL_JsqKg0NpDi1Zf1T+f2rYw5UuVfK7+kjWj1_edFWH8EStjXw@mail.gmail.com/
Maybe at the end we could find some kind of generic driver if no specific hotplug mecanism is involved and if we find a generic way (maybe configfs) to provide the addon DT.
IMHO, before diving in a generic driver, basics need to be there and at least one "specific" driver should be present to validate concepts discussed here.
Best regards,
Hervé
Quoted 29 lines · Geert Uytterhoeven
Hi Ayush,
Quoted 26 lines · Ayush Singh
Quoted 25 lines · Geert Uytterhoeven
Quoted 24 lines · Herve Codina
Quoted 14 lines · On Mon, 15 Sep 2025 14:51:41 +1000 David Gibson <[email protected]>…
Quoted 3 lines · Herve Codina
From the addon board point of view, the only think we can
say is "me, as an addon board, I need a connector of type 'foo' and a connector of type 'bar'".Agreed.
Quoted 8 lines
Also, at base board level, statically defined in the DT connA is described (type 'foo'), connB and connC are described (type 'bar').
The choice to map connA to the type 'foo' connector expected by the addon and the choice to map connB or connC to the type 'bar' connector expected by the addon can only be done at runtime and probably with the help of a driver that have the knowledge of the 3 connectors.
Quoted 6 lines
Agreed.
Quoted 2 lines
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
Yes. Although if the addons have an EEPROM, or some other sort of ID register, it may be possible for some connector drivers to probe this.
Right, I think we agree that a driver is needed to help in the mapping at least when multiple connectors are involved.
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines
I agree you need a driver to read an ID EEPROM.
But why would you need a driver if no ID EEPROM is involved? If the connector types on base board and add-on match, it should work.How would a connector be disabled in such a setup? I guess maybe status property can be used while applying overlay to check if the connector is enabled. But maybe that goes outside the scope of fdtoverlay?
Why would you want to disable a connector?
So a lot of embedded SoCs (eg. TI AM6254 [0]) have co-processors (M4F in case of AM6254). These co-processors can run full blow RTOS (most BeagleBoard boards like PocketBeagle 2 [1] have Zephyr support). When using a peripheral from the co-processor running such RTOS, it needs to be disabled on Linux side.
Quoted 10 lines
Quoted 3 lines
Also, I would assume that most such connectors would want to provide some kind of configfs based API to add/remove addon boards.
Yes, we need some way to configure add-on board add/remove, and on which connector(s).
Gr{oetje,eeting}s,
Geert
Best Regards
Ayush Singh
Quoted 8 lines · Herve Codina
Hi David,
+CC Wolfram
Quoted 1 line · On Mon, 15 Sep 2025 14:51:41 +1000 David Gibson <[email protected]>…
On Thu, Sep 11, 2025 at 10:48:28AM +0200, Herve Codina wrote:
[snip]
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
I have the feeling that the choice of physical connectors to which the addon board is connected to is a human choice when the board is connected.
Yes. Although if the addons have an EEPROM, or some other sort of ID register, it may be possible for some connector drivers to probe this.
Right, I think we agree that a driver is needed to help in the mapping at least when multiple connectors are involved.
Yes. Although it's likely this could be handled by a single, trivial driver for cases where there's nothing probeable and you just rely on being told the right thing by the user. This is kind of the connector equivalent of "simple-bus".
[snip]
Quoted 52 lines
Quoted 36 lines
Thoughts above suggest a different direction, but here's what I was thinking before:
base board:
connector { /export/ "i2c" &i2c0; };addon:
eeprom@10 { compatible = "foo,eeprom"; bus-reg = <&i2c 0x10>; }Or, if the addon had multiple i2c devices, maybe something like:
board-i2c { compatible = "i2c-simple-bridge"; bus-ranges = <&i2c 0 0x3ff>; /* Whole addr space */ eeprom@10 { compatible = "foo,eeprom"; reg = <0x10>; } widget@20 { compatible = "vendor,widget"; reg = <0x20>; } }Writing that, I realise I2C introduces some complications for this. Because it has #size-cells = <0>, ranges doesn't really work (without listing every single address to be translated). Likewise, because we always need the parent bus phandle, we can't use the trick of an empty 'ranges' to mean an identity mapping.
Quoted 4 lines
We could invent encodings to address those, but given the addon with multiple connectors case provides another incentive for a single connector to allow adding nodes in multiple (but strictly enumerated) places in the base device tree provides a better approach.
and the "place in base device tree" is the goal of the extension bus.
The strict enumeration of nodes enumerated is done by two means:
- extension busses at connector level
Those extensions are described as connector sub-nodes.
The addon DT can only add nodes in those sub-nodes to describe devices connected to the relared extension bus.
- export symbols
An addon DT can only use symbols exported to reference symbols outside the addon DT itself.
Quoted 2 lines
Can I assume that bus extensions we proposed (i2c-bus-extension and spi-bus-extension) could be a correct solution ?
Maybe? I prefer the idea of a universal mechanism, not one that's defined per-bus-type.
Also, IIUC the way bus extension operates is a bit different - nodes would be "physically" added under the bus extension node, but treated logically as if they go under the main bus. What I'm proposing here is something at the actualy overlay application layer that allows nodes to be added to different parts of the base device tree - so you could add your i2c device under the main i2c bus.
That approach does complicate removal, but its not as bad as overlays at the moment, because a) it could be limited to adding new nodes, not modifying existing ones and b) the connector would specify exactly the places that additions are allowed.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David,
On Thu, 18 Sep 2025 13:16:32 +1000
David Gibson <[email protected]> wrote:
...
Quoted 59 lines
Quoted 52 lines
Quoted 36 lines
Thoughts above suggest a different direction, but here's what I was thinking before:
base board:
connector { /export/ "i2c" &i2c0; };addon:
eeprom@10 { compatible = "foo,eeprom"; bus-reg = <&i2c 0x10>; }Or, if the addon had multiple i2c devices, maybe something like:
board-i2c { compatible = "i2c-simple-bridge"; bus-ranges = <&i2c 0 0x3ff>; /* Whole addr space */ eeprom@10 { compatible = "foo,eeprom"; reg = <0x10>; } widget@20 { compatible = "vendor,widget"; reg = <0x20>; } }Writing that, I realise I2C introduces some complications for this. Because it has #size-cells = <0>, ranges doesn't really work (without listing every single address to be translated). Likewise, because we always need the parent bus phandle, we can't use the trick of an empty 'ranges' to mean an identity mapping.
Quoted 4 lines
We could invent encodings to address those, but given the addon with multiple connectors case provides another incentive for a single connector to allow adding nodes in multiple (but strictly enumerated) places in the base device tree provides a better approach.
and the "place in base device tree" is the goal of the extension bus.
The strict enumeration of nodes enumerated is done by two means:
- extension busses at connector level
Those extensions are described as connector sub-nodes.
The addon DT can only add nodes in those sub-nodes to describe devices connected to the relared extension bus.
- export symbols
An addon DT can only use symbols exported to reference symbols outside the addon DT itself.Quoted 2 lines
Can I assume that bus extensions we proposed (i2c-bus-extension and spi-bus-extension) could be a correct solution ?
Maybe? I prefer the idea of a universal mechanism, not one that's defined per-bus-type.
Quoted 6 lines
Also, IIUC the way bus extension operates is a bit different - nodes would be "physically" added under the bus extension node, but treated logically as if they go under the main bus. What I'm proposing here is something at the actualy overlay application layer that allows nodes to be added to different parts of the base device tree - so you could add your i2c device under the main i2c bus.
I think we should avoid this kind of node dispatching here and there in the base DT.
We work on decoupling busses wired to a connector and dispatching nodes looks like this decoupling is ignored.
IMHO, keeping devices available on an addon board as nodes under the connector is a real hardware representation.
Also, at runtime, once an addon board DT is applied, when you look at your current DT either using /proc/device-tree or some links such as /sys/bus/devices/.../of_node, the connector and extension bus appear and clearly identify devices behind the connector.
Quoted 6 lines
That approach does complicate removal, but its not as bad as overlays at the moment, because a) it could be limited to adding new nodes, not modifying existing ones and b) the connector would specify exactly the places that additions are allowed.
I think bus extensions comply with a) and b).
Yes, bus extensions need to be handled per-bus types but they have the advantage of keeping the hardware reality well described and visible at runtime in term of "wiring" topology.
Whatever the solution, this will already be handled per-bus types. Only busses that support runtime DT node addition/removal (OF_RECONFIG_* notifications in the kernel implementation) will support adding or removing nodes.
Your approach is more complex, dispatch node here and there and actually is also a per-bus types solution.
I think, in order to choose between both solutions, the main question is:
Do we want to dispatch nodes provided by an addon DT everywhere in the base DT ?
IMHO, the answer is no.
Rob, others, any opinion ?
Best regards,
Hervé
Quoted 108 lines · On Thu, 18 Sep 2025 09:44:09 +0200 Herve Codina <[email protected]>…
Hi David,
On Thu, 18 Sep 2025 13:16:32 +1000
David Gibson <[email protected]> wrote:...
Quoted 59 lines
Quoted 52 lines
Quoted 36 lines
Thoughts above suggest a different direction, but here's what I was thinking before:
base board:
connector { /export/ "i2c" &i2c0; };addon:
eeprom@10 { compatible = "foo,eeprom"; bus-reg = <&i2c 0x10>; }Or, if the addon had multiple i2c devices, maybe something like:
board-i2c { compatible = "i2c-simple-bridge"; bus-ranges = <&i2c 0 0x3ff>; /* Whole addr space */ eeprom@10 { compatible = "foo,eeprom"; reg = <0x10>; } widget@20 { compatible = "vendor,widget"; reg = <0x20>; } }Writing that, I realise I2C introduces some complications for this. Because it has #size-cells = <0>, ranges doesn't really work (without listing every single address to be translated). Likewise, because we always need the parent bus phandle, we can't use the trick of an empty 'ranges' to mean an identity mapping.
Quoted 4 lines
We could invent encodings to address those, but given the addon with multiple connectors case provides another incentive for a single connector to allow adding nodes in multiple (but strictly enumerated) places in the base device tree provides a better approach.
and the "place in base device tree" is the goal of the extension bus.
The strict enumeration of nodes enumerated is done by two means:
- extension busses at connector level
Those extensions are described as connector sub-nodes.
The addon DT can only add nodes in those sub-nodes to describe devices connected to the relared extension bus.
- export symbols
An addon DT can only use symbols exported to reference symbols outside the addon DT itself.Quoted 2 lines
Can I assume that bus extensions we proposed (i2c-bus-extension and spi-bus-extension) could be a correct solution ?
Maybe? I prefer the idea of a universal mechanism, not one that's defined per-bus-type.
Quoted 6 lines
Also, IIUC the way bus extension operates is a bit different - nodes would be "physically" added under the bus extension node, but treated logically as if they go under the main bus. What I'm proposing here is something at the actualy overlay application layer that allows nodes to be added to different parts of the base device tree - so you could add your i2c device under the main i2c bus.
I think we should avoid this kind of node dispatching here and there in the base DT.
We work on decoupling busses wired to a connector and dispatching nodes looks like this decoupling is ignored.
IMHO, keeping devices available on an addon board as nodes under the connector is a real hardware representation.
Also, at runtime, once an addon board DT is applied, when you look at your current DT either using
/proc/device-treeor some links such as/sys/bus/devices/.../of_node, the connector and extension bus appear and clearly identify devices behind the connector.Quoted 6 lines
That approach does complicate removal, but its not as bad as overlays at the moment, because a) it could be limited to adding new nodes, not modifying existing ones and b) the connector would specify exactly the places that additions are allowed.
I think bus extensions comply with a) and b).
Yes, bus extensions need to be handled per-bus types but they have the advantage of keeping the hardware reality well described and visible at runtime in term of "wiring" topology.
Whatever the solution, this will already be handled per-bus types. Only busses that support runtime DT node addition/removal (OF_RECONFIG_* notifications in the kernel implementation) will support adding or removing nodes.
Your approach is more complex, dispatch node here and there and actually is also a per-bus types solution.
Quoted 8 lines
I think, in order to choose between both solutions, the main question is:
Do we want to dispatch nodes provided by an addon DT everywhere in the base DT ?IMHO, the answer is no.
Rob, others, any opinion ?
The base DT describes the base board hardware.
With this in mind, adding a node at some location other than behind a connector node means that you add a new device on this board and not on something behind a connector. In other words this describes a physical modification of the base board itself.
Best regards,
Hervé
Quoted 73 lines · Herve Codina
Hi David,
On Thu, 18 Sep 2025 13:16:32 +1000
David Gibson <[email protected]> wrote:...
Quoted 59 lines
Quoted 52 lines
Quoted 36 lines
Thoughts above suggest a different direction, but here's what I was thinking before:
base board:
connector { /export/ "i2c" &i2c0; };addon:
eeprom@10 { compatible = "foo,eeprom"; bus-reg = <&i2c 0x10>; }Or, if the addon had multiple i2c devices, maybe something like:
board-i2c { compatible = "i2c-simple-bridge"; bus-ranges = <&i2c 0 0x3ff>; /* Whole addr space */ eeprom@10 { compatible = "foo,eeprom"; reg = <0x10>; } widget@20 { compatible = "vendor,widget"; reg = <0x20>; } }Writing that, I realise I2C introduces some complications for this. Because it has #size-cells = <0>, ranges doesn't really work (without listing every single address to be translated). Likewise, because we always need the parent bus phandle, we can't use the trick of an empty 'ranges' to mean an identity mapping.
Quoted 4 lines
We could invent encodings to address those, but given the addon with multiple connectors case provides another incentive for a single connector to allow adding nodes in multiple (but strictly enumerated) places in the base device tree provides a better approach.
and the "place in base device tree" is the goal of the extension bus.
The strict enumeration of nodes enumerated is done by two means:
- extension busses at connector level
Those extensions are described as connector sub-nodes.
The addon DT can only add nodes in those sub-nodes to describe devices connected to the relared extension bus.
- export symbols
An addon DT can only use symbols exported to reference symbols outside the addon DT itself.Quoted 2 lines
Can I assume that bus extensions we proposed (i2c-bus-extension and spi-bus-extension) could be a correct solution ?
Maybe? I prefer the idea of a universal mechanism, not one that's defined per-bus-type.
Quoted 6 lines
Also, IIUC the way bus extension operates is a bit different - nodes would be "physically" added under the bus extension node, but treated logically as if they go under the main bus. What I'm proposing here is something at the actualy overlay application layer that allows nodes to be added to different parts of the base device tree - so you could add your i2c device under the main i2c bus.
Quoted 2 lines
I think we should avoid this kind of node dispatching here and there in the base DT.
Until I saw Geert's multi-connector case, I would have agreed. That case makes me thing differently: in order to support that case we already have to handle adding information in multiple places (under all of the connectors the addon uses). Given we have to handle that anyway, I wonder if it makes more sense to lean into that, and allow updates to multiple (strictly enumerated) places.
Quoted 2 lines
We work on decoupling busses wired to a connector and dispatching nodes looks like this decoupling is ignored.
I don't really follow what you're saying here.
Quoted 2 lines
IMHO, keeping devices available on an addon board as nodes under the connector is a real hardware representation.
It's *a* real hardware representation, but it's not the only real hardware representation. Placing the new nodes under connectors prioritises the physical connections. Placing them under various nodes on the base board prioritises the logical-bus connections. I'd argue that the latter is slightly more important, since the primary consumer of the device tree is the OS, to which the logical connections are usually more important.
But in any case, real hardware isn't necessarily a tree, so we have to compromise somewhere.
Quoted 4 lines
Also, at runtime, once an addon board DT is applied, when you look at your current DT either using
/proc/device-treeor some links such as/sys/bus/devices/.../of_node, the connector and extension bus appear and clearly identify devices behind the connector.
That's certainly nice, but we already lose this in the multi-connector case, so I don't think it can be a hard requirement.
Quoted 6 lines
Quoted 4 lines
That approach does complicate removal, but its not as bad as overlays at the moment, because a) it could be limited to adding new nodes, not modifying existing ones and b) the connector would specify exactly the places that additions are allowed.
I think bus extensions comply with a) and b).
Bus extensions aren't directly relevant to (a) and (b) - those are about the actual overlay/addon application mechanism. Bus extensions are one of several possible approaches to allowing a more restrictive (and therefore manageable) way of dynamically updating the dt, while still being able to represent multi-bus devices.
Quoted 8 lines
Yes, bus extensions need to be handled per-bus types but they have the advantage of keeping the hardware reality well described and visible at runtime in term of "wiring" topology.
Whatever the solution, this will already be handled per-bus types. Only busses that support runtime DT node addition/removal (OF_RECONFIG_* notifications in the kernel implementation) will support adding or removing nodes.
First, I don't see that the implementation need affect the spec here. Second, bus-reg has possible applications even if there isn't dynamic reconfiguration.
Quoted 3 lines
Your approach is more complex, dispatch node here and there and actually is also a per-bus types solution.
Again, I don't follow you.
Quoted 5 lines
I think, in order to choose between both solutions, the main question is:
Do we want to dispatch nodes provided by an addon DT everywhere in the base DT ?IMHO, the answer is no.
Everywhere, no, absolutely not. That's one of the things that's awful about the current overlay mechanism.
Multiple places - as specified by the base board / connector, maybe.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Quoted 71 lines · David Gibson
Quoted 70 lines · Herve Codina
Hi David,
On Thu, 18 Sep 2025 13:16:32 +1000
David Gibson <[email protected]> wrote:...
Quoted 63 lines
Quoted 51 lines
Quoted 36 lines
Thoughts above suggest a different direction, but here's what I was thinking before:
base board:
connector { /export/ "i2c" &i2c0; };addon:
eeprom@10 { compatible = "foo,eeprom"; bus-reg = <&i2c 0x10>; }Or, if the addon had multiple i2c devices, maybe something like:
board-i2c { compatible = "i2c-simple-bridge"; bus-ranges = <&i2c 0 0x3ff>; /* Whole addr space */ eeprom@10 { compatible = "foo,eeprom"; reg = <0x10>; } widget@20 { compatible = "vendor,widget"; reg = <0x20>; } }Writing that, I realise I2C introduces some complications for this. Because it has #size-cells = <0>, ranges doesn't really work (without listing every single address to be translated). Likewise, because we always need the parent bus phandle, we can't use the trick of an empty 'ranges' to mean an identity mapping.
Quoted 4 lines
We could invent encodings to address those, but given the addon with multiple connectors case provides another incentive for a single connector to allow adding nodes in multiple (but strictly enumerated) places in the base device tree provides a better approach.
and the "place in base device tree" is the goal of the extension bus.
The strict enumeration of nodes enumerated is done by two means:
- extension busses at connector level
Those extensions are described as connector sub-nodes.
The addon DT can only add nodes in those sub-nodes to describe devices connected to the relared extension bus.
- export symbols
An addon DT can only use symbols exported to reference symbols outside the addon DT itself.Quoted 2 lines
Can I assume that bus extensions we proposed (i2c-bus-extension and spi-bus-extension) could be a correct solution ?
Maybe? I prefer the idea of a universal mechanism, not one that's defined per-bus-type.
Also, IIUC the way bus extension operates is a bit different - nodes would be "physically" added under the bus extension node, but treated logically as if they go under the main bus. What I'm proposing here is something at the actualy overlay application layer that allows nodes to be added to different parts of the base device tree - so you could add your i2c device under the main i2c bus.
Quoted 8 lines
Quoted 2 lines
I think we should avoid this kind of node dispatching here and there in the base DT.
Until I saw Geert's multi-connector case, I would have agreed. That case makes me thing differently: in order to support that case we already have to handle adding information in multiple places (under all of the connectors the addon uses). Given we have to handle that anyway, I wonder if it makes more sense to lean into that, and allow updates to multiple (strictly enumerated) places.
Well, I don't love this idea. Here are my main qalms about the approach of adding devices directly to the actual i2c/spi etc nodes.
1. In boards with multiple connectors, they sometimes share the same i2c. Now assume that someone decided to connect the same i2c device to both the connectors. If we are using something like bus extension, while the node would be added, it will fail in the registration since you cannot add the same address device a second time. However, if we are adding the device directly to the main_i2c, the overlay application will just end up modifying the exact same device node. There is no error, or even a 2nd device node in this case. It is just lost.
2. How well will overlay adding and removing work when the same tree nodes are modified by multiple connectors? I have not looked at the internals of overlay resolution so not sure, but I don't want dynamic addition and removal of devices in independent connectors to somehow become coupled.
Quoted 54 lines
Quoted 2 lines
We work on decoupling busses wired to a connector and dispatching nodes looks like this decoupling is ignored.
I don't really follow what you're saying here.
Quoted 2 lines
IMHO, keeping devices available on an addon board as nodes under the connector is a real hardware representation.
It's *a* real hardware representation, but it's not the only real hardware representation. Placing the new nodes under connectors prioritises the physical connections. Placing them under various nodes on the base board prioritises the logical-bus connections. I'd argue that the latter is slightly more important, since the primary consumer of the device tree is the OS, to which the logical connections are usually more important.
But in any case, real hardware isn't necessarily a tree, so we have to compromise somewhere.
Quoted 4 lines
Also, at runtime, once an addon board DT is applied, when you look at your current DT either using
/proc/device-treeor some links such as/sys/bus/devices/.../of_node, the connector and extension bus appear and clearly identify devices behind the connector.That's certainly nice, but we already lose this in the multi-connector case, so I don't think it can be a hard requirement.
Quoted 5 lines
Quoted 4 lines
That approach does complicate removal, but its not as bad as overlays at the moment, because a) it could be limited to adding new nodes, not modifying existing ones and b) the connector would specify exactly the places that additions are allowed.
I think bus extensions comply with a) and b).
Bus extensions aren't directly relevant to (a) and (b) - those are about the actual overlay/addon application mechanism. Bus extensions are one of several possible approaches to allowing a more restrictive (and therefore manageable) way of dynamically updating the dt, while still being able to represent multi-bus devices.
Quoted 8 lines
Yes, bus extensions need to be handled per-bus types but they have the advantage of keeping the hardware reality well described and visible at runtime in term of "wiring" topology.
Whatever the solution, this will already be handled per-bus types. Only busses that support runtime DT node addition/removal (OF_RECONFIG_* notifications in the kernel implementation) will support adding or removing nodes.
First, I don't see that the implementation need affect the spec here. Second, bus-reg has possible applications even if there isn't dynamic reconfiguration.
Quoted 2 lines
Your approach is more complex, dispatch node here and there and actually is also a per-bus types solution.
Again, I don't follow you.
Quoted 4 lines
I think, in order to choose between both solutions, the main question is:
Do we want to dispatch nodes provided by an addon DT everywhere in the base DT ?
Quoted 5 lines
Quoted 1 line
IMHO, the answer is no.
Everywhere, no, absolutely not. That's one of the things that's awful about the current overlay mechanism.
Multiple places - as specified by the base board / connector, maybe.
Best Regards,
Ayush Singh
Quoted 85 lines · On Fri, 19 Sep 2025 10:47:17 +0530 Ayush Singh <[email protected]> wrote:
Quoted 71 lines · David Gibson
Quoted 70 lines · Herve Codina
Hi David,
On Thu, 18 Sep 2025 13:16:32 +1000
David Gibson <[email protected]> wrote:...
Quoted 63 lines
Quoted 51 lines
Quoted 36 lines
Thoughts above suggest a different direction, but here's what I was thinking before:
base board:
connector { /export/ "i2c" &i2c0; };addon:
eeprom@10 { compatible = "foo,eeprom"; bus-reg = <&i2c 0x10>; }Or, if the addon had multiple i2c devices, maybe something like:
board-i2c { compatible = "i2c-simple-bridge"; bus-ranges = <&i2c 0 0x3ff>; /* Whole addr space */ eeprom@10 { compatible = "foo,eeprom"; reg = <0x10>; } widget@20 { compatible = "vendor,widget"; reg = <0x20>; } }Writing that, I realise I2C introduces some complications for this. Because it has #size-cells = <0>, ranges doesn't really work (without listing every single address to be translated). Likewise, because we always need the parent bus phandle, we can't use the trick of an empty 'ranges' to mean an identity mapping.
Quoted 4 lines
We could invent encodings to address those, but given the addon with multiple connectors case provides another incentive for a single connector to allow adding nodes in multiple (but strictly enumerated) places in the base device tree provides a better approach.
and the "place in base device tree" is the goal of the extension bus.
The strict enumeration of nodes enumerated is done by two means:
- extension busses at connector level
Those extensions are described as connector sub-nodes.
The addon DT can only add nodes in those sub-nodes to describe devices connected to the relared extension bus.
- export symbols
An addon DT can only use symbols exported to reference symbols outside the addon DT itself.Quoted 2 lines
Can I assume that bus extensions we proposed (i2c-bus-extension and spi-bus-extension) could be a correct solution ?
Maybe? I prefer the idea of a universal mechanism, not one that's defined per-bus-type.
Also, IIUC the way bus extension operates is a bit different - nodes would be "physically" added under the bus extension node, but treated logically as if they go under the main bus. What I'm proposing here is something at the actualy overlay application layer that allows nodes to be added to different parts of the base device tree - so you could add your i2c device under the main i2c bus.
Quoted 8 lines
Quoted 2 lines
I think we should avoid this kind of node dispatching here and there in the base DT.
Until I saw Geert's multi-connector case, I would have agreed. That case makes me thing differently: in order to support that case we already have to handle adding information in multiple places (under all of the connectors the addon uses). Given we have to handle that anyway, I wonder if it makes more sense to lean into that, and allow updates to multiple (strictly enumerated) places.
Well, I don't love this idea. Here are my main qalms about the approach of adding devices directly to the actual i2c/spi etc nodes.
Quoted 8 lines
1. In boards with multiple connectors, they sometimes share the same i2c. Now assume that someone decided to connect the same i2c device to both the connectors. If we are using something like bus extension, while the node would be added, it will fail in the registration since you cannot add the same address device a second time. However, if we are adding the device directly to the
main_i2c, the overlay application will just end up modifying the exact same device node. There is no error, or even a 2nd device node in this case. It is just lost.
Thinking out loud: what about preventing loading any overlay that does more than just adding nodes? IOW forbidding to create properties in nodes already in the live tree, and modifying existing properties.
I think being very restrictive in terms of overlays the implementation can accept is a good idea in general. A requirement can be relaxed in the future, but forbidding what used to be allowed would be a nightmare.
Best regards,
Luca
Signature · 3 lines
Luca Ceresoli, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
Quoted 94 lines · Ayush Singh
Quoted 71 lines · David Gibson
Quoted 70 lines · Herve Codina
Hi David,
On Thu, 18 Sep 2025 13:16:32 +1000
David Gibson <[email protected]> wrote:...
Quoted 63 lines
Quoted 51 lines
Quoted 36 lines
Thoughts above suggest a different direction, but here's what I was thinking before:
base board:
connector { /export/ "i2c" &i2c0; };addon:
eeprom@10 { compatible = "foo,eeprom"; bus-reg = <&i2c 0x10>; }Or, if the addon had multiple i2c devices, maybe something like:
board-i2c { compatible = "i2c-simple-bridge"; bus-ranges = <&i2c 0 0x3ff>; /* Whole addr space */ eeprom@10 { compatible = "foo,eeprom"; reg = <0x10>; } widget@20 { compatible = "vendor,widget"; reg = <0x20>; } }Writing that, I realise I2C introduces some complications for this. Because it has #size-cells = <0>, ranges doesn't really work (without listing every single address to be translated). Likewise, because we always need the parent bus phandle, we can't use the trick of an empty 'ranges' to mean an identity mapping.
Quoted 4 lines
We could invent encodings to address those, but given the addon with multiple connectors case provides another incentive for a single connector to allow adding nodes in multiple (but strictly enumerated) places in the base device tree provides a better approach.
and the "place in base device tree" is the goal of the extension bus.
The strict enumeration of nodes enumerated is done by two means:
- extension busses at connector level
Those extensions are described as connector sub-nodes.
The addon DT can only add nodes in those sub-nodes to describe devices connected to the relared extension bus.
- export symbols
An addon DT can only use symbols exported to reference symbols outside the addon DT itself.Quoted 2 lines
Can I assume that bus extensions we proposed (i2c-bus-extension and spi-bus-extension) could be a correct solution ?
Maybe? I prefer the idea of a universal mechanism, not one that's defined per-bus-type.
Also, IIUC the way bus extension operates is a bit different - nodes would be "physically" added under the bus extension node, but treated logically as if they go under the main bus. What I'm proposing here is something at the actualy overlay application layer that allows nodes to be added to different parts of the base device tree - so you could add your i2c device under the main i2c bus.
Quoted 8 lines
Quoted 2 lines
I think we should avoid this kind of node dispatching here and there in the base DT.
Until I saw Geert's multi-connector case, I would have agreed. That case makes me thing differently: in order to support that case we already have to handle adding information in multiple places (under all of the connectors the addon uses). Given we have to handle that anyway, I wonder if it makes more sense to lean into that, and allow updates to multiple (strictly enumerated) places.
Well, I don't love this idea. Here are my main qalms about the approach of adding devices directly to the actual i2c/spi etc nodes.
1. In boards with multiple connectors, they sometimes share the same i2c. Now assume that someone decided to connect the same i2c device to both the connectors. If we are using something like bus extension, while the node would be added, it will fail in the registration since you cannot add the same address device a second time. However, if we are adding the device directly to the
main_i2c, the overlay application will just end up modifying the exact same device node. There is no error, or even a 2nd device node in this case. It is just lost.
Quoted 4 lines
2. How well will overlay adding and removing work when the same tree nodes are modified by multiple connectors? I have not looked at the internals of overlay resolution so not sure, but I don't want dynamic addition and removal of devices in independent connectors to somehow become coupled.
Ah, right. To be clear: we absolutely don't want multiple addons altering the same nodes. But I think we could do that in ways other than putting everything under a connector. This is exactly why I think we should think this through as an end-to-end problem, rather trying to do it as a tweak to the existing (crap) overlay system.
So, if we're thinking of this as an entirely new way of updating the base dt - not "an overlay" - we can decide on the rules to ensure that addition and removal is sane. Two obvious ones I think we should definitely have are:
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
b) Addons can only add nodes in places that are explicitly allowed by the connectors they're connecting to.
We could consider further rules as well though. For example, we could say that i2c devices in an addon shouldn't be added directly under the base board's i2c controller, but under a subnode of that i2c controller assigned to that connector (which would likely have an empty 'ranges' property meaning addresses are mapped without translation). Not really sure if that rule has more benefits or drawbacks, but it's worth contemplating.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David,
Quoted 111 lines · On Tue, 23 Sep 2025 18:09:13 +1000 David Gibson <[email protected]>…
Quoted 94 lines · Ayush Singh
Quoted 71 lines · David Gibson
Quoted 70 lines · Herve Codina
Hi David,
On Thu, 18 Sep 2025 13:16:32 +1000
David Gibson <[email protected]> wrote:...
Quoted 63 lines
Quoted 51 lines
Quoted 36 lines
Thoughts above suggest a different direction, but here's what I was thinking before:
base board:
connector { /export/ "i2c" &i2c0; };addon:
eeprom@10 { compatible = "foo,eeprom"; bus-reg = <&i2c 0x10>; }Or, if the addon had multiple i2c devices, maybe something like:
board-i2c { compatible = "i2c-simple-bridge"; bus-ranges = <&i2c 0 0x3ff>; /* Whole addr space */ eeprom@10 { compatible = "foo,eeprom"; reg = <0x10>; } widget@20 { compatible = "vendor,widget"; reg = <0x20>; } }Writing that, I realise I2C introduces some complications for this. Because it has #size-cells = <0>, ranges doesn't really work (without listing every single address to be translated). Likewise, because we always need the parent bus phandle, we can't use the trick of an empty 'ranges' to mean an identity mapping.
Quoted 4 lines
We could invent encodings to address those, but given the addon with multiple connectors case provides another incentive for a single connector to allow adding nodes in multiple (but strictly enumerated) places in the base device tree provides a better approach.
and the "place in base device tree" is the goal of the extension bus.
The strict enumeration of nodes enumerated is done by two means:
- extension busses at connector level
Those extensions are described as connector sub-nodes.
The addon DT can only add nodes in those sub-nodes to describe devices connected to the relared extension bus.
- export symbols
An addon DT can only use symbols exported to reference symbols outside the addon DT itself.Quoted 2 lines
Can I assume that bus extensions we proposed (i2c-bus-extension and spi-bus-extension) could be a correct solution ?
Maybe? I prefer the idea of a universal mechanism, not one that's defined per-bus-type.
Also, IIUC the way bus extension operates is a bit different - nodes would be "physically" added under the bus extension node, but treated logically as if they go under the main bus. What I'm proposing here is something at the actualy overlay application layer that allows nodes to be added to different parts of the base device tree - so you could add your i2c device under the main i2c bus.
Quoted 8 lines
Quoted 2 lines
I think we should avoid this kind of node dispatching here and there in the base DT.
Until I saw Geert's multi-connector case, I would have agreed. That case makes me thing differently: in order to support that case we already have to handle adding information in multiple places (under all of the connectors the addon uses). Given we have to handle that anyway, I wonder if it makes more sense to lean into that, and allow updates to multiple (strictly enumerated) places.
Well, I don't love this idea. Here are my main qalms about the approach of adding devices directly to the actual i2c/spi etc nodes.
1. In boards with multiple connectors, they sometimes share the same i2c. Now assume that someone decided to connect the same i2c device to both the connectors. If we are using something like bus extension, while the node would be added, it will fail in the registration since you cannot add the same address device a second time. However, if we are adding the device directly to the
main_i2c, the overlay application will just end up modifying the exact same device node. There is no error, or even a 2nd device node in this case. It is just lost.Quoted 4 lines
2. How well will overlay adding and removing work when the same tree nodes are modified by multiple connectors? I have not looked at the internals of overlay resolution so not sure, but I don't want dynamic addition and removal of devices in independent connectors to somehow become coupled.
Ah, right. To be clear: we absolutely don't want multiple addons altering the same nodes. But I think we could do that in ways other than putting everything under a connector. This is exactly why I think we should think this through as an end-to-end problem, rather trying to do it as a tweak to the existing (crap) overlay system.
So, if we're thinking of this as an entirely new way of updating the base dt - not "an overlay" - we can decide on the rules to ensure that addition and removal is sane. Two obvious ones I think we should definitely have are:
Quoted 4 lines
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
Quoted 3 lines
b) Addons can only add nodes in places that are explicitly allowed by the connectors they're connecting to.
I fully agree with those both a) and b) rules.
Quoted 8 lines
We could consider further rules as well though. For example, we could say that i2c devices in an addon shouldn't be added directly under the base board's i2c controller, but under a subnode of that i2c controller assigned to that connector (which would likely have an empty 'ranges' property meaning addresses are mapped without translation). Not really sure if that rule has more benefits or drawbacks, but it's worth contemplating.
IMHO, no extra rules are needed in DT addon rules to constraint i2c devices to be added in a connector node, a connector sub-node or an i2c controller node.
This will be constrained by the connector itself (out of DT addon rules).
I mean, according to rule b), the connector will allow some destination places. Either it will allow the i2c controller node or a connector sub-node.
This is specific to the connector definition and it should be out of generic DT addon rules.
Best regards,
Hervé
Hi Hervé,
Quoted 13 lines · Herve Codina
Quoted 11 lines · On Tue, 23 Sep 2025 18:09:13 +1000 David Gibson <[email protected]>…
Ah, right. To be clear: we absolutely don't want multiple addons altering the same nodes. But I think we could do that in ways other than putting everything under a connector. This is exactly why I think we should think this through as an end-to-end problem, rather trying to do it as a tweak to the existing (crap) overlay system.
So, if we're thinking of this as an entirely new way of updating the base dt - not "an overlay" - we can decide on the rules to ensure that addition and removal is sane. Two obvious ones I think we should definitely have are:
Quoted 8 lines
Quoted 4 lines
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
What if the add-on board contains a provider for the base board. E.g. the connector has a clock input, fed by an optional clock generator on the add-on board. Hooking that into the system requires modifying a clocks property in the base board, cfr. [1].
Or is there some other solution?
I was also wondering about endpoints, as they have two sides: one on the base board, and one on the add-on board. But it seems that typically both ends are added by the extension, so these fall under rule b.
Thanks!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Quoted 31 lines · On Tue, 23 Sep 2025 12:29:27 +0200 Geert Uytterhoeven <[email protected]>…
Hi Hervé,
Quoted 13 lines · Herve Codina
Quoted 11 lines · On Tue, 23 Sep 2025 18:09:13 +1000 David Gibson <[email protected]>…
Ah, right. To be clear: we absolutely don't want multiple addons altering the same nodes. But I think we could do that in ways other than putting everything under a connector. This is exactly why I think we should think this through as an end-to-end problem, rather trying to do it as a tweak to the existing (crap) overlay system.
So, if we're thinking of this as an entirely new way of updating the base dt - not "an overlay" - we can decide on the rules to ensure that addition and removal is sane. Two obvious ones I think we should definitely have are:
Quoted 8 lines
Quoted 4 lines
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
What if the add-on board contains a provider for the base board. E.g. the connector has a clock input, fed by an optional clock generator on the add-on board. Hooking that into the system requires modifying a clocks property in the base board, cfr. [1].
Or is there some other solution?
Quoted 8 lines
I was also wondering about endpoints, as they have two sides: one on the base board, and one on the add-on board. But it seems that typically both ends are added by the extension, so these fall under rule b.
Thanks!
Hi Geert,
Addon DT we talk about is not a way to fine tune base board devices.
For the clock, you need a clock driver which is able to support clock hot-plugging. Same for endpoint, the remote endpoint part should support hot-plugging.
I don't think that addon DT should support what is done in the dtso you pointed out.
Best regards,
Hervé
Quoted 43 lines · Herve Codina
Quoted 31 lines · On Tue, 23 Sep 2025 12:29:27 +0200 Geert Uytterhoeven <[email protected]>…
Hi Hervé,
Quoted 13 lines · Herve Codina
Quoted 11 lines · On Tue, 23 Sep 2025 18:09:13 +1000 David Gibson <[email protected]>…
Ah, right. To be clear: we absolutely don't want multiple addons altering the same nodes. But I think we could do that in ways other than putting everything under a connector. This is exactly why I think we should think this through as an end-to-end problem, rather trying to do it as a tweak to the existing (crap) overlay system.
So, if we're thinking of this as an entirely new way of updating the base dt - not "an overlay" - we can decide on the rules to ensure that addition and removal is sane. Two obvious ones I think we should definitely have are:
Quoted 8 lines
Quoted 4 lines
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
What if the add-on board contains a provider for the base board. E.g. the connector has a clock input, fed by an optional clock generator on the add-on board. Hooking that into the system requires modifying a clocks property in the base board, cfr. [1].
Or is there some other solution?Quoted 8 lines
I was also wondering about endpoints, as they have two sides: one on the base board, and one on the add-on board. But it seems that typically both ends are added by the extension, so these fall under rule b.
Thanks!
Quoted 6 lines
Hi Geert,
Addon DT we talk about is not a way to fine tune base board devices.
For the clock, you need a clock driver which is able to support clock hot-plugging. Same for endpoint, the remote endpoint part should support hot-plugging.
Why should these drivers need hot-plug support, they are attached and then the board is booted. Nothing is hot-plugged here.
Quoted 3 lines
I don't think that addon DT should support what is done in the dtso you pointed out.
The pointed out DTSO is a good example of exactly what needs to be supported, clocks, pinmux, bidirectional endpoints will all be needed to support a large number of add-on boards.
Andrew
Quoted 3 lines
Best regards,
Hervé
Quoted 46 lines · Andrew Davis
Quoted 45 lines · Herve Codina
Quoted 31 lines · On Tue, 23 Sep 2025 12:29:27 +0200 Geert Uytterhoeven <[email protected]>…
Hi Hervé,
Quoted 13 lines · Herve Codina
Quoted 11 lines · On Tue, 23 Sep 2025 18:09:13 +1000 David Gibson <[email protected]>…
Ah, right. To be clear: we absolutely don't want multiple addons altering the same nodes. But I think we could do that in ways other than putting everything under a connector. This is exactly why I think we should think this through as an end-to-end problem, rather trying to do it as a tweak to the existing (crap) overlay system.
So, if we're thinking of this as an entirely new way of updating the base dt - not "an overlay" - we can decide on the rules to ensure that addition and removal is sane. Two obvious ones I think we should definitely have are:
Quoted 8 lines
Quoted 4 lines
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
What if the add-on board contains a provider for the base board. E.g. the connector has a clock input, fed by an optional clock generator on the add-on board. Hooking that into the system requires modifying a clocks property in the base board, cfr. [1].
Or is there some other solution?Quoted 8 lines
I was also wondering about endpoints, as they have two sides: one on the base board, and one on the add-on board. But it seems that typically both ends are added by the extension, so these fall under rule b.
Thanks!
Hi Geert,
Quoted 7 lines
Quoted 4 lines
Addon DT we talk about is not a way to fine tune base board devices.
For the clock, you need a clock driver which is able to support clock hot-plugging. Same for endpoint, the remote endpoint part should support hot-plugging.
Why should these drivers need hot-plug support, they are attached and then the board is booted. Nothing is hot-plugged here.
That's a reasonable case, but not AIUI, the case that Hervé (and others) are trying to deal with. The existing overlay mechanics are not as problematic when you don't have to deal with hot unplug.
Here we're trying to design a protocol that's suitable for things that can (at least in principle) be hot plugged and unplugged.
As a little background here the existing overlay mechanism was never designed for hotplugging let alone hot unplugging. It was built for boot time, or pre-boot use, "tweaking" a mostly correct device tree.
In fact... it wasn't even really designed for that. Its semantics were basically just copied from dtc's *compile time* overlay support. That wasn't designed for any kind of plugging, hot, cold, whatever. It was designed for building DTs for a bunch of similar but not identical boards from a common base (such as a SoC tree).
Moved to runtime with dtbo, that was already pretty clunky. Attempting to use it for hotplug is just awful.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Quoted 25 lines · Geert Uytterhoeven
Hi Hervé,
Quoted 13 lines · Herve Codina
Quoted 11 lines · On Tue, 23 Sep 2025 18:09:13 +1000 David Gibson <[email protected]>…
Ah, right. To be clear: we absolutely don't want multiple addons altering the same nodes. But I think we could do that in ways other than putting everything under a connector. This is exactly why I think we should think this through as an end-to-end problem, rather trying to do it as a tweak to the existing (crap) overlay system.
So, if we're thinking of this as an entirely new way of updating the base dt - not "an overlay" - we can decide on the rules to ensure that addition and removal is sane. Two obvious ones I think we should definitely have are:
Quoted 8 lines
Quoted 4 lines
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
Quoted 5 lines
What if the add-on board contains a provider for the base board. E.g. the connector has a clock input, fed by an optional clock generator on the add-on board. Hooking that into the system requires modifying a clocks property in the base board, cfr. [1].
Or is there some other solution?
Hmm. My first inclination would be that this case is not in scope for the protocol we're trying to design now. If the widget provides things to the base board as well as the other way around, it's no longer an "addon" for the purposes of this spec.
But it's possible I've underestimated how common / useful such a case is.
Note that I'd expect the existing overlay mechanism to still be around. It may be ugly and not very well thought out, but its drawbacks are much less severe if you're not dealing with hot unplug.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Quoted 34 lines · David Gibson
Quoted 20 lines · Geert Uytterhoeven
Hi Hervé,
Quoted 17 lines · Herve Codina
Quoted 15 lines · On Tue, 23 Sep 2025 18:09:13 +1000 David Gibson <[email protected]>…
Ah, right. To be clear: we absolutely don't want multiple addons altering the same nodes. But I think we could do that in ways other than putting everything under a connector. This is exactly why I think we should think this through as an end-to-end problem, rather trying to do it as a tweak to the existing (crap) overlay system.
So, if we're thinking of this as an entirely new way of updating the base dt - not "an overlay" - we can decide on the rules to ensure that addition and removal is sane. Two obvious ones I think we should definitely have are:
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
Quoted 8 lines
Quoted 3 lines
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
What if the add-on board contains a provider for the base board. E.g. the connector has a clock input, fed by an optional clock generator on the add-on board. Hooking that into the system requires modifying a clocks property in the base board, cfr. [1].
Or is there some other solution?Hmm. My first inclination would be that this case is not in scope for the protocol we're trying to design now. If the widget provides things to the base board as well as the other way around, it's no longer an "addon" for the purposes of this spec.
Quoted 7 lines
But it's possible I've underestimated how common / useful such a case is.
Note that I'd expect the existing overlay mechanism to still be around. It may be ugly and not very well thought out, but its drawbacks are much less severe if you're not dealing with hot unplug.
Well, while that was not an initial use-case in my mind, external clock inputs are a valid use-case when talking about connectors for board headers specifically (e.g. pocketbeagle connector).
Best Regards,
Ayush Singh
Quoted 39 lines · Ayush Singh
Quoted 37 lines · David Gibson
Quoted 20 lines · Geert Uytterhoeven
Hi Hervé,
Quoted 17 lines · Herve Codina
Quoted 15 lines · On Tue, 23 Sep 2025 18:09:13 +1000 David Gibson <[email protected]>…
Ah, right. To be clear: we absolutely don't want multiple addons altering the same nodes. But I think we could do that in ways other than putting everything under a connector. This is exactly why I think we should think this through as an end-to-end problem, rather trying to do it as a tweak to the existing (crap) overlay system.
So, if we're thinking of this as an entirely new way of updating the base dt - not "an overlay" - we can decide on the rules to ensure that addition and removal is sane. Two obvious ones I think we should definitely have are:
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
Quoted 8 lines
Quoted 3 lines
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
What if the add-on board contains a provider for the base board. E.g. the connector has a clock input, fed by an optional clock generator on the add-on board. Hooking that into the system requires modifying a clocks property in the base board, cfr. [1].
Or is there some other solution?Hmm. My first inclination would be that this case is not in scope for the protocol we're trying to design now. If the widget provides things to the base board as well as the other way around, it's no longer an "addon" for the purposes of this spec.
But it's possible I've underestimated how common / useful such a case is.
Quoted 8 lines
Quoted 4 lines
Note that I'd expect the existing overlay mechanism to still be around. It may be ugly and not very well thought out, but its drawbacks are much less severe if you're not dealing with hot unplug.
Well, while that was not an initial use-case in my mind, external clock inputs are a valid use-case when talking about connectors for board headers specifically (e.g. pocketbeagle connector).
I guess I'm not familiar enough with modern embedded hardware. I'm having a hard time wrapping my head around what's going on here. If the external clock input is optional (hence under a connector), how is anything on the base board dependent on it? If nothing on the base board is dependent, why do we need to modify its properties to represent it?
Is this a design flaw in the clocks binding?
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David,
Quoted 44 lines · David Gibson
Quoted 35 lines · Ayush Singh
Quoted 34 lines · David Gibson
Quoted 18 lines · Herve Codina
Quoted 17 lines
Quoted 15 lines · On Tue, 23 Sep 2025 18:09:13 +1000 David Gibson <[email protected]>…
Ah, right. To be clear: we absolutely don't want multiple addons altering the same nodes. But I think we could do that in ways other than putting everything under a connector. This is exactly why I think we should think this through as an end-to-end problem, rather trying to do it as a tweak to the existing (crap) overlay system.
So, if we're thinking of this as an entirely new way of updating the base dt - not "an overlay" - we can decide on the rules to ensure that addition and removal is sane. Two obvious ones I think we should definitely have are:
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
Quoted 8 lines
Quoted 3 lines
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
What if the add-on board contains a provider for the base board. E.g. the connector has a clock input, fed by an optional clock generator on the add-on board. Hooking that into the system requires modifying a clocks property in the base board, cfr. [1].
Or is there some other solution?Hmm. My first inclination would be that this case is not in scope for the protocol we're trying to design now. If the widget provides things to the base board as well as the other way around, it's no longer an "addon" for the purposes of this spec.
But it's possible I've underestimated how common / useful such a case is.
Quoted 7 lines
Quoted 3 lines
Note that I'd expect the existing overlay mechanism to still be around. It may be ugly and not very well thought out, but its drawbacks are much less severe if you're not dealing with hot unplug.
Well, while that was not an initial use-case in my mind, external clock inputs are a valid use-case when talking about connectors for board headers specifically (e.g. pocketbeagle connector).
Quoted 8 lines
I guess I'm not familiar enough with modern embedded hardware. I'm having a hard time wrapping my head around what's going on here. If the external clock input is optional (hence under a connector), how is anything on the base board dependent on it? If nothing on the base board is dependent, why do we need to modify its properties to represent it?
Is this a design flaw in the clocks binding?
In my example, the external clock input is indeed optional, and not used by the base board itself. Still, it is a clock input to the SoC, and may be used as a reference clock when an add-on board is connected that needs to use the exact clock frequency of that reference clock.
https://elixir.bootlin.com/linux/v6.17/source/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtsoAUDIO_CLKIN_V is the optional clock input to the SoC. GP1_25/SL_SW2_V/TPU is the reference clock (actually it is not generated on the add-on board, but by a PWM controller on the base board, but it could just be a crystal oscillator on the add-on board instead)
I hope this makes it clearer.
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Quoted 5 lines · Geert Uytterhoeven
Hi David,
Quoted 2 lines · David Gibson
Quoted 1 line · Ayush Singh
On 9/24/25 09:41, David Gibson wrote:
[snip]
Quoted 42 lines
Quoted 28 lines
Quoted 20 lines
Quoted 20 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
Quoted 8 lines
Quoted 3 lines
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
What if the add-on board contains a provider for the base board. E.g. the connector has a clock input, fed by an optional clock generator on the add-on board. Hooking that into the system requires modifying a clocks property in the base board, cfr. [1].
Or is there some other solution?Hmm. My first inclination would be that this case is not in scope for the protocol we're trying to design now. If the widget provides things to the base board as well as the other way around, it's no longer an "addon" for the purposes of this spec.
But it's possible I've underestimated how common / useful such a case is.
Quoted 7 lines
Quoted 3 lines
Note that I'd expect the existing overlay mechanism to still be around. It may be ugly and not very well thought out, but its drawbacks are much less severe if you're not dealing with hot unplug.
Well, while that was not an initial use-case in my mind, external clock inputs are a valid use-case when talking about connectors for board headers specifically (e.g. pocketbeagle connector).
Quoted 8 lines
I guess I'm not familiar enough with modern embedded hardware. I'm having a hard time wrapping my head around what's going on here. If the external clock input is optional (hence under a connector), how is anything on the base board dependent on it? If nothing on the base board is dependent, why do we need to modify its properties to represent it?
Is this a design flaw in the clocks binding?
In my example, the external clock input is indeed optional, and not used by the base board itself. Still, it is a clock input to the SoC, and may be used as a reference clock when an add-on board is connected that needs to use the exact clock frequency of that reference clock.
Quoted 8 lines
https://elixir.bootlin.com/linux/v6.17/source/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso
AUDIO_CLKIN_Vis the optional clock input to the SoC. GP1_25/SL_SW2_V/TPU is the reference clock (actually it is not generated on the add-on board, but by a PWM controller on the base board, but it could just be a crystal oscillator on the add-on board instead)I hope this makes it clearer.
I think so.
IIUC, the problem is that while both the producer and the consumer of the clock are addons, it's routed through the SoC, which is why it requires some representation there.
What seems like the logical approach to me is for the base board to have essentially an unresolved pointer to the clock input. I'm not really sure how that could be sensibly encoded, though.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Quoted 60 lines · On Fri, 10 Oct 2025 18:58:24 +1100 David Gibson <[email protected]>…
Quoted 5 lines · Geert Uytterhoeven
Hi David,
Quoted 2 lines · David Gibson
Quoted 1 line · Ayush Singh
On 9/24/25 09:41, David Gibson wrote:
[snip]
Quoted 42 lines
Quoted 28 lines
Quoted 20 lines
Quoted 20 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
Quoted 8 lines
Quoted 3 lines
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
What if the add-on board contains a provider for the base board. E.g. the connector has a clock input, fed by an optional clock generator on the add-on board. Hooking that into the system requires modifying a clocks property in the base board, cfr. [1].
Or is there some other solution?Hmm. My first inclination would be that this case is not in scope for the protocol we're trying to design now. If the widget provides things to the base board as well as the other way around, it's no longer an "addon" for the purposes of this spec.
But it's possible I've underestimated how common / useful such a case is.
Quoted 7 lines
Quoted 3 lines
Note that I'd expect the existing overlay mechanism to still be around. It may be ugly and not very well thought out, but its drawbacks are much less severe if you're not dealing with hot unplug.
Well, while that was not an initial use-case in my mind, external clock inputs are a valid use-case when talking about connectors for board headers specifically (e.g. pocketbeagle connector).
Quoted 8 lines
I guess I'm not familiar enough with modern embedded hardware. I'm having a hard time wrapping my head around what's going on here. If the external clock input is optional (hence under a connector), how is anything on the base board dependent on it? If nothing on the base board is dependent, why do we need to modify its properties to represent it?
Is this a design flaw in the clocks binding?
In my example, the external clock input is indeed optional, and not used by the base board itself. Still, it is a clock input to the SoC, and may be used as a reference clock when an add-on board is connected that needs to use the exact clock frequency of that reference clock.
Quoted 8 lines
https://elixir.bootlin.com/linux/v6.17/source/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso
AUDIO_CLKIN_Vis the optional clock input to the SoC. GP1_25/SL_SW2_V/TPU is the reference clock (actually it is not generated on the add-on board, but by a PWM controller on the base board, but it could just be a crystal oscillator on the add-on board instead)I hope this makes it clearer.
I think so.
Quoted 8 lines
IIUC, the problem is that while both the producer and the consumer of the clock are addons, it's routed through the SoC, which is why it requires some representation there.
What seems like the logical approach to me is for the base board to have essentially an unresolved pointer to the clock input. I'm not really sure how that could be sensibly encoded, though.
I don't think that having unresolved symbols in the base DT is the right direction. This base DT is used and so all symbols have to be resolved. If any symbols are not resolved (either in addon DT or base DT), this DT should not be used. For the base DT, "not used" means no boot.
Do we really want to support DT used in runtime with some "invalid" parts ?
IMHO, if the base DT need a resource wired at the connector and provided by the addon, the base DT need to reference the connector. From the base DT point of view, the consumed resource is the one provided at the connector.
if a clock is wired at the connector the connector can be seen as a clock controller. This clock controller should be a kind of "bridge" between the base DT clock consumer and the addon board provider and it should perform the link without having any unresolved symbols in the base DT side.
Best regards,
Hervé
Quoted 116 lines · Herve Codina
Hi David,
Quoted 111 lines · On Tue, 23 Sep 2025 18:09:13 +1000 David Gibson <[email protected]>…
Quoted 94 lines · Ayush Singh
Quoted 71 lines · David Gibson
Quoted 70 lines · Herve Codina
Hi David,
On Thu, 18 Sep 2025 13:16:32 +1000
David Gibson <[email protected]> wrote:...
Quoted 63 lines
Quoted 51 lines
Quoted 36 lines
Thoughts above suggest a different direction, but here's what I was thinking before:
base board:
connector { /export/ "i2c" &i2c0; };addon:
eeprom@10 { compatible = "foo,eeprom"; bus-reg = <&i2c 0x10>; }Or, if the addon had multiple i2c devices, maybe something like:
board-i2c { compatible = "i2c-simple-bridge"; bus-ranges = <&i2c 0 0x3ff>; /* Whole addr space */ eeprom@10 { compatible = "foo,eeprom"; reg = <0x10>; } widget@20 { compatible = "vendor,widget"; reg = <0x20>; } }Writing that, I realise I2C introduces some complications for this. Because it has #size-cells = <0>, ranges doesn't really work (without listing every single address to be translated). Likewise, because we always need the parent bus phandle, we can't use the trick of an empty 'ranges' to mean an identity mapping.
Quoted 4 lines
We could invent encodings to address those, but given the addon with multiple connectors case provides another incentive for a single connector to allow adding nodes in multiple (but strictly enumerated) places in the base device tree provides a better approach.
and the "place in base device tree" is the goal of the extension bus.
The strict enumeration of nodes enumerated is done by two means:
- extension busses at connector level
Those extensions are described as connector sub-nodes.
The addon DT can only add nodes in those sub-nodes to describe devices connected to the relared extension bus.
- export symbols
An addon DT can only use symbols exported to reference symbols outside the addon DT itself.Quoted 2 lines
Can I assume that bus extensions we proposed (i2c-bus-extension and spi-bus-extension) could be a correct solution ?
Maybe? I prefer the idea of a universal mechanism, not one that's defined per-bus-type.
Also, IIUC the way bus extension operates is a bit different - nodes would be "physically" added under the bus extension node, but treated logically as if they go under the main bus. What I'm proposing here is something at the actualy overlay application layer that allows nodes to be added to different parts of the base device tree - so you could add your i2c device under the main i2c bus.
Quoted 8 lines
Quoted 2 lines
I think we should avoid this kind of node dispatching here and there in the base DT.
Until I saw Geert's multi-connector case, I would have agreed. That case makes me thing differently: in order to support that case we already have to handle adding information in multiple places (under all of the connectors the addon uses). Given we have to handle that anyway, I wonder if it makes more sense to lean into that, and allow updates to multiple (strictly enumerated) places.
Well, I don't love this idea. Here are my main qalms about the approach of adding devices directly to the actual i2c/spi etc nodes.
1. In boards with multiple connectors, they sometimes share the same i2c. Now assume that someone decided to connect the same i2c device to both the connectors. If we are using something like bus extension, while the node would be added, it will fail in the registration since you cannot add the same address device a second time. However, if we are adding the device directly to the
main_i2c, the overlay application will just end up modifying the exact same device node. There is no error, or even a 2nd device node in this case. It is just lost.Quoted 4 lines
2. How well will overlay adding and removing work when the same tree nodes are modified by multiple connectors? I have not looked at the internals of overlay resolution so not sure, but I don't want dynamic addition and removal of devices in independent connectors to somehow become coupled.
Ah, right. To be clear: we absolutely don't want multiple addons altering the same nodes. But I think we could do that in ways other than putting everything under a connector. This is exactly why I think we should think this through as an end-to-end problem, rather trying to do it as a tweak to the existing (crap) overlay system.
So, if we're thinking of this as an entirely new way of updating the base dt - not "an overlay" - we can decide on the rules to ensure that addition and removal is sane. Two obvious ones I think we should definitely have are:
Quoted 8 lines
Quoted 4 lines
a) Addons can only add completely new nodes, never modify existing ones. This means that whatever addons are present at runtime, every node has a single well defined owner (either base board or addon).
In this rule I suppose that "never modify existing ones" should be understood as "never modify, add or remove properties in existing ones". Because, of course adding a full node in a existing one is allowed (rule b).
Yes, that's what I meant. I'd add never delete subnodes as well. on add. Remove obviously would delete subnodes, but only exactly the ones that were added on add.
Quoted 14 lines
Quoted 2 lines
b) Addons can only add nodes in places that are explicitly allowed by the connectors they're connecting to.
I fully agree with those both a) and b) rules.
Quoted 8 lines
We could consider further rules as well though. For example, we could say that i2c devices in an addon shouldn't be added directly under the base board's i2c controller, but under a subnode of that i2c controller assigned to that connector (which would likely have an empty 'ranges' property meaning addresses are mapped without translation). Not really sure if that rule has more benefits or drawbacks, but it's worth contemplating.
Quoted 5 lines
IMHO, no extra rules are needed in DT addon rules to constraint i2c devices to be added in a connector node, a connector sub-node or an i2c controller node.
This will be constrained by the connector itself (out of DT addon rules).
At this point I'm just considering the end-to-end rules we want to enforce. Exactly what stage of the process enforces each rule is another question.
Quoted 2 lines
I mean, according to rule b), the connector will allow some destination places. Either it will allow the i2c controller node or a connector sub-node.
Sure.
Quoted 2 lines
This is specific to the connector definition and it should be out of generic DT addon rules.
Hang on... what distinction are you seeing between the "connector definition" and "generic DT addon rules". As I see it we're trying to create a protocol that defines both the base rules and what a "connector" even means.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David,
On Wed, 24 Sep 2025 13:54:22 +1000
David Gibson <[email protected]> wrote:
...
Quoted 16 lines
Quoted 6 lines
IMHO, no extra rules are needed in DT addon rules to constraint i2c devices to be added in a connector node, a connector sub-node or an i2c controller node.
This will be constrained by the connector itself (out of DT addon rules).
At this point I'm just considering the end-to-end rules we want to enforce. Exactly what stage of the process enforces each rule is another question.
Quoted 2 lines
I mean, according to rule b), the connector will allow some destination places. Either it will allow the i2c controller node or a connector sub-node.
Sure.
Quoted 8 lines
Quoted 2 lines
This is specific to the connector definition and it should be out of generic DT addon rules.
Hang on... what distinction are you seeing between the "connector definition" and "generic DT addon rules". As I see it we're trying to create a protocol that defines both the base rules and what a "connector" even means.
The "generic DT addon rules" give rules related to addon from a DT perspective. In other word "What an addon DT can do"
- export symbols
- import symbols
- Add full node only
- Don't allow to modify existing node
- ...
The way addon are used is what I put behind "connector definition". The connector is a specific node in a DT with a specific comptible string. The definition of this node will tell "how to use it". For instance:
- There is 2 gpios available and an addon can use it with <&connector 0> and
<&connector 1>.
- There is an i2c bus available and an addon can use if with <&i2c-a>
- The hotplug mecanism used for this specific connector (gpio, eeprom, ...) is also part of the "connector definition".
An external board DT supposed to be connected to this connector should
- a) Provide its description using an addon DT (compliant with "generic DT addon rules")
and
- b) Use resources from connector the board is connected to (compliant with "connector definition").
"generic DT addon rules": DT specification
"connector definition": Connector binding
Today, connectors are going to use the addon feature but I didn't want to restrict addon feature to connectors.
For instance, a FPGA driver could use the addon feature with an addon DT to describe the internal part of the FPGA related to the FPGA bitstream loaded by the FPGA driver. That might make sense, right ?
Also upstream in the kernel, PCI boards can be described using DT.
https://elixir.bootlin.com/linux/v6.16/source/drivers/misc/lan966x_pci.c
https://elixir.bootlin.com/linux/v6.16/source/drivers/misc/lan966x_pci.dtso
Using addon DT in that case makes sense too even if a "connector" is not present.
Best regards,
Hervé
Quoted 54 lines · Herve Codina
Hi David,
On Wed, 24 Sep 2025 13:54:22 +1000
David Gibson <[email protected]> wrote:...
Quoted 16 lines
Quoted 6 lines
IMHO, no extra rules are needed in DT addon rules to constraint i2c devices to be added in a connector node, a connector sub-node or an i2c controller node.
This will be constrained by the connector itself (out of DT addon rules).
At this point I'm just considering the end-to-end rules we want to enforce. Exactly what stage of the process enforces each rule is another question.
Quoted 2 lines
I mean, according to rule b), the connector will allow some destination places. Either it will allow the i2c controller node or a connector sub-node.
Sure.
Quoted 8 lines
Quoted 2 lines
This is specific to the connector definition and it should be out of generic DT addon rules.
Hang on... what distinction are you seeing between the "connector definition" and "generic DT addon rules". As I see it we're trying to create a protocol that defines both the base rules and what a "connector" even means.
The "generic DT addon rules" give rules related to addon from a DT perspective. In other word "What an addon DT can do"
- export symbols
- import symbols
- Add full node only
- Don't allow to modify existing node
- ...The way addon are used is what I put behind "connector definition". The connector is a specific node in a DT with a specific comptible string. The definition of this node will tell "how to use it". For instance:
- There is 2 gpios available and an addon can use it with <&connector 0> and<&connector 1>.- There is an i2c bus available and an addon can use if with <&i2c-a>
- The hotplug mecanism used for this specific connector (gpio, eeprom, ...) is also part of the "connector definition".An external board DT supposed to be connected to this connector should
- a) Provide its description using an addon DT (compliant with "generic DT addon rules")
and
Quoted 5 lines
- b) Use resources from connector the board is connected to (compliant with "connector definition").
"generic DT addon rules": DT specification
"connector definition": Connector binding
Ok. I think there are some further possible distinctions here between:
a. Rules for connectors in general
b. Rules for a specific connector type (defined by the connector type
binding)
c. Rules for a specific connector instance (defined by the property
values in that instance).
Possible we can avoid using one or more of those categories, but we need to consider them and do so conciously.
Quoted 2 lines
Today, connectors are going to use the addon feature but I didn't want to restrict addon feature to connectors.
Hmm. I'm not sure this is a good idea. I had been envisaging this new "addon" support as explicitly tied to connectors - you can't addon, except in a way the base board allows, and connectors are the way it allows.
Quoted 3 lines
For instance, a FPGA driver could use the addon feature with an addon DT to describe the internal part of the FPGA related to the FPGA bitstream loaded by the FPGA driver. That might make sense, right ?
With the distinction from the connector case being that the driver defines how to interpret the addon at runtime, rather than the base DT defining it statically?
Quoted 5 lines
Also upstream in the kernel, PCI boards can be described using DT.
https://elixir.bootlin.com/linux/v6.16/source/drivers/misc/lan966x_pci.c
https://elixir.bootlin.com/linux/v6.16/source/drivers/misc/lan966x_pci.dtsoUsing addon DT in that case makes sense too even if a "connector" is not present.
Ok. So I think the model you're suggesting is this:
* A bus/port driver (let's call it an "addon driver") can allow addon DTs to be plugged in and removed, under constraints defined by that driver at runtime.
* The connector driver would be one specific addon driver, that can handle a pretty broad range of not-too-complex addons. The constraints for the addon DT are defined by the properties of the connector in the base DT, rather than by runtime logic in the driver.
Is that correct?
A few observations
- This effectively makes an addon driver a special case of a discoverable bus/port driver. Or even DT addons as a library that a bus/port driver can use. Rather than directly updating the Linux device model, the driver selects an addon DT and uses that to update the Linux device model.
- The distinction between a connector and a general addon driver, is a bit like that between the simple-bus driver and a PCI host bridge driver. The former handles a fairly wide range of relatively simple cases, the latter handles a more complex and specialized case.
I don't dislike this model, but it does raise some questions (these are not rhetorical):
1) Is DT a good way of describing the addon?
After all, the addon driver could make updates directly to the Linux device model from whatever format is convenient.
2) Does it make sense to use the addon to alter the global DT?
Even if the addon is described by a DT, the addon/connector driver could read that DT and the system DT and make corresponding updates to the Linux device model without altering the system DT first.
Signature · 4 lines
David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David,
Quoted 72 lines · On Mon, 29 Sep 2025 19:23:21 +1000 David Gibson <[email protected]>…
Quoted 54 lines · Herve Codina
Hi David,
On Wed, 24 Sep 2025 13:54:22 +1000
David Gibson <[email protected]> wrote:...
Quoted 16 lines
Quoted 6 lines
IMHO, no extra rules are needed in DT addon rules to constraint i2c devices to be added in a connector node, a connector sub-node or an i2c controller node.
This will be constrained by the connector itself (out of DT addon rules).
At this point I'm just considering the end-to-end rules we want to enforce. Exactly what stage of the process enforces each rule is another question.
Quoted 2 lines
I mean, according to rule b), the connector will allow some destination places. Either it will allow the i2c controller node or a connector sub-node.
Sure.
Quoted 8 lines
Quoted 2 lines
This is specific to the connector definition and it should be out of generic DT addon rules.
Hang on... what distinction are you seeing between the "connector definition" and "generic DT addon rules". As I see it we're trying to create a protocol that defines both the base rules and what a "connector" even means.
The "generic DT addon rules" give rules related to addon from a DT perspective. In other word "What an addon DT can do"
- export symbols
- import symbols
- Add full node only
- Don't allow to modify existing node
- ...The way addon are used is what I put behind "connector definition". The connector is a specific node in a DT with a specific comptible string. The definition of this node will tell "how to use it". For instance:
- There is 2 gpios available and an addon can use it with <&connector 0> and<&connector 1>.- There is an i2c bus available and an addon can use if with <&i2c-a>
- The hotplug mecanism used for this specific connector (gpio, eeprom, ...) is also part of the "connector definition".An external board DT supposed to be connected to this connector should
- a) Provide its description using an addon DT (compliant with "generic DT addon rules")
andQuoted 5 lines
- b) Use resources from connector the board is connected to (compliant with "connector definition").
"generic DT addon rules": DT specification
"connector definition": Connector bindingOk. I think there are some further possible distinctions here between:
a. Rules for connectors in general
b. Rules for a specific connector type (defined by the connector type
binding)
c. Rules for a specific connector instance (defined by the property
values in that instance).Possible we can avoid using one or more of those categories, but we need to consider them and do so conciously.
Quoted 7 lines
Quoted 2 lines
Today, connectors are going to use the addon feature but I didn't want to restrict addon feature to connectors.
Hmm. I'm not sure this is a good idea. I had been envisaging this new "addon" support as explicitly tied to connectors - you can't addon, except in a way the base board allows, and connectors are the way it allows.
I agree with that.
I think we just need to clarify what is the definition of "connector" in this context.
I have the feeling that a "connector" for you is where an addon is going to be applied.
In my mind a connector was the piece of hardware where the addon board is connected.
Most of the time, this piece of hardware will be represented as a node in the DT and the addon DT will be applied to this node.
I made the distinction in case of PMOD use case (Geert's use case with multiple connector). In that case we need to find, probably with external help, connectors connected to the addon board.
I have the feeling that in that case the description will be:
/* Base board DT */
pmod-group {
pmod-connector1 {
...
};
pmod-connector2 {
...
};
pmod-connector3 {
...
};};
The addon DT will be applied to pmod-group and the pmod-group driver selects multiple connectors (pmod-connector1 and/or pmod-connector2 and/or pmod-connector3) according to the addon needs and some external help in order to applied the addon DT.
https://lore.kernel.org/all/[email protected]/
Quoted 8 lines
Quoted 4 lines
For instance, a FPGA driver could use the addon feature with an addon DT to describe the internal part of the FPGA related to the FPGA bitstream loaded by the FPGA driver. That might make sense, right ?
With the distinction from the connector case being that the driver defines how to interpret the addon at runtime, rather than the base DT defining it statically?
Yes
Quoted 13 lines
Quoted 6 lines
Also upstream in the kernel, PCI boards can be described using DT.
https://elixir.bootlin.com/linux/v6.16/source/drivers/misc/lan966x_pci.c
https://elixir.bootlin.com/linux/v6.16/source/drivers/misc/lan966x_pci.dtsoUsing addon DT in that case makes sense too even if a "connector" is not present.
Ok. So I think the model you're suggesting is this:
* A bus/port driver (let's call it an "addon driver") can allow addon DTs to be plugged in and removed, under constraints defined by that driver at runtime.
Quoted 7 lines
* The connector driver would be one specific addon driver, that can handle a pretty broad range of not-too-complex addons. The constraints for the addon DT are defined by the properties of the connector in the base DT, rather than by runtime logic in the driver.
Is that correct?
Both properties of the connector and runtime logic.
In multiple connector cases, some runtime logic will be needed.
Also, in my use case, several steps are required:
1) Apply an addon DT to describe EEPROM available on all addon boards we supports.
2) Read the eeprom to identify the board
3) Select the right full addon DT based on the board idendified
4) Apply the full addon DT
Quoted 15 lines
A few observations
- This effectively makes an addon driver a special case of a discoverable bus/port driver. Or even DT addons as a library that a bus/port driver can use. Rather than directly updating the Linux device model, the driver selects an addon DT and uses that to update the Linux device model.
- The distinction between a connector and a general addon driver, is a bit like that between the simple-bus driver and a PCI host bridge driver. The former handles a fairly wide range of relatively simple cases, the latter handles a more complex and specialized case.
Quoted 7 lines
I don't dislike this model, but it does raise some questions (these are not rhetorical):
1) Is DT a good way of describing the addon?
After all, the addon driver could make updates directly to the Linux device model from whatever format is convenient.
The DT goal is to describe hardware and we are describing hardware available on an addon board. DT description seems perfectly legit for this use case.
Let's try as an exercise. Now we have device tree (DT), let's say we want to describe addons using the new "Another Representation of Generic Hardware" (ARGH) syntax.
We need to:
* implement arghc (similar to dtc)
* write argh-bindings for chips that already have dt-bindings
* write new argh_*() functions similar to of_*() functions
* write new toooling like make argh_binding_check and make arghs_check
* etc
Or we could look for an existing format and decide to use the device tree format, which is maybe not perfect, but it works well for a lot of things and has all these and more implemented already.
Quoted 7 lines
2) Does it make sense to use the addon to alter the global DT?
Even if the addon is described by a DT, the addon/connector driver could read that DT and the system DT and make corresponding updates to the Linux device model without altering the system DT first.
May I missed something but I think we already discussed this and you appeared to agree with my arguments in favor of letting the addon alter very specific nodes in the base tree that are explicitly marked as suitable in the connector description.
https://lore.kernel.org/all/aMebXe-yJy34kST8@zatzit/
Best regards,
Hervé