From d0eb55e2b031d56368f7c0b6e83425f4286f2eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 28 Jan 2020 16:58:33 -0800 Subject: [PATCH 1/2] dts: bindings: support 'is-device' binding marker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- dts/binding-template.yaml | 7 +++++++ scripts/dts/edtlib.py | 15 ++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/dts/binding-template.yaml b/dts/binding-template.yaml index aad638239c9d3..66575dedc8e24 100644 --- a/dts/binding-template.yaml +++ b/dts/binding-template.yaml @@ -7,6 +7,13 @@ description: | # Used to map nodes to bindings 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 +# hierarchy. +# +# (This is used to track dependencies between such devices.) +is-device: true + # The 'compatible' above would match this node: # # device { diff --git a/scripts/dts/edtlib.py b/scripts/dts/edtlib.py index 24ff5ff77dee9..828369c74db99 100644 --- a/scripts/dts/edtlib.py +++ b/scripts/dts/edtlib.py @@ -484,9 +484,9 @@ def _check_binding(self, binding, binding_path): _err("malformed or empty '{}' in {}" .format(prop, binding_path)) - ok_top = {"title", "description", "compatible", "properties", "#cells", - "bus", "on-bus", "parent-bus", "child-bus", "parent", "child", - "child-binding", "sub-node"} + ok_top = {"title", "description", "compatible", "is-device", + "properties", "#cells", "bus", "on-bus", "parent-bus", + "child-bus", "parent", "child", "child-binding", "sub-node"} for prop in binding: if prop not in ok_top and not prop.endswith("-cells"): @@ -645,6 +645,10 @@ class Node: name: The name of the node + is_device: + True if the node's binding signals that it corresponds to a Zephyr + device model struct device. False otherwise. + unit_addr: An integer with the ...@ portion of the node name, translated through any 'ranges' properties on parent nodes, or None if @@ -755,6 +759,11 @@ def name(self): "See the class docstring" return self._node.name + @property + def is_device(self): + "See the class docstring" + return self._binding and self._binding.get('is-device', False) + @property def unit_addr(self): "See the class docstring" From b345d6976132cf984352b25fe36a4d2b96c8b55d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 28 Jan 2020 17:00:55 -0800 Subject: [PATCH 2/2] dts: gen_defines: emit dependency ordinal related macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- scripts/dts/gen_defines.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/scripts/dts/gen_defines.py b/scripts/dts/gen_defines.py index eb07229aaf06a..425572165d31c 100755 --- a/scripts/dts/gen_defines.py +++ b/scripts/dts/gen_defines.py @@ -52,6 +52,7 @@ def main(): continue write_node_comment(node) + write_deps(node) write_regs(node) write_irqs(node) write_props(node) @@ -166,6 +167,21 @@ def relativize(path): return path +def write_deps(node): + # Writes dependency ordinal information for the node. + + def dep_ords(nodes): + return [node.dep_ordinal for node in nodes] + + 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])) + 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])) + + def write_regs(node): # Writes address/size output for the registers in the node's 'reg' property