[PATCH 3/9] dtc: dt-check-style: Handle root node in overlays

From: Krzysztof Kozlowski

Date: Sun Jul 26 2026 - 11:50:50 EST


Detection of overriding/extending a root node should be a bit more
complex than comparing node name from regex, because overlays use often
'&{/} {' notation. Check for expected syntax before creating DtsLine
and store it as 'is_root' attribute for further logic.

This fixes false positives for property order for root nodes in overlays.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@xxxxxxxxxxxxxxxx>
---
scripts/dtc/dt-check-style | 14 +++++--
.../dt-style-selftest/bad/dts-property-order.dtso | 49 ++++++++++++++++++++++
.../expected/dts-property-order.dtso.txt | 7 ++++
3 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style
index 96deffc0d8a7..1937c6feb57e 100755
--- a/scripts/dtc/dt-check-style
+++ b/scripts/dtc/dt-check-style
@@ -77,18 +77,19 @@ def is_preprocessor(stripped):


class DtsLine:
- __slots__ = ('lineno', 'raw', 'linetype', 'indent_str', 'stripped',
+ __slots__ = ('lineno', 'raw', 'linetype', 'indent_str', 'stripped', 'is_root',
'prop_name', 'continuations',
'node_name', 'node_addr', 'label', 'ref_name', 'depth',
'closures')

- def __init__(self, lineno, raw, linetype, depth, indent_str, stripped):
+ def __init__(self, lineno, raw, linetype, depth, indent_str, stripped, is_root = False):
self.lineno = lineno # 1-based within the block
self.raw = raw
self.linetype = linetype
self.indent_str = indent_str # leading whitespace as-is
self.depth = depth
self.stripped = stripped
+ self.is_root = is_root
self.prop_name = None
self.continuations = []
self.node_name = None
@@ -228,7 +229,10 @@ def classify_lines(text):
continue

if code.endswith('{'):
- dl = DtsLine(i, raw, LineType.NODE_OPEN, depth, indent_str, code)
+ is_root = False
+ if code == '&{/} {' or code == '/ {':
+ is_root = True
+ dl = DtsLine(i, raw, LineType.NODE_OPEN, depth, indent_str, code, is_root=is_root)
parse_node_header(dl)
out.append(dl)
depth += 1
@@ -550,7 +554,9 @@ def check_child_name_order(ctx):
for c in children:
if c.node_addr is not None:
continue
- if c.node_name in (None, '/'):
+ if c.node_name is None:
+ continue
+ if c.is_root:
continue
if c.ref_name is not None:
continue
diff --git a/scripts/dtc/dt-style-selftest/bad/dts-property-order.dtso b/scripts/dtc/dt-style-selftest/bad/dts-property-order.dtso
new file mode 100644
index 000000000000..81ac2b092b96
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/dts-property-order.dtso
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+/*
+ * Test fixture: Incorrect property order
+ */
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ compatible = "example,test-board", "example,test-soc";
+ model = "DT style selftest";
+ qcom,board-id = <8 0>;
+ chassis-type = "handset";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ reg = <0x0 0x0>;
+ compatible = "arm,cortex-a57";
+ device_type = "cpu";
+ enable-method = "psci";
+ };
+ };
+
+ pmu {
+ compatible = "example,pmu";
+
+ status = "disabled";
+ dma-coherent;
+ };
+
+ soc@0 {
+ ranges = <0 0 0 0xc0000000>;
+ compatible = "simple-bus";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ interrupt-controller@10000 {
+ reg = <0x10000 0x1000>;
+ interrupts = <1 2 3>,
+ <4 5 6>,
+ <7 8 9>;
+ compatible = "example,intc";
+ };
+ };
+};
diff --git a/scripts/dtc/dt-style-selftest/expected/dts-property-order.dtso.txt b/scripts/dtc/dt-style-selftest/expected/dts-property-order.dtso.txt
new file mode 100644
index 000000000000..a78b8c042aa5
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/dts-property-order.dtso.txt
@@ -0,0 +1,7 @@
+# mode=strict
+bad/dts-property-order.dtso:13: [property-order] property 'chassis-type' out of canonical order (should sort before 'qcom,board-id')
+bad/dts-property-order.dtso:21: [property-order] property 'compatible' out of canonical order (should sort before 'reg')
+bad/dts-property-order.dtso:22: [property-order] property 'device_type' out of canonical order (should sort before 'compatible')
+bad/dts-property-order.dtso:31: [property-order] property 'dma-coherent' out of canonical order (should sort before 'status')
+bad/dts-property-order.dtso:36: [property-order] property 'compatible' out of canonical order (should sort before 'ranges')
+bad/dts-property-order.dtso:46: [property-order] property 'compatible' out of canonical order (should sort before 'interrupts')

--
2.53.0