-
Notifications
You must be signed in to change notification settings - Fork 8.2k
[RFC] DT: emit ordinals #22292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] DT: emit ordinals #22292
Conversation
Setting 'is-device: true' at the top level of a binding YAML file will cause the build system to treat the resulting node specially. In particular, it will be considered to correspond to a struct device. This will enable us to emit dependency ordinals for devices and the other devices they depend on from device tree bindings. This in turn will allow us to make the Zephyr device model more aware of DT. Signed-off-by: Martí Bolívar <[email protected]>
Emit macros for: - a node's device tree dependency ordinal - the dependency ordinals of the devices and nodes it depends on - the dependency ordinals of the devices and nodes that depend on it This enables the Zephyr build system to track this information for dynamic binary device power management based on usage. Signed-off-by: Martí Bolívar <[email protected]>
| @property | ||
| def is_device(self): | ||
| "See the class docstring" | ||
| return self._binding and self._binding.get('is-device', False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should default to True. As long as we have a matching-compat, we're likely to be a struct device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted.
ulfalizer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some nits
| compatible: "manufacturer,device" | ||
|
|
||
| # Set this to a truthy value if this binding is describing a node that | ||
| # has a struct device representation within the Zephyr device |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could make it "... has a 'struct device' representation ..."
Was wondering what kind of device a "struct device" is.
| @property | ||
| def is_device(self): | ||
| "See the class docstring" | ||
| return self._binding and self._binding.get('is-device', False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a personal quirk, but make it "is-device" instead of 'is-device' for consistency with the rest of the code.
| dep_ords([n for n in node.depends_on if n.is_device])) | ||
| out_node_init(node, 'SUPPORTS_NODES', dep_ords(node.required_by)) | ||
| out_node_init(node, 'SUPPORTS_DEVS', | ||
| dep_ords([n for n in node.required_by if n.is_device])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use double quotes for strings here too, for consistency.
| out_node(node, 'ORDINAL', node.dep_ordinal) | ||
| out_node_init(node, 'REQUIRES_NODES', dep_ords(node.depends_on)) | ||
| out_node_init(node, 'REQUIRES_DEVS', | ||
| dep_ords([n for n in node.depends_on if n.is_device])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe dep or the like instead of n. Not sure what n stands for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, this isn't enough to capture parameterized dependencies; I'll rethink this. I guess we'll need to special-case by type of dependency (clock subsystem, interrupt controller, GPIO spec, etc.)
| is_device: | ||
| True if the node's binding signals that it corresponds to a Zephyr | ||
| device model struct device. False otherwise. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'struct device'
|
This adds a Zephyr software feature "usable for Zephyr device structure" to the bindings that should be hardware specific only. At least from the naming it should be clear that this for Zephyr (aka "zephyr,is-device", "is_zephyr_device"). Why not add a zephyr specific property to base.yaml: By this you can specify and get the same information, but the Zephyr specific is only in the Zephyr specific base.yaml. No changes needed for edtlib.py. In the DTS of the device you would set 'zephyr,is-device' as any other device property. |
|
@b0661 |
Ok, I see. It's just the dream to have edtlib.py as a generic tool, not a specific tool for Zephyr. Reducing the view to Zephyr could create the situation that Zepyhr has an umbrella device driver where only the umbrella device gets the 'is-device' property. All the devices under the umbrella are no devices in this view as no device structure has to be created. Out of tree driver developers with another view on what is a device will get a problem (which can be solved by providing binding file overwrite in edtlib.py, see #22255). Maybe I'm too peculiar and anyway there is a workaround on the way. |
I was unaware that anybody intended to use edtlib outside of Zephyr. Is this true? I thought dtlib was the generic part, and edtlib was where we were supposed to put all the special sauce.
I don't follow. I think whether or not a node in DT corresponds to a In this case, what I ultimately want to do in zephyr is to obtain the direct This filtering is up to the drivers to decide, and I think of the zephyr specific DT bindings for a driver as being logically part of that driver. TL;DR: I'm ultimately trying to let drivers signal to edtlib that some nodes are relevant parts of this dependency hierarchy, while other nodes are not. Then gen_defines can in turn tell me what I need to know about it. I don't get why FreeRTOS is relevant here. What am I missing? |
|
@ulfalizer thank you for the review. I'll address the nits if this RFC seems reasonable and we want to move forward with an ordinal-based approach for device numbering. |
This has been mentioned before by @galak, he might want to weigh in. |
Yes me - somehow. edtlib.py feeds the inline code generator (not gen_defines.py). The inline code generator is used for a Zephyr based project but shall/will also be used for a project that does not run on Zephyr.
I thought gen_defines.py is where the Zephyr special sauce is cooked and edtlib extends the DTS for ease of use but does not create new info.
I don´t follow either. I though you want to make the creation of a device struct dependent on the 'is-device' property in the binding.
It is just an example for another RTOS that might use the bindings and edtlib.
Nothing. We just have a different understanding of the functionality that edtlib shall provide and what shall be the functionality that is outside of edtlib and the bindings. As already mentioned:
I just expressed my opinion. I do NOT vote against this PR. |
|
I'm getting a bit lost in understanding the domain model here, and wonder whether everybody commenting shares an understanding. I believe what we want to know, for a given devicetree node with a compatible, is whether that compatible identifies something that has a driver, and consequently that the node describes an instance of a device supported by that driver, for which dependency information must be provided. That is, compatibles correspond to drivers; devicetree nodes correspond to device instances associated with a driver. (Is there any case where we'd have two nodes with the same compatible, one of which represents a device and another does not? I hope not, but if so we need to understand how that could happen.) As such I don't think an Since what we're trying to identify is devicetree nodes that correspond to device instances associated with a driver in Zephyr, I agree that the name should be marked with |
This was discussed today at the dev meeting. @galak agreed that edtlib should be OS agnostic wherever possible. The consensus was also that ordinal-based power management is the clear way forward, so we will need to emit this information in some form TBD. I think that makes this RFC a success. I'll think of another way to do this and take it forward in another PR. Thanks for the comments! |
Emit dependency ordinals for devices in devicetree.
The idea is we can start using these for hierarchical device management, so also extend the bindings language to express when nodes correspond to Zephyr devices. This lets us emit structure initializers that let devices track their dependencies in a ROM friendly way.
Going this way will let us use
__device_<ORDINAL>as the identifier for each struct device with a DT-aware device init macro in the same style as #20253, but with dependency info implicitly embedded in the number. It remains to be seen how that would best fit into the existing init levels and priorities.This also lets us resolve devices at build time if their ordinals are known constants. It would require a look up table to get a device from its ordinal in the general case.