Re: Device tree representation of (hotplug) connectors: discussion at ELCE
From: David Gibson <hidden>
Date: 2025-09-08 04:36:13
Also in:
lkml
On Thu, Sep 04, 2025 at 11:15:44AM +0530, Ayush Singh wrote:
On 9/4/25 10:53, David Gibson wrote:quoted
On Tue, Sep 02, 2025 at 10:57:10AM +0200, Luca Ceresoli wrote:
[snip]
quoted
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.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.
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
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.
Yes, it would.
quoted
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.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]
[1]: https://lore.kernel.org/all/20250618082313.549140-1-herve.codina@bootlin.com/ (local) [2]: https://lore.kernel.org/all/20250729-spi-bus-extension-v1-0-b20c73f2161a@beagleboard.org/ (local)quoted
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.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. -- 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
Attachments
- signature.asc [application/pgp-signature] 833 bytes