From 0d4dca10b2ac156b598f96b4dadb44ac7001380b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 3 Nov 2020 08:34:04 -0800 Subject: [PATCH] scripts: edtlib: child binding compatibles match parents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: #29758 Commit 7165b77a81f35bd76fbbdc391f8c76f3d64d58a4 ("scripts: edtlib: refactor for first class bindings") introduced a Binding class. Its child_binding instance attribute has a compatible which can be None. Adjust this behavior so the child Binding object has the same compatible as the parent binding which ultimately has a compatible. Without this, sanitycheck's expr_parser is doing some matching on compatibles in child nodes that is producing unexpected results. Signed-off-by: Martí Bolívar --- scripts/dts/edtlib.py | 22 +++++++++++++++++++--- scripts/dts/testedtlib.py | 1 - 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/scripts/dts/edtlib.py b/scripts/dts/edtlib.py index ce461bef28e..89dccca34bc 100644 --- a/scripts/dts/edtlib.py +++ b/scripts/dts/edtlib.py @@ -1390,9 +1390,10 @@ class Binding: The free-form description of the binding. compatible: - The compatible string the binding matches. This may be None if the - Binding object is a child binding or if it's inferred from node - properties. + The compatible string the binding matches. This is None if the Binding is + inferred from node properties. If the Binding is a child binding, then + this will be inherited from the parent binding unless the child binding + explicitly sets its own compatible. prop2specs: A collections.OrderedDict mapping property names to PropertySpec objects @@ -1508,6 +1509,14 @@ class Binding: if key.endswith("-cells"): self.specifier2cells[key[:-len("-cells")]] = val + # Make child binding compatibles match ours if they are missing. + if self.compatible is not None: + child = self.child_binding + while child is not None: + if child.compatible is None: + child.compatible = self.compatible + child = child.child_binding + # Drop the reference to the open warn file. This is necessary # to make this object pickleable, but also allows it to get # garbage collected and closed if nobody else is using it. @@ -1528,8 +1537,15 @@ class Binding: @property def compatible(self): "See the class docstring" + if hasattr(self, '_compatible'): + return self._compatible return self.raw.get('compatible') + @compatible.setter + def compatible(self, compatible): + "See the class docstring" + self._compatible = compatible + @property def bus(self): "See the class docstring" diff --git a/scripts/dts/testedtlib.py b/scripts/dts/testedtlib.py index 8fc6d244f92..1f901ea3370 100644 --- a/scripts/dts/testedtlib.py +++ b/scripts/dts/testedtlib.py @@ -137,7 +137,6 @@ def test_bus(): assert str(edt.get_node("/buses/foo-bus/node/nested").binding_path) == \ hpath("test-bindings/device-on-foo-bus.yaml") -@pytest.mark.xfail def test_child_binding(): '''Test 'child-binding:' in bindings''' edt = edtlib.EDT("test.dts", ["test-bindings"])