:p
atchew
Login
Changes in v4: 1. Drop patch: "dtc: dt-check-style: Do not sort top-level nodes in DTS by unit address" This needs more work. 2. Patch #1: Rename rule tab-in-dts to tab-in-yaml 3. Drop "memory@a0000000" in examples, because it messes with top-level sorting. Use a "cpus" node to test node and device_type property ordering. 4. Add more test-cases: within existing commits and a new patch at the end: "dtc: dt-check-style: Add more DTS test cases" 5. Handle #include and /include/ without trailing space Link to v3: https://patch.msgid.link/20260706-dts-style-checker-v3-0-03ffacff9226@oss.qualcomm.com Changes in v3: 1. Patch #2: Use re.search 2. Patch #2: Add dts-mixed-indent.dts test case 3. Several new patches 3-7. v2: https://lore.kernel.org/r/20260706102421.343639-4-krzysztof.kozlowski@oss.qualcomm.com/ Changes in v2: 1. Patch #2: Rework idea. 2. Adjust function doc/comment. v1: https://lore.kernel.org/r/20260706071446.87669-2-krzysztof.kozlowski@oss.qualcomm.com/ (I was not using b4 for v1 and v2, so b4 diff might fail) Best regards, Krzysztof --- Krzysztof Kozlowski (7): dtc: dt-check-style: Narrow disallowing of tab in DTS only to YAML dtc: dt-check-style: Allow space-aligning indentation in DTS dtc: dt-check-style: Rework handling YAML/DTS in rules dtc: dt-check-style: Expect first device_type dtc: dt-check-style: Handle properly DTC-style includes dtc: dt-check-style: Print proper line number of indentation detection place dtc: dt-check-style: Add more DTS test cases .../devicetree/bindings/dts-coding-style.rst | 15 +-- scripts/dtc/dt-check-style | 104 ++++++++++++--------- .../dt-style-selftest/bad/dts-child-name-order.dts | 30 ++++++ .../bad/dts-extend-node-child-name-order.dts | 23 +++++ .../bad/dts-extend-node-digit-node-order.dts | 31 ++++++ .../dtc/dt-style-selftest/bad/dts-mixed-indent.dts | 20 ++++ .../dt-style-selftest/bad/dts-property-order.dts | 43 +++++++++ .../bad/yaml-prop-order-device-type.yaml | 31 ++++++ .../expected/dts-child-name-order.dts.txt | 2 + .../dts-extend-node-child-name-order.dts.txt | 2 + .../dts-extend-node-digit-node-order.dts.txt | 2 + .../expected/dts-mixed-indent.dts.txt | 8 ++ .../expected/dts-property-order.dts.txt | 6 ++ .../dt-style-selftest/expected/dts-spaces.dts.txt | 2 +- .../expected/yaml-indent-strict.yaml.txt | 2 +- .../expected/yaml-mixed-indent.yaml.txt | 3 +- .../expected/yaml-prop-order-device-type.yaml.txt | 2 + .../dt-style-selftest/expected/yaml-tab.yaml.txt | 2 +- .../good/dts-child-name-order.dts | 30 ++++++ .../good/dts-digit-node-order.dts | 41 ++++++++ scripts/dtc/dt-style-selftest/good/dts-dtc.dts | 21 +++++ .../good/dts-extend-node-child-name-order.dts | 23 +++++ .../good/dts-extend-node-digit-node-order.dts | 31 ++++++ .../dt-style-selftest/good/dts-preprocessor.dts | 21 +++++ .../dt-style-selftest/good/dts-property-order.dts | 41 ++++++++ scripts/dtc/dt-style-selftest/good/soc.dtsi | 47 ++++++++++ 26 files changed, 526 insertions(+), 57 deletions(-) --- base-commit: 37de3f626a5094b9f3af93bf4c93a6130f8a8b6d change-id: 20260706-dts-style-checker-750a187f41d7 Best regards, -- Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
DTS in the bindings (example in a YAML file) does not have tabs at all, but regular DTS do, therefore entire check check_tab_in_dts() has confusing name and should apply only to YAML files. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v2: 1. New patch --- scripts/dtc/dt-check-style | 8 ++++---- scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt | 2 +- scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ def check_trailing_whitespace(ctx): yield (dl.lineno, 'trailing whitespace') -def check_tab_in_dts(ctx): +def check_tab_in_yaml_example(ctx): """Reject literal tabs in DTS lines when input is YAML. For YAML examples, indent and content must use spaces. Tabs inside @@ -XXX,XX +XXX,XX @@ RULES = [ Rule('trailing-whitespace', 'relaxed', 'no trailing whitespace on any line', check_trailing_whitespace), - Rule('tab-in-dts', 'relaxed', - 'YAML examples may not contain tab characters', - check_tab_in_dts, applies_to=('yaml',)), + Rule('tab-in-yaml', 'relaxed', + 'YAML (also DTS examples) may not contain tab characters', + check_tab_in_yaml_example, applies_to=('yaml',)), Rule('mixed-indent-chars', 'relaxed', 'indent must not mix tabs and spaces', check_mixed_indent_chars), diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt index XXXXXXX..XXXXXXX 100644 --- a/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt +++ b/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt @@ -XXX,XX +XXX,XX @@ # mode=relaxed bad/yaml-mixed-indent.yaml:27: example 0 [mixed-indent-chars] mixed tabs and spaces in indent -bad/yaml-mixed-indent.yaml:27: example 0 [tab-in-dts] tab character not allowed in DTS example +bad/yaml-mixed-indent.yaml:27: example 0 [tab-in-yaml] tab character not allowed in DTS example diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt index XXXXXXX..XXXXXXX 100644 --- a/scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt +++ b/scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt @@ -XXX,XX +XXX,XX @@ # mode=relaxed -bad/yaml-tab.yaml:28: example 0 [tab-in-dts] tab character not allowed in DTS example +bad/yaml-tab.yaml:28: example 0 [tab-in-yaml] tab character not allowed in DTS example -- 2.53.0
DTS often have spaces after tabs in indentation for aligning continued lines of comments or list properties, thus allow such cases to avoid many false positives. What we can easily detect is a space followed by tab or too many spaces (more than alignment). OTOH, DTS example in YAML files does not have tabs at all and there is already rule for that, thus there is no point to check for mixed indentation there. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v3: 1. Use re.search 2. Add dts-mixed-indent.dts test case v2: https://lore.kernel.org/r/20260706102421.343639-4-krzysztof.kozlowski@oss.qualcomm.com/ Changes in v2: 1. Rework idea. 2. Adjust function doc/comment. v1: https://lore.kernel.org/r/20260706071446.87669-2-krzysztof.kozlowski@oss.qualcomm.com/ --- scripts/dtc/dt-check-style | 9 ++++++--- .../dtc/dt-style-selftest/bad/dts-mixed-indent.dts | 20 ++++++++++++++++++++ .../expected/dts-mixed-indent.dts.txt | 8 ++++++++ .../expected/yaml-mixed-indent.yaml.txt | 1 - 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ def check_tab_in_yaml_example(ctx): def check_mixed_indent_chars(ctx): - """Indent must be all-spaces or all-tabs, never mixed on one line.""" + """Indent must be all-tabs, except for aligning indentation (comments + or continued lines).""" for dl in ctx.lines: if not dl.indent_str: continue if dl.linetype == LineType.PREPROCESSOR: continue - if ' ' in dl.indent_str and '\t' in dl.indent_str: + if re.search(r' \t', dl.indent_str): yield (dl.lineno, 'mixed tabs and spaces in indent') + if dl.indent_str.count(' ') > 7: + yield (dl.lineno, 'too many space characters in indent (more than 7)') def detect_indent_unit(ctx): @@ -XXX,XX +XXX,XX @@ RULES = [ check_tab_in_yaml_example, applies_to=('yaml',)), Rule('mixed-indent-chars', 'relaxed', 'indent must not mix tabs and spaces', - check_mixed_indent_chars), + check_mixed_indent_chars, applies_to=('dts', 'dtsi', 'dtso')), Rule('unclosed-block-comment', 'relaxed', 'every /* block comment must close with */', check_unclosed_block_comment), diff --git a/scripts/dtc/dt-style-selftest/bad/dts-mixed-indent.dts b/scripts/dtc/dt-style-selftest/bad/dts-mixed-indent.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/dts-mixed-indent.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* Test fixture: a .dts using wrong indent. */ + +/dts-v1/; + +/ { + compatible = "example,test-board"; + #address-cells = <1>; + #size-cells = <1>; + + soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + clocks = <1>, + <2>, + <3>; + resets = <5>; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/expected/dts-mixed-indent.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-mixed-indent.dts.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/dts-mixed-indent.dts.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/dts-mixed-indent.dts:11: [indent-consistent] indent mismatch (expected depth 1 * '\t') +bad/dts-mixed-indent.dts:11: [mixed-indent-chars] too many space characters in indent (more than 7) +bad/dts-mixed-indent.dts:12: [indent-consistent] indent mismatch (expected depth 2 * '\t') +bad/dts-mixed-indent.dts:12: [mixed-indent-chars] mixed tabs and spaces in indent +bad/dts-mixed-indent.dts:13: [indent-consistent] indent mismatch (expected depth 2 * '\t') +bad/dts-mixed-indent.dts:13: [mixed-indent-chars] mixed tabs and spaces in indent +bad/dts-mixed-indent.dts:18: [indent-consistent] indent mismatch (expected depth 2 * '\t') diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt index XXXXXXX..XXXXXXX 100644 --- a/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt +++ b/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt @@ -XXX,XX +XXX,XX @@ # mode=relaxed -bad/yaml-mixed-indent.yaml:27: example 0 [mixed-indent-chars] mixed tabs and spaces in indent bad/yaml-mixed-indent.yaml:27: example 0 [tab-in-yaml] tab character not allowed in DTS example -- 2.53.0
Individual rules behave differently depending whether they handle bindings (YAML) or DTS, but the code was focusing on type of indentation (spaces vs tabs). That indentation is actually irrelevant in some rules, so differentiate based on file type. This will be more relevant in the future when more rules act differently on DTS, than on bindings. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v3: New patch --- scripts/dtc/dt-check-style | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ def collect_labels_and_refs(text): class Ctx: """Context passed to each rule check. Carries the parsed lines, - raw text, mode, and indent kind.""" + raw text, mode and kind.""" - def __init__(self, lines, text, mode, indent_kind): + def __init__(self, lines, text, mode, kind): self.lines = lines self.text = text self.mode = mode # 'relaxed' or 'strict' - self.indent_kind = indent_kind # 'spaces' or 'tab' + if kind in DTS_FAMILY: + self.file_type = 'dts' + else: + self.file_type = 'yaml' class Rule: @@ -XXX,XX +XXX,XX @@ def check_tab_in_yaml_example(ctx): a #define value are tolerated (those are CPP macros, not DTS). For .dts files, this rule does not apply -- tabs are required. """ - if ctx.indent_kind != 'spaces': + if ctx.file_type != 'yaml': return for dl in ctx.lines: if dl.linetype == LineType.PREPROCESSOR: @@ -XXX,XX +XXX,XX @@ def check_indent_unit_strict(ctx): unit = detect_indent_unit(ctx) if unit is None: return - if ctx.indent_kind == 'spaces': + if ctx.file_type == 'yaml': if unit != ' ': yield (1, 'indent unit must be 4 spaces in strict mode, ' 'got %r' % unit) @@ -XXX,XX +XXX,XX @@ def check_indent_consistent(ctx): unit = detect_indent_unit(ctx) if unit is None: return - if ctx.indent_kind == 'spaces': + if ctx.file_type == 'yaml': if unit not in (' ', ' '): return # let check_indent_unit_* report this else: @@ -XXX,XX +XXX,XX @@ def select_rules(mode, input_kind): # Block runner # --------------------------------------------------------------------------- -def check_block(text, mode, indent_kind, input_type): +def check_block(text, mode, input_type): """Run all selected rules on a single block of DTS text. Returns a list of (lineno, rule_name, message) tuples.""" lines = classify_lines(text) - ctx = Ctx(lines, text, mode, indent_kind) + ctx = Ctx(lines, text, mode, input_type) rules = select_rules(mode, input_type) findings = [] for r in rules: @@ -XXX,XX +XXX,XX @@ def collect_findings(filepath, mode): formatted output strings; count is the number of findings.""" kind = input_kind(filepath) if kind == 'yaml': - indent_kind = 'spaces' iterator = iter_yaml_examples(filepath) elif kind in DTS_FAMILY: - indent_kind = 'tab' iterator = iter_dts_file(filepath) else: return (['%s: unknown file type, skipping' % filepath], 0) out = [] for text, base, idx in iterator: - for lineno, rule, msg in check_block(text, mode, indent_kind, kind): + for lineno, rule, msg in check_block(text, mode, kind): abs_line = base + lineno - 1 ex_tag = '' if idx is None else ' example %d' % idx out.append('%s:%d:%s [%s] %s' % -- 2.53.0
A few nodes do have "device_type" property which is mostly, but not always, the first property in a device node, when applicable. Adjust the DTS coding style rules to actually expect the device_type first and improve the dt-check-style to handle this correctly. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v3: New patch --- .../devicetree/bindings/dts-coding-style.rst | 15 ++++---- scripts/dtc/dt-check-style | 29 ++++++++------- .../dt-style-selftest/bad/dts-property-order.dts | 43 ++++++++++++++++++++++ .../bad/yaml-prop-order-device-type.yaml | 31 ++++++++++++++++ .../expected/dts-property-order.dts.txt | 6 +++ .../expected/yaml-prop-order-device-type.yaml.txt | 2 + .../dt-style-selftest/good/dts-property-order.dts | 41 +++++++++++++++++++++ 7 files changed, 147 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/dts-coding-style.rst b/Documentation/devicetree/bindings/dts-coding-style.rst index XXXXXXX..XXXXXXX 100644 --- a/Documentation/devicetree/bindings/dts-coding-style.rst +++ b/Documentation/devicetree/bindings/dts-coding-style.rst @@ -XXX,XX +XXX,XX @@ Order of Properties in Device Node The following order of properties in device nodes is preferred: -1. "compatible" -2. "reg" -3. "ranges" -4. Standard/common properties (defined by common bindings, e.g. without +1. "device_type" (if applicable) +2. "compatible" +3. "reg" +4. "ranges" +5. Standard/common properties (defined by common bindings, e.g. without vendor-prefixes) -5. Vendor-specific properties -6. "status" (if applicable), preceded by a blank line if there is content +6. Vendor-specific properties +7. "status" (if applicable), preceded by a blank line if there is content before the property -7. Child nodes, where each node is preceded with a blank line +8. Child nodes, where each node is preceded with a blank line The "status" property is by default "okay", thus it can be omitted. diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ def check_child_name_order(ctx): def _property_bucket(name): """Return the canonical bucket index for a property: - 0 compatible - 1 reg / reg-names - 2 ranges - 3 standard properties (no vendor comma in #-stripped name) - 4 vendor-specific properties - 5 status + 0 device_type + 1 compatible + 2 reg / reg-names + 3 ranges + 4 standard properties (no vendor comma in #-stripped name) + 5 vendor-specific properties + 6 status Plus a sub-key inside the bucket for fixed slots (compatible, reg, reg-names, ranges, status). 'standard' and 'vendor' return None for the sub-key, signalling that the within-bucket key is computed by the pairing rules.""" stripped = name.lstrip('#') - if name == 'compatible': + if name == 'device_type': return (0, 0) - if name == 'reg': + if name == 'compatible': return (1, 0) - if name == 'reg-names': - return (1, 1) - if name == 'ranges': + if name == 'reg': return (2, 0) + if name == 'reg-names': + return (2, 1) + if name == 'ranges': + return (3, 0) if name == 'status': - return (5, 0) - return (4 if ',' in stripped else 3, None) + return (6, 0) + return (5 if ',' in stripped else 4, None) # Declarative pairing rules: each is a callable diff --git a/scripts/dtc/dt-style-selftest/bad/dts-property-order.dts b/scripts/dtc/dt-style-selftest/bad/dts-property-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/dts-property-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* + * Test fixture: Incorrect property order + */ + +/dts-v1/; + +/ { + 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/bad/yaml-prop-order-device-type.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-prop-order-device-type.yaml new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/yaml-prop-order-device-type.yaml @@ -XXX,XX +XXX,XX @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/test-bad-prop-order.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Test fixture with device_type + +maintainers: + - Test User <test@example.com> + +properties: + compatible: + const: example,test-prop-order-device-type + reg: + maxItems: 1 + device_type: true + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + device@1000 { + compatible = "example,test-prop-order"; + device_type = "cpu"; + reg = <0x1000 0x100>; + }; diff --git a/scripts/dtc/dt-style-selftest/expected/dts-property-order.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-property-order.dts.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/dts-property-order.dts.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/dts-property-order.dts:15: [property-order] property 'compatible' out of canonical order (should sort before 'reg') +bad/dts-property-order.dts:16: [property-order] property 'device_type' out of canonical order (should sort before 'compatible') +bad/dts-property-order.dts:25: [property-order] property 'dma-coherent' out of canonical order (should sort before 'status') +bad/dts-property-order.dts:30: [property-order] property 'compatible' out of canonical order (should sort before 'ranges') +bad/dts-property-order.dts:40: [property-order] property 'compatible' out of canonical order (should sort before 'interrupts') diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-prop-order-device-type.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-prop-order-device-type.yaml.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/yaml-prop-order-device-type.yaml.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/yaml-prop-order-device-type.yaml:29: example 0 [property-order] property 'device_type' out of canonical order (should sort before 'compatible') diff --git a/scripts/dtc/dt-style-selftest/good/dts-property-order.dts b/scripts/dtc/dt-style-selftest/good/dts-property-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-property-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* + * Test fixture: Incorrect property order + */ + +/dts-v1/; + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + }; + + pmu { + compatible = "example,pmu"; + dma-coherent; + + status = "disabled"; + }; + + soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-controller@10000 { + compatible = "example,intc"; + reg = <0x10000 0x1000>; + interrupts = <1 2 3>; + }; + }; +}; -- 2.53.0
dt-check-style was not properly handling DTC directives (starting with '/', e.g. /dts-v1/ or /include/), thus a few DTS files had false positive like: apm/apm-merlin.dts:1: [indent-unit-dts] indent unit must be 1 tab in DTS, got '\t\t' Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v3: New patch --- scripts/dtc/dt-check-style | 11 ++++- scripts/dtc/dt-style-selftest/good/dts-dtc.dts | 21 ++++++++++ .../dt-style-selftest/good/dts-preprocessor.dts | 21 ++++++++++ scripts/dtc/dt-style-selftest/good/soc.dtsi | 47 ++++++++++++++++++++++ 4 files changed, 98 insertions(+), 2 deletions(-) diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ re_cpp_directive = re.compile( r'^#\s*(include|define|undef|ifdef|ifndef|if|else|elif|endif|' r'pragma|error|warning)\b') +re_dtc_directive = re.compile( + r'^/(dts-v1|include)/') + # label: name@addr { -- label and addr optional; name can be "/" # Per the DT spec a node name may start with a digit (e.g. 1wire@...). # The address part is captured loosely (any non-space, non-brace run) so @@ -XXX,XX +XXX,XX @@ re_ref_node = re.compile( def is_preprocessor(stripped): """Tell C preprocessor directives apart from DTS '#'-prefixed props.""" - return re_cpp_directive.match(stripped) is not None + if re_cpp_directive.match(stripped) is not None: + return True + if re_dtc_directive.match(stripped) is not None: + return True + return False class DtsLine: @@ -XXX,XX +XXX,XX @@ def classify_lines(text): out.append(dl) continue - if stripped.startswith('#') and is_preprocessor(stripped): + if (stripped.startswith('#') or stripped.startswith('/')) and is_preprocessor(stripped): dl = DtsLine(i, raw, LineType.PREPROCESSOR, indent_str, stripped) dl.depth = depth diff --git a/scripts/dtc/dt-style-selftest/good/dts-dtc.dts b/scripts/dtc/dt-style-selftest/good/dts-dtc.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-dtc.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* + * Test fixture: dtc directive + */ + +/dts-v1/; + +/include/ "soc.dtsi" +/include/"soc-other.dtsi" + +/ { + compatible = "example,test-board"; + #address-cells = <1>; + #size-cells = <1>; + + leds { + led-0 { + compatible = "example,led"; + }; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/good/dts-preprocessor.dts b/scripts/dtc/dt-style-selftest/good/dts-preprocessor.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-preprocessor.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* + * Test fixture: preprocessor directive + */ + +/dts-v1/; + +#include "soc.dtsi" +#include<dt-bindings/gpio/gpio.h> + +/ { + compatible = "example,test-board"; + #address-cells = <1>; + #size-cells = <1>; + + leds { + led-0 { + compatible = "example,led"; + }; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/good/soc.dtsi b/scripts/dtc/dt-style-selftest/good/soc.dtsi new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/soc.dtsi @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + }; + + pmu { + compatible = "example,pmu"; + }; + + soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-controller@10000 { + compatible = "example,intc"; + reg = <0x10000 0x1000>; + interrupts = <1 2 3>, + <4 5 6>, + <7 8 9>; + }; + + serial@20000 { + compatible = "example,serial"; + reg = <0x20000 0x1000>; + }; + + serial@30000 { + compatible = "example,serial"; + reg = <0x30000 0x1000>; + }; + }; +}; -- 2.53.0
Script judges the indentation however always suggests it is the first line which is wrong, e.g.: sigmastar/mstar-infinity2m.dtsi:1: [indent-unit-dts] indent unit must be 1 tab in DTS, got '\t\t' Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- scripts/dtc/dt-check-style | 24 +++++++++++----------- .../dt-style-selftest/expected/dts-spaces.dts.txt | 2 +- .../expected/yaml-indent-strict.yaml.txt | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ def detect_indent_unit(ctx): if not dl.indent_str: continue if dl.indent_str == '\t': - return '\t' + return ('\t', dl.lineno) if dl.indent_str == ' ': - return ' ' + return (' ', dl.lineno) if dl.indent_str == ' ': - return ' ' + return (' ', dl.lineno) # Anything else at depth 1 is non-canonical; flag elsewhere. - return dl.indent_str - return None + return (dl.indent_str, dl.lineno) + return (None, None) def check_indent_unit_relaxed(ctx): """YAML examples: 2 or 4 spaces. Never tabs or other widths.""" - unit = detect_indent_unit(ctx) + (unit, lineno) = detect_indent_unit(ctx) if unit is None: return if unit not in (' ', ' '): - yield (1, 'indent unit must be 2 or 4 spaces, got %r' % unit) + yield (lineno, 'indent unit must be 2 or 4 spaces, got %r' % unit) def check_indent_unit_dts(ctx): """DTS files: 1 tab per level. Always required.""" - unit = detect_indent_unit(ctx) + (unit, lineno) = detect_indent_unit(ctx) if unit is None: return if unit != '\t': - yield (1, 'indent unit must be 1 tab in DTS, got %r' % unit) + yield (lineno, 'indent unit must be 1 tab in DTS, got %r' % unit) def check_indent_unit_strict(ctx): """YAML: must be exactly 4 spaces. DTS: 1 tab (same as relaxed).""" - unit = detect_indent_unit(ctx) + (unit, lineno) = detect_indent_unit(ctx) if unit is None: return if ctx.file_type == 'yaml': if unit != ' ': - yield (1, 'indent unit must be 4 spaces in strict mode, ' + yield (lineno, 'indent unit must be 4 spaces in strict mode, ' 'got %r' % unit) def check_indent_consistent(ctx): """All indented lines must be a multiple of the detected unit.""" - unit = detect_indent_unit(ctx) + (unit, lineno) = detect_indent_unit(ctx) if unit is None: return if ctx.file_type == 'yaml': diff --git a/scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt index XXXXXXX..XXXXXXX 100644 --- a/scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt +++ b/scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt @@ -XXX,XX +XXX,XX @@ # mode=relaxed -bad/dts-spaces.dts:1: [indent-unit-dts] indent unit must be 1 tab in DTS, got ' ' +bad/dts-spaces.dts:9: [indent-unit-dts] indent unit must be 1 tab in DTS, got ' ' diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-indent-strict.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-indent-strict.yaml.txt index XXXXXXX..XXXXXXX 100644 --- a/scripts/dtc/dt-style-selftest/expected/yaml-indent-strict.yaml.txt +++ b/scripts/dtc/dt-style-selftest/expected/yaml-indent-strict.yaml.txt @@ -XXX,XX +XXX,XX @@ # mode=strict -bad/yaml-indent-strict.yaml:26: example 0 [indent-unit-strict] indent unit must be 4 spaces in strict mode, got ' ' +bad/yaml-indent-strict.yaml:27: example 0 [indent-unit-strict] indent unit must be 4 spaces in strict mode, got ' ' -- 2.53.0
Add a few more test cases for valid and incorrect DTS for dt-check-style. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v4: 1. New patch --- .../dt-style-selftest/bad/dts-child-name-order.dts | 30 ++++++++++++++++ .../bad/dts-extend-node-child-name-order.dts | 23 ++++++++++++ .../bad/dts-extend-node-digit-node-order.dts | 31 ++++++++++++++++ .../expected/dts-child-name-order.dts.txt | 2 ++ .../dts-extend-node-child-name-order.dts.txt | 2 ++ .../dts-extend-node-digit-node-order.dts.txt | 2 ++ .../good/dts-child-name-order.dts | 30 ++++++++++++++++ .../good/dts-digit-node-order.dts | 41 ++++++++++++++++++++++ .../good/dts-extend-node-child-name-order.dts | 23 ++++++++++++ .../good/dts-extend-node-digit-node-order.dts | 31 ++++++++++++++++ 10 files changed, 215 insertions(+) diff --git a/scripts/dtc/dt-style-selftest/bad/dts-child-name-order.dts b/scripts/dtc/dt-style-selftest/bad/dts-child-name-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/dts-child-name-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + pmu { + compatible = "example,pmu"; + + /* Include labels to be sure they do not affect sorting */ + foo: foo { + label = "foo"; + }; + + label_bar: bar { + label = "bar"; + }; + }; + + memory@a0000000 { + device_type = "memory"; + reg = <0x0 0xa0000000 0x0 0x0>; + }; + + pmu-2 { + compatible = "example,pmu"; + + /* Just reference labels to avoid strict warnings */ + example,foo = <&foo>, <&label_bar>; + } +}; diff --git a/scripts/dtc/dt-style-selftest/bad/dts-extend-node-child-name-order.dts b/scripts/dtc/dt-style-selftest/bad/dts-extend-node-child-name-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/dts-extend-node-child-name-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + pmu { + compatible = "example,pmu"; + + /* Just reference labels to avoid strict warnings */ + example,foo = <&foo>, <&label_bar>; + } +}; + +&pmu { + /* Include labels to be sure they do not affect sorting */ + foo: foo { + label = "foo"; + }; + + label_bar: bar { + label = "bar"; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/bad/dts-extend-node-digit-node-order.dts b/scripts/dtc/dt-style-selftest/bad/dts-extend-node-digit-node-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/dts-extend-node-digit-node-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + soc: soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + #address-cells = <1>; + #size-cells = <1>; + }; +}; + +&soc { + serial@20000 { + compatible = "example,serial"; + reg = <0x20000 0x1000>; + }; + + interrupt-controller@10000 { + compatible = "example,intc"; + reg = <0x10000 0x1000>; + interrupts = <1 2 3>; + }; + + serial@30000 { + compatible = "example,serial"; + reg = <0x30000 0x1000>; + }; +} diff --git a/scripts/dtc/dt-style-selftest/expected/dts-child-name-order.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-child-name-order.dts.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/dts-child-name-order.dts.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/dts-child-name-order.dts:14: [child-name-order] child node 'bar' out of name order diff --git a/scripts/dtc/dt-style-selftest/expected/dts-extend-node-child-name-order.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-extend-node-child-name-order.dts.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/dts-extend-node-child-name-order.dts.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/dts-extend-node-child-name-order.dts:20: [child-name-order] child node 'bar' out of name order diff --git a/scripts/dtc/dt-style-selftest/expected/dts-extend-node-digit-node-order.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-extend-node-digit-node-order.dts.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/dts-extend-node-digit-node-order.dts.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/dts-extend-node-digit-node-order.dts:21: [child-address-order] child node @10000 out of address order diff --git a/scripts/dtc/dt-style-selftest/good/dts-child-name-order.dts b/scripts/dtc/dt-style-selftest/good/dts-child-name-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-child-name-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + memory@a0000000 { + device_type = "memory"; + reg = <0x0 0xa0000000 0x0 0x0>; + }; + + pmu { + compatible = "example,pmu"; + + /* Include labels to be sure they do not affect sorting */ + label_bar: bar { + label = "bar"; + }; + + foo: foo { + label = "foo"; + }; + }; + + pmu-2 { + compatible = "example,pmu"; + + /* Just reference labels to avoid strict warnings */ + example,foo = <&foo>, <&label_bar>; + } +}; diff --git a/scripts/dtc/dt-style-selftest/good/dts-digit-node-order.dts b/scripts/dtc/dt-style-selftest/good/dts-digit-node-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-digit-node-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + /* TODO: uncomment when child-address-order is fixed for top-level */ + /* + memory@a0000000 { + device_type = "memory"; + reg = <0x0 0xa0000000 0x0 0x0>; + }; + */ + + pmu { + compatible = "example,pmu"; + }; + + soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-controller@10000 { + compatible = "example,intc"; + reg = <0x10000 0x1000>; + interrupts = <1 2 3>; + }; + + serial@20000 { + compatible = "example,serial"; + reg = <0x20000 0x1000>; + }; + + serial@30000 { + compatible = "example,serial"; + reg = <0x30000 0x1000>; + }; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/good/dts-extend-node-child-name-order.dts b/scripts/dtc/dt-style-selftest/good/dts-extend-node-child-name-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-extend-node-child-name-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + pmu { + compatible = "example,pmu"; + + /* Just reference labels to avoid strict warnings */ + example,foo = <&foo>, <&label_bar>; + } +}; + +&pmu { + /* Include labels to be sure they do not affect sorting */ + label_bar: bar { + label = "bar"; + }; + + foo: foo { + label = "foo"; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/good/dts-extend-node-digit-node-order.dts b/scripts/dtc/dt-style-selftest/good/dts-extend-node-digit-node-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-extend-node-digit-node-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + soc: soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + #address-cells = <1>; + #size-cells = <1>; + }; +}; + +&soc { + interrupt-controller@10000 { + compatible = "example,intc"; + reg = <0x10000 0x1000>; + interrupts = <1 2 3>; + }; + + serial@20000 { + compatible = "example,serial"; + reg = <0x20000 0x1000>; + }; + + serial@30000 { + compatible = "example,serial"; + reg = <0x30000 0x1000>; + }; +} -- 2.53.0
Changes in v5: 1. Patch #2, dtc: dt-check-style: Allow space-aligning indentation in DTS: Handle also line continuations for properties. 2. Update docs, other minor style/docs comments from Sashiko - Link to v4: https://patch.msgid.link/20260708-dts-style-checker-v4-0-c175e6401150@oss.qualcomm.com Changes in v4: 1. Drop patch: "dtc: dt-check-style: Do not sort top-level nodes in DTS by unit address" This needs more work. 2. Patch #1: Rename rule tab-in-dts to tab-in-yaml 3. Drop "memory@a0000000" in examples, because it messes with top-level sorting. Use a "cpus" node to test node and device_type property ordering. 4. Add more test-cases: within existing commits and a new patch at the end: "dtc: dt-check-style: Add more DTS test cases" 5. Handle #include and /include/ without trailing space Link to v3: https://patch.msgid.link/20260706-dts-style-checker-v3-0-03ffacff9226@oss.qualcomm.com Changes in v3: 1. Patch #2: Use re.search 2. Patch #2: Add dts-mixed-indent.dts test case 3. Several new patches 3-7. v2: https://lore.kernel.org/r/20260706102421.343639-4-krzysztof.kozlowski@oss.qualcomm.com/ Changes in v2: 1. Patch #2: Rework idea. 2. Adjust function doc/comment. v1: https://lore.kernel.org/r/20260706071446.87669-2-krzysztof.kozlowski@oss.qualcomm.com/ (I was not using b4 for v1 and v2, so b4 diff might fail) Best regards, Krzysztof --- Krzysztof Kozlowski (7): dtc: dt-check-style: Narrow disallowing of tab in DTS only to YAML dtc: dt-check-style: Allow space-aligning indentation in DTS dtc: dt-check-style: Rework handling YAML/DTS in rules dtc: dt-check-style: Expect first device_type dtc: dt-check-style: Handle properly DTC-style includes dtc: dt-check-style: Print proper line number of indentation detection place dtc: dt-check-style: Add more DTS test cases .../devicetree/bindings/dts-coding-style.rst | 15 +-- scripts/dtc/dt-check-style | 120 ++++++++++++--------- .../dt-style-selftest/bad/dts-child-name-order.dts | 30 ++++++ .../bad/dts-extend-node-child-name-order.dts | 23 ++++ .../bad/dts-extend-node-digit-node-order.dts | 31 ++++++ .../dtc/dt-style-selftest/bad/dts-mixed-indent.dts | 21 ++++ .../dt-style-selftest/bad/dts-property-order.dts | 43 ++++++++ .../bad/yaml-prop-order-device-type.yaml | 31 ++++++ .../expected/dts-child-name-order.dts.txt | 2 + .../dts-extend-node-child-name-order.dts.txt | 2 + .../dts-extend-node-digit-node-order.dts.txt | 2 + .../expected/dts-mixed-indent.dts.txt | 9 ++ .../expected/dts-property-order.dts.txt | 6 ++ .../dt-style-selftest/expected/dts-spaces.dts.txt | 2 +- .../expected/yaml-indent-strict.yaml.txt | 2 +- .../expected/yaml-mixed-indent.yaml.txt | 3 +- .../expected/yaml-prop-order-device-type.yaml.txt | 2 + .../dt-style-selftest/expected/yaml-tab.yaml.txt | 2 +- .../good/dts-child-name-order.dts | 30 ++++++ .../good/dts-digit-node-order.dts | 41 +++++++ scripts/dtc/dt-style-selftest/good/dts-dtc.dts | 21 ++++ .../good/dts-extend-node-child-name-order.dts | 23 ++++ .../good/dts-extend-node-digit-node-order.dts | 31 ++++++ .../dt-style-selftest/good/dts-preprocessor.dts | 21 ++++ .../dt-style-selftest/good/dts-property-order.dts | 41 +++++++ scripts/dtc/dt-style-selftest/good/soc.dtsi | 47 ++++++++ 26 files changed, 540 insertions(+), 61 deletions(-) --- base-commit: 37de3f626a5094b9f3af93bf4c93a6130f8a8b6d change-id: 20260706-dts-style-checker-750a187f41d7 Best regards, -- Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
DTS in the bindings (example in a YAML file) does not have tabs at all, but regular DTS do, therefore entire check check_tab_in_dts() has confusing name and should apply only to YAML files. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v2: 1. New patch --- scripts/dtc/dt-check-style | 8 ++++---- scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt | 2 +- scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ def check_trailing_whitespace(ctx): yield (dl.lineno, 'trailing whitespace') -def check_tab_in_dts(ctx): +def check_tab_in_yaml_example(ctx): """Reject literal tabs in DTS lines when input is YAML. For YAML examples, indent and content must use spaces. Tabs inside @@ -XXX,XX +XXX,XX @@ RULES = [ Rule('trailing-whitespace', 'relaxed', 'no trailing whitespace on any line', check_trailing_whitespace), - Rule('tab-in-dts', 'relaxed', - 'YAML examples may not contain tab characters', - check_tab_in_dts, applies_to=('yaml',)), + Rule('tab-in-yaml', 'relaxed', + 'YAML (also DTS examples) may not contain tab characters', + check_tab_in_yaml_example, applies_to=('yaml',)), Rule('mixed-indent-chars', 'relaxed', 'indent must not mix tabs and spaces', check_mixed_indent_chars), diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt index XXXXXXX..XXXXXXX 100644 --- a/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt +++ b/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt @@ -XXX,XX +XXX,XX @@ # mode=relaxed bad/yaml-mixed-indent.yaml:27: example 0 [mixed-indent-chars] mixed tabs and spaces in indent -bad/yaml-mixed-indent.yaml:27: example 0 [tab-in-dts] tab character not allowed in DTS example +bad/yaml-mixed-indent.yaml:27: example 0 [tab-in-yaml] tab character not allowed in DTS example diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt index XXXXXXX..XXXXXXX 100644 --- a/scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt +++ b/scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt @@ -XXX,XX +XXX,XX @@ # mode=relaxed -bad/yaml-tab.yaml:28: example 0 [tab-in-dts] tab character not allowed in DTS example +bad/yaml-tab.yaml:28: example 0 [tab-in-yaml] tab character not allowed in DTS example -- 2.53.0
DTS often have spaces after tabs in indentation for aligning continued lines of comments or list properties, thus allow such cases to avoid many false positives. What we can easily detect is a space followed by tab or too many spaces (more than alignment). OTOH, DTS example in YAML files does not have tabs at all and there is already rule for that, thus there is no point to check for mixed indentation there. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v3: 1. Use re.search 2. Add dts-mixed-indent.dts test case v2: https://lore.kernel.org/r/20260706102421.343639-4-krzysztof.kozlowski@oss.qualcomm.com/ Changes in v2: 1. Rework idea. 2. Adjust function doc/comment. v1: https://lore.kernel.org/r/20260706071446.87669-2-krzysztof.kozlowski@oss.qualcomm.com/ --- scripts/dtc/dt-check-style | 16 +++++++++++++--- .../dtc/dt-style-selftest/bad/dts-mixed-indent.dts | 21 +++++++++++++++++++++ .../expected/dts-mixed-indent.dts.txt | 9 +++++++++ .../expected/yaml-mixed-indent.yaml.txt | 1 - 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ def check_tab_in_yaml_example(ctx): def check_mixed_indent_chars(ctx): - """Indent must be all-spaces or all-tabs, never mixed on one line.""" + """Indent must be all-tabs, except for aligning indentation (comments + or continued lines).""" for dl in ctx.lines: if not dl.indent_str: continue if dl.linetype == LineType.PREPROCESSOR: continue - if ' ' in dl.indent_str and '\t' in dl.indent_str: + if re.search(r' \t', dl.indent_str): yield (dl.lineno, 'mixed tabs and spaces in indent') + if dl.indent_str.count(' ') > 7: + yield (dl.lineno, 'too many space characters in indent (more than 7)') + for cont in dl.continuations: + if not cont.indent_str: + continue + if cont.linetype == LineType.PREPROCESSOR: + continue + if re.search(r' \t', cont.indent_str): + yield (cont.lineno, 'mixed tabs and spaces in indent') def detect_indent_unit(ctx): @@ -XXX,XX +XXX,XX @@ RULES = [ check_tab_in_yaml_example, applies_to=('yaml',)), Rule('mixed-indent-chars', 'relaxed', 'indent must not mix tabs and spaces', - check_mixed_indent_chars), + check_mixed_indent_chars, applies_to=('dts', 'dtsi', 'dtso')), Rule('unclosed-block-comment', 'relaxed', 'every /* block comment must close with */', check_unclosed_block_comment), diff --git a/scripts/dtc/dt-style-selftest/bad/dts-mixed-indent.dts b/scripts/dtc/dt-style-selftest/bad/dts-mixed-indent.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/dts-mixed-indent.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* Test fixture: a .dts using wrong indent. */ + +/dts-v1/; + +/ { + compatible = "example,test-board"; + #address-cells = <1>; + #size-cells = <1>; + + soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + clocks = <1>, + <2>, + <3>, + <4>; + resets = <5>; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/expected/dts-mixed-indent.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-mixed-indent.dts.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/dts-mixed-indent.dts.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/dts-mixed-indent.dts:11: [indent-consistent] indent mismatch (expected depth 1 * '\t') +bad/dts-mixed-indent.dts:11: [mixed-indent-chars] too many space characters in indent (more than 7) +bad/dts-mixed-indent.dts:12: [indent-consistent] indent mismatch (expected depth 2 * '\t') +bad/dts-mixed-indent.dts:12: [mixed-indent-chars] mixed tabs and spaces in indent +bad/dts-mixed-indent.dts:13: [indent-consistent] indent mismatch (expected depth 2 * '\t') +bad/dts-mixed-indent.dts:13: [mixed-indent-chars] mixed tabs and spaces in indent +bad/dts-mixed-indent.dts:16: [mixed-indent-chars] mixed tabs and spaces in indent +bad/dts-mixed-indent.dts:19: [indent-consistent] indent mismatch (expected depth 2 * '\t') diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt index XXXXXXX..XXXXXXX 100644 --- a/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt +++ b/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt @@ -XXX,XX +XXX,XX @@ # mode=relaxed -bad/yaml-mixed-indent.yaml:27: example 0 [mixed-indent-chars] mixed tabs and spaces in indent bad/yaml-mixed-indent.yaml:27: example 0 [tab-in-yaml] tab character not allowed in DTS example -- 2.53.0
Individual rules behave differently depending whether they handle bindings (YAML) or DTS, but the code was focusing on type of indentation (spaces vs tabs). That indentation is actually irrelevant in some rules, so differentiate based on file type. This will be more relevant in the future when more rules act differently on DTS, than on bindings. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v3: New patch --- scripts/dtc/dt-check-style | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ def collect_labels_and_refs(text): class Ctx: """Context passed to each rule check. Carries the parsed lines, - raw text, mode, and indent kind.""" + raw text, mode and kind.""" - def __init__(self, lines, text, mode, indent_kind): + def __init__(self, lines, text, mode, kind): self.lines = lines self.text = text self.mode = mode # 'relaxed' or 'strict' - self.indent_kind = indent_kind # 'spaces' or 'tab' + if kind in DTS_FAMILY: + self.file_type = 'dts' + else: + self.file_type = 'yaml' class Rule: @@ -XXX,XX +XXX,XX @@ def check_tab_in_yaml_example(ctx): a #define value are tolerated (those are CPP macros, not DTS). For .dts files, this rule does not apply -- tabs are required. """ - if ctx.indent_kind != 'spaces': + if ctx.file_type != 'yaml': return for dl in ctx.lines: if dl.linetype == LineType.PREPROCESSOR: @@ -XXX,XX +XXX,XX @@ def check_indent_unit_strict(ctx): unit = detect_indent_unit(ctx) if unit is None: return - if ctx.indent_kind == 'spaces': + if ctx.file_type == 'yaml': if unit != ' ': yield (1, 'indent unit must be 4 spaces in strict mode, ' 'got %r' % unit) @@ -XXX,XX +XXX,XX @@ def check_indent_consistent(ctx): unit = detect_indent_unit(ctx) if unit is None: return - if ctx.indent_kind == 'spaces': + if ctx.file_type == 'yaml': if unit not in (' ', ' '): return # let check_indent_unit_* report this else: @@ -XXX,XX +XXX,XX @@ def select_rules(mode, input_kind): # Block runner # --------------------------------------------------------------------------- -def check_block(text, mode, indent_kind, input_type): +def check_block(text, mode, input_type): """Run all selected rules on a single block of DTS text. Returns a list of (lineno, rule_name, message) tuples.""" lines = classify_lines(text) - ctx = Ctx(lines, text, mode, indent_kind) + ctx = Ctx(lines, text, mode, input_type) rules = select_rules(mode, input_type) findings = [] for r in rules: @@ -XXX,XX +XXX,XX @@ def collect_findings(filepath, mode): formatted output strings; count is the number of findings.""" kind = input_kind(filepath) if kind == 'yaml': - indent_kind = 'spaces' iterator = iter_yaml_examples(filepath) elif kind in DTS_FAMILY: - indent_kind = 'tab' iterator = iter_dts_file(filepath) else: return (['%s: unknown file type, skipping' % filepath], 0) out = [] for text, base, idx in iterator: - for lineno, rule, msg in check_block(text, mode, indent_kind, kind): + for lineno, rule, msg in check_block(text, mode, kind): abs_line = base + lineno - 1 ex_tag = '' if idx is None else ' example %d' % idx out.append('%s:%d:%s [%s] %s' % -- 2.53.0
A few nodes do have "device_type" property which is mostly, but not always, the first property in a device node, when applicable. Adjust the DTS coding style rules to actually expect the device_type first and improve the dt-check-style to handle this correctly. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v3: New patch --- .../devicetree/bindings/dts-coding-style.rst | 15 ++++---- scripts/dtc/dt-check-style | 33 +++++++++-------- .../dt-style-selftest/bad/dts-property-order.dts | 43 ++++++++++++++++++++++ .../bad/yaml-prop-order-device-type.yaml | 31 ++++++++++++++++ .../expected/dts-property-order.dts.txt | 6 +++ .../expected/yaml-prop-order-device-type.yaml.txt | 2 + .../dt-style-selftest/good/dts-property-order.dts | 41 +++++++++++++++++++++ 7 files changed, 149 insertions(+), 22 deletions(-) diff --git a/Documentation/devicetree/bindings/dts-coding-style.rst b/Documentation/devicetree/bindings/dts-coding-style.rst index XXXXXXX..XXXXXXX 100644 --- a/Documentation/devicetree/bindings/dts-coding-style.rst +++ b/Documentation/devicetree/bindings/dts-coding-style.rst @@ -XXX,XX +XXX,XX @@ Order of Properties in Device Node The following order of properties in device nodes is preferred: -1. "compatible" -2. "reg" -3. "ranges" -4. Standard/common properties (defined by common bindings, e.g. without +1. "device_type" (if applicable) +2. "compatible" +3. "reg" +4. "ranges" +5. Standard/common properties (defined by common bindings, e.g. without vendor-prefixes) -5. Vendor-specific properties -6. "status" (if applicable), preceded by a blank line if there is content +6. Vendor-specific properties +7. "status" (if applicable), preceded by a blank line if there is content before the property -7. Child nodes, where each node is preceded with a blank line +8. Child nodes, where each node is preceded with a blank line The "status" property is by default "okay", thus it can be omitted. diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ def check_child_name_order(ctx): def _property_bucket(name): """Return the canonical bucket index for a property: - 0 compatible - 1 reg / reg-names - 2 ranges - 3 standard properties (no vendor comma in #-stripped name) - 4 vendor-specific properties - 5 status - Plus a sub-key inside the bucket for fixed slots (compatible, reg, - reg-names, ranges, status). 'standard' and 'vendor' return None for + 0 device_type + 1 compatible + 2 reg / reg-names + 3 ranges + 4 standard properties (no vendor comma in #-stripped name) + 5 vendor-specific properties + 6 status + Plus a sub-key inside the bucket for fixed slots (device_type, compatible, + reg, reg-names, ranges, status). 'standard' and 'vendor' return None for the sub-key, signalling that the within-bucket key is computed by the pairing rules.""" stripped = name.lstrip('#') - if name == 'compatible': + if name == 'device_type': return (0, 0) - if name == 'reg': + if name == 'compatible': return (1, 0) - if name == 'reg-names': - return (1, 1) - if name == 'ranges': + if name == 'reg': return (2, 0) + if name == 'reg-names': + return (2, 1) + if name == 'ranges': + return (3, 0) if name == 'status': - return (5, 0) - return (4 if ',' in stripped else 3, None) + return (6, 0) + return (5 if ',' in stripped else 4, None) # Declarative pairing rules: each is a callable diff --git a/scripts/dtc/dt-style-selftest/bad/dts-property-order.dts b/scripts/dtc/dt-style-selftest/bad/dts-property-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/dts-property-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* + * Test fixture: Incorrect property order + */ + +/dts-v1/; + +/ { + 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/bad/yaml-prop-order-device-type.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-prop-order-device-type.yaml new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/yaml-prop-order-device-type.yaml @@ -XXX,XX +XXX,XX @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/test-bad-prop-order.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Test fixture with device_type + +maintainers: + - Test User <test@example.com> + +properties: + compatible: + const: example,test-prop-order-device-type + reg: + maxItems: 1 + device_type: true + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + device@1000 { + compatible = "example,test-prop-order-device-type"; + device_type = "cpu"; + reg = <0x1000 0x100>; + }; diff --git a/scripts/dtc/dt-style-selftest/expected/dts-property-order.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-property-order.dts.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/dts-property-order.dts.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/dts-property-order.dts:15: [property-order] property 'compatible' out of canonical order (should sort before 'reg') +bad/dts-property-order.dts:16: [property-order] property 'device_type' out of canonical order (should sort before 'compatible') +bad/dts-property-order.dts:25: [property-order] property 'dma-coherent' out of canonical order (should sort before 'status') +bad/dts-property-order.dts:30: [property-order] property 'compatible' out of canonical order (should sort before 'ranges') +bad/dts-property-order.dts:40: [property-order] property 'compatible' out of canonical order (should sort before 'interrupts') diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-prop-order-device-type.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-prop-order-device-type.yaml.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/yaml-prop-order-device-type.yaml.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/yaml-prop-order-device-type.yaml:29: example 0 [property-order] property 'device_type' out of canonical order (should sort before 'compatible') diff --git a/scripts/dtc/dt-style-selftest/good/dts-property-order.dts b/scripts/dtc/dt-style-selftest/good/dts-property-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-property-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* + * Test fixture: Incorrect property order + */ + +/dts-v1/; + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + }; + + pmu { + compatible = "example,pmu"; + dma-coherent; + + status = "disabled"; + }; + + soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-controller@10000 { + compatible = "example,intc"; + reg = <0x10000 0x1000>; + interrupts = <1 2 3>; + }; + }; +}; -- 2.53.0
dt-check-style was not properly handling DTC directives (starting with '/', e.g. /dts-v1/ or /include/), thus a few DTS files had false positive like: apm/apm-merlin.dts:1: [indent-unit-dts] indent unit must be 1 tab in DTS, got '\t\t' Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v3: New patch --- scripts/dtc/dt-check-style | 11 ++++- scripts/dtc/dt-style-selftest/good/dts-dtc.dts | 21 ++++++++++ .../dt-style-selftest/good/dts-preprocessor.dts | 21 ++++++++++ scripts/dtc/dt-style-selftest/good/soc.dtsi | 47 ++++++++++++++++++++++ 4 files changed, 98 insertions(+), 2 deletions(-) diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ re_cpp_directive = re.compile( r'^#\s*(include|define|undef|ifdef|ifndef|if|else|elif|endif|' r'pragma|error|warning)\b') +re_dtc_directive = re.compile( + r'^/(dts-v1|include)/') + # label: name@addr { -- label and addr optional; name can be "/" # Per the DT spec a node name may start with a digit (e.g. 1wire@...). # The address part is captured loosely (any non-space, non-brace run) so @@ -XXX,XX +XXX,XX @@ re_ref_node = re.compile( def is_preprocessor(stripped): """Tell C preprocessor directives apart from DTS '#'-prefixed props.""" - return re_cpp_directive.match(stripped) is not None + if re_cpp_directive.match(stripped) is not None: + return True + if re_dtc_directive.match(stripped) is not None: + return True + return False class DtsLine: @@ -XXX,XX +XXX,XX @@ def classify_lines(text): out.append(dl) continue - if stripped.startswith('#') and is_preprocessor(stripped): + if (stripped.startswith('#') or stripped.startswith('/')) and is_preprocessor(stripped): dl = DtsLine(i, raw, LineType.PREPROCESSOR, indent_str, stripped) dl.depth = depth diff --git a/scripts/dtc/dt-style-selftest/good/dts-dtc.dts b/scripts/dtc/dt-style-selftest/good/dts-dtc.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-dtc.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* + * Test fixture: dtc directive + */ + +/dts-v1/; + +/include/ "soc.dtsi" +/include/"soc-other.dtsi" + +/ { + compatible = "example,test-board"; + #address-cells = <1>; + #size-cells = <1>; + + leds { + led-0 { + compatible = "example,led"; + }; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/good/dts-preprocessor.dts b/scripts/dtc/dt-style-selftest/good/dts-preprocessor.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-preprocessor.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* + * Test fixture: preprocessor directive + */ + +/dts-v1/; + +#include "soc.dtsi" +#include<dt-bindings/gpio/gpio.h> + +/ { + compatible = "example,test-board"; + #address-cells = <1>; + #size-cells = <1>; + + leds { + led-0 { + compatible = "example,led"; + }; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/good/soc.dtsi b/scripts/dtc/dt-style-selftest/good/soc.dtsi new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/soc.dtsi @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + }; + + pmu { + compatible = "example,pmu"; + }; + + soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-controller@10000 { + compatible = "example,intc"; + reg = <0x10000 0x1000>; + interrupts = <1 2 3>, + <4 5 6>, + <7 8 9>; + }; + + serial@20000 { + compatible = "example,serial"; + reg = <0x20000 0x1000>; + }; + + serial@30000 { + compatible = "example,serial"; + reg = <0x30000 0x1000>; + }; + }; +}; -- 2.53.0
Script judges the indentation however always suggests it is the first line which is wrong, e.g.: sigmastar/mstar-infinity2m.dtsi:1: [indent-unit-dts] indent unit must be 1 tab in DTS, got '\t\t' Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- scripts/dtc/dt-check-style | 29 +++++++++++----------- .../dt-style-selftest/expected/dts-spaces.dts.txt | 2 +- .../expected/yaml-indent-strict.yaml.txt | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style index XXXXXXX..XXXXXXX 100755 --- a/scripts/dtc/dt-check-style +++ b/scripts/dtc/dt-check-style @@ -XXX,XX +XXX,XX @@ def check_mixed_indent_chars(ctx): def detect_indent_unit(ctx): """Find the indent unit used at depth 1 in this block. - Returns one of: ' ' (2 spaces), ' ' (4 spaces), '\\t' (tab), - or None if depth-1 is empty or ambiguous.""" + Returns tuple of string (one of: ' ' (2 spaces), ' ' (4 spaces), + '\\t' (tab), or None if depth-1 is empty or ambiguous) and line number when + detection was made).""" for dl in ctx.lines: if dl.depth != 1: continue @@ -XXX,XX +XXX,XX @@ def detect_indent_unit(ctx): if not dl.indent_str: continue if dl.indent_str == '\t': - return '\t' + return ('\t', dl.lineno) if dl.indent_str == ' ': - return ' ' + return (' ', dl.lineno) if dl.indent_str == ' ': - return ' ' + return (' ', dl.lineno) # Anything else at depth 1 is non-canonical; flag elsewhere. - return dl.indent_str - return None + return (dl.indent_str, dl.lineno) + return (None, None) def check_indent_unit_relaxed(ctx): """YAML examples: 2 or 4 spaces. Never tabs or other widths.""" - unit = detect_indent_unit(ctx) + (unit, lineno) = detect_indent_unit(ctx) if unit is None: return if unit not in (' ', ' '): - yield (1, 'indent unit must be 2 or 4 spaces, got %r' % unit) + yield (lineno, 'indent unit must be 2 or 4 spaces, got %r' % unit) def check_indent_unit_dts(ctx): """DTS files: 1 tab per level. Always required.""" - unit = detect_indent_unit(ctx) + (unit, lineno) = detect_indent_unit(ctx) if unit is None: return if unit != '\t': - yield (1, 'indent unit must be 1 tab in DTS, got %r' % unit) + yield (lineno, 'indent unit must be 1 tab in DTS, got %r' % unit) def check_indent_unit_strict(ctx): """YAML: must be exactly 4 spaces. DTS: 1 tab (same as relaxed).""" - unit = detect_indent_unit(ctx) + (unit, lineno) = detect_indent_unit(ctx) if unit is None: return if ctx.file_type == 'yaml': if unit != ' ': - yield (1, 'indent unit must be 4 spaces in strict mode, ' + yield (lineno, 'indent unit must be 4 spaces in strict mode, ' 'got %r' % unit) def check_indent_consistent(ctx): """All indented lines must be a multiple of the detected unit.""" - unit = detect_indent_unit(ctx) + (unit, lineno) = detect_indent_unit(ctx) if unit is None: return if ctx.file_type == 'yaml': diff --git a/scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt index XXXXXXX..XXXXXXX 100644 --- a/scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt +++ b/scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt @@ -XXX,XX +XXX,XX @@ # mode=relaxed -bad/dts-spaces.dts:1: [indent-unit-dts] indent unit must be 1 tab in DTS, got ' ' +bad/dts-spaces.dts:9: [indent-unit-dts] indent unit must be 1 tab in DTS, got ' ' diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-indent-strict.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-indent-strict.yaml.txt index XXXXXXX..XXXXXXX 100644 --- a/scripts/dtc/dt-style-selftest/expected/yaml-indent-strict.yaml.txt +++ b/scripts/dtc/dt-style-selftest/expected/yaml-indent-strict.yaml.txt @@ -XXX,XX +XXX,XX @@ # mode=strict -bad/yaml-indent-strict.yaml:26: example 0 [indent-unit-strict] indent unit must be 4 spaces in strict mode, got ' ' +bad/yaml-indent-strict.yaml:27: example 0 [indent-unit-strict] indent unit must be 4 spaces in strict mode, got ' ' -- 2.53.0
Add a few more test cases for valid and incorrect DTS for dt-check-style. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> --- Changes in v4: 1. New patch --- .../dt-style-selftest/bad/dts-child-name-order.dts | 30 ++++++++++++++++ .../bad/dts-extend-node-child-name-order.dts | 23 ++++++++++++ .../bad/dts-extend-node-digit-node-order.dts | 31 ++++++++++++++++ .../expected/dts-child-name-order.dts.txt | 2 ++ .../dts-extend-node-child-name-order.dts.txt | 2 ++ .../dts-extend-node-digit-node-order.dts.txt | 2 ++ .../good/dts-child-name-order.dts | 30 ++++++++++++++++ .../good/dts-digit-node-order.dts | 41 ++++++++++++++++++++++ .../good/dts-extend-node-child-name-order.dts | 23 ++++++++++++ .../good/dts-extend-node-digit-node-order.dts | 31 ++++++++++++++++ 10 files changed, 215 insertions(+) diff --git a/scripts/dtc/dt-style-selftest/bad/dts-child-name-order.dts b/scripts/dtc/dt-style-selftest/bad/dts-child-name-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/dts-child-name-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + pmu { + compatible = "example,pmu"; + + /* Include labels to be sure they do not affect sorting */ + foo: foo { + label = "foo"; + }; + + label_bar: bar { + label = "bar"; + }; + }; + + memory@a0000000 { + device_type = "memory"; + reg = <0x0 0xa0000000 0x0 0x0>; + }; + + pmu-2 { + compatible = "example,pmu"; + + /* Just reference labels to avoid strict warnings */ + example,foo = <&foo>, <&label_bar>; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/bad/dts-extend-node-child-name-order.dts b/scripts/dtc/dt-style-selftest/bad/dts-extend-node-child-name-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/dts-extend-node-child-name-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + pmu { + compatible = "example,pmu"; + + /* Just reference labels to avoid strict warnings */ + example,foo = <&foo>, <&label_bar>; + }; +}; + +&pmu { + /* Include labels to be sure they do not affect sorting */ + foo: foo { + label = "foo"; + }; + + label_bar: bar { + label = "bar"; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/bad/dts-extend-node-digit-node-order.dts b/scripts/dtc/dt-style-selftest/bad/dts-extend-node-digit-node-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/bad/dts-extend-node-digit-node-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + soc: soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + #address-cells = <1>; + #size-cells = <1>; + }; +}; + +&soc { + serial@20000 { + compatible = "example,serial"; + reg = <0x20000 0x1000>; + }; + + interrupt-controller@10000 { + compatible = "example,intc"; + reg = <0x10000 0x1000>; + interrupts = <1 2 3>; + }; + + serial@30000 { + compatible = "example,serial"; + reg = <0x30000 0x1000>; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/expected/dts-child-name-order.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-child-name-order.dts.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/dts-child-name-order.dts.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/dts-child-name-order.dts:14: [child-name-order] child node 'bar' out of name order diff --git a/scripts/dtc/dt-style-selftest/expected/dts-extend-node-child-name-order.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-extend-node-child-name-order.dts.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/dts-extend-node-child-name-order.dts.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/dts-extend-node-child-name-order.dts:20: [child-name-order] child node 'bar' out of name order diff --git a/scripts/dtc/dt-style-selftest/expected/dts-extend-node-digit-node-order.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-extend-node-digit-node-order.dts.txt new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/expected/dts-extend-node-digit-node-order.dts.txt @@ -XXX,XX +XXX,XX @@ +# mode=strict +bad/dts-extend-node-digit-node-order.dts:21: [child-address-order] child node @10000 out of address order diff --git a/scripts/dtc/dt-style-selftest/good/dts-child-name-order.dts b/scripts/dtc/dt-style-selftest/good/dts-child-name-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-child-name-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + memory@a0000000 { + device_type = "memory"; + reg = <0x0 0xa0000000 0x0 0x0>; + }; + + pmu { + compatible = "example,pmu"; + + /* Include labels to be sure they do not affect sorting */ + label_bar: bar { + label = "bar"; + }; + + foo: foo { + label = "foo"; + }; + }; + + pmu-2 { + compatible = "example,pmu"; + + /* Just reference labels to avoid strict warnings */ + example,foo = <&foo>, <&label_bar>; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/good/dts-digit-node-order.dts b/scripts/dtc/dt-style-selftest/good/dts-digit-node-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-digit-node-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + /* TODO: uncomment when child-address-order is fixed for top-level */ + /* + memory@a0000000 { + device_type = "memory"; + reg = <0x0 0xa0000000 0x0 0x0>; + }; + */ + + pmu { + compatible = "example,pmu"; + }; + + soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-controller@10000 { + compatible = "example,intc"; + reg = <0x10000 0x1000>; + interrupts = <1 2 3>; + }; + + serial@20000 { + compatible = "example,serial"; + reg = <0x20000 0x1000>; + }; + + serial@30000 { + compatible = "example,serial"; + reg = <0x30000 0x1000>; + }; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/good/dts-extend-node-child-name-order.dts b/scripts/dtc/dt-style-selftest/good/dts-extend-node-child-name-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-extend-node-child-name-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + pmu { + compatible = "example,pmu"; + + /* Just reference labels to avoid strict warnings */ + example,foo = <&foo>, <&label_bar>; + }; +}; + +&pmu { + /* Include labels to be sure they do not affect sorting */ + label_bar: bar { + label = "bar"; + }; + + foo: foo { + label = "foo"; + }; +}; diff --git a/scripts/dtc/dt-style-selftest/good/dts-extend-node-digit-node-order.dts b/scripts/dtc/dt-style-selftest/good/dts-extend-node-digit-node-order.dts new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/dtc/dt-style-selftest/good/dts-extend-node-digit-node-order.dts @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/ { + #address-cells = <1>; + #size-cells = <1>; + + soc: soc@0 { + compatible = "simple-bus"; + ranges = <0 0 0 0xc0000000>; + + #address-cells = <1>; + #size-cells = <1>; + }; +}; + +&soc { + interrupt-controller@10000 { + compatible = "example,intc"; + reg = <0x10000 0x1000>; + interrupts = <1 2 3>; + }; + + serial@20000 { + compatible = "example,serial"; + reg = <0x20000 0x1000>; + }; + + serial@30000 { + compatible = "example,serial"; + reg = <0x30000 0x1000>; + }; +}; -- 2.53.0