* Re: [PATCH v4 1/3] dt-bindings: add DTS style checker
From: sashiko-bot @ 2026-05-22 18:17 UTC (permalink / raw)
To: Daniel Golle; +Cc: devicetree, conor+dt, robh
In-Reply-To: <457f328d4c5d639482fddf40e79be61b97db5814.1779472837.git.daniel@makrotopia.org>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [Medium] Code following a block comment on the same line is completely ignored, breaking parsing state and nesting depth.
- [Medium] Multi-line C preprocessor directives (macros) using `\` continuations are mishandled, corrupting the parsing state and triggering false-positive style warnings.
- [Medium] The unused-labels checker regex matches inside string literals and misses labels on nodes starting with digits.
- [Medium] Syntactic checks operating on `dl.raw` incorrectly process the contents of unclosed block comments on `PROPERTY` lines, causing false positives.
- [Medium] The regex for node headers rejects nodes with malformed unit addresses, allowing them to bypass the unit-address format check.
- [Low] Multiple closing braces on the same line break depth tracking and cause cascading false positive warnings.
--
commit 6b49caf90b5c4741b273da5e02e9f53fa30ea1bc
Author: Daniel Golle <daniel@makrotopia.org>
dt-bindings: add DTS style checker
Add a Python tool that checks DTS coding style on examples in YAML binding
files and on .dts/.dtsi/.dtso source files. Rules are kept in a declarative
registry, tagged as 'relaxed' or 'strict'.
> diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style
> new file mode 100755
> index 0000000000000..93cb1d7d2985c
> --- /dev/null
> +++ b/scripts/dtc/dt-check-style
[ ... ]
> +re_node_header = re.compile(
> + r'^(?:([a-zA-Z_][a-zA-Z0-9_]*):\s*)?'
> + r'([a-zA-Z0-9][a-zA-Z0-9,._+-]*|/)'
> + r'(?:@([0-9a-fA-F,]+))?'
> + r'\s*\{$')
[Severity: Medium]
Will this regex reject nodes with malformed unit addresses, allowing them to
bypass the unit-address format check?
If the unit address contains characters outside this set, such as the x in
memory@0x1000, the entire regex match fails and dl.node_addr remains None.
Because check_unit_address_format() skips validation if dl.node_addr is None,
does this allow malformed unit addresses containing 0x to bypass the very
check designed to flag them?
[ ... ]
> + if in_block_comment:
> + ltype = (LineType.COMMENT_END if '*/' in stripped
> + else LineType.COMMENT_BODY)
> + if ltype == LineType.COMMENT_END:
> + in_block_comment = False
> + dl = DtsLine(i, raw, ltype, indent_str, stripped)
> + dl.depth = depth
> + out.append(dl)
> + continue
> +
> + if stripped.startswith('/*'):
> + if '*/' in stripped:
> + ltype = LineType.COMMENT
> + else:
> + in_block_comment = True
> + ltype = LineType.COMMENT_START
> + dl = DtsLine(i, raw, ltype, indent_str, stripped)
> + dl.depth = depth
> + out.append(dl)
> + continue
[Severity: Medium]
Does this code skip parsing for any valid DTS code following a block comment
on the exact same line?
If a line starts with /* and contains */, or if an open block comment ends on
the line, the script sets the line type and immediately executes continue.
Could this lead to desynchronized nesting depth tracking by ignoring
constructs like /* ... */ }; or /* ... */ foo = <1>;, incorrectly classifying
subsequent lines and triggering cascading false positive violations?
> +
> + if stripped.startswith('//'):
> + dl = DtsLine(i, raw, LineType.COMMENT, indent_str, stripped)
> + dl.depth = depth
> + out.append(dl)
> + continue
> +
> + if stripped.startswith('#') and is_preprocessor(stripped):
> + dl = DtsLine(i, raw, LineType.PREPROCESSOR,
> + indent_str, stripped)
> + dl.depth = depth
> + out.append(dl)
> + prev_complete = True
> + continue
[Severity: Medium]
Does this logic mishandle multi-line C preprocessor directives using
backslash continuations?
If the directive has trailing backslashes to continue macros to subsequent
lines, the continuation lines do not start with #.
Are these improperly parsed as standard DTS properties or continuations,
inappropriately applying DTS constraints to internal C code and triggering
false positives?
[ ... ]
> + if code == '};' or code == '}':
> + depth = max(depth - 1, 0)
> + dl = DtsLine(i, raw, LineType.NODE_CLOSE, indent_str, code)
> + dl.depth = depth
> + out.append(dl)
> + prev_complete = True
> + continue
[Severity: Low]
Will this fail to decrement nesting depth if a single line contains multiple
closures?
If code contains }; };, this exact-match condition fails.
Does the line then improperly fall through and get classified as
LineType.PROPERTY, corrupting depth tracking for subsequent lines and
incorrectly flagging them for indentation violations?
[ ... ]
> +def collect_labels_and_refs(text):
> + """Return (defined_labels, referenced_labels) found anywhere outside
> + /* */ comments. Labels named fake_intc* (injected by
> + dt-extract-example) are skipped."""
> + # Strip block comments first so labels inside them don't count
> + stripped = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL)
> + # Strip line comments
> + stripped = re.sub(r'//[^\n]*', '', stripped)
> + defined = set()
> + referenced = set()
> + for m in re.finditer(r'(?:^|[\s{])([a-zA-Z_][a-zA-Z0-9_]*):\s*[a-zA-Z/&]',
> + stripped):
[Severity: Medium]
Does this regex match inside string literals and miss labels on nodes
starting with digits?
Since string literals are not stripped before searching for labels, words
followed by colons inside strings like prop = "Error: failed"; could be added
to the defined set and flagged as unused.
Additionally, because the regex requires the character following the colon to
be a letter, /, or &, does it fail to capture labels attached to nodes
starting with a digit like label: 1wire@10 {?
[ ... ]
> +def _strip_strings_and_comments(text):
> + """Remove string literals and /* */ + // comments from a single
> + line, replacing them with empty strings. Used so syntactic checks
> + (whitespace, hex case, etc.) don't false-positive on contents of
> + quoted strings or comments."""
> + text = re.sub(r'"(?:[^"\\]|\\.)*"', '""', text)
> + text = re.sub(r'/\*.*?\*/', '', text)
> + text = re.sub(r'//.*$', '', text)
> + return text
[Severity: Medium]
Will syntactic checks incorrectly process the contents of unclosed block
comments on PROPERTY lines?
Because the regex only removes block comments that both open and close on the
same line, if a line contains an unclosed block comment like
prop = <1>; /* ... 0xABC, the regex fails to match.
Does the comment text remain intact, causing checks like check_hex_case() to
yield false positive errors for uppercase hex values inside the comment?
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1779472837.git.daniel@makrotopia.org?part=1
^ permalink raw reply
* Re: [PATCH v3] arm64: dts: renesas: r8a779md: Add support for R-Car M3Le R8A779MD Geist
From: sashiko-bot @ 2026-05-22 18:12 UTC (permalink / raw)
To: Marek Vasut; +Cc: conor+dt, devicetree, wsa+renesas, robh
In-Reply-To: <20260522172000.15096-1-marek.vasut+renesas@mailbox.org>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] Undocumented compatible strings for new hardware variants
- [Low] Inverted brightness-levels array violating semantics and causing logic error
--
commit 8e773037ec40fa18ba2cb58aa7b9d32280d8b5cb
Author: Nguyen Tran <nguyen.tran.pz@bp.renesas.com>
arm64: dts: renesas: r8a779md: Add support for R-Car M3Le R8A779MD Geist
Add support for the Geist board based on the Renesas R-Car R8A779MD (M3Le)
SoC, a register-compatible variant of the R8A77965 (M3-N) with reduced set
of peripherals.
> diff --git a/arch/arm64/boot/dts/renesas/r8a779md-geist.dts b/arch/arm64/boot/dts/renesas/r8a779md-geist.dts
> new file mode 100644
> index 0000000000000..11024bd12eb63
> --- /dev/null
> +++ b/arch/arm64/boot/dts/renesas/r8a779md-geist.dts
> @@ -0,0 +1,720 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/*
> + * Device Tree Source for the Geist board with R-Car M3Le
> + *
> + * Copyright (C) 2025-2026 Renesas Electronics Corp.
> + */
> +
> +/dts-v1/;
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include "r8a779md.dtsi"
> +
> +/ {
> + model = "Renesas Geist board based on r8a779md";
> + compatible = "renesas,geist", "renesas,r8a779md", "renesas,r8a77965";
[Severity: Low]
Are the YAML device tree bindings for the new renesas,geist and
renesas,r8a779md compatible strings included in a separate patch?
According to the subsystem guidelines, new compatible strings must be added
to the schema. For renesas,r8a779md (a variant of renesas,r8a77965),
omitting it from existing if-then conditional blocks where previous
generations appear causes schema validation to be incomplete, rendering
dtbs_check unable to validate the node correctly.
[ ... ]
> + backlight: backlight {
> + compatible = "pwm-backlight";
> + pwms = <&pwm1 0 50000>;
> +
> + brightness-levels = <256 128 64 16 8 4 0>;
[Severity: Low]
Does this inverted brightness-levels array violate the device tree
specification to work around missing PWM_POLARITY_INVERTED support?
The DT common.yaml specification requires brightness levels to be strictly
increasing, with 0 being the darkest.
This inverted array introduces a logic error in
drivers/video/backlight/pwm_bl.c. In pwm_backlight_is_linear(), max_val (0)
- min_val (256) triggers an unsigned integer underflow (4294967040).
This underflow creates a massive arbitrary error margin, completely
breaking the linearity check and causing the driver to unconditionally
misclassify the backlight as linear in sysfs.
> + default-brightness-level = <6>;
> +
> + power-supply = <®_12v>;
> + enable-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
> + };
[ ... ]
> +&i2c2 {
> + pinctrl-0 = <&i2c2_pins>;
> + pinctrl-names = "default";
> + clock-frequency = <100000>;
> + status = "okay";
[ ... ]
> + /* Pin-to-pin, register map, and control compatible with CS2000 and CS2200 */
> + cs2500: clock-controller@4f {
> + #clock-cells = <0>;
> + compatible = "cirrus,cs2500", "cirrus,cs2000-cp";
[Severity: Low]
Is the cirrus,cs2500 compatible string missing its YAML binding schema?
Just like the board compatible strings above, adding a new hardware variant
requires updating the device tree bindings.
> + reg = <0x4f>;
> + clocks = <&audio_clkout>, <&x12_clk>;
> + clock-names = "clk_in", "ref_clk";
> +
> + assigned-clocks = <&cs2500>;
> + assigned-clock-rates = <24576000>; /* 1/1 divide */
> + };
> +};
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260522172000.15096-1-marek.vasut+renesas@mailbox.org?part=1
^ permalink raw reply
* Re: [PATCH 1/3] dt-bindings: vendor-prefixes: Add Axelera AI
From: Heiko Stuebner @ 2026-05-22 18:12 UTC (permalink / raw)
To: devicetree, linux-rockchip, linux-kernel, robh, krzk+dt, conor+dt,
Patrick Barsanti
Cc: linux-amarula, michael, dario.binacchi, Patrick Barsanti
In-Reply-To: <20260522174918.61523-2-patrick.barsanti@amarulasolutions.com>
Am Freitag, 22. Mai 2026, 19:49:16 Mitteleuropäische Sommerzeit schrieb Patrick Barsanti:
> Axelera AI is an EU-based provider of AIPUs for edge AI inference.
>
> Link: https://axelera.ai/
> Signed-off-by: Patrick Barsanti <patrick.barsanti@amarulasolutions.com>
> ---
> Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index 28784d66ae7b..595ad9423ece 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -217,6 +217,8 @@ patternProperties:
> description: Avnet, Inc.
> "^awinic,.*":
> description: Shanghai Awinic Technology Co., Ltd.
> + "^axelera,.*":
> + description: Axelera AI
description: Axelera AI B.V.
Which is the dutch equivalent to a Ltd., so that is the full company name.
See
https://axelera.ai/hubfs/Axelera%20T%26C%20Sales%20Feb%202026.pdf?hsLang=en
> "^axentia,.*":
> description: Axentia Technologies AB
> "^axiado,.*":
>
^ permalink raw reply
* Re: [PATCH v5 11/13] iio: frequency: ad9910: show channel priority in debugfs
From: Jonathan Cameron @ 2026-05-22 18:07 UTC (permalink / raw)
To: Rodrigo Alencar via B4 Relay
Cc: rodrigo.alencar, linux-iio, devicetree, linux-kernel, linux-doc,
linux-hardening, Lars-Peter Clausen, Michael Hennerich,
David Lechner, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, Jonathan Corbet, Shuah Khan,
Kees Cook, Gustavo A. R. Silva
In-Reply-To: <20260517-ad9910-iio-driver-v5-11-31599c88314a@analog.com>
On Sun, 17 May 2026 19:37:55 +0100
Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:
> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
>
> Expose frequency_source, phase_source and amplitude_source attributes in
> debugfs. Those indicate from which channel the specific DDS parameter is
> being sourced by returning its label. The implementation follows the
> priority table found in the datasheet.
>
Examples here would be good.
I guess maybe this suffers the same label problem as the parent stuff.
Same solution?
> Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
^ permalink raw reply
* [PATCH v4 3/3] dt-bindings: add self-test fixtures for style checker
From: Daniel Golle @ 2026-05-22 18:04 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Nathan Chancellor,
Nicolas Schier, Saravana Kannan, Daniel Golle, Miguel Ojeda,
Gary Guo, Tamir Duberstein, Thomas Weißschuh, Steven Rostedt,
Masahiro Yamada, Aleksander Jan Bajkowski, Guenter Roeck,
Test User, devicetree, linux-kernel, linux-kbuild
In-Reply-To: <cover.1779472837.git.daniel@makrotopia.org>
Provide good/ and bad/ DTS and YAML fixtures plus a small runner that
feeds them to dt-check-style and diffs the output against expected
text files. Wired into a new top-level dt_style_selftest make target
so the suite can be exercised independently of the full tree.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
Changes since v3:
- run.sh: replace the bash-only "<()" process substitution with a
POSIX temp-file plus stdin diff, so the runner works when /bin/sh
is dash
- run.sh: check dt-check-style's exit status -- good/ fixtures must
exit 0, bad/ fixtures must exit 1 -- instead of discarding it with
"|| true"
- add fixtures for the checker fixes in this revision:
good/dts-cont-align.dts (tab-and-space aligned multi-line
property), bad/yaml-digit-node-order.yaml (digit-leading node
names), bad/yaml-trailing-comment.yaml (trailing // and /* */
comments) and bad/yaml-value-ws-multiline.yaml (multi-line cell
array)
- update bad/yaml-value-ws.yaml (and its expected output) to
exercise the reworked value-whitespace rule
Changes since v2:
- append a trailing newline to every expected/*.txt fixture (Rob)
- restore the trailing whitespace inside yaml-trailing-ws.yaml
that had been silently stripped during re-application, so the
selftest actually exercises the trailing-whitespace rule
Changes since v1:
- new patch (Krzysztof: "would be happy to see at least a few test
cases for it")
---
Makefile | 6 ++
.../dtc/dt-style-selftest/bad/dts-spaces.dts | 13 ++++
.../bad/yaml-child-addr-order.yaml | 41 +++++++++++
.../bad/yaml-child-name-order.yaml | 37 ++++++++++
.../bad/yaml-cont-align.yaml | 30 ++++++++
.../bad/yaml-digit-node-order.yaml | 37 ++++++++++
.../dt-style-selftest/bad/yaml-hex-case.yaml | 29 ++++++++
.../bad/yaml-indent-strict.yaml | 29 ++++++++
.../bad/yaml-line-length.yaml | 29 ++++++++
.../bad/yaml-mixed-indent.yaml | 29 ++++++++
.../bad/yaml-node-close.yaml | 31 ++++++++
.../bad/yaml-prop-order.yaml | 29 ++++++++
.../bad/yaml-prop-pairing.yaml | 33 +++++++++
.../bad/yaml-required-blank.yaml | 33 +++++++++
.../dtc/dt-style-selftest/bad/yaml-tab.yaml | 29 ++++++++
| 26 +++++++
.../bad/yaml-trailing-ws.yaml | 29 ++++++++
.../dt-style-selftest/bad/yaml-unit-addr.yaml | 29 ++++++++
.../bad/yaml-unused-label.yaml | 29 ++++++++
.../bad/yaml-value-ws-multiline.yaml | 27 +++++++
.../dt-style-selftest/bad/yaml-value-ws.yaml | 29 ++++++++
.../expected/dts-spaces.dts.txt | 2 +
.../expected/yaml-child-addr-order.yaml.txt | 2 +
.../expected/yaml-child-name-order.yaml.txt | 2 +
.../expected/yaml-cont-align.yaml.txt | 2 +
.../expected/yaml-digit-node-order.yaml.txt | 2 +
.../expected/yaml-hex-case.yaml.txt | 2 +
.../expected/yaml-indent-strict.yaml.txt | 2 +
.../expected/yaml-line-length.yaml.txt | 2 +
.../expected/yaml-mixed-indent.yaml.txt | 3 +
.../expected/yaml-node-close.yaml.txt | 2 +
.../expected/yaml-prop-order.yaml.txt | 2 +
.../expected/yaml-prop-pairing.yaml.txt | 3 +
.../expected/yaml-required-blank.yaml.txt | 3 +
.../expected/yaml-tab.yaml.txt | 2 +
| 2 +
.../expected/yaml-trailing-ws.yaml.txt | 2 +
.../expected/yaml-unit-addr.yaml.txt | 2 +
.../expected/yaml-unused-label.yaml.txt | 2 +
.../expected/yaml-value-ws-multiline.yaml.txt | 2 +
.../expected/yaml-value-ws.yaml.txt | 2 +
.../dt-style-selftest/good/dts-cont-align.dts | 27 +++++++
.../dtc/dt-style-selftest/good/dts-tab.dts | 30 ++++++++
.../dt-style-selftest/good/yaml-4space.yaml | 41 +++++++++++
scripts/dtc/dt-style-selftest/run.sh | 71 +++++++++++++++++++
45 files changed, 816 insertions(+)
create mode 100644 scripts/dtc/dt-style-selftest/bad/dts-spaces.dts
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-child-addr-order.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-child-name-order.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-cont-align.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-digit-node-order.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-hex-case.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-indent-strict.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-line-length.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-mixed-indent.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-node-close.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-prop-order.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-prop-pairing.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-required-blank.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-tab.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-trailing-comment.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-trailing-ws.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-unit-addr.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-unused-label.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-value-ws-multiline.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-value-ws.yaml
create mode 100644 scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-child-addr-order.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-child-name-order.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-cont-align.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-digit-node-order.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-hex-case.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-indent-strict.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-line-length.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-node-close.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-prop-order.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-prop-pairing.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-required-blank.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-trailing-comment.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-trailing-ws.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-unit-addr.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-unused-label.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-value-ws-multiline.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-value-ws.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/good/dts-cont-align.dts
create mode 100644 scripts/dtc/dt-style-selftest/good/dts-tab.dts
create mode 100644 scripts/dtc/dt-style-selftest/good/yaml-4space.yaml
create mode 100755 scripts/dtc/dt-style-selftest/run.sh
diff --git a/Makefile b/Makefile
index b7b80e84e1eb..2436ed72ca83 100644
--- a/Makefile
+++ b/Makefile
@@ -295,6 +295,7 @@ no-dot-config-targets := $(clean-targets) \
cscope gtags TAGS tags help% %docs check% coccicheck \
$(version_h) headers headers_% archheaders archscripts \
%asm-generic kernelversion %src-pkg dt_binding_check \
+ dt_style_selftest \
outputmakefile rustavailable rustfmt rustfmtcheck \
run-command
no-sync-config-targets := $(no-dot-config-targets) %install modules_sign kernelrelease \
@@ -1645,6 +1646,10 @@ PHONY += dt_compatible_check
dt_compatible_check: dt_binding_schemas
$(Q)$(MAKE) $(build)=$(dtbindingtree) $@
+PHONY += dt_style_selftest
+dt_style_selftest:
+ $(Q)$(srctree)/scripts/dtc/dt-style-selftest/run.sh
+
# ---------------------------------------------------------------------------
# Modules
@@ -1847,6 +1852,7 @@ help:
echo ' dtbs_install - Install dtbs to $(INSTALL_DTBS_PATH)'; \
echo ' dt_binding_check - Validate device tree binding documents and examples'; \
echo ' dt_binding_schemas - Build processed device tree binding schemas'; \
+ echo ' dt_style_selftest - Run dt-check-style fixture tests'; \
echo ' dtbs_check - Validate device tree source files';\
echo '')
diff --git a/scripts/dtc/dt-style-selftest/bad/dts-spaces.dts b/scripts/dtc/dt-style-selftest/bad/dts-spaces.dts
new file mode 100644
index 000000000000..905a91824a50
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/dts-spaces.dts
@@ -0,0 +1,13 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+ *
+ * Test fixture: a .dts using space indent (must use tabs).
+ */
+
+/dts-v1/;
+
+/ {
+ compatible = "example,test-board";
+ #address-cells = <1>;
+ #size-cells = <1>;
+};
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-child-addr-order.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-child-addr-order.yaml
new file mode 100644
index 000000000000..3df56e69a1ff
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-child-addr-order.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-child-order.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with addressed children out of order
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-child-order
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ bus@10000 {
+ compatible = "simple-bus";
+ reg = <0x10000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ device@200 {
+ compatible = "example,test-child-order";
+ reg = <0x200 0x10>;
+ };
+
+ device@100 {
+ compatible = "example,test-child-order";
+ reg = <0x100 0x10>;
+ };
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-child-name-order.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-child-name-order.yaml
new file mode 100644
index 000000000000..35d85e5573c2
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-child-name-order.yaml
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-child-name-order.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with unaddressed children out of name order
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-child-name-order
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ bus@10000 {
+ compatible = "simple-bus";
+ reg = <0x10000 0x1000>;
+
+ foo {
+ label = "foo";
+ };
+
+ bar {
+ label = "bar";
+ };
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-cont-align.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-cont-align.yaml
new file mode 100644
index 000000000000..92778540b056
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-cont-align.yaml
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-cont-align.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with mis-aligned multi-line property
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-cont-align
+ reg:
+ maxItems: 2
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ foo@1000 {
+ compatible = "example,test-cont-align";
+ reg = <0x1000 0x100>,
+ <0x2000 0x100>;
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-digit-node-order.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-digit-node-order.yaml
new file mode 100644
index 000000000000..44a9d25e5ba0
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-digit-node-order.yaml
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-digit-node-order.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with digit-leading nodes out of address order
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-digit-node-order
+
+required:
+ - compatible
+
+additionalProperties: false
+
+examples:
+ - |
+ bus@0 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ 3d-engine@20 {
+ compatible = "example,3d-engine";
+ reg = <0x20 0x4>;
+ };
+
+ 1wire@10 {
+ compatible = "example,1wire";
+ reg = <0x10 0x4>;
+ };
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-hex-case.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-hex-case.yaml
new file mode 100644
index 000000000000..b26d1bf58de9
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-hex-case.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-hex-case.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with uppercase hex literals
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-hex-case
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ foo@1000 {
+ compatible = "example,test-hex-case";
+ reg = <0xABCD 0x100>;
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-indent-strict.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-indent-strict.yaml
new file mode 100644
index 000000000000..bee4cf118d73
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-indent-strict.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-indent-strict.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture using 2-space indent (rejected by strict mode)
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-indent-strict
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ device@1000 {
+ compatible = "example,test-indent-strict";
+ reg = <0x1000 0x100>;
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-line-length.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-line-length.yaml
new file mode 100644
index 000000000000..64427bf1c385
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-line-length.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-line-length.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture exceeding 80 columns
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-line-length
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ foo@1000 {
+ compatible = "example,test-line-length-this-is-a-very-long-name-indeed-yeah";
+ reg = <0x1000 0x100>;
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-mixed-indent.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-mixed-indent.yaml
new file mode 100644
index 000000000000..5401d1a423a1
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-mixed-indent.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-mixed-indent.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture mixing tabs and spaces in indent
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-mixed
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ device@1000 {
+ compatible = "example,test-mixed";
+ reg = <0x1000 0x100>;
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-node-close.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-node-close.yaml
new file mode 100644
index 000000000000..e107659fd9e8
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-node-close.yaml
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-node-close.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with closing brace not on its own line
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-node-close
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ bus@10000 {
+ compatible = "simple-bus";
+ reg = <0x10000 0x1000>;
+
+ empty {};
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-prop-order.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-prop-order.yaml
new file mode 100644
index 000000000000..75582a3d2f6e
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-prop-order.yaml
@@ -0,0 +1,29 @@
+# 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 reg before compatible
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-prop-order
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ device@1000 {
+ reg = <0x1000 0x100>;
+ compatible = "example,test-prop-order";
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-prop-pairing.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-prop-pairing.yaml
new file mode 100644
index 000000000000..767ab21c39f3
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-prop-pairing.yaml
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-prop-pairing.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture exercising <x>-names and pinctrl-names pairing
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-prop-pairing
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ foo@1000 {
+ compatible = "example,test-prop-pairing";
+ reg = <0x1000 0x100>;
+ clock-names = "bus";
+ clocks = <&clk 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&p0>;
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-required-blank.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-required-blank.yaml
new file mode 100644
index 000000000000..8bb53240cffa
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-required-blank.yaml
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-required-blank.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture missing required blank lines
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-required-blank
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ bus@10000 {
+ compatible = "simple-bus";
+ reg = <0x10000 0x1000>;
+ status = "okay";
+ child@100 {
+ reg = <0x100>;
+ };
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-tab.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-tab.yaml
new file mode 100644
index 000000000000..487d07ff8cb6
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-tab.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-tab.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with a tab in a DTS line
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-tab
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ device@1000 {
+ compatible = "example,test-tab";
+ reg = <0x1000 0x100>; /* registers */
+ };
--git a/scripts/dtc/dt-style-selftest/bad/yaml-trailing-comment.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-trailing-comment.yaml
new file mode 100644
index 000000000000..2368ada8106f
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-trailing-comment.yaml
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-trailing-comment.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with properties out of order behind trailing comments
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-trailing-comment
+
+required:
+ - compatible
+
+additionalProperties: false
+
+examples:
+ - |
+ foo@0 { /* the device node */
+ reg = <0x0 0x4>; /* registers */
+ compatible = "example,test-trailing-comment"; // misplaced
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-trailing-ws.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-trailing-ws.yaml
new file mode 100644
index 000000000000..5c4b4bd833c5
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-trailing-ws.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-trailing.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with trailing whitespace
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-trailing
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ device@1000 {
+ compatible = "example,test-trailing";
+ reg = <0x1000 0x100>;
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-unit-addr.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-unit-addr.yaml
new file mode 100644
index 000000000000..93705cd45410
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-unit-addr.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-unit-addr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with malformed unit address
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-unit-addr
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ foo@01000 {
+ compatible = "example,test-unit-addr";
+ reg = <0x1000 0x100>;
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-unused-label.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-unused-label.yaml
new file mode 100644
index 000000000000..28d7176cbf08
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-unused-label.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-unused-label.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with an unused label
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-unused-label
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ dev: device@1000 {
+ compatible = "example,test-unused-label";
+ reg = <0x1000 0x100>;
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-value-ws-multiline.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-value-ws-multiline.yaml
new file mode 100644
index 000000000000..504bf0931c27
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-value-ws-multiline.yaml
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-value-ws-multiline.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with extra whitespace in a multi-line cell array
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-value-ws-multiline
+
+required:
+ - compatible
+
+additionalProperties: false
+
+examples:
+ - |
+ foo@0 {
+ compatible = "example,test-value-ws-multiline";
+ reg = < 0x0 0x4
+ 0x8 0xc>;
+ };
diff --git a/scripts/dtc/dt-style-selftest/bad/yaml-value-ws.yaml b/scripts/dtc/dt-style-selftest/bad/yaml-value-ws.yaml
new file mode 100644
index 000000000000..342ab9f399f1
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/bad/yaml-value-ws.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-bad-value-ws.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture with extra whitespace inside <...>
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-value-ws
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ foo@1000 {
+ compatible = "example,test-value-ws";
+ reg = < 0x1000 0x100 >;
+ };
diff --git a/scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt b/scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt
new file mode 100644
index 000000000000..070025c4568c
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt
@@ -0,0 +1,2 @@
+# mode=relaxed
+bad/dts-spaces.dts:1: [indent-unit-dts] indent unit must be 1 tab in DTS, got ' '
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-child-addr-order.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-child-addr-order.yaml.txt
new file mode 100644
index 000000000000..f0db79a0018b
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-child-addr-order.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-child-addr-order.yaml:37: example 0 [child-address-order] child node @100 out of address order
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-child-name-order.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-child-name-order.yaml.txt
new file mode 100644
index 000000000000..bb434b126191
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-child-name-order.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-child-name-order.yaml:34: example 0 [child-name-order] child node 'bar' out of name order
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-cont-align.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-cont-align.yaml.txt
new file mode 100644
index 000000000000..b5576dd0f6b1
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-cont-align.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-cont-align.yaml:29: example 0 [continuation-alignment] continuation should align to column 11 (under "<" or \")
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-digit-node-order.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-digit-node-order.yaml.txt
new file mode 100644
index 000000000000..6de275e2dcb5
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-digit-node-order.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-digit-node-order.yaml:33: example 0 [child-address-order] child node @10 out of address order
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-hex-case.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-hex-case.yaml.txt
new file mode 100644
index 000000000000..6600f7cd1ba5
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-hex-case.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-hex-case.yaml:28: example 0 [hex-case] hex literal '0xABCD' must be lowercase
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
new file mode 100644
index 000000000000..5ef290d3a847
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-indent-strict.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-indent-strict.yaml:26: example 0 [indent-unit-strict] indent unit must be 4 spaces in strict mode, got ' '
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-line-length.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-line-length.yaml.txt
new file mode 100644
index 000000000000..89b36360caa4
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-line-length.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-line-length.yaml:27: example 0 [line-length] line exceeds 80 columns (81)
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
new file mode 100644
index 000000000000..c989f8f19853
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt
@@ -0,0 +1,3 @@
+# 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
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-node-close.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-node-close.yaml.txt
new file mode 100644
index 000000000000..ee894747b5b9
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-node-close.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-node-close.yaml:30: example 0 [node-close-alone] closing brace must be on its own line
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-prop-order.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-prop-order.yaml.txt
new file mode 100644
index 000000000000..578df7209170
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-prop-order.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-prop-order.yaml:28: example 0 [property-order] property 'compatible' out of canonical order (should sort before 'reg')
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-prop-pairing.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-prop-pairing.yaml.txt
new file mode 100644
index 000000000000..e6e21349a939
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-prop-pairing.yaml.txt
@@ -0,0 +1,3 @@
+# mode=strict
+bad/yaml-prop-pairing.yaml:30: example 0 [property-order] property 'clocks' out of canonical order (should sort before 'clock-names')
+bad/yaml-prop-pairing.yaml:32: example 0 [property-order] property 'pinctrl-0' out of canonical order (should sort before 'pinctrl-names')
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-required-blank.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-required-blank.yaml.txt
new file mode 100644
index 000000000000..04ea0bacdcb9
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-required-blank.yaml.txt
@@ -0,0 +1,3 @@
+# mode=strict
+bad/yaml-required-blank.yaml:29: example 0 [required-blank-lines] "status" must be preceded by a blank line
+bad/yaml-required-blank.yaml:30: example 0 [required-blank-lines] child node must be preceded by a blank line
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt
new file mode 100644
index 000000000000..9e83246fbaa1
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt
@@ -0,0 +1,2 @@
+# mode=relaxed
+bad/yaml-tab.yaml:28: example 0 [tab-in-dts] tab character not allowed in DTS example
--git a/scripts/dtc/dt-style-selftest/expected/yaml-trailing-comment.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-trailing-comment.yaml.txt
new file mode 100644
index 000000000000..69dbb1d03239
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-trailing-comment.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-trailing-comment.yaml:25: example 0 [property-order] property 'compatible' out of canonical order (should sort before 'reg')
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-trailing-ws.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-trailing-ws.yaml.txt
new file mode 100644
index 000000000000..cfdbc8476c73
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-trailing-ws.yaml.txt
@@ -0,0 +1,2 @@
+# mode=relaxed
+bad/yaml-trailing-ws.yaml:27: example 0 [trailing-whitespace] trailing whitespace
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-unit-addr.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-unit-addr.yaml.txt
new file mode 100644
index 000000000000..b52f0ef20bee
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-unit-addr.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-unit-addr.yaml:26: example 0 [unit-address-format] unit address '01000' has leading zeros
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-unused-label.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-unused-label.yaml.txt
new file mode 100644
index 000000000000..4f00202f0902
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-unused-label.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-unused-label.yaml:26: example 0 [unused-labels] label 'dev' defined but never &-referenced
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-value-ws-multiline.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-value-ws-multiline.yaml.txt
new file mode 100644
index 000000000000..3df55b1762d0
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-value-ws-multiline.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-value-ws-multiline.yaml:25: example 0 [value-whitespace] extra whitespace inside <...>
diff --git a/scripts/dtc/dt-style-selftest/expected/yaml-value-ws.yaml.txt b/scripts/dtc/dt-style-selftest/expected/yaml-value-ws.yaml.txt
new file mode 100644
index 000000000000..cbb5f88fe85f
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/expected/yaml-value-ws.yaml.txt
@@ -0,0 +1,2 @@
+# mode=strict
+bad/yaml-value-ws.yaml:28: example 0 [value-whitespace] extra whitespace inside <...>
diff --git a/scripts/dtc/dt-style-selftest/good/dts-cont-align.dts b/scripts/dtc/dt-style-selftest/good/dts-cont-align.dts
new file mode 100644
index 000000000000..5c5ffdd1a7df
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/good/dts-cont-align.dts
@@ -0,0 +1,27 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+ *
+ * Test fixture: tab-indented .dts with a tab-and-space aligned
+ * multi-line property. Continuation lines mix tabs for indent and
+ * spaces for alignment by design; that must not be flagged.
+ */
+
+/dts-v1/;
+
+/ {
+ compatible = "example,test-board";
+ #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>;
+ pinmux = <
+ 0x01
+ 0x02
+ >;
+ };
+};
diff --git a/scripts/dtc/dt-style-selftest/good/dts-tab.dts b/scripts/dtc/dt-style-selftest/good/dts-tab.dts
new file mode 100644
index 000000000000..14295811c2bc
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/good/dts-tab.dts
@@ -0,0 +1,30 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+ *
+ * Test fixture: a properly formatted .dts using one-tab indent.
+ */
+
+/dts-v1/;
+
+/ {
+ compatible = "example,test-board";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ bus@10000 {
+ compatible = "simple-bus";
+ reg = <0x10000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ device@100 {
+ compatible = "example,test";
+ reg = <0x100 0x10>;
+ };
+
+ device@200 {
+ compatible = "example,test";
+ reg = <0x200 0x10>;
+ };
+ };
+};
diff --git a/scripts/dtc/dt-style-selftest/good/yaml-4space.yaml b/scripts/dtc/dt-style-selftest/good/yaml-4space.yaml
new file mode 100644
index 000000000000..1502f803c24c
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/good/yaml-4space.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/test-good-4space.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Test fixture for dt-check-style
+
+maintainers:
+ - Test User <test@example.com>
+
+properties:
+ compatible:
+ const: example,test-4space
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ bus@10000 {
+ compatible = "simple-bus";
+ reg = <0x10000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ device@100 {
+ compatible = "example,test-4space";
+ reg = <0x100 0x10>;
+ };
+
+ device@200 {
+ compatible = "example,test-4space";
+ reg = <0x200 0x10>;
+ };
+ };
diff --git a/scripts/dtc/dt-style-selftest/run.sh b/scripts/dtc/dt-style-selftest/run.sh
new file mode 100755
index 000000000000..8117dd9be90a
--- /dev/null
+++ b/scripts/dtc/dt-style-selftest/run.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Run dt-check-style against fixtures under good/ and bad/.
+# good/ files must produce no output and exit 0 in both modes.
+# bad/ files must produce the expected output (in expected/<name>.txt)
+# and exit 1.
+#
+# The mode used for a bad fixture is whichever produces a violation:
+# trailing-whitespace and tab fixtures use the default (relaxed),
+# the rest use --mode=strict. The expected output files name the
+# mode in their first line.
+
+set -u
+
+here=$(cd "$(dirname "$0")" && pwd)
+tool="$here/../dt-check-style"
+fail=0
+
+run() {
+ file=$1
+ mode=$2
+ "$tool" --mode="$mode" "$file" 2>&1
+}
+
+# good/ -- must exit 0 and produce no output in both modes
+for f in "$here"/good/*; do
+ [ -e "$f" ] || continue
+ for mode in relaxed strict; do
+ out=$(run "$f" "$mode")
+ rc=$?
+ if [ -n "$out" ] || [ "$rc" -ne 0 ]; then
+ echo "FAIL good/$mode: $(basename "$f") (exit $rc, want 0):"
+ echo "$out" | sed 's/^/ /'
+ fail=$((fail + 1))
+ fi
+ done
+done
+
+# bad/ -- must match expected/<name>.txt
+for f in "$here"/bad/*; do
+ [ -e "$f" ] || continue
+ name=$(basename "$f")
+ expected="$here/expected/$name.txt"
+ if [ ! -f "$expected" ]; then
+ echo "FAIL bad: missing $expected"
+ fail=$((fail + 1))
+ continue
+ fi
+ mode=$(head -1 "$expected" | sed 's/^# mode=//')
+ body=$(tail -n +2 "$expected")
+ out=$(run "$f" "$mode")
+ rc=$?
+ # Strip the directory prefix so expected files are portable.
+ out=$(printf '%s\n' "$out" | sed "s|$here/bad/|bad/|g")
+ if [ "$out" != "$body" ] || [ "$rc" -ne 1 ]; then
+ echo "FAIL bad/$mode: $name (exit $rc, want 1):"
+ bf=$(mktemp)
+ printf '%s\n' "$body" > "$bf"
+ printf '%s\n' "$out" | diff -u "$bf" - | sed 's/^/ /'
+ rm -f "$bf"
+ fail=$((fail + 1))
+ fi
+done
+
+if [ "$fail" -eq 0 ]; then
+ echo "PASS"
+ exit 0
+fi
+echo "FAILED ($fail)"
+exit 1
--
2.54.0
^ permalink raw reply related
* [PATCH v4 1/3] dt-bindings: add DTS style checker
From: Daniel Golle @ 2026-05-22 18:04 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Nathan Chancellor,
Nicolas Schier, Saravana Kannan, Daniel Golle, Miguel Ojeda,
Gary Guo, Tamir Duberstein, Thomas Weißschuh, Steven Rostedt,
Masahiro Yamada, Aleksander Jan Bajkowski, Guenter Roeck,
Test User, devicetree, linux-kernel, linux-kbuild
In-Reply-To: <cover.1779472837.git.daniel@makrotopia.org>
Add a Python tool that checks DTS coding style on examples in YAML
binding files and on .dts/.dtsi/.dtso source files. Rules are kept in
a small declarative registry, each tagged 'relaxed' (default; must be
zero-violation on the current tree) or 'strict' (opt-in for new
submissions). Promoting a rule from strict to relaxed is a one-line
edit once the tree is clean.
Relaxed mode covers trailing whitespace, tab characters in YAML
examples, mixed tab+space indents, and missing tabs in .dts files.
Strict adds indent unit and consistency checks, blank-line placement,
sibling address ordering, "compatible" and "reg" ordering, and unused
labels.
The tool reads file paths from @argfile and parallelises across CPUs
via -j N. With no -j given it picks up $PARALLELISM (set by
scripts/jobserver-exec from the GNU make jobserver) and falls back to
os.cpu_count() otherwise. Running as one Python invocation amortises
the ruamel.yaml import across the whole tree -- ~2s on a 32-CPU host
vs ~28s sequential.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
Changes since v3:
- node and property name regexes now accept a leading digit; the
DT spec permits node names like 1wire@10 or 3d-engine@20
- classify_lines() strips trailing // and /* */ comments before the
structural endswith() checks (new _split_code() helper), so a line
such as "node { /* c */" or "prop = <1>; // c" is no longer
misclassified as a property or continuation
- continuation-alignment now compares display columns (tabs expanded
to 8) instead of raw string length, so tab-and-space aligned .dts
continuation lines are not falsely flagged; the column helper is
shared with line-length
- value-whitespace flags only whitespace directly inside the
brackets (after '<', before '>') and checks single- and
multi-line cell lists; it no longer flags inter-value spacing
Changes since v2:
- route findings output from stdout to stderr so a quiet
dt_binding_check produces no output (Rob)
Changes since v1:
- renamed dt-check-example-style -> dt-check-style; tool now also
accepts .dts/.dtsi/.dtso files directly (tab-indent variant) and
distinguishes .dts/.dtsi/.dtso so unused-labels skips .dtsi/.dtso
where labels are exported to includers/applies-to
- rules declared in a registry tagged relaxed/strict; default
relaxed mode is zero-violation on the current tree
- added -j N with $PARALLELISM (jobserver) awareness
- dropped node-name [a-z0-9-] check (Rob: better as a meta-schema)
- property-order rebuilt around buckets + declarative pairing rules
(<x>-names after <x>, pinctrl-names after last pinctrl-N) plus
natural-sort fallback
- added child-name-order, required-blank-lines, hex-case,
unit-address-format, value-whitespace, node-close-alone,
line-length and continuation-alignment to strict mode
---
scripts/dtc/dt-check-style | 1120 ++++++++++++++++++++++++++++++++++++
1 file changed, 1120 insertions(+)
create mode 100755 scripts/dtc/dt-check-style
diff --git a/scripts/dtc/dt-check-style b/scripts/dtc/dt-check-style
new file mode 100755
index 000000000000..93cb1d7d2985
--- /dev/null
+++ b/scripts/dtc/dt-check-style
@@ -0,0 +1,1120 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Check DTS coding style on YAML binding examples and on
+# .dts/.dtsi/.dtso source files. Enforces rules from
+# Documentation/devicetree/bindings/dts-coding-style.rst.
+#
+# Two modes:
+# --mode=relaxed (default)
+# Only rules that produce zero warnings on the current tree.
+# Suitable for dt_binding_check.
+# --mode=strict
+# All rules. Required for new submissions.
+#
+# Two input types (auto-detected by file extension):
+# *.yaml -- DT binding; check each example block
+# *.dts/*.dtsi/*.dtso -- DTS source; whole file is one block
+#
+# Rules are declared in a registry (see RULES below); each rule is
+# tagged with the lowest mode that runs it. Promoting a rule from
+# 'strict' to 'relaxed' is a one-line change.
+
+import argparse
+import re
+import sys
+from enum import Enum, auto
+
+import ruamel.yaml
+
+
+# ---------------------------------------------------------------------------
+# Line classification
+# ---------------------------------------------------------------------------
+
+class LineType(Enum):
+ BLANK = auto()
+ COMMENT = auto() # // ... or /* ... */ on one line
+ COMMENT_START = auto() # /* without closing */
+ COMMENT_BODY = auto() # inside a multi-line comment
+ COMMENT_END = auto() # closing */
+ PREPROCESSOR = auto() # #include / #define / #ifdef / ...
+ NODE_OPEN = auto() # something { (with optional label/name/addr)
+ NODE_CLOSE = auto() # };
+ PROPERTY = auto() # name = value; or name;
+ CONTINUATION = auto() # continuation of a multi-line property
+
+
+re_cpp_directive = re.compile(
+ r'^#\s*(include|define|undef|ifdef|ifndef|if|else|elif|endif|'
+ r'pragma|error|warning)\b')
+
+# 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@...).
+re_node_header = re.compile(
+ r'^(?:([a-zA-Z_][a-zA-Z0-9_]*):\s*)?'
+ r'([a-zA-Z0-9][a-zA-Z0-9,._+-]*|/)'
+ r'(?:@([0-9a-fA-F,]+))?'
+ r'\s*\{$')
+
+re_ref_node = re.compile(
+ r'^&([a-zA-Z_][a-zA-Z0-9_]*)\s*\{$')
+
+
+def is_preprocessor(stripped):
+ """Tell C preprocessor directives apart from DTS '#'-prefixed props."""
+ return re_cpp_directive.match(stripped) is not None
+
+
+class DtsLine:
+ __slots__ = ('lineno', 'raw', 'linetype', 'indent_str', 'stripped',
+ 'prop_name', 'continuations',
+ 'node_name', 'node_addr', 'label', 'ref_name', 'depth')
+
+ def __init__(self, lineno, raw, linetype, indent_str, stripped):
+ self.lineno = lineno # 1-based within the block
+ self.raw = raw
+ self.linetype = linetype
+ self.indent_str = indent_str # leading whitespace as-is
+ self.stripped = stripped
+ self.prop_name = None
+ self.continuations = []
+ self.node_name = None
+ self.node_addr = None
+ self.label = None
+ self.ref_name = None
+ self.depth = 0 # filled in by classify_lines
+
+
+def _split_code(text):
+ """Return (code, opens_block) for a leading-stripped line: the
+ code portion with // and /* */ comments removed (string literals
+ kept verbatim), and whether a /* */ block comment is left open.
+ The code portion is right-stripped so the endswith() checks in
+ classify_lines see code only, not a trailing comment or blanks."""
+ out = []
+ i = 0
+ n = len(text)
+ while i < n:
+ c = text[i]
+ if c == '"':
+ j = i + 1
+ while j < n:
+ if text[j] == '\\':
+ j += 2
+ continue
+ if text[j] == '"':
+ j += 1
+ break
+ j += 1
+ out.append(text[i:j])
+ i = j
+ continue
+ if c == '/' and i + 1 < n and text[i + 1] == '/':
+ break
+ if c == '/' and i + 1 < n and text[i + 1] == '*':
+ end = text.find('*/', i + 2)
+ if end < 0:
+ return (''.join(out).rstrip(), True)
+ i = end + 2
+ continue
+ out.append(c)
+ i += 1
+ return (''.join(out).rstrip(), False)
+
+
+def classify_lines(text):
+ """Return a list of DtsLine. Tracks { } depth and groups
+ continuation lines onto their leading PROPERTY line."""
+ out = []
+ in_block_comment = False
+ prev_complete = True
+ depth = 0
+
+ # Split preserving the indent string verbatim
+ re_lead = re.compile(r'^([ \t]*)(.*)$')
+
+ for i, raw in enumerate(text.split('\n'), start=1):
+ m = re_lead.match(raw)
+ indent_str = m.group(1)
+ stripped = m.group(2)
+
+ if not stripped:
+ dl = DtsLine(i, raw, LineType.BLANK, '', '')
+ dl.depth = depth
+ out.append(dl)
+ continue
+
+ if in_block_comment:
+ ltype = (LineType.COMMENT_END if '*/' in stripped
+ else LineType.COMMENT_BODY)
+ if ltype == LineType.COMMENT_END:
+ in_block_comment = False
+ dl = DtsLine(i, raw, ltype, indent_str, stripped)
+ dl.depth = depth
+ out.append(dl)
+ continue
+
+ if stripped.startswith('/*'):
+ if '*/' in stripped:
+ ltype = LineType.COMMENT
+ else:
+ in_block_comment = True
+ ltype = LineType.COMMENT_START
+ dl = DtsLine(i, raw, ltype, indent_str, stripped)
+ dl.depth = depth
+ out.append(dl)
+ continue
+
+ if stripped.startswith('//'):
+ dl = DtsLine(i, raw, LineType.COMMENT, indent_str, stripped)
+ dl.depth = depth
+ out.append(dl)
+ continue
+
+ if stripped.startswith('#') and is_preprocessor(stripped):
+ dl = DtsLine(i, raw, LineType.PREPROCESSOR,
+ indent_str, stripped)
+ dl.depth = depth
+ out.append(dl)
+ prev_complete = True
+ continue
+
+ # Drop a trailing comment so the structural suffix checks
+ # below see code only; a '/*' left open carries over.
+ code, opens_block = _split_code(stripped)
+ if opens_block:
+ in_block_comment = True
+
+ if not prev_complete:
+ dl = DtsLine(i, raw, LineType.CONTINUATION, indent_str, code)
+ dl.depth = depth
+ out.append(dl)
+ prev_complete = (code.endswith(';') or
+ code.endswith('{') or
+ code.endswith('};'))
+ continue
+
+ if code == '};' or code == '}':
+ depth = max(depth - 1, 0)
+ dl = DtsLine(i, raw, LineType.NODE_CLOSE, indent_str, code)
+ dl.depth = depth
+ out.append(dl)
+ prev_complete = True
+ continue
+
+ if code.endswith('{'):
+ dl = DtsLine(i, raw, LineType.NODE_OPEN, indent_str, code)
+ parse_node_header(dl)
+ dl.depth = depth
+ out.append(dl)
+ depth += 1
+ prev_complete = True
+ continue
+
+ # Property (or first line of a multi-line property).
+ dl = DtsLine(i, raw, LineType.PROPERTY, indent_str, code)
+ parse_property_name(dl)
+ dl.depth = depth
+ out.append(dl)
+ prev_complete = code.endswith(';')
+
+ # Group continuation lines onto their leading PROPERTY.
+ last_prop = None
+ grouped = []
+ for dl in out:
+ if dl.linetype == LineType.CONTINUATION and last_prop is not None:
+ last_prop.continuations.append(dl)
+ continue
+ if dl.linetype == LineType.PROPERTY:
+ last_prop = dl
+ elif dl.linetype != LineType.BLANK and \
+ dl.linetype not in (LineType.COMMENT, LineType.COMMENT_BODY,
+ LineType.COMMENT_END,
+ LineType.COMMENT_START):
+ last_prop = None
+ grouped.append(dl)
+ return grouped
+
+
+def parse_node_header(dl):
+ m = re_node_header.match(dl.stripped)
+ if m:
+ dl.label = m.group(1)
+ dl.node_name = m.group(2)
+ dl.node_addr = m.group(3)
+ return
+ m = re_ref_node.match(dl.stripped)
+ if m:
+ dl.ref_name = m.group(1)
+
+
+def parse_property_name(dl):
+ m = re.match(r'^([a-zA-Z0-9#][a-zA-Z0-9,._+#-]*)\s*[=;]', dl.stripped)
+ if m:
+ dl.prop_name = m.group(1)
+
+
+def collect_labels_and_refs(text):
+ """Return (defined_labels, referenced_labels) found anywhere outside
+ /* */ comments. Labels named fake_intc* (injected by
+ dt-extract-example) are skipped."""
+ # Strip block comments first so labels inside them don't count
+ stripped = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL)
+ # Strip line comments
+ stripped = re.sub(r'//[^\n]*', '', stripped)
+ defined = set()
+ referenced = set()
+ for m in re.finditer(r'(?:^|[\s{])([a-zA-Z_][a-zA-Z0-9_]*):\s*[a-zA-Z/&]',
+ stripped):
+ name = m.group(1)
+ if not name.startswith('fake_intc'):
+ defined.add(name)
+ for m in re.finditer(r'&([a-zA-Z_][a-zA-Z0-9_]*)', stripped):
+ referenced.add(m.group(1))
+ return defined, referenced
+
+
+# ---------------------------------------------------------------------------
+# Rule registry
+# ---------------------------------------------------------------------------
+
+class Ctx:
+ """Context passed to each rule check. Carries the parsed lines,
+ raw text, mode, and indent kind."""
+
+ def __init__(self, lines, text, mode, indent_kind):
+ self.lines = lines
+ self.text = text
+ self.mode = mode # 'relaxed' or 'strict'
+ self.indent_kind = indent_kind # 'spaces' or 'tab'
+
+
+class Rule:
+ __slots__ = ('name', 'mode', 'description', 'check', 'applies_to')
+
+ def __init__(self, name, mode, description, check,
+ applies_to=('yaml', 'dts', 'dtsi', 'dtso')):
+ self.name = name
+ self.mode = mode # 'relaxed' or 'strict'
+ self.description = description
+ self.check = check
+ self.applies_to = applies_to # input types this rule covers
+
+
+# --- individual rule check functions --------------------------------------
+
+def check_trailing_whitespace(ctx):
+ for dl in ctx.lines:
+ if dl.raw != dl.raw.rstrip():
+ yield (dl.lineno, 'trailing whitespace')
+
+
+def check_tab_in_dts(ctx):
+ """Reject literal tabs in DTS lines when input is YAML.
+
+ For YAML examples, indent and content must use spaces. Tabs inside
+ 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':
+ return
+ for dl in ctx.lines:
+ if dl.linetype == LineType.PREPROCESSOR:
+ continue
+ if dl.linetype == LineType.BLANK:
+ continue
+ if '\t' in dl.raw:
+ yield (dl.lineno, 'tab character not allowed in DTS example')
+
+
+def check_mixed_indent_chars(ctx):
+ """Indent must be all-spaces or all-tabs, never mixed on one line."""
+ 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:
+ yield (dl.lineno, 'mixed tabs and spaces in indent')
+
+
+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."""
+ for dl in ctx.lines:
+ if dl.depth != 1:
+ continue
+ if dl.linetype in (LineType.BLANK, LineType.PREPROCESSOR):
+ continue
+ if dl.linetype in (LineType.COMMENT_BODY, LineType.COMMENT_END):
+ continue
+ if not dl.indent_str:
+ continue
+ if dl.indent_str == '\t':
+ return '\t'
+ if dl.indent_str == ' ':
+ return ' '
+ if dl.indent_str == ' ':
+ return ' '
+ # Anything else at depth 1 is non-canonical; flag elsewhere.
+ return dl.indent_str
+ return None
+
+
+def check_indent_unit_relaxed(ctx):
+ """YAML examples: 2 or 4 spaces. Never tabs or other widths."""
+ unit = 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)
+
+
+def check_indent_unit_dts(ctx):
+ """DTS files: 1 tab per level. Always required."""
+ unit = 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)
+
+
+def check_indent_unit_strict(ctx):
+ """YAML: must be exactly 4 spaces. DTS: 1 tab (same as relaxed)."""
+ unit = detect_indent_unit(ctx)
+ if unit is None:
+ return
+ if ctx.indent_kind == 'spaces':
+ if unit != ' ':
+ yield (1, '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)
+ if unit is None:
+ return
+ if ctx.indent_kind == 'spaces':
+ if unit not in (' ', ' '):
+ return # let check_indent_unit_* report this
+ else:
+ if unit != '\t':
+ return
+
+ for dl in ctx.lines:
+ if dl.linetype in (LineType.BLANK, LineType.PREPROCESSOR):
+ continue
+ if dl.linetype == LineType.CONTINUATION:
+ continue # continuations align to <, not to indent unit
+ if dl.linetype in (LineType.COMMENT_BODY, LineType.COMMENT_END):
+ continue
+ if not dl.indent_str:
+ continue
+ # The indent must be 'unit' repeated dl.depth times, exactly.
+ # NODE_CLOSE lines have depth equal to the post-decrement value,
+ # which matches the indent expected.
+ expected = unit * dl.depth
+ if dl.indent_str != expected:
+ yield (dl.lineno,
+ 'indent mismatch (expected depth %d * %r)' %
+ (dl.depth, unit))
+
+
+def check_blank_lines(ctx):
+ """No two consecutive blank lines, no leading/trailing blank lines
+ in any node body."""
+ lines = ctx.lines
+ # Consecutive blanks
+ for i in range(1, len(lines)):
+ if lines[i].linetype == LineType.BLANK and \
+ lines[i - 1].linetype == LineType.BLANK:
+ yield (lines[i].lineno, 'consecutive blank lines')
+ # Blank right after { or right before }
+ for i, dl in enumerate(lines):
+ if dl.linetype != LineType.BLANK:
+ continue
+ prev = lines[i - 1] if i > 0 else None
+ nxt = lines[i + 1] if i + 1 < len(lines) else None
+ if prev is not None and prev.linetype == LineType.NODE_OPEN:
+ yield (dl.lineno, 'blank line at start of node body')
+ if nxt is not None and nxt.linetype == LineType.NODE_CLOSE:
+ yield (dl.lineno, 'blank line at end of node body')
+
+
+def _walk_bodies(lines):
+ """Yield lists of immediate-child NODE_OPEN lines for each node body
+ in the input. Skips ref-nodes (&label) since those don't have an
+ intrinsic ordering."""
+ body_stack = [[]]
+ for dl in lines:
+ if dl.linetype == LineType.NODE_OPEN:
+ body_stack[-1].append(dl)
+ body_stack.append([])
+ continue
+ if dl.linetype == LineType.NODE_CLOSE:
+ if len(body_stack) <= 1:
+ # Unbalanced; ignore to avoid crashing on malformed input
+ continue
+ yield body_stack.pop()
+ continue
+ while body_stack:
+ yield body_stack.pop()
+
+
+def _natural_sort_key(s):
+ """Split a string into a tuple of (kind, value) pairs that compares
+ numeric runs as ints, so 'foo10' sorts after 'foo2'."""
+ parts = []
+ for part in re.split(r'(\d+)', s):
+ if part.isdigit():
+ parts.append((0, int(part)))
+ else:
+ parts.append((1, part))
+ return tuple(parts)
+
+
+def check_child_address_order(ctx):
+ """Addressed siblings (foo@N) must appear in ascending address
+ order within their parent node body."""
+ for children in _walk_bodies(ctx.lines):
+ addressed = []
+ for c in children:
+ if c.node_addr is None:
+ continue
+ try:
+ parts = tuple(int(p, 16) for p in c.node_addr.split(','))
+ except ValueError:
+ continue
+ addressed.append((parts, c))
+ for i in range(1, len(addressed)):
+ if addressed[i][0] < addressed[i - 1][0]:
+ dl = addressed[i][1]
+ yield (dl.lineno,
+ 'child node @%s out of address order' %
+ dl.node_addr)
+
+
+def check_child_name_order(ctx):
+ """Unaddressed siblings must appear in natural-sort order by node
+ name within their parent node body. Addressed children are scoped
+ by check_child_address_order; reference nodes (&label { ... }) and
+ the root node are skipped."""
+ for children in _walk_bodies(ctx.lines):
+ unaddressed = []
+ for c in children:
+ if c.node_addr is not None:
+ continue
+ if c.node_name in (None, '/'):
+ continue
+ if c.ref_name is not None:
+ continue
+ unaddressed.append((_natural_sort_key(c.node_name), c))
+ for i in range(1, len(unaddressed)):
+ if unaddressed[i][0] < unaddressed[i - 1][0]:
+ dl = unaddressed[i][1]
+ yield (dl.lineno,
+ 'child node %r out of name order' % dl.node_name)
+
+
+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
+ the sub-key, signalling that the within-bucket key is computed by
+ the pairing rules."""
+ stripped = name.lstrip('#')
+ if name == 'compatible':
+ return (0, 0)
+ if name == 'reg':
+ return (1, 0)
+ if name == 'reg-names':
+ return (1, 1)
+ if name == 'ranges':
+ return (2, 0)
+ if name == 'status':
+ return (5, 0)
+ return (4 if ',' in stripped else 3, None)
+
+
+# Declarative pairing rules: each is a callable
+# (name, all_names) -> anchor_name_or_None
+# If a rule returns an anchor, the property sorts immediately after the
+# anchor. Rules are tried in order; the first match wins. If none
+# matches, the within-bucket key falls back to natural sort by the
+# #-stripped name.
+
+def _pair_pinctrl_names(name, all_names):
+ """pinctrl-names follows the highest pinctrl-N in the same node."""
+ if name != 'pinctrl-names':
+ return None
+ cands = [n for n in all_names if re.match(r'^pinctrl-\d+$', n)]
+ if not cands:
+ return None
+ return max(cands, key=_natural_sort_key)
+
+
+def _pair_x_names(name, all_names):
+ """Generic <x>-names follows its owning property. The owner is
+ usually plural (clocks/clock-names, dmas/dma-names,
+ resets/reset-names) but occasionally singular (reg/reg-names is
+ handled by the fixed slot above; this rule catches anything else)."""
+ if not name.endswith('-names'):
+ return None
+ base = name[:-len('-names')]
+ # Try plural and singular forms.
+ if (base + 's') in all_names:
+ return base + 's'
+ if base in all_names:
+ return base
+ return None
+
+
+PAIRING_RULES = (_pair_pinctrl_names, _pair_x_names)
+
+
+def _property_sort_key(name, all_names):
+ """Sort key for a property among its node-body siblings.
+
+ Format: (bucket, within_key, tiebreak). 'within_key' for
+ standard/vendor buckets follows pairing rules: a property paired
+ with anchor X sorts as if it were X with a higher tiebreak."""
+ bucket, fixed_sub = _property_bucket(name)
+ if fixed_sub is not None:
+ return (bucket, (), fixed_sub)
+
+ for rule in PAIRING_RULES:
+ anchor = rule(name, all_names)
+ if anchor is not None:
+ return (bucket, _natural_sort_key(anchor.lstrip('#')), 1)
+
+ return (bucket, _natural_sort_key(name.lstrip('#')), 0)
+
+
+def check_property_order(ctx):
+ """Properties within a node body must appear in canonical order:
+ compatible, reg(/reg-names), ranges, then the standard group, then
+ the vendor-specific group, then status. Inside the standard and
+ vendor groups, pairing rules apply (e.g. <x>-names follows <x>);
+ everything else falls back to natural sort by the #-stripped name."""
+ lines = ctx.lines
+ for i, dl in enumerate(lines):
+ if dl.linetype != LineType.NODE_OPEN:
+ continue
+ body_depth = dl.depth + 1
+ props = []
+ for j in range(i + 1, len(lines)):
+ d = lines[j]
+ if d.linetype == LineType.NODE_CLOSE and \
+ d.depth == body_depth - 1:
+ break
+ if d.linetype == LineType.PROPERTY and d.depth == body_depth \
+ and d.prop_name is not None:
+ props.append(d)
+ if len(props) < 2:
+ continue
+ all_names = [p.prop_name for p in props]
+ keyed = [(p, _property_sort_key(p.prop_name, all_names))
+ for p in props]
+ for k in range(1, len(keyed)):
+ if keyed[k][1] < keyed[k - 1][1]:
+ p = keyed[k][0]
+ prev = keyed[k - 1][0]
+ yield (p.lineno,
+ 'property %r out of canonical order '
+ '(should sort before %r)' %
+ (p.prop_name, prev.prop_name))
+
+
+def _strip_strings_and_comments(text):
+ """Remove string literals and /* */ + // comments from a single
+ line, replacing them with empty strings. Used so syntactic checks
+ (whitespace, hex case, etc.) don't false-positive on contents of
+ quoted strings or comments."""
+ text = re.sub(r'"(?:[^"\\]|\\.)*"', '""', text)
+ text = re.sub(r'/\*.*?\*/', '', text)
+ text = re.sub(r'//.*$', '', text)
+ return text
+
+
+def check_required_blank_lines(ctx):
+ """A blank line must precede each child node and the 'status'
+ property within a node body, except when these are the first
+ substantive item in the body."""
+ lines = ctx.lines
+ for i, open_dl in enumerate(lines):
+ if open_dl.linetype != LineType.NODE_OPEN:
+ continue
+ body_depth = open_dl.depth + 1
+ prev_substantive = None
+ between_blanks = 0
+ depth_inside = 0
+ for j in range(i + 1, len(lines)):
+ d = lines[j]
+ if d.linetype == LineType.NODE_CLOSE and \
+ d.depth == body_depth - 1 and depth_inside == 0:
+ break
+ # Track depth inside nested children so we only look at
+ # immediate-body items.
+ if d.linetype == LineType.NODE_OPEN and \
+ d.depth >= body_depth and depth_inside > 0:
+ depth_inside += 1
+ continue
+ if d.linetype == LineType.NODE_CLOSE and depth_inside > 0:
+ depth_inside -= 1
+ continue
+ if depth_inside > 0:
+ continue
+ if d.linetype == LineType.BLANK:
+ if prev_substantive is not None:
+ between_blanks += 1
+ continue
+ if d.linetype in (LineType.COMMENT, LineType.COMMENT_START,
+ LineType.COMMENT_BODY, LineType.COMMENT_END,
+ LineType.PREPROCESSOR):
+ continue
+ if d.linetype == LineType.CONTINUATION:
+ continue
+
+ needs_blank = False
+ if d.linetype == LineType.NODE_OPEN:
+ needs_blank = True
+ depth_inside = 1 # entered the child body
+ elif d.linetype == LineType.PROPERTY and d.prop_name == 'status':
+ needs_blank = True
+
+ if needs_blank and prev_substantive is not None and \
+ between_blanks == 0:
+ if d.linetype == LineType.NODE_OPEN:
+ yield (d.lineno,
+ 'child node must be preceded by a blank line')
+ else:
+ yield (d.lineno,
+ '"status" must be preceded by a blank line')
+
+ prev_substantive = d
+ between_blanks = 0
+
+
+def check_hex_case(ctx):
+ """Hex literals (0xN) must use lowercase digits and prefix."""
+ for dl in ctx.lines:
+ if dl.linetype in (LineType.BLANK, LineType.COMMENT,
+ LineType.COMMENT_START, LineType.COMMENT_BODY,
+ LineType.COMMENT_END, LineType.PREPROCESSOR):
+ continue
+ text = _strip_strings_and_comments(dl.raw)
+ for m in re.finditer(r'\b0[xX][0-9a-fA-F]+\b', text):
+ lit = m.group(0)
+ if any(c.isupper() for c in lit[2:]) or lit[1] == 'X':
+ yield (dl.lineno,
+ 'hex literal %r must be lowercase' % lit)
+
+
+def check_unit_address_format(ctx):
+ """Unit addresses must be lowercase hex without leading zeros.
+ For multi-cell addresses (comma-separated), each part is checked
+ independently. A single '0' is permitted (canonical zero)."""
+ for dl in ctx.lines:
+ if dl.linetype != LineType.NODE_OPEN:
+ continue
+ if dl.node_addr is None:
+ continue
+ addr = dl.node_addr
+ for part in addr.split(','):
+ if any(c in 'ABCDEF' for c in part):
+ yield (dl.lineno,
+ 'unit address %r must be lowercase hex' % addr)
+ break
+ if len(part) > 1 and part.startswith('0'):
+ yield (dl.lineno,
+ 'unit address %r has leading zeros' % addr)
+ break
+
+
+def check_value_whitespace(ctx):
+ """A <...> cell list must have no whitespace directly after '<'
+ or directly before '>'. Continuation lines are joined onto the
+ property so a <...> split across lines is checked too; a '<' or
+ '>' at a line break is glued straight to the neighbouring value,
+ so the break itself is not counted as padding. Outside strings
+ and comments only."""
+ for dl in ctx.lines:
+ if dl.linetype != LineType.PROPERTY:
+ continue
+ segs = [_strip_strings_and_comments(dl.raw).strip()]
+ for cont in dl.continuations:
+ segs.append(_strip_strings_and_comments(cont.stripped).strip())
+ text = ''
+ for s in segs:
+ if not s:
+ continue
+ if not text or text.endswith('<') or s.startswith('>'):
+ text += s
+ else:
+ text += ' ' + s
+ for m in re.finditer(r'<([^<>]*)>', text):
+ content = m.group(1)
+ if content and content != content.strip():
+ yield (dl.lineno, 'extra whitespace inside <...>')
+ break
+
+
+def check_node_close_alone(ctx):
+ """The closing '};' of a node must be on its own line. The
+ classifier already accepts only `};` or `}` as NODE_CLOSE; any
+ other line that still contains `};` (in code, not in strings or
+ comments) is mixing a node close with something else."""
+ for dl in ctx.lines:
+ if dl.linetype in (LineType.BLANK, LineType.COMMENT,
+ LineType.COMMENT_START, LineType.COMMENT_BODY,
+ LineType.COMMENT_END, LineType.PREPROCESSOR,
+ LineType.NODE_CLOSE):
+ continue
+ text = _strip_strings_and_comments(dl.raw)
+ if '};' in text:
+ yield (dl.lineno,
+ 'closing brace must be on its own line')
+
+
+def _display_col(text):
+ """Visual column width of text, with tabs expanded to the next
+ 8-column stop, matching how printf and most editors render a
+ line and the kernel-wide line length convention."""
+ col = 0
+ for ch in text:
+ if ch == '\t':
+ col = (col // 8 + 1) * 8
+ else:
+ col += 1
+ return col
+
+
+def check_line_length(ctx):
+ """Lines must not exceed 80 columns; tabs count as 8 (see
+ _display_col)."""
+ for dl in ctx.lines:
+ if dl.linetype == LineType.BLANK:
+ continue
+ cols = _display_col(dl.raw)
+ if cols > 80:
+ yield (dl.lineno,
+ 'line exceeds 80 columns (%d)' % cols)
+
+
+def check_continuation_alignment(ctx):
+ """A multi-line property's continuation lines must align their
+ first non-whitespace character to the display column of the first
+ '<' or '"' after the '=' in the leading line. Display columns are
+ used so tab-indented .dts files (where a continuation aligns with
+ tabs plus spaces) are compared correctly."""
+ for dl in ctx.lines:
+ if dl.linetype != LineType.PROPERTY:
+ continue
+ if not dl.continuations:
+ continue
+ eq = dl.raw.find('=')
+ if eq < 0:
+ continue
+ # First '<' or '"' after '='
+ rest = dl.raw[eq + 1:]
+ m = re.search(r'[<"]', rest)
+ if not m:
+ continue
+ target_col = _display_col(dl.raw[:eq + 1 + m.start()])
+ for cont in dl.continuations:
+ if _display_col(cont.indent_str) != target_col:
+ yield (cont.lineno,
+ 'continuation should align to column %d '
+ '(under "<" or \\")' % (target_col + 1))
+
+
+def check_unused_labels(ctx):
+ """Labels defined but never referenced are clutter."""
+ defined, referenced = collect_labels_and_refs(ctx.text)
+ for label in sorted(defined - referenced):
+ # Find the line where this label is defined for line-number
+ # reporting.
+ m = re.search(r'(?m)^.*\b' + re.escape(label) + r'\s*:', ctx.text)
+ lineno = ctx.text[:m.start()].count('\n') + 1 if m else 1
+ yield (lineno, 'label %r defined but never &-referenced' % label)
+
+
+# --- registry --------------------------------------------------------------
+
+RULES = [
+ # 'relaxed' is the default; rules in this group must produce zero
+ # output on a clean kernel tree (post the small prep-cleanup
+ # commit at the head of this series).
+ 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('mixed-indent-chars', 'relaxed',
+ 'indent must not mix tabs and spaces',
+ check_mixed_indent_chars),
+
+ # DTS files always use tabs; this is not negotiable per kernel
+ # coding style (.dts files are real source). Relaxed mode.
+ Rule('indent-unit-dts', 'relaxed',
+ 'DTS files: 1 tab per nesting level',
+ check_indent_unit_dts,
+ applies_to=('dts', 'dtsi', 'dtso')),
+
+ # 'strict' rules are opt-in (e.g. for new submissions via
+ # checkpatch.pl in a follow-up series). They flag many existing
+ # files and can be promoted to relaxed once those are cleaned up.
+ Rule('indent-unit', 'strict',
+ 'YAML: 2 or 4 spaces per level',
+ check_indent_unit_relaxed, applies_to=('yaml',)),
+ Rule('indent-unit-strict', 'strict',
+ 'YAML: must be 4 spaces per level',
+ check_indent_unit_strict, applies_to=('yaml',)),
+ Rule('indent-consistent', 'strict',
+ 'every line indented at depth * unit',
+ check_indent_consistent),
+ Rule('blank-lines', 'strict',
+ 'no consecutive blanks; no blanks at node body edges',
+ check_blank_lines),
+ Rule('child-address-order', 'strict',
+ 'addressed siblings must be in ascending address order',
+ check_child_address_order),
+ Rule('child-name-order', 'strict',
+ 'unaddressed siblings must be in natural-sort name order',
+ check_child_name_order),
+ Rule('property-order', 'strict',
+ 'canonical bucket + pairing + natural-sort order of properties',
+ check_property_order),
+ Rule('required-blank-lines', 'strict',
+ 'blank line before child nodes and before "status"',
+ check_required_blank_lines),
+ Rule('hex-case', 'strict',
+ 'hex literals must be lowercase',
+ check_hex_case),
+ Rule('unit-address-format', 'strict',
+ 'unit addresses must be lowercase hex without leading zeros',
+ check_unit_address_format),
+ Rule('value-whitespace', 'strict',
+ 'no whitespace directly inside <...> brackets',
+ check_value_whitespace),
+ Rule('node-close-alone', 'strict',
+ 'closing brace must be on its own line',
+ check_node_close_alone),
+ Rule('line-length', 'strict',
+ 'lines must not exceed 80 columns',
+ check_line_length),
+ Rule('continuation-alignment', 'strict',
+ 'multi-line property continuations align under "<" or "\\""',
+ check_continuation_alignment),
+ Rule('unused-labels', 'strict',
+ 'every label must be &-referenced in the same example/file '
+ '(skipped for .dtsi/.dtso since labels there are exported)',
+ check_unused_labels, applies_to=('yaml', 'dts')),
+]
+
+
+def select_rules(mode, input_kind):
+ """Return rules that apply to the given mode and input type."""
+ rank = {'relaxed': 0, 'strict': 1}
+ out = []
+ for r in RULES:
+ if rank[r.mode] > rank[mode]:
+ continue
+ if input_kind not in r.applies_to:
+ continue
+ out.append(r)
+ return out
+
+
+# ---------------------------------------------------------------------------
+# Block runner
+# ---------------------------------------------------------------------------
+
+def check_block(text, mode, indent_kind, 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)
+ rules = select_rules(mode, input_type)
+ findings = []
+ for r in rules:
+ for lineno, msg in r.check(ctx):
+ findings.append((lineno, r.name, msg))
+ findings.sort(key=lambda t: (t[0], t[1]))
+ return findings
+
+
+# ---------------------------------------------------------------------------
+# Input drivers (YAML examples vs raw DTS)
+# ---------------------------------------------------------------------------
+
+def _yaml_loader():
+ return ruamel.yaml.YAML()
+
+
+def iter_yaml_examples(filepath):
+ """Yield (example_text, base_lineno_in_file, example_index) tuples."""
+ yaml = _yaml_loader()
+ try:
+ with open(filepath, encoding='utf-8') as f:
+ data = yaml.load(f)
+ except Exception as e:
+ print('%s: error loading YAML: %s' % (filepath, e),
+ file=sys.stderr)
+ return
+ if not isinstance(data, dict) or 'examples' not in data:
+ return
+ examples = data['examples']
+ if not hasattr(examples, '__iter__'):
+ return
+ for i, ex in enumerate(examples):
+ if not isinstance(ex, str):
+ continue
+ try:
+ base = examples.lc.item(i)[0] + 2
+ except Exception:
+ base = 1
+ yield (str(ex), base, i)
+
+
+def iter_dts_file(filepath):
+ """Treat the whole file as a single block."""
+ try:
+ with open(filepath, encoding='utf-8') as f:
+ text = f.read()
+ except Exception as e:
+ print('%s: error reading: %s' % (filepath, e), file=sys.stderr)
+ return
+ yield (text, 1, None)
+
+
+# ---------------------------------------------------------------------------
+# Top-level processing
+# ---------------------------------------------------------------------------
+
+def input_kind(filepath):
+ p = filepath.lower()
+ if p.endswith('.yaml') or p.endswith('.yml'):
+ return 'yaml'
+ if p.endswith('.dts'):
+ return 'dts'
+ if p.endswith('.dtsi'):
+ return 'dtsi'
+ if p.endswith('.dtso'):
+ return 'dtso'
+ return None
+
+
+# All input types that use tab indentation and follow DTS coding style.
+DTS_FAMILY = ('dts', 'dtsi', 'dtso')
+
+
+def collect_findings(filepath, mode):
+ """Return a (lines, count) pair for filepath. lines is a list of
+ 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):
+ abs_line = base + lineno - 1
+ ex_tag = '' if idx is None else ' example %d' % idx
+ out.append('%s:%d:%s [%s] %s' %
+ (filepath, abs_line, ex_tag, rule, msg))
+ return (out, len(out))
+
+
+# Worker entry point for ProcessPoolExecutor.map(). Top-level so it is
+# picklable on every platform.
+def _worker(args):
+ filepath, mode = args
+ return collect_findings(filepath, mode)
+
+
+def main():
+ import os
+ ap = argparse.ArgumentParser(
+ description='Check DTS coding style on YAML examples and '
+ '.dts/.dtsi/.dtso files.',
+ fromfile_prefix_chars='@')
+ ap.add_argument('--mode', choices=('relaxed', 'strict'),
+ default='relaxed',
+ help='which rule set to apply (default: relaxed)')
+ ap.add_argument('-j', '--jobs', type=int, default=0,
+ metavar='N',
+ help='run N workers in parallel (default: respect '
+ 'the make jobserver via $PARALLELISM, otherwise '
+ 'os.cpu_count(); use 1 to disable multiprocessing)')
+ ap.add_argument('--list-rules', action='store_true',
+ help='print all rules with their mode and exit')
+ ap.add_argument('files', nargs='*', metavar='file',
+ help='YAML binding files or .dts/.dtsi/.dtso files; '
+ 'use @argfile to read paths from a file')
+ args = ap.parse_args()
+
+ if args.list_rules:
+ for r in RULES:
+ applies = ','.join(r.applies_to)
+ print('%-22s %-7s [%s] %s' %
+ (r.name, r.mode, applies, r.description))
+ return 0
+
+ if not args.files:
+ ap.error('no input files')
+
+ if args.jobs > 0:
+ jobs = args.jobs
+ else:
+ # When invoked under scripts/jobserver-exec, $PARALLELISM
+ # holds the slot count make has reserved for us; this lets
+ # `make -j N dt_binding_check` constrain our worker pool to N.
+ try:
+ jobs = int(os.environ['PARALLELISM'])
+ except (KeyError, ValueError):
+ jobs = os.cpu_count() or 1
+ # Single-process path: keep import surface small for tests and
+ # easy debugging.
+ if jobs == 1 or len(args.files) == 1:
+ total = 0
+ for f in args.files:
+ lines, n = collect_findings(f, args.mode)
+ for line in lines:
+ print(line, file=sys.stderr)
+ total += n
+ return 1 if total else 0
+
+ # Multi-process path. ex.map preserves input order so output is
+ # deterministic across runs.
+ from concurrent.futures import ProcessPoolExecutor
+ total = 0
+ work = [(f, args.mode) for f in args.files]
+ chunk = max(1, len(work) // (jobs * 8)) if work else 1
+ with ProcessPoolExecutor(max_workers=jobs) as ex:
+ for lines, n in ex.map(_worker, work, chunksize=chunk):
+ for line in lines:
+ print(line, file=sys.stderr)
+ total += n
+ return 1 if total else 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
--
2.54.0
^ permalink raw reply related
* [PATCH v4 2/3] dt-bindings: wire style checker into dt_binding_check
From: Daniel Golle @ 2026-05-22 18:04 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Nathan Chancellor,
Nicolas Schier, Saravana Kannan, Daniel Golle, Miguel Ojeda,
Gary Guo, Tamir Duberstein, Thomas Weißschuh, Steven Rostedt,
Masahiro Yamada, Aleksander Jan Bajkowski, Guenter Roeck,
Test User, devicetree, linux-kernel, linux-kbuild
In-Reply-To: <cover.1779472837.git.daniel@makrotopia.org>
Run dt-check-style as part of dt_binding_check_one. The recipe wraps
the tool with scripts/jobserver-exec so worker count follows the GNU
make jobserver -- `make -j N dt_binding_check` constrains the checker
to N workers rather than spawning one per CPU.
Default mode (relaxed) is zero-violation on the current tree, so this
does not introduce new warnings into make dt_binding_check. Stricter
rules are available via --mode=strict (eg. for use by checkpatch.pl in
a future series).
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
Changes since v3:
- build the @argfile with f=$(mktemp) and remove it with rm -f
(matching cmd_mk_schema), instead of Kbuild's $(tmp-target)
which leaves a stale .tmp_.dt-style.checked in the build tree
Changes since v2:
- use Kbuild's $(tmp-target) instead of mktemp so build output
stays inside the build folder (Nathan)
- collapse the conditional cleanup tail into the familiar
"&& touch $@ || true" pattern, matching cmd_chk_bindings;
keeps future warnings non-fatal (Rob, Nathan)
- retained the explicit $(PYTHON3) prefix (Rob asked why it
differs from the rest of this Makefile): per
Documentation/kbuild/makefiles.rst "Script invocation",
in-tree scripts should be called through their interpreter so
the executable bit and shebang are not relied on and the
user's $(PYTHON3) override is respected. The neighbouring
recipes invoke their Python helpers directly because those
come from external packages (dtschema's dt-extract-*,
dt-check-compatible, dt-doc-validate), which is the case Rob
asked about and which sits outside that rule.
Changes since v1:
- dropped xargs -n200 -P$(nproc) sharding; single Python invocation
with file list via @argfile
- dropped `|| true`: relaxed mode is zero-output today
- wrapped under scripts/jobserver-exec so worker count follows the
make jobserver
---
Documentation/devicetree/bindings/Makefile | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile
index 7b668f7fd400..00149e824261 100644
--- a/Documentation/devicetree/bindings/Makefile
+++ b/Documentation/devicetree/bindings/Makefile
@@ -46,6 +46,18 @@ quiet_cmd_chk_bindings = CHKDT $(src)
xargs -n200 -P$$(nproc) $(DT_DOC_CHECKER) -u $(src)) \
&& touch $@ || true
+DT_CHK_STYLE = $(srctree)/scripts/dtc/dt-check-style
+
+# Feed the file list to the checker via @argfile in a single Python
+# process so the ruamel.yaml import is paid once. scripts/jobserver-exec
+# claims slots from the GNU make jobserver and exposes the count via
+# $PARALLELISM, which dt-check-style picks up to size its worker pool.
+quiet_cmd_chk_style = STYLE $(src)
+ cmd_chk_style = f=$$(mktemp) && $(find_cmd) > $$f && \
+ $(PYTHON3) $(srctree)/scripts/jobserver-exec \
+ $(PYTHON3) $(DT_CHK_STYLE) @$$f \
+ && touch $@ || true; rm -f $$f
+
quiet_cmd_mk_schema = SCHEMA $@
cmd_mk_schema = f=$$(mktemp) ; \
$(find_all_cmd) > $$f ; \
@@ -62,13 +74,16 @@ override DTC_FLAGS := \
$(obj)/processed-schema.json: $(DT_DOCS) check_dtschema_version FORCE
$(call if_changed,mk_schema)
-targets += .dt-binding.checked .yamllint.checked
+targets += .dt-binding.checked .yamllint.checked .dt-style.checked
$(obj)/.yamllint.checked: $(DT_DOCS) $(src)/.yamllint FORCE
$(if $(DT_SCHEMA_LINT),$(call if_changed,yamllint),)
$(obj)/.dt-binding.checked: $(DT_DOCS) FORCE
$(call if_changed,chk_bindings)
+$(obj)/.dt-style.checked: $(DT_DOCS) FORCE
+ $(call if_changed,chk_style)
+
always-y += processed-schema.json
targets += $(patsubst $(obj)/%,%, $(CHK_DT_EXAMPLES))
targets += $(patsubst $(obj)/%.dtb,%.dts, $(CHK_DT_EXAMPLES))
@@ -82,7 +97,7 @@ dt_compatible_check: $(obj)/processed-schema.json
$(Q)$(srctree)/scripts/dtc/dt-extract-compatibles $(srctree) | xargs dt-check-compatible -v -s $<
PHONY += dt_binding_check_one
-dt_binding_check_one: $(obj)/.dt-binding.checked $(obj)/.yamllint.checked
+dt_binding_check_one: $(obj)/.dt-binding.checked $(obj)/.yamllint.checked $(obj)/.dt-style.checked
PHONY += dt_binding_check
dt_binding_check: dt_binding_check_one $(CHK_DT_EXAMPLES)
--
2.54.0
^ permalink raw reply related
* [PATCH v4 0/3] dt-bindings: automated coding style check for DTS examples
From: Daniel Golle @ 2026-05-22 18:04 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Nathan Chancellor,
Nicolas Schier, Saravana Kannan, Daniel Golle, Miguel Ojeda,
Gary Guo, Tamir Duberstein, Thomas Weißschuh, Steven Rostedt,
Masahiro Yamada, Aleksander Jan Bajkowski, Guenter Roeck,
Test User, devicetree, linux-kernel, linux-kbuild
Documentation/devicetree/bindings/dts-coding-style.rst documents
the style expected of DT examples and source files, but nothing
existing actually enforces it. dtc tolerates arbitrary whitespace,
yamllint only sees the YAML envelope and not the DTS content
inside literal block scalars, and so reviewers spend cycles
flagging issues that tooling could catch.
Add scripts/dtc/dt-check-style, a Python tool that checks DTS
coding style on YAML binding examples and on .dts/.dtsi/.dtso
source files. Rules live in a small declarative registry; each
rule is tagged 'relaxed' (default) or 'strict' (opt-in for new
submissions). Promoting a rule from strict to relaxed is a
one-line edit once the tree catches up.
Relaxed mode covers trailing whitespace, tab characters in YAML
examples, mixed tab+space indents, and the per-input-type indent
character (1 tab for .dts/.dtsi/.dtso). It is zero-violation on
the current tree and runs as part of dt_binding_check_one, so no
new warnings appear in `make dt_binding_check`.
Strict mode adds indent unit and depth consistency; blank-line
policy (no consecutive blanks or blanks at body edges; required
blank line before each child node and before "status"); property
ordering by canonical bucket (compatible, reg/reg-names, ranges,
standard, vendor, status) with declarative within-bucket pairing
rules (<x>-names follows <x>, pinctrl-names follows the last
pinctrl-N) and natural-sort fallback; sibling node ordering by
unit address or natural-sort name; line length (80 columns);
continuation alignment of multi-line property values under the
first '<' or '"' after the '='; lowercase hex literals and unit
addresses; no whitespace padding inside <...>; closing-brace
placement; and unused-label detection (skipped for .dtsi/.dtso
since labels there are exported to includers/applies-to).
Together these constrain a DT structure to a single canonical
rendering modulo the author's choice of when to wrap properties
for readability. Comments are intentionally out of scope. Strict
mode is opt-in, intended for use by checkpatch.pl in a follow-up
series.
The tool reads file paths from @argfile and parallelises across
CPUs via -j N. With no -j given it picks up $PARALLELISM (set by
scripts/jobserver-exec from the GNU make jobserver) and falls
back to os.cpu_count() otherwise. Running as one Python
invocation amortises the ruamel.yaml import across the whole
tree -- ~2s on a 32-CPU host vs ~28s sequential. ruamel.yaml is
the only non-stdlib dependency, already required by dtschema.
A selftest under scripts/dtc/dt-style-selftest/ pairs good/ and
bad/ fixtures with expected output so rule behaviour can be
exercised independently of the full tree via the
dt_style_selftest top-level make target.
---
v1: https://lore.kernel.org/all/cover.1776700167.git.daniel@makrotopia.org/
v2: https://lore.kernel.org/all/cover.1777471439.git.daniel@makrotopia.org/
v3: https://lore.kernel.org/all/cover.1778454442.git.daniel@makrotopia.org/
Changes since v3:
- dt-check-style: accept node and property names that begin
with a digit (the DT spec permits names like 1wire@10)
- dt-check-style: strip trailing // and /* */ comments before
line classification, so a trailing comment on a node-open or
property line no longer causes misclassification
- dt-check-style: continuation-alignment compares display
columns (tabs expanded to 8) instead of raw string length,
removing many false positives on tab-indented .dts files
- dt-check-style: value-whitespace flags only whitespace directly
inside the brackets (after '<', before '>'), on single- and
multi-line cell lists; it no longer flags inter-value spacing,
which is often deliberate column alignment
- Makefile: build the @argfile with mktemp and remove it, so no
stale .tmp_.dt-style.checked is left in the build tree
- run.sh: drop bash-only process substitution (POSIX sh now)
and check the checker's exit status
- selftest: add fixtures for the above (digit-leading nodes,
trailing comments, multi-line cell arrays, tab+space aligned
continuations) and update yaml-value-ws for the reworked
value-whitespace rule
Changes since v2:
- route findings to stderr so a quiet dt_binding_check produces
no output (Rob)
- switch the Makefile recipe from mktemp to Kbuild's
$(tmp-target) so build output stays inside the build folder
(Nathan)
- collapse the recipe's exit-handling tail into the familiar
"&& touch $@ || true" pattern, matching cmd_chk_bindings;
keeps future warnings non-fatal (Rob, Nathan)
- explain in patch 2/3 why the recipe uses an explicit
$(PYTHON3) prefix where the neighbouring recipes call their
scripts directly (Rob)
- append a trailing newline to every expected/*.txt selftest
fixture (Rob)
- restore the trailing whitespace inside yaml-trailing-ws.yaml
that had been silently stripped during re-application, so the
selftest actually exercises the trailing-whitespace rule
Changes since v1:
- rules declared in a registry tagged relaxed/strict; default
relaxed mode is zero-violation on the current tree
- tool now also accepts .dts/.dtsi/.dtso files directly (with a
tab-indent variant); unused-labels skipped for .dtsi/.dtso
where labels are exported to includers/applies-to
- renamed dt-check-example-style -> dt-check-style
- added -j N with $PARALLELISM (jobserver) awareness
- dropped node-name [a-z0-9-] check (Rob: better as a meta-schema)
- property-order rebuilt around buckets + declarative pairing
rules plus natural-sort fallback
- added child-name-order, required-blank-lines, hex-case,
unit-address-format, value-whitespace, node-close-alone,
line-length and continuation-alignment to strict mode
- new selftest patch (Krzysztof: "would be happy to see at
least a few test cases for it")
Default relaxed mode is zero-violation on the current tree.
Strict-mode violation counts on a current tree (5506 YAML
bindings, 6530 in-tree .dts/.dtsi/.dtso under arch/):
rule yaml dts
property-order 14554 245000
continuation-alignment 1857 93536
indent-consistent 1562 48720
required-blank-lines 1876 48563
line-length 105 26322
child-name-order 667 16821
mixed-indent-chars 0 13294
unused-labels 3611 11628
child-address-order 63 4076
blank-lines 82 1866
node-close-alone 38 774
value-whitespace 38 715
hex-case 78 669
indent-unit-dts -- 190
unit-address-format 5 39
trailing-whitespace 0 10
indent-unit-strict 1492 --
indent-unit 179 --
(YAML and DTS columns reflect the rules that apply to each input
type; e.g. indent-unit-strict is YAML-only since .dts files use
tabs, indent-unit-dts is the equivalent DTS-only check.
unused-labels is skipped for .dtsi/.dtso since labels there are
exported to includers/applies-to.)
The script was written with generous help from Claude Opus 4.7,
since my Python is even worse than my DTS coding style.
Daniel Golle (3):
dt-bindings: add DTS style checker
dt-bindings: wire style checker into dt_binding_check
dt-bindings: add self-test fixtures for style checker
Documentation/devicetree/bindings/Makefile | 19 +-
Makefile | 6 +
scripts/dtc/dt-check-style | 1120 +++++++++++++++++
.../dtc/dt-style-selftest/bad/dts-spaces.dts | 13 +
.../bad/yaml-child-addr-order.yaml | 41 +
.../bad/yaml-child-name-order.yaml | 37 +
.../bad/yaml-cont-align.yaml | 30 +
.../bad/yaml-digit-node-order.yaml | 37 +
.../dt-style-selftest/bad/yaml-hex-case.yaml | 29 +
.../bad/yaml-indent-strict.yaml | 29 +
.../bad/yaml-line-length.yaml | 29 +
.../bad/yaml-mixed-indent.yaml | 29 +
.../bad/yaml-node-close.yaml | 31 +
.../bad/yaml-prop-order.yaml | 29 +
.../bad/yaml-prop-pairing.yaml | 33 +
.../bad/yaml-required-blank.yaml | 33 +
.../dtc/dt-style-selftest/bad/yaml-tab.yaml | 29 +
.../bad/yaml-trailing-comment.yaml | 26 +
.../bad/yaml-trailing-ws.yaml | 29 +
.../dt-style-selftest/bad/yaml-unit-addr.yaml | 29 +
.../bad/yaml-unused-label.yaml | 29 +
.../bad/yaml-value-ws-multiline.yaml | 27 +
.../dt-style-selftest/bad/yaml-value-ws.yaml | 29 +
.../expected/dts-spaces.dts.txt | 2 +
.../expected/yaml-child-addr-order.yaml.txt | 2 +
.../expected/yaml-child-name-order.yaml.txt | 2 +
.../expected/yaml-cont-align.yaml.txt | 2 +
.../expected/yaml-digit-node-order.yaml.txt | 2 +
.../expected/yaml-hex-case.yaml.txt | 2 +
.../expected/yaml-indent-strict.yaml.txt | 2 +
.../expected/yaml-line-length.yaml.txt | 2 +
.../expected/yaml-mixed-indent.yaml.txt | 3 +
.../expected/yaml-node-close.yaml.txt | 2 +
.../expected/yaml-prop-order.yaml.txt | 2 +
.../expected/yaml-prop-pairing.yaml.txt | 3 +
.../expected/yaml-required-blank.yaml.txt | 3 +
.../expected/yaml-tab.yaml.txt | 2 +
.../expected/yaml-trailing-comment.yaml.txt | 2 +
.../expected/yaml-trailing-ws.yaml.txt | 2 +
.../expected/yaml-unit-addr.yaml.txt | 2 +
.../expected/yaml-unused-label.yaml.txt | 2 +
.../expected/yaml-value-ws-multiline.yaml.txt | 2 +
.../expected/yaml-value-ws.yaml.txt | 2 +
.../dt-style-selftest/good/dts-cont-align.dts | 27 +
.../dtc/dt-style-selftest/good/dts-tab.dts | 30 +
.../dt-style-selftest/good/yaml-4space.yaml | 41 +
scripts/dtc/dt-style-selftest/run.sh | 71 ++
47 files changed, 1953 insertions(+), 2 deletions(-)
create mode 100755 scripts/dtc/dt-check-style
create mode 100644 scripts/dtc/dt-style-selftest/bad/dts-spaces.dts
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-child-addr-order.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-child-name-order.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-cont-align.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-digit-node-order.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-hex-case.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-indent-strict.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-line-length.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-mixed-indent.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-node-close.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-prop-order.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-prop-pairing.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-required-blank.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-tab.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-trailing-comment.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-trailing-ws.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-unit-addr.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-unused-label.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-value-ws-multiline.yaml
create mode 100644 scripts/dtc/dt-style-selftest/bad/yaml-value-ws.yaml
create mode 100644 scripts/dtc/dt-style-selftest/expected/dts-spaces.dts.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-child-addr-order.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-child-name-order.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-cont-align.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-digit-node-order.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-hex-case.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-indent-strict.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-line-length.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-mixed-indent.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-node-close.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-prop-order.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-prop-pairing.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-required-blank.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-tab.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-trailing-comment.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-trailing-ws.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-unit-addr.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-unused-label.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-value-ws-multiline.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/expected/yaml-value-ws.yaml.txt
create mode 100644 scripts/dtc/dt-style-selftest/good/dts-cont-align.dts
create mode 100644 scripts/dtc/dt-style-selftest/good/dts-tab.dts
create mode 100644 scripts/dtc/dt-style-selftest/good/yaml-4space.yaml
create mode 100755 scripts/dtc/dt-style-selftest/run.sh
--
2.54.0
^ permalink raw reply
* Re: [PATCH v5 06/13] iio: frequency: ad9910: initial driver implementation
From: Jonathan Cameron @ 2026-05-22 18:03 UTC (permalink / raw)
To: Rodrigo Alencar via B4 Relay
Cc: rodrigo.alencar, linux-iio, devicetree, linux-kernel, linux-doc,
linux-hardening, Lars-Peter Clausen, Michael Hennerich,
David Lechner, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, Jonathan Corbet, Shuah Khan,
Kees Cook, Gustavo A. R. Silva
In-Reply-To: <20260517-ad9910-iio-driver-v5-6-31599c88314a@analog.com>
On Sun, 17 May 2026 19:37:50 +0100
Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:
> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
>
> Add the core AD9910 DDS driver infrastructure with single tone mode
> support. This includes SPI register access, profile management via GPIO
> pins, PLL/DAC configuration from firmware properties, and single tone
> frequency/phase/amplitude control through IIO attributes.
>
> Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
Hi Rodrigo
A couple of potential nice to haves.
Jonathan
> +
> +static int ad9910_parse_fw(struct ad9910_state *st)
> +{
> + static const char * const refclk_out_drv0[] = {
> + "disabled", "low", "medium", "high",
> + };
> + struct device *dev = &st->spi->dev;
> + u32 tmp[2];
> + int ret;
> +
> + st->data.pll_enabled = device_property_read_bool(dev, "adi,pll-enable");
> + if (st->data.pll_enabled) {
> + tmp[0] = AD9910_ICP_MIN_uA;
> + device_property_read_u32(dev, "adi,charge-pump-current-microamp", &tmp[0]);
Might be a good idea to move to the pattern that seems to be becoming
the preferred way to do this and do
if (device_property_present()) {
ret = device_property_read_u32()...
...
} else {
...
}
That is slightly nicer ad picks up malformed DT. I know I was the advocate for
the set a default and don't check ret but I'm learning!
> + if (tmp[0] < AD9910_ICP_MIN_uA || tmp[0] > AD9910_ICP_MAX_uA)
> + return dev_err_probe(dev, -ERANGE,
> + "invalid charge pump current %u\n", tmp[0]);
> + st->data.pll_charge_pump_current = tmp[0];
> +
> + ret = device_property_match_property_string(dev,
> + "adi,refclk-out-drive-strength",
> + refclk_out_drv0,
> + ARRAY_SIZE(refclk_out_drv0));
> + if (ret < 0)
Similarly good to know if failure to match actually means wasn't there or not.
> + st->data.refclk_out_drv = AD9910_REFCLK_OUT_DRV_DISABLED;
> + else
> + st->data.refclk_out_drv = ret;
> + }
> +
> + tmp[1] = AD9910_DAC_IOUT_DEFAULT_uA;
And similar again.
> + device_property_read_u32_array(dev, "output-range-microamp", tmp,
> + ARRAY_SIZE(tmp));
> + if (tmp[1] < AD9910_DAC_IOUT_MIN_uA || tmp[1] > AD9910_DAC_IOUT_MAX_uA)
> + return dev_err_probe(dev, -ERANGE,
> + "Invalid DAC output current %u uA\n", tmp[1]);
> + st->data.dac_output_current = tmp[1];
> +
> + return 0;
> +}
> +static const struct spi_device_id ad9910_id[] = {
> + { "ad9910" },
Request to simplify what Uwe is busy doing (assuming he'll get to spi
at somepoint). Please use a named initializer like we always do for
of_device_id.
> + { }
> +};
> +MODULE_DEVICE_TABLE(spi, ad9910_id);
^ permalink raw reply
* [PATCH v3 5/5] arm64: dts: qcom: Add Shikra EVK boards
From: Komal Bajaj @ 2026-05-22 18:02 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj, Imran Shaik, Monish Chunara,
Rakesh Kota, Raviteja Laggyshetty, Sneh Mankad, Vishnu Santhosh,
Xueyao An
In-Reply-To: <20260522-shikra-dt-v3-0-80ffde8a3dc4@oss.qualcomm.com>
Add device trees for the Shikra EVK platform, which combines each
of Shikra SoM variant with a common carrier board.
Three EVK boards are introduced:
- shikra-cqm-evk.dts: pairs with CQ2390M SoM (retail, with modem)
- shikra-cqs-evk.dts: pairs with CQ2390S SoM (retail, without modem)
- shikra-iqs-evk.dts: pairs with IQ2390S SoM (industrial, without modem)
Also add shikra-evk.dtsi, it represents the common carrier-board and
daughter-card configuration shared across all Shikra EVK variants.
Co-developed-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
Co-developed-by: Monish Chunara <quic_mchunara@quicinc.com>
Signed-off-by: Monish Chunara <quic_mchunara@quicinc.com>
Co-developed-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Co-developed-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
Signed-off-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
Co-developed-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
Co-developed-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
Co-developed-by: Xueyao An <xueyao.an@oss.qualcomm.com>
Signed-off-by: Xueyao An <xueyao.an@oss.qualcomm.com>
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/Makefile | 3 +++
arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts | 40 +++++++++++++++++++++++++++++
arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts | 40 +++++++++++++++++++++++++++++
arch/arm64/boot/dts/qcom/shikra-evk.dtsi | 14 ++++++++++
arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts | 40 +++++++++++++++++++++++++++++
5 files changed, 137 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 795cee4757ab..3801f280c8cc 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -333,6 +333,9 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm850-huawei-matebook-e-2019.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm850-lenovo-yoga-c630.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdm850-samsung-w737.dtb
dtb-$(CONFIG_ARCH_QCOM) += sdx75-idp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += shikra-cqm-evk.dtb
+dtb-$(CONFIG_ARCH_QCOM) += shikra-cqs-evk.dtb
+dtb-$(CONFIG_ARCH_QCOM) += shikra-iqs-evk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm4250-oneplus-billie2.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm4450-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6115-fxtec-pro1x.dtb
diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
new file mode 100644
index 000000000000..0a52ab9b7a4c
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/dts-v1/;
+
+#include "shikra-cqm-som.dtsi"
+#include "shikra-evk.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. Shikra CQM EVK";
+ compatible = "qcom,shikra-cqm-evk", "qcom,shikra-cqm-som", "qcom,shikra";
+ chassis-type = "embedded";
+
+ aliases {
+ mmc0 = &sdhc_1;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm4125_l20>;
+ vqmmc-supply = <&pm4125_l14>;
+
+ pinctrl-0 = <&sdc1_state_on>;
+ pinctrl-1 = <&sdc1_state_off>;
+ pinctrl-names = "default", "sleep";
+
+ non-removable;
+ supports-cqe;
+ no-sdio;
+ no-sd;
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
new file mode 100644
index 000000000000..b3f19a64d7ae
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/dts-v1/;
+
+#include "shikra-cqm-som.dtsi"
+#include "shikra-evk.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. Shikra CQS EVK";
+ compatible = "qcom,shikra-cqs-evk", "qcom,shikra-cqs-som", "qcom,shikra";
+ chassis-type = "embedded";
+
+ aliases {
+ mmc0 = &sdhc_1;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm4125_l20>;
+ vqmmc-supply = <&pm4125_l14>;
+
+ pinctrl-0 = <&sdc1_state_on>;
+ pinctrl-1 = <&sdc1_state_off>;
+ pinctrl-names = "default", "sleep";
+
+ non-removable;
+ supports-cqe;
+ no-sdio;
+ no-sd;
+
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/shikra-evk.dtsi b/arch/arm64/boot/dts/qcom/shikra-evk.dtsi
new file mode 100644
index 000000000000..8b03d4eafa6d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-evk.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+&qupv3_0 {
+ firmware-name = "qcom/shikra/qupv3fw.elf";
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts b/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts
new file mode 100644
index 000000000000..3003a47bd759
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/dts-v1/;
+
+#include "shikra-iqs-som.dtsi"
+#include "shikra-evk.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. Shikra IQS EVK";
+ compatible = "qcom,shikra-iqs-evk", "qcom,shikra-iqs-som", "qcom,shikra";
+ chassis-type = "embedded";
+
+ aliases {
+ mmc0 = &sdhc_1;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&sdhc_1 {
+ vmmc-supply = <&pm8150_l17>;
+ vqmmc-supply = <&pm8150_s4>;
+
+ pinctrl-0 = <&sdc1_state_on>;
+ pinctrl-1 = <&sdc1_state_off>;
+ pinctrl-names = "default", "sleep";
+
+ non-removable;
+ supports-cqe;
+ no-sdio;
+ no-sd;
+
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH v3 4/5] arm64: dts: qcom: Add Shikra IQ2390S SoM platform
From: Komal Bajaj @ 2026-05-22 18:02 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj
In-Reply-To: <20260522-shikra-dt-v3-0-80ffde8a3dc4@oss.qualcomm.com>
Add device tree include for the IQ2390S variant of the Shikra
System-on-Module, an industrial compute module integrating the Shikra
SoC and PMIC for industrial IoT applications, designed to mount on
carrier boards.
- shikra-iqs-som.dtsi: Industrial SoM without modem (PM8150 PMIC)
The DTSI includes the common shikra.dtsi and adds PM8150 PMIC regulator
definitions specific to this variant.
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi | 170 +++++++++++++++++++++++++++
1 file changed, 170 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi b/arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi
new file mode 100644
index 000000000000..73945bf42112
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+#include "shikra.dtsi"
+#include "pm8150.dtsi"
+
+/ {
+ gpio-key {
+ compatible = "gpio-keys";
+ label = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vol_up_n>;
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_VOLUMEUP>;
+ wakeup-source;
+ debounce-interval = <15>;
+ linux,can-disable;
+ };
+ };
+};
+
+&pm8150_gpios {
+ vol_up_n: vol-up-n-state {
+ pins = "gpio6";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ input-enable;
+ bias-pull-up;
+ power-source = <0>;
+ };
+
+};
+
+&pon_pwrkey {
+ status = "okay";
+};
+
+&pon_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&rpm_requests {
+ regulators {
+ compatible = "qcom,rpm-pm8150-regulators";
+
+ pm8150_s4: s4 {
+ regulator-min-microvolt = <1080000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ pm8150_s5: s5 {
+ regulator-min-microvolt = <1574000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ pm8150_s6: s6 {
+ regulator-min-microvolt = <382000>;
+ regulator-max-microvolt = <1352000>;
+ };
+
+ pm8150_s7: s7 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm8150_s8: s8 {
+ regulator-min-microvolt = <570000>;
+ regulator-max-microvolt = <650000>;
+ };
+
+ pm8150_l1: l1 {
+ regulator-min-microvolt = <312000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm8150_l2: l2 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ pm8150_l3: l3 {
+ regulator-min-microvolt = <312000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm8150_l4: l4 {
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <975000>;
+ };
+
+ pm8150_l5: l5 {
+ regulator-min-microvolt = <788000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm8150_l6: l6 {
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ pm8150_l7: l7 {
+ regulator-min-microvolt = <1504000>;
+ regulator-max-microvolt = <2000000>;
+ };
+
+ pm8150_l8: l8 {
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm8150_l9: l9 {
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ pm8150_l10: l10 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ };
+
+ pm8150_l11: l11 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm8150_l12: l12 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <1950000>;
+ };
+
+ pm8150_l13: l13 {
+ regulator-min-microvolt = <2921000>;
+ regulator-max-microvolt = <3230000>;
+ };
+
+ pm8150_l14: l14 {
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <1910000>;
+ };
+
+ pm8150_l15: l15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1900000>;
+ };
+
+ pm8150_l16: l16 {
+ regulator-min-microvolt = <1504000>;
+ regulator-max-microvolt = <3544000>;
+ };
+
+ pm8150_l17: l17 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <3544000>;
+ };
+
+ pm8150_l18: l18 {
+ regulator-min-microvolt = <400000>;
+ regulator-max-microvolt = <728000>;
+ };
+ };
+};
--
2.34.1
^ permalink raw reply related
* [PATCH v3 3/5] arm64: dts: qcom: Add Shikra CQ2390M SoM platform
From: Komal Bajaj @ 2026-05-22 18:02 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj, Rakesh Kota
In-Reply-To: <20260522-shikra-dt-v3-0-80ffde8a3dc4@oss.qualcomm.com>
Add device tree include for the CQ2390M variant of the Shikra
System-on-Module, a compact compute module integrating the Shikra SoC
and PMIC for IoT applications, designed to mount on carrier boards.
- shikra-cqm-som.dtsi: Retail SoM with modem (PM4125 and PM8005 PMIC)
The DTSI includes the common shikra.dtsi, adds PM4125 and PM8005 PMIC
regulator definitions specific to this variant.
Co-developed-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi | 156 +++++++++++++++++++++++++++
1 file changed, 156 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
new file mode 100644
index 000000000000..97966cff8896
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+#include "shikra.dtsi"
+#include "pm4125.dtsi"
+#include "pm8005.dtsi"
+
+/ {
+ gpio-key {
+ compatible = "gpio-keys";
+ label = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vol_up_n>;
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&pm4125_gpios 9 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <KEY_VOLUMEUP>;
+ wakeup-source;
+ debounce-interval = <15>;
+ linux,can-disable;
+ };
+ };
+};
+
+&pm4125_gpios {
+ vol_up_n: vol-up-n-state {
+ pins = "gpio9";
+ function = PMIC_GPIO_FUNC_NORMAL;
+ input-enable;
+ bias-pull-up;
+ power-source = <0>;
+ };
+};
+
+&pm4125_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&pm8005_regulators {
+ status = "disabled";
+};
+
+
+&rpm_requests {
+ regulators {
+ compatible = "qcom,rpm-pm2250-regulators";
+
+ pm4125_s2: s2 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ pm4125_l3: l3 {
+ regulator-min-microvolt = <624000>;
+ regulator-max-microvolt = <650000>;
+ };
+
+ pm4125_l4: l4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ };
+
+ pm4125_l5: l5 {
+ regulator-min-microvolt = <1232000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm4125_l6: l6 {
+ regulator-min-microvolt = <788000>;
+ regulator-max-microvolt = <1050000>;
+ };
+
+ pm4125_l7: l7 {
+ regulator-min-microvolt = <664000>;
+ regulator-max-microvolt = <664000>;
+ };
+
+ pm4125_l8: l8 {
+ regulator-min-microvolt = <928000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ pm4125_l9: l9 {
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ pm4125_l10: l10 {
+ regulator-min-microvolt = <1304000>;
+ regulator-max-microvolt = <1304000>;
+ };
+
+ pm4125_l12: l12 {
+ regulator-min-microvolt = <928000>;
+ regulator-max-microvolt = <975000>;
+ };
+
+ pm4125_l13: l13 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm4125_l14: l14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm4125_l15: l15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm4125_l16: l16 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ pm4125_l17: l17 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3544000>;
+ };
+
+ pm4125_l18: l18 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ };
+
+ pm4125_l19: l19 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ };
+
+ pm4125_l20: l20 {
+ regulator-min-microvolt = <2952000>;
+ regulator-max-microvolt = <2952000>;
+ };
+
+ pm4125_l21: l21 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3056000>;
+ };
+
+ pm4125_l22: l22 {
+ regulator-min-microvolt = <3304000>;
+ regulator-max-microvolt = <3304000>;
+ };
+ };
+};
--
2.34.1
^ permalink raw reply related
* [PATCH v3 2/5] arm64: dts: qcom: Introduce Shikra SoC base dtsi
From: Komal Bajaj @ 2026-05-22 18:02 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj, Imran Shaik, Monish Chunara,
Rakesh Kota, Raviteja Laggyshetty, Sneh Mankad, Vishnu Santhosh,
Xueyao An, Konrad Dybcio
In-Reply-To: <20260522-shikra-dt-v3-0-80ffde8a3dc4@oss.qualcomm.com>
Add initial device tree support for the Qualcomm Shikra SoC,
an IoT-focused platform built around a heterogeneous CPU cluster
(Cortex-A55 + Cortex-A78C) with RPM-based power and clock management.
Enable support for the following peripherals:
- CPU nodes
- Global Clock Controller (GCC)
- RPM-based clock controller (RPMCC) and power domains (RPMPD)
- Interrupt controller
- Top Level Mode Multiplexer (TLMM)
- Debug UART
- eMMC host controller
- System timer and watchdog
Co-developed-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
Co-developed-by: Monish Chunara <quic_mchunara@quicinc.com>
Signed-off-by: Monish Chunara <quic_mchunara@quicinc.com>
Co-developed-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
Co-developed-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
Signed-off-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
Co-developed-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
Co-developed-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
Co-developed-by: Xueyao An <xueyao.an@oss.qualcomm.com>
Signed-off-by: Xueyao An <xueyao.an@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra.dtsi | 842 +++++++++++++++++++++++++++++++++++
1 file changed, 842 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
new file mode 100644
index 000000000000..a4334d99c1f3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
@@ -0,0 +1,842 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <dt-bindings/clock/qcom,rpmcc.h>
+#include <dt-bindings/clock/qcom,shikra-gcc.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
+#include <dt-bindings/interconnect/qcom,rpm-icc.h>
+#include <dt-bindings/interconnect/qcom,shikra.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+/ {
+ interrupt-parent = <&intc>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ clocks {
+ xo_board: xo-board {
+ compatible = "fixed-clock";
+ clock-frequency = <38400000>;
+ #clock-cells = <0>;
+ };
+
+ sleep_clk: sleep-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <32764>;
+ #clock-cells = <0>;
+ };
+ };
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ next-level-cache = <&l3>;
+ capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <100>;
+ };
+
+ cpu1: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ next-level-cache = <&l3>;
+ capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <100>;
+ };
+
+ cpu2: cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0 0x200>;
+ enable-method = "psci";
+ next-level-cache = <&l3>;
+ capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <100>;
+ };
+
+ cpu3: cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a78c";
+ reg = <0x0 0x300>;
+ enable-method = "psci";
+ next-level-cache = <&l2_3>;
+ capacity-dmips-mhz = <1946>;
+ dynamic-power-coefficient = <489>;
+
+ l2_3: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
+ next-level-cache = <&l3>;
+ cache-size = <0x40000>;
+ };
+ };
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+
+ core1 {
+ cpu = <&cpu1>;
+ };
+
+ core2 {
+ cpu = <&cpu2>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpu3>;
+ };
+ };
+ };
+
+ l3: l3-cache {
+ compatible = "cache";
+ cache-level = <3>;
+ cache-unified;
+ cache-size = <0x80000>;
+ };
+ };
+
+ firmware {
+ scm {
+ compatible = "qcom,scm-shikra", "qcom,scm";
+ clocks = <&rpmcc RPM_SMD_CE1_CLK>;
+ clock-names = "core";
+ qcom,dload-mode = <&tcsr_regs 0x13000>;
+ #reset-cells = <1>;
+ interconnects = <&system_noc MASTER_CRYPTO_CORE0 RPM_ALWAYS_TAG
+ &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ /* We expect the bootloader to fill in the size */
+ reg = <0x0 0x80000000 0x0 0x0>;
+ };
+
+ pmu-a55 {
+ compatible = "arm,cortex-a55-pmu";
+ interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH &ppi_cluster0>;
+ };
+
+ pmu-a78c {
+ compatible = "arm,cortex-a78-pmu";
+ interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH &ppi_cluster1>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ rpm: remoteproc {
+ compatible = "qcom,shikra-rpm-proc", "qcom,rpm-proc";
+
+ glink-edge {
+ compatible = "qcom,glink-rpm";
+ interrupts = <GIC_SPI 194 IRQ_TYPE_EDGE_RISING 0>;
+ qcom,rpm-msg-ram = <&rpm_msg_ram>;
+ mboxes = <&apcs_glb 0>;
+
+ rpm_requests: rpm-requests {
+ compatible = "qcom,rpm-shikra", "qcom,glink-smd-rpm";
+ qcom,glink-channels = "rpm_requests";
+
+ rpmcc: clock-controller {
+ compatible = "qcom,rpmcc-shikra", "qcom,rpmcc";
+ clocks = <&xo_board>;
+ clock-names = "xo";
+ #clock-cells = <1>;
+ };
+
+ rpmpd: power-controller {
+ compatible = "qcom,shikra-rpmpd";
+ #power-domain-cells = <1>;
+ operating-points-v2 = <&rpmpd_opp_table>;
+
+ rpmpd_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ rpmpd_opp_min_svs: opp1 {
+ opp-level = <RPM_SMD_LEVEL_MIN_SVS>;
+ };
+
+ rpmpd_opp_low_svs: opp2 {
+ opp-level = <RPM_SMD_LEVEL_LOW_SVS>;
+ };
+
+ rpmpd_opp_svs: opp3 {
+ opp-level = <RPM_SMD_LEVEL_SVS>;
+ };
+
+ rpmpd_opp_svs_plus: opp4 {
+ opp-level = <RPM_SMD_LEVEL_SVS_PLUS>;
+ };
+
+ rpmpd_opp_nom: opp5 {
+ opp-level = <RPM_SMD_LEVEL_NOM>;
+ };
+
+ rpmpd_opp_nom_plus: opp6 {
+ opp-level = <RPM_SMD_LEVEL_NOM_PLUS>;
+ };
+
+ rpmpd_opp_turbo: opp7 {
+ opp-level = <RPM_SMD_LEVEL_TURBO>;
+ };
+
+ rpmpd_opp_turbo_plus: opp8 {
+ opp-level = <RPM_SMD_LEVEL_TURBO_NO_CPR>;
+ };
+ };
+ };
+ };
+ };
+
+ mpm: interrupt-controller {
+ compatible = "qcom,mpm";
+ qcom,rpm-msg-ram = <&apss_mpm>;
+ interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING 0>;
+ mboxes = <&apcs_glb 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ #power-domain-cells = <0>;
+ interrupt-parent = <&intc>;
+ qcom,mpm-pin-count = <96>;
+ qcom,mpm-pin-map = <2 275>, /* TSENS0 uplow */
+ <12 422>, /* DWC3 ss_phy_irq */
+ <58 272>, /* QUSB2_PHY dmse_hv_vddmx */
+ <59 273>, /* QUSB2_PHY dpse_hv_vddmx */
+ <86 183>, /* MPM wake, SPMI */
+ <90 157>, /* QUSB2_PHY DM */
+ <91 158>; /* QUSB2_PHY DP */
+ };
+ };
+
+ reserved_memory: reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ hyp_mem: hyp@80000000 {
+ reg = <0x0 0x80000000 0x0 0x1600000>;
+ no-map;
+ };
+
+ xblboot_mem: xblboot@85e00000 {
+ reg = <0x0 0x85e00000 0x0 0x100000>;
+ no-map;
+ };
+
+ secdata_apss_mem: secdata-apss@85fff000 {
+ reg = <0x0 0x85fff000 0x0 0x1000>;
+ no-map;
+ };
+
+ smem_mem: smem@86000000 {
+ compatible = "qcom,smem";
+ reg = <0x0 0x86000000 0x0 0x200000>;
+ no-map;
+
+ hwlocks = <&tcsr_mutex 3>;
+ };
+
+ audio_heap_mem: audio-heap@86200000 {
+ reg = <0x0 0x86200000 0x0 0x100000>;
+ no-map;
+ };
+
+ tz_stat_mem: tz-stat@a0000000 {
+ reg = <0x0 0xa0000000 0x0 0x100000>;
+ no-map;
+ };
+
+ qtee_mem: qtee@a1300000 {
+ reg = <0x0 0xa1300000 0x0 0x500000>;
+ no-map;
+ };
+
+ tz_apps_mem: tz-apps@a1800000 {
+ reg = <0x0 0xa1800000 0x0 0x2100000>;
+ no-map;
+ };
+
+ mpss_wlan_mem: mpss-wlan@ab000000 {
+ reg = <0x0 0xab000000 0x0 0x6e00000>;
+ no-map;
+ };
+
+ wlan_mem: wlan@b2300000 {
+ reg = <0x0 0xb2300000 0x0 0x100000>;
+ no-map;
+ };
+
+ cdsp_mem: cdsp@b2400000 {
+ reg = <0x0 0xb2400000 0x0 0x1900000>;
+ no-map;
+ };
+
+ gpu_micro_code_mem: gpu-micro-code@b3d00000 {
+ reg = <0x0 0xb3d00000 0x0 0x2000>;
+ no-map;
+ };
+
+ video_mem: video@b3d02000 {
+ reg = <0x0 0xb3d02000 0x0 0x700000>;
+ no-map;
+ };
+
+ lmcu_mem: lmcu@b4402000 {
+ reg = <0x0 0xb4402000 0x0 0x300000>;
+ no-map;
+ };
+
+ lmcu_dtb_mem: lmcu-dtb@b4702000 {
+ reg = <0x0 0xb4702000 0x0 0x40000>;
+ no-map;
+ };
+ };
+
+ soc: soc@0 {
+ compatible = "simple-bus";
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+ ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+
+ tcsr_mutex: syscon@340000 {
+ compatible = "qcom,tcsr-mutex";
+ reg = <0x0 0x00340000 0x0 0x20000>;
+ #hwlock-cells = <1>;
+ };
+
+ tcsr_regs: syscon@3c0000 {
+ compatible = "qcom,shikra-tcsr", "syscon";
+ reg = <0x0 0x003c0000 0x0 0x40000>;
+ };
+
+ tlmm: pinctrl@500000 {
+ compatible = "qcom,shikra-tlmm";
+ reg = <0x0 0x00500000 0x0 0x700000>;
+
+ interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH 0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ gpio-ranges = <&tlmm 0 0 165>;
+ wakeup-parent = <&mpm>;
+
+ qup_uart0_default: qup-uart0-default-state {
+ pins = "gpio0", "gpio1";
+ function = "qup0_se0";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sdc1_state_on: sdc1-on-state {
+ clk-pins {
+ pins = "sdc1_clk";
+ drive-strength = <6>;
+ bias-disable;
+ };
+
+ cmd-pins {
+ pins = "sdc1_cmd";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+
+ data-pins {
+ pins = "sdc1_data";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+
+ rclk-pins {
+ pins = "sdc1_rclk";
+ bias-pull-down;
+ };
+ };
+
+ sdc1_state_off: sdc1-off-state {
+ clk-pins {
+ pins = "sdc1_clk";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ cmd-pins {
+ pins = "sdc1_cmd";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ data-pins {
+ pins = "sdc1_data";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+
+ rclk-pins {
+ pins = "sdc1_rclk";
+ bias-bus-hold;
+ };
+ };
+ };
+
+ mem_noc: interconnect@d00000 {
+ compatible = "qcom,shikra-mem-noc-core";
+ reg = <0x0 0x00d00000 0x0 0x43080>;
+ clocks = <&gcc GCC_DDRSS_GPU_AXI_CLK>;
+ clock-names = "gpu_axi";
+ #interconnect-cells = <2>;
+ };
+
+ llcc: system-cache-controller@e00000 {
+ compatible = "qcom,shikra-llcc";
+ reg = <0x0 0x00e00000 0x0 0x80000>,
+ <0x0 0x00f00000 0x0 0x80000>,
+ <0x0 0x01000000 0x0 0x80000>;
+ reg-names = "llcc0_base",
+ "llcc1_base",
+ "llcc_broadcast_base";
+ interrupts = <GIC_SPI 539 IRQ_TYPE_LEVEL_HIGH 0>;
+ };
+
+ gcc: clock-controller@1400000 {
+ compatible = "qcom,shikra-gcc";
+ reg = <0x0 0x01400000 0x0 0x1f0000>;
+ clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+ <&sleep_clk>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>,
+ <0>;
+ power-domains = <&rpmpd RPMPD_VDDCX>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
+ system_noc: interconnect@1880000 {
+ compatible = "qcom,shikra-sys-noc";
+ reg = <0x0 0x01880000 0x0 0x6a080>;
+ clocks = <&gcc GCC_EMAC0_AXI_SYS_NOC_CLK>,
+ <&gcc GCC_EMAC1_AXI_SYS_NOC_CLK>,
+ <&gcc GCC_SYS_NOC_USB2_PRIM_AXI_CLK>,
+ <&gcc GCC_SYS_NOC_USB3_PRIM_AXI_CLK>;
+ clock-names = "emac0_axi",
+ "emac1_axi",
+ "usb2_axi",
+ "usb3_axi";
+ #interconnect-cells = <2>;
+
+ clk_virt: interconnect-clk {
+ compatible = "qcom,shikra-clk-virt";
+ #interconnect-cells = <2>;
+ };
+
+ mc_virt: interconnect-mc {
+ compatible = "qcom,shikra-mc-virt";
+ #interconnect-cells = <2>;
+ };
+
+ mmrt_virt: interconnect-mmrt {
+ compatible = "qcom,shikra-mmrt-virt";
+ #interconnect-cells = <2>;
+ };
+
+ mmnrt_virt: interconnect-mmnrt {
+ compatible = "qcom,shikra-mmnrt-virt";
+ #interconnect-cells = <2>;
+ };
+ };
+
+ config_noc: interconnect@1900000 {
+ compatible = "qcom,shikra-config-noc";
+ reg = <0x0 0x01900000 0x0 0x8080>;
+ #interconnect-cells = <2>;
+ };
+
+ qfprom: efuse@1b44000 {
+ compatible = "qcom,shikra-qfprom", "qcom,qfprom";
+ reg = <0x0 0x01b44000 0x0 0x3000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qusb2_hstx_trim_1: hstx-trim@25b {
+ reg = <0x25b 0x1>;
+ bits = <1 4>;
+ };
+
+ gpu_speed_bin: gpu-speed-bin@2006 {
+ reg = <0x2006 0x2>;
+ bits = <5 8>;
+ };
+ };
+
+ spmi_bus: spmi@1c40000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0x0 0x01c40000 0x0 0x1100>,
+ <0x0 0x01e00000 0x0 0x2000000>,
+ <0x0 0x03e00000 0x0 0x100000>,
+ <0x0 0x03f00000 0x0 0xa0000>,
+ <0x0 0x01c0a000 0x0 0x26000>;
+ reg-names = "core",
+ "chnls",
+ "obsrvr",
+ "intr",
+ "cnfg";
+ interrupts-extended = <&mpm 86 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "periph_irq";
+ interrupt-controller;
+ #interrupt-cells = <4>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ qcom,channel = <0>;
+ qcom,ee = <0>;
+ };
+
+ rpm_msg_ram: sram@45f0000 {
+ compatible = "qcom,rpm-msg-ram", "mmio-sram";
+ reg = <0x0 0x045f0000 0x0 0x7000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0x045f0000 0x7000>;
+
+ apss_mpm: sram@1b8 {
+ reg = <0x1b8 0x48>;
+ };
+ };
+
+ sram@4690000 {
+ compatible = "qcom,rpm-stats";
+ reg = <0x0 0x04690000 0x0 0x14000>;
+ };
+
+ sdhc_1: mmc@4744000 {
+ compatible = "qcom,shikra-sdhci", "qcom,sdhci-msm-v5";
+
+ reg = <0x0 0x04744000 0x0 0x1000>,
+ <0x0 0x04745000 0x0 0x1000>;
+ reg-names = "hc",
+ "cqhci";
+
+ iommus = <&apps_smmu 0xc0 0x0>;
+
+ interrupts = <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "hc_irq",
+ "pwr_irq";
+
+ clocks = <&gcc GCC_SDCC1_AHB_CLK>,
+ <&gcc GCC_SDCC1_APPS_CLK>,
+ <&rpmcc RPM_SMD_XO_CLK_SRC>;
+ clock-names = "iface",
+ "core",
+ "xo";
+
+ interconnects = <&system_noc MASTER_SDCC_1 RPM_ALWAYS_TAG
+ &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>,
+ <&mem_noc MASTER_AMPSS_M0 RPM_ACTIVE_TAG
+ &config_noc SLAVE_SDCC_1 RPM_ACTIVE_TAG>;
+ interconnect-names = "sdhc-ddr",
+ "cpu-sdhc";
+
+ power-domains = <&rpmpd RPMPD_VDDCX>;
+ operating-points-v2 = <&sdhc1_opp_table>;
+
+ qcom,dll-config = <0x000f642c>;
+ qcom,ddr-config = <0x80040868>;
+
+ bus-width = <8>;
+
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+
+ resets = <&gcc GCC_SDCC1_BCR>;
+
+ status = "disabled";
+
+ sdhc1_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ required-opps = <&rpmpd_opp_low_svs>;
+ opp-peak-kBps = <250000 133320>;
+ opp-avg-kBps = <104000 0>;
+ };
+
+ opp-384000000 {
+ opp-hz = /bits/ 64 <384000000>;
+ required-opps = <&rpmpd_opp_nom>;
+ opp-peak-kBps = <800000 300000>;
+ opp-avg-kBps = <400000 0>;
+ };
+ };
+ };
+
+ qupv3_0: geniqup@4ac0000 {
+ compatible = "qcom,geni-se-qup";
+ reg = <0x0 0x04ac0000 0x0 0x2000>;
+
+ clocks = <&gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>,
+ <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>;
+ clock-names = "m-ahb",
+ "s-ahb";
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ uart0: serial@4a80000 {
+ compatible = "qcom,geni-debug-uart";
+ reg = <0x0 0x04a80000 0x0 0x4000>;
+
+ interrupts = <GIC_SPI 527 IRQ_TYPE_LEVEL_HIGH 0>;
+
+ clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+ clock-names = "se";
+
+ interconnects = <&clk_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG
+ &clk_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
+ <&mem_noc MASTER_AMPSS_M0 RPM_ALWAYS_TAG
+ &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>;
+ interconnect-names = "qup-core",
+ "qup-config";
+
+ pinctrl-0 = <&qup_uart0_default>;
+ pinctrl-names = "default";
+
+ status = "disabled";
+ };
+ };
+
+ sram@c11e000 {
+ compatible = "qcom,shikra-imem", "mmio-sram";
+ reg = <0x0 0x0c11e000 0x0 0x1000>;
+ ranges = <0x0 0x0 0x0c11e000 0x1000>;
+
+ no-memory-wc;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pil-sram@94c {
+ compatible = "qcom,pil-reloc-info";
+ reg = <0x94c 0xc8>;
+ };
+ };
+
+ apps_smmu: iommu@c600000 {
+ compatible = "qcom,shikra-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+ reg = <0x0 0x0c600000 0x0 0x80000>;
+ #iommu-cells = <2>;
+ #global-interrupts = <1>;
+
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH 0>;
+ };
+
+ intc: interrupt-controller@f200000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0xf200000 0x0 0x10000>,
+ <0x0 0xf240000 0x0 0x80000>;
+
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+
+ #interrupt-cells = <4>;
+ interrupt-controller;
+
+ #redistributor-regions = <1>;
+ redistributor-stride = <0x0 0x20000>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ppi-partitions {
+ ppi_cluster0: interrupt-partition-0 {
+ affinity = <&cpu0 &cpu1 &cpu2>;
+ };
+
+ ppi_cluster1: interrupt-partition-1 {
+ affinity = <&cpu3>;
+ };
+ };
+ };
+
+ apcs_glb: mailbox@f400000 {
+ compatible = "qcom,shikra-apss-shared", "qcom,sdm845-apss-shared";
+ reg = <0x0 0x0f400000 0x0 0x1000>;
+ #mbox-cells = <1>;
+ };
+
+ watchdog@f410000 {
+ compatible = "qcom,apss-wdt-shikra", "qcom,kpss-wdt";
+ reg = <0x0 0x0f410000 0x0 0x1000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&sleep_clk>;
+ };
+
+ timer@f420000 {
+ compatible = "arm,armv7-timer-mem";
+ reg = <0x0 0x0f420000 0x0 0x1000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x0 0x10000000>;
+
+ frame@f421000 {
+ reg = <0x0f421000 0x1000>,
+ <0x0f422000 0x1000>;
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH 0>;
+ };
+
+ frame@f423000 {
+ reg = <0x0f423000 0x1000>;
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+
+ frame@f425000 {
+ reg = <0x0f425000 0x1000>;
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+
+ frame@f427000 {
+ reg = <0x0f427000 0x1000>;
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+
+ frame@f429000 {
+ reg = <0x0f429000 0x1000>;
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+
+ frame@f42b000 {
+ reg = <0x0f42b000 0x1000>;
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+
+ frame@f42d000 {
+ reg = <0x0f42d000 0x1000>;
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";
+ };
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+
+ interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 2 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 3 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 0 IRQ_TYPE_LEVEL_LOW 0>;
+ };
+};
--
2.34.1
^ permalink raw reply related
* [PATCH v3 1/5] dt-bindings: arm: qcom: Document Shikra and its EVK boards
From: Komal Bajaj @ 2026-05-22 18:02 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj
In-Reply-To: <20260522-shikra-dt-v3-0-80ffde8a3dc4@oss.qualcomm.com>
Shikra is a Qualcomm IoT SoC available in a System-on-Module (SoM)
form factor. The SoM integrates the Shikra SoC, PMICs, and essential
passives, and is designed to be mounted on carrier boards.
Three eSoM variant are introduced:
- CQM: retail variant with integrated modem
- CQS: retail variant without modem
- IQS: industrial-grade variant without modem
Each SoM variant pairs with a common EVK carrier board provides debug
UART, USB, and other peripheral interfaces.
Add compatible strings for the CQ2390M, CQ2390S, IQ2390S SoM variant and its
corresponding EVK boards.
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
Documentation/devicetree/bindings/arm/qcom.yaml | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index 50cc18a6ec5e..cf7d241f8107 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -989,6 +989,24 @@ properties:
- xiaomi,polaris
- const: qcom,sdm845
+ - items:
+ - enum:
+ - qcom,shikra-cqm-evk
+ - const: qcom,shikra-cqm-som
+ - const: qcom,shikra
+
+ - items:
+ - enum:
+ - qcom,shikra-cqs-evk
+ - const: qcom,shikra-cqs-som
+ - const: qcom,shikra
+
+ - items:
+ - enum:
+ - qcom,shikra-iqs-evk
+ - const: qcom,shikra-iqs-som
+ - const: qcom,shikra
+
- items:
- enum:
- oneplus,billie2
--
2.34.1
^ permalink raw reply related
* [PATCH v3 0/5] arm64: dts: qcom: Add initial device tree support for Shikra
From: Komal Bajaj @ 2026-05-22 18:02 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
monish.chunara, Komal Bajaj, Imran Shaik, Monish Chunara,
Rakesh Kota, Raviteja Laggyshetty, Sneh Mankad, Vishnu Santhosh,
Xueyao An, Konrad Dybcio
Add initial device tree support for the Qualcomm Shikra SoC.
Shikra ships in a SoM form factor; this series covers the CQ2390M,
CQ2390S and IQ2390S SoM variants and their EVK boards.
The series adds:
- dt-bindings for the Shikra SoC, CQ2390M/CQ2390S/IQ2390S EVK boards
- SoC base DTSI
- CQ2390M SoM DTSI with PM4125 and PM8005 PMIC regulator definitions
- IQ2390S SoM DTSI with PM8150 PMIC regulator definitions
- EVK DTS files enabling UART and eMMC on the carrier board
Note: USB support is intentionally dropped from this series. It will be
sent separately once the USB driver changes for Shikra are concluded.
Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
---
Changes in v3:
- Drop USB nodes from this series; will be sent separately pending
conclusion of USB driver changes for Shikra
- Fix CPU3 reg address (0x300 -> 0x10000) and memory base (0xa0000000 -> 0x80000000) (sashiko-bot)
- Fix power-domain macro: QCM2290_VDDCX -> RPMPD_VDDCX for sdhc (sashiko-bot)
- Fix MPM interrupt number for ss_phy_irq (8 -> 9) (sashiko-bot)
- Rename SoM variant CQ7790M to CQ2390M (Konrad)
- Add PMIC DTSI includes to CQ2390M and IQ2390S SoM
- Link to v2: https://lore.kernel.org/r/20260519-shikra-dt-v2-0-c01b90fb4395@oss.qualcomm.com
Changes in v2:
- Update SoM/EVK combination bindings (Krzysztof)
- Add per-CPU-type PMU nodes with PPI partitions for the heterogeneous
cluster (Cortex-A55 + Cortex-A78C) (Konrad)
- Use full product names CQ2390M/CQ2390S in commit messages (Krzysztof)
- Update RPM interconnect tags and power-domain to RPMPD for sdhc (sashiko-bot)
- Update to use MPM for ss_phy_irq instead of direct GIC for usb (sashiko-bot)
- Add IQ2390S SoM (PM8150 PMIC) and IQS EVK board support
- Link to v1: https://lore.kernel.org/r/20260512-shikra-dt-v1-0-716438330dd0@oss.qualcomm.com
---
Komal Bajaj (5):
dt-bindings: arm: qcom: Document Shikra and its EVK boards
arm64: dts: qcom: Introduce Shikra SoC base dtsi
arm64: dts: qcom: Add Shikra CQ2390M SoM platform
arm64: dts: qcom: Add Shikra IQ2390S SoM platform
arm64: dts: qcom: Add Shikra EVK boards
Documentation/devicetree/bindings/arm/qcom.yaml | 18 +
arch/arm64/boot/dts/qcom/Makefile | 3 +
arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts | 40 ++
arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi | 156 +++++
arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts | 40 ++
arch/arm64/boot/dts/qcom/shikra-evk.dtsi | 14 +
arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts | 40 ++
arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi | 170 +++++
arch/arm64/boot/dts/qcom/shikra.dtsi | 842 ++++++++++++++++++++++++
9 files changed, 1323 insertions(+)
---
base-commit: c1ecb239fa3456529a32255359fc78b69eb9d847
change-id: 20260511-shikra-dt-d75d97454646
prerequisite-change-id: 20260429-shikra-pinctrl-fd71ab6ecd6f:v4
prerequisite-patch-id: d84e0b4c2788ab6cfcefc9806e7a6011eef8f91d
prerequisite-patch-id: c92359b721d8c28f4a62887052d0fbb2cb64480a
prerequisite-change-id: 20260320-shikra_icc-b1fcef45122d:v3
prerequisite-patch-id: d36ec191324b7992a56c463a15ff09bacd8d7ba1
prerequisite-patch-id: c6edf2e05d1409667c9674b765dbd0917401a903
prerequisite-change-id: 20260429-add_pm8150_regulators-a373f53eb48f:v1
prerequisite-patch-id: b312905695c635bf1e3deab87b718c92adf07f54
prerequisite-patch-id: 390dee07914f18c7df08c57b3c59c25d1588b62f
prerequisite-change-id: 20260429-add_rpmpd_shikra-f57873b2fa7c:v3
prerequisite-patch-id: 2aab0b42cafb535b31c5154002c12f381a52be9a
prerequisite-patch-id: 599ed97f57ef0783f69d4c22384e91e66a2888f6
prerequisite-change-id: 20260429-shikra-gcc-rpmcc-clks-2094edfff3b0:v2
prerequisite-patch-id: 5a0fbdd458785da2d0e850c851a05046672ecadf
prerequisite-patch-id: 1f98e515a52bbeb25e2a960a804afe16c6a472a1
prerequisite-patch-id: a64476b2ba6e0f2a55928baf72ec32672ee0123c
prerequisite-patch-id: d0c8651205232862b40f942929e1efdaa3084eb3
prerequisite-change-id: 20260430-shikra_mailbox_and_rpm_changes-2de7fe8e964f:v3
prerequisite-patch-id: e80ea7940b9817449cec21afa6e9e443e007166f
prerequisite-patch-id: 2526e0507d3b5c065eafd75a657d7f903af8488f
prerequisite-patch-id: c3b7e18cd60d1f779b88ace2fae1227d3d37d83e
prerequisite-change-id: 20260430-shikra-smmu-binding-7befe45ecf2a:v1
prerequisite-patch-id: 657d2fa91247aa0c222b595c41328087f04f01a2
prerequisite-change-id: 20260430-shikra-imem-binding-a7bb9d2f16d2:v1
prerequisite-patch-id: 80d8ab865b7b0663c5b2878b45b55e2e4fde9c19
prerequisite-change-id: 20260501-shikra-scm-binding-a7ff5fabd0f2:v1
prerequisite-patch-id: 8e645e1c6ad6182de4813a726c293654324de1df
prerequisite-change-id: 20260501-shikra-tcsr-binding-fff1689e4097:v1
prerequisite-patch-id: f6781d2cf0829ccb32f1400623c95739972f2ee2
prerequisite-change-id: 20260501-shikra-wdog-binding-33873dcfa81f:v1
prerequisite-patch-id: de5184831054bcb48889fca16b2f4b5e95da9935
prerequisite-change-id: 20260501-shikra-qfprom-binding-c262fa19640a:v2
prerequisite-patch-id: f284f0dc01674ea0a78c8cf40ada72a7a1636463
prerequisite-change-id: 20260502-shikra-llcc-binding-7832b24ef74f:v1
prerequisite-patch-id: b9e53d2b5b494d4a957a691340fb2563f3dd681c
prerequisite-message-id: 20260508101544.736317-1-monish.chunara@oss.qualcomm.com
prerequisite-patch-id: 2a9d88175f19bfdb9495a704681ff0093da5566c
Best regards,
--
Komal Bajaj <komal.bajaj@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH 1/5] dt-bindings: remoteproc: imx_rproc: document optional "memory-region-names"
From: Frank Li @ 2026-05-22 18:00 UTC (permalink / raw)
To: Laurentiu Mihalcea
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sascha Hauer, Peng Fan,
Fabio Estevam, Pengutronix Kernel Team, linux-remoteproc,
devicetree, imx, linux-arm-kernel, linux-kernel
In-Reply-To: <20260522111849.783-2-laurentiumihalcea111@gmail.com>
On Fri, May 22, 2026 at 04:18:45AM -0700, Laurentiu Mihalcea wrote:
> From: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
>
> Document the optional "memory-region-names" property.
Need add reason why need memory-region-names.
Try to fix previous use undocument ABI method, which depend memory node
name. But now prefer use morden memory-region-names to fetch related
resource.
you can rephrase it.
Frank
>
> Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
> ---
> .../devicetree/bindings/remoteproc/fsl,imx-rproc.yaml | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> index c18f71b64889..6679b10f9da5 100644
> --- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> +++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> @@ -62,6 +62,14 @@ properties:
> minItems: 1
> maxItems: 32
>
> + memory-region-names:
> + minItems: 1
> + maxItems: 32
> + items:
> + oneOf:
> + - const: rsc-table
> + - pattern: '^vdev[0-9](buffer|vring[0-9])$'
> +
> power-domains:
> minItems: 2
> maxItems: 8
> --
> 2.43.0
>
^ permalink raw reply
* Re: [PATCH v2 5/5] arm64: dts: qcom: Add Shikra EVK boards
From: Komal Bajaj @ 2026-05-22 17:52 UTC (permalink / raw)
To: sashiko-reviews
Cc: robh, devicetree, vkoul, neil.armstrong, linux-phy, conor+dt,
olteanv
In-Reply-To: <20260519123738.BD9C3C2BCB3@smtp.kernel.org>
On 5/19/2026 6:07 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [High] shikra-cqs-evk.dts incorrectly includes the modem-enabled SoM dtsi file (shikra-cqm-som.dtsi) instead of its corresponding CQS dtsi file.
> --
>
> commit f25002d6be7ef75f4f5e2dd5f32e45a22f06fc01
> Author: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
>
> arm64: dts: qcom: Add Shikra EVK boards
>
> This commit adds device trees for the Shikra EVK platform, combining different
> Shikra SoM variants with a common carrier board. It introduces three specific
> EVK board configurations: CQM (with modem), CQS (no modem), and IQS (no
> modem), along with a shared common include file.
>
>> diff --git a/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
>> new file mode 100644
>> index 0000000000000..ee460d8c6a877
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
>> @@ -0,0 +1,61 @@
>> +// SPDX-License-Identifier: BSD-3-Clause
>> +/*
>> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include "shikra-cqm-som.dtsi"
> The commit message states that shikra-cqs-evk.dts pairs with the CQ2390S SoM
> which has no modem support. Does this incorrectly include the modem-enabled
> SoM file instead of its corresponding CQS dtsi file?
>
> Inheriting the hardware description of the CQM board might lead to incorrect
> behavior, such as wasted reserved-memory allocations, or potential probe
> failures when the kernel attempts to initialize the non-existent modem.
#include "shikra-cqm-som.dtsi" is intentional and correct. CQ2390S SoM
shares the same PMIC configuration and the same reserved-memory layout
as the CQM variant because the modem processor would still brought up on
the CQS to run auxiliary services, it just lacks the RF/modem-peripheral
hardware.
Thanks
Komal
>
>> +#include "shikra-evk.dtsi"
>> +
>> +/ {
>> + model = "Qualcomm Technologies, Inc. Shikra CQS EVK";
>> + compatible = "qcom,shikra-cqs-evk", "qcom,shikra-cqs-som", "qcom,shikra";
> [ ... ]
>
^ permalink raw reply
* [PATCH 3/3] arm64: dts: rockchip: Add Axelera AI metis-sbc
From: Patrick Barsanti @ 2026-05-22 17:49 UTC (permalink / raw)
To: devicetree, linux-rockchip, linux-kernel, heiko, robh, krzk+dt,
conor+dt
Cc: linux-amarula, michael, dario.binacchi, Patrick Barsanti
In-Reply-To: <20260522174918.61523-1-patrick.barsanti@amarulasolutions.com>
Add minimal device tree for the Axelera AI Metis Compute Board
(rk3588-metis-sbc).
It offers efficient AI compute for multi-stream computer vision and
GenAI applications in a compact design. It features a quad-core
Axelera AI Metis AIPU and an RK3588 SoC processor.
This basic version of the dts supports:
- Console
- eMMC
- HDMI
- 4x USB-A
- 2x Gigabit Ethernet
- RTC
- Enumeration of on-board Axelera Metis AIPU
Link: https://axelera.ai/evaluation-systems/metis-compute-board
Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Signed-off-by: Patrick Barsanti <patrick.barsanti@amarulasolutions.com>
---
arch/arm64/boot/dts/rockchip/Makefile | 1 +
.../boot/dts/rockchip/rk3588-metis-sbc.dts | 840 ++++++++++++++++++
2 files changed, 841 insertions(+)
create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-metis-sbc.dts
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index cb55c6b70d0e..8241f6ec2606 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -192,6 +192,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-h96-max-v58.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar-ethernet-switch.dtbo
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar-pre-ict-tester.dtbo
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-metis-sbc.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-mnt-reform2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6-lts.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-metis-sbc.dts b/arch/arm64/boot/dts/rockchip/rk3588-metis-sbc.dts
new file mode 100644
index 000000000000..56d734f9f25b
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-metis-sbc.dts
@@ -0,0 +1,840 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3588.dtsi"
+
+/ {
+ model = "Axelera AI Metis Compute Board";
+ compatible = "axelera,metis-sbc", "rockchip,rk3588";
+
+ aliases {
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac1;
+ mmc0 = &sdhci;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ hdmi0-con {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi0_con_in: endpoint {
+ remote-endpoint = <&hdmi0_out_con>;
+ };
+ };
+ };
+
+ pcie20_avdd0v85: pcie20-avdd0v85 {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "pcie20_avdd0v85";
+ vin-supply = <&vdda_0v85_s0>;
+ };
+
+ pcie20_avdd1v8: pcie20-avdd1v8 {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "pcie20_avdd1v8";
+ vin-supply = <&vcca_1v8_s0>;
+ };
+
+ pcie30_avdd0v75: pcie30-avdd0v75 {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "pcie30_avdd0v75";
+ vin-supply = <&hdmi_vdda0v85_s0>;
+ };
+
+ pcie30_avdd1v8: pcie30-avdd1v8 {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "pcie30_avdd1v8";
+ vin-supply = <&vcca_1v8_s0>;
+ };
+
+ vbus5v0_typec: vbus5v0-typec {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; /* TYPEC5V_PWREN */
+ pinctrl-0 = <&typec5v_pwren>;
+ pinctrl-names = "default";
+ regulator-name = "usbc_ss_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sus>;
+ };
+
+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3 {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-name = "vcc_1v1_nldo_s3";
+ vin-supply = <&vcc4v0_sys>;
+ };
+
+ vcc_1v8_pcie: vcc-1v8-pcie {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; /* PCIE30_PWREN_H */
+ pinctrl-0 = <&pcie30_pwren_h>;
+ pinctrl-names = "default";
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_pcie";
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc_1v8_s3>;
+ };
+
+ vcc_3v3_sd_s0: vcc-3v3-sd-s0 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; /* SDMMC_PWREN */
+ pinctrl-0 = <&sdmmc_pwren>;
+ pinctrl-names = "default";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vsd_3v3";
+ startup-delay-us = <1000000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc12v_dcin: vcc12v-dcin {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-name = "12vsus";
+ };
+
+ vcc3v3_hubreset: vcc3v3-hubreset {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 RK_PB2 GPIO_ACTIVE_HIGH>; /* USB_HUB_RST_N */
+ pinctrl-0 = <&usb_hub_rst_n>;
+ pinctrl-names = "default";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc3v3_hubreset";
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc3v3_m2: vcc3v3-m2 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>; /* PCIE_PWREN_H */
+ pinctrl-0 = <&pcie_pwren_h>;
+ pinctrl-names = "default";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "3v_m2";
+ vin-supply = <&vcc3v3_sus>;
+ };
+
+ vcc3v3_sus: vcc3v3-sus {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "3vsus";
+ vin-supply = <&vcc12v_dcin>;
+ };
+
+ vcc4v0_sys: vcc4v0-sys {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <4000000>;
+ regulator-name = "vcc4v0_sys";
+ vin-supply = <&vcc12v_dcin>;
+ };
+
+ vcc5v0_host: vcc5v0-host {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>; /* USB_HOST_PWREN */
+ pinctrl-0 = <&usb_host_pwren>;
+ pinctrl-names = "default";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "vcc5v0_host";
+ vin-supply = <&vcc5v0_sus>;
+ };
+
+ vcc5v0_sus: vcc5v0-sus {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "5vsus";
+ vin-supply = <&vcc12v_dcin>;
+ };
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ mem-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ mem-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+ mem-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+ mem-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&gmac0 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy0>;
+ /* Use rgmii-rxid mode to disable rx delay inside Soc */
+ phy-mode = "rgmii-rxid";
+ pinctrl-0 = <&gmac0_miim
+ &gmac0_tx_bus2
+ &gmac0_rx_bus2
+ &gmac0_rgmii_clk
+ &gmac0_rgmii_bus>;
+ pinctrl-names = "default";
+ tx_delay = <0x44>;
+ snps,reset-gpio = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>; /* GMAC0_RST_N */
+ snps,reset-active-low;
+ /* Reset time is 20ms, 100ms for rtl8211f */
+ snps,reset-delays-us = <0 20000 100000>;
+ status = "okay";
+};
+
+&gmac1 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy1>;
+ /* Use rgmii-rxid mode to disable rx delay inside Soc */
+ phy-mode = "rgmii-rxid";
+ pinctrl-0 = <&gmac1_miim
+ &gmac1_tx_bus2
+ &gmac1_rx_bus2
+ &gmac1_rgmii_clk
+ &gmac1_rgmii_bus>;
+ pinctrl-names = "default";
+ tx_delay = <0x43>;
+ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; /* GMAC1_RST_N */
+ snps,reset-active-low;
+ /* Reset time is 20ms, 100ms for rtl8211f */
+ snps,reset-delays-us = <0 20000 100000>;
+ status = "okay";
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu_s0>;
+ status = "okay";
+};
+
+&hdmi0 {
+ pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd_sbc &hdmim0_tx0_scl &hdmim0_tx0_sda>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&hdmi0_in {
+ hdmi0_in_vp0: endpoint {
+ remote-endpoint = <&vp0_out_hdmi0>;
+ };
+};
+
+&hdmi0_out {
+ hdmi0_out_con: endpoint {
+ remote-endpoint = <&hdmi0_con_in>;
+ };
+};
+
+&hdmi0_sound {
+ status = "okay";
+};
+
+&hdptxphy0 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-0 = <&i2c0m2_xfer>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc4v0_sys>;
+ fcs,suspend-voltage-selector = <1>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc4v0_sys>;
+ fcs,suspend-voltage-selector = <1>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c1 {
+ pinctrl-0 = <&i2c1m2_xfer>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ vdd_npu_s0: vdd_npu_mem_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-name = "vdd_npu_s0";
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc4v0_sys>;
+ fcs,suspend-voltage-selector = <1>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c6 {
+ status = "okay";
+
+ rtc: rtc@68 {
+ compatible = "ti,bq32000";
+ reg = <0x68>;
+ };
+};
+
+&i2s5_8ch {
+ status = "okay";
+};
+
+&mdio0 {
+ rgmii_phy0: phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1>;
+ };
+};
+
+&mdio1 {
+ rgmii_phy1: phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x3>;
+ };
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ pinctrl-0 = <&pciex4_perst_n>;
+ pinctrl-names = "default";
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>; /* PCIEX4_PERST_N */
+ /*
+ * Add specific mapping required by the onboard
+ * Axelera Metis AIPU to function.
+ */
+ ranges = <0x81000000 0x0 0xf0100000 0x0 0xf0100000 0x0 0x100000
+ 0x82000000 0x0 0x40000000 0x9 0x00000000 0x0 0x20000000
+ 0xc3000000 0x0 0x60000000 0x9 0x20000000 0x0 0x20000000>;
+ /*
+ * Set to 1v8 because the electronics on the pcie3x4 slot
+ * do not receive 3v3 supply at all, but vpcie3v3-supply
+ * must be specified.
+ */
+ vpcie3v3-supply = <&vcc_1v8_pcie>;
+ status = "okay";
+};
+
+&pinctrl {
+ hdmi {
+ hdmim0_tx0_hpd_sbc: hdmim0-tx0-hpd-sbc {
+ rockchip,pins = <3 RK_PD4 3 &pcfg_pull_none>;
+ };
+ };
+
+ pci {
+ pcie_pwren_h: pcie-pwren-h {
+ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie30_pwren_h: pcie30-pwren-h {
+ rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pciex1_clkreq_n: pciex1-clkreq-n {
+ rockchip,pins = <4 RK_PA0 4 &pcfg_pull_down>;
+ };
+
+ pcie_wake_n: pcie-wake-n { /* M.2_TYPE_B1 wake irq */
+ rockchip,pins = <4 RK_PA1 4 &pcfg_pull_down>;
+ };
+
+ pciex1_perst_n: pciex1-perst-n { /* pcie reset */
+ rockchip,pins = <4 RK_PA2 4 &pcfg_pull_none>;
+ };
+
+ pciex4_perst_n: pciex4-perst-n { /* pcie3x4 reset */
+ rockchip,pins = <4 RK_PB6 4 &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_pwren: sdmmc-pwren {
+ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ usb {
+ usb_hub_rst_n: usb-hub-rst-n {
+ rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ usb_host_pwren: usb-host-pwren {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb-typec {
+ cc_int_n: cc-int-n {
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ typec5v_pwren: typec5v-pwren {
+ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&vcca_1v8_s0>;
+ status = "okay";
+};
+
+/* eMMC */
+&sdhci {
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ no-sd;
+ no-sdio;
+ non-removable;
+ full-pwr-cycle-in-suspend;
+ status = "okay";
+};
+
+&spi2 {
+ assigned-clock-rates = <200000000>;
+ assigned-clocks = <&cru CLK_SPI2>;
+ num-cs = <1>;
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ reg = <0x0>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA7 IRQ_TYPE_LEVEL_LOW>; /* PMIC_INT_L */
+ spi-max-frequency = <1000000>;
+ system-power-controller;
+ vcc1-supply = <&vcc4v0_sys>;
+ vcc2-supply = <&vcc4v0_sys>;
+ vcc3-supply = <&vcc4v0_sys>;
+ vcc4-supply = <&vcc4v0_sys>;
+ vcc5-supply = <&vcc4v0_sys>;
+ vcc6-supply = <&vcc4v0_sys>;
+ vcc7-supply = <&vcc4v0_sys>;
+ vcc8-supply = <&vcc4v0_sys>;
+ vcc9-supply = <&vcc4v0_sys>;
+ vcc10-supply = <&vcc4v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc4v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc4v0_sys>;
+
+ regulators {
+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+ regulator-boot-on;
+ regulator-enable-ramp-delay = <400>;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-name = "vdd_gpu_s0";
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <800000>;
+ regulator-name = "vdd_log_s0";
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-name = "vdd_vdenc_s0";
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-name = "vdd_ddr_s0";
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vdd2_ddr_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-name = "vdd_2v0_pldo_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vddq_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcca_1v8_s0: pldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcca_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdda_1v2_s0: pldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "vdda_1v2_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca_3v3_s0: pldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcca_3v3_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vccio_sd_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca1v8_pldo6_s3: pldo-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcca1v8_pldo6_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdda_ddr_pll_s0: nldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdda_ddr_pll_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ hdmi_vdda0v85_s0: nldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <837500>;
+ regulator-max-microvolt = <837500>;
+ regulator-name = "hdmi_vdda0v85_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda_0v85_s0: nldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdda_0v85_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&u2phy1 {
+ status = "okay";
+};
+
+&u2phy1_otg {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+&usb_host1_xhci {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbdp_phy1 {
+ phy-supply = <&vcc3v3_hubreset>;
+ status = "okay";
+};
+
+&vop {
+ status = "okay";
+};
+
+&vop_mmu {
+ status = "okay";
+};
+
+&vp0 {
+ vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+ remote-endpoint = <&hdmi0_in_vp0>;
+ };
+};
--
2.53.0
^ permalink raw reply related
* [PATCH 2/3] dt-bindings: arm: rockchip: Add Axelera AI Metis Compute Board
From: Patrick Barsanti @ 2026-05-22 17:49 UTC (permalink / raw)
To: devicetree, linux-rockchip, linux-kernel, heiko, robh, krzk+dt,
conor+dt
Cc: linux-amarula, michael, dario.binacchi, Patrick Barsanti
In-Reply-To: <20260522174918.61523-1-patrick.barsanti@amarulasolutions.com>
The Axelera AI Metis Compute Board is a SBC based on the Rockchip RK3588
SoC.
Specification:
- Rockchip RK3588
- 16GB LPDDR4
- Axelera AI Metis AIPU, 4GB/16GB LPDDR4X
- 64GB eMMC
- uSD slot
- 2x SATA ports
- 2x Gigabit LAN
- 1x M.2 E key
- 1x M.2 B key
- 1x HDMI2.0
- 1x USB-C with DP
- 4x USB3.1
Link: https://axelera.ai/evaluation-systems/metis-compute-board
Signed-off-by: Patrick Barsanti <patrick.barsanti@amarulasolutions.com>
---
Documentation/devicetree/bindings/arm/rockchip.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 1a9dde18626d..a784c9eddc50 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -107,6 +107,11 @@ properties:
- asus,rk3566-tinker-board-3s
- const: rockchip,rk3566
+ - description: Axelera AI Metis Compute Board
+ items:
+ - const: axelera,metis-sbc
+ - const: rockchip,rk3588
+
- description: Beelink A1
items:
- const: azw,beelink-a1
--
2.53.0
^ permalink raw reply related
* [PATCH 1/3] dt-bindings: vendor-prefixes: Add Axelera AI
From: Patrick Barsanti @ 2026-05-22 17:49 UTC (permalink / raw)
To: devicetree, linux-rockchip, linux-kernel, heiko, robh, krzk+dt,
conor+dt
Cc: linux-amarula, michael, dario.binacchi, Patrick Barsanti
In-Reply-To: <20260522174918.61523-1-patrick.barsanti@amarulasolutions.com>
Axelera AI is an EU-based provider of AIPUs for edge AI inference.
Link: https://axelera.ai/
Signed-off-by: Patrick Barsanti <patrick.barsanti@amarulasolutions.com>
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 28784d66ae7b..595ad9423ece 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -217,6 +217,8 @@ patternProperties:
description: Avnet, Inc.
"^awinic,.*":
description: Shanghai Awinic Technology Co., Ltd.
+ "^axelera,.*":
+ description: Axelera AI
"^axentia,.*":
description: Axentia Technologies AB
"^axiado,.*":
--
2.53.0
^ permalink raw reply related
* [PATCH 0/3] arm64: dts: rockchip: Add support for Axelera Metis SBC
From: Patrick Barsanti @ 2026-05-22 17:49 UTC (permalink / raw)
To: devicetree, linux-rockchip, linux-kernel, heiko, robh, krzk+dt,
conor+dt
Cc: linux-amarula, michael, dario.binacchi, Patrick Barsanti
The Axelera AI Metis Compute Board is a SBC based on the Rockchip RK3588
SoC. It offers efficient AI compute for multi-stream computer vision and
generative AI applications in a compact design.
Product page [1].
This series was tested against Linux 7.1-rc4
(5200f5f493f79f14bbdc349e402a40dfb32f23c8), and aims to introduce basic
support for the board, which includes the console, the eMMC,
the two Gigabit Ethernet ports, the four USB ports and
the HDMI connector.
[1]: https://axelera.ai/evaluation-systems/metis-compute-board
Patrick Barsanti (3):
dt-bindings: vendor-prefixes: Add Axelera AI
dt-bindings: arm: rockchip: Add Axelera AI Metis Compute Board
arm64: dts: rockchip: Add Axelera AI metis-sbc
.../devicetree/bindings/arm/rockchip.yaml | 5 +
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
arch/arm64/boot/dts/rockchip/Makefile | 1 +
.../boot/dts/rockchip/rk3588-metis-sbc.dts | 840 ++++++++++++++++++
4 files changed, 848 insertions(+)
create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-metis-sbc.dts
--
2.53.0
^ permalink raw reply
* Re: [PATCH v5 04/13] Documentation: ABI: testing: add parent entry for iio channels
From: Jonathan Cameron @ 2026-05-22 17:47 UTC (permalink / raw)
To: Rodrigo Alencar via B4 Relay
Cc: rodrigo.alencar, linux-iio, devicetree, linux-kernel, linux-doc,
linux-hardening, Lars-Peter Clausen, Michael Hennerich,
David Lechner, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, Jonathan Corbet, Shuah Khan,
Kees Cook, Gustavo A. R. Silva
In-Reply-To: <20260517-ad9910-iio-driver-v5-4-31599c88314a@analog.com>
On Sun, 17 May 2026 19:37:48 +0100
Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:
> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
>
> Add documentation for a read-only sysfs attribute that allows to expose
> parent-child relationships between IIO channels.
>
> Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 925a33fd309a..399944974e34 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -2118,6 +2118,19 @@ Description:
> specific attributes. This is useful for userspace to be able to
> better identify an individual channel.
>
> +What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_parent
> +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_parent
> +What: /sys/bus/iio/devices/iio:deviceX/in_altvoltageY_parent
> +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_parent
> +KernelVersion: 7.1
> +Contact: linux-iio@vger.kernel.org
> +Description:
> + Read-only attribute containing the label of the parent channel
> + for hierarchical channel relationships. Only present on channels
> + that have a parent channel with a valid label. This is useful for
> + userspace to organize channels in tree-like structures that reflects
> + the physical or logical relationships between them.
Perhaps an example would be useful?
Otherwise it seems reasonable. One vague concern I have is maybe we end
up with a channel that actually has no other existence than as a parent.
Image two signals mixed into one. If that mixed signal has nothing to control
it wouldn't normally show up in the ABI.
I guess we can give it a label though to ensure there is something there
(even when not using labels for this!).
J
> +
> What: /sys/bus/iio/devices/iio:deviceX/in_phaseY_raw
> KernelVersion: 4.18
> Contact: linux-iio@vger.kernel.org
>
^ permalink raw reply
* Re: [PATCH v5 03/13] iio: core: add hierarchical channel relationships
From: Jonathan Cameron @ 2026-05-22 17:45 UTC (permalink / raw)
To: Rodrigo Alencar
Cc: rodrigo.alencar, linux-iio, devicetree, linux-kernel, linux-doc,
linux-hardening, Lars-Peter Clausen, Michael Hennerich,
David Lechner, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, Jonathan Corbet, Shuah Khan,
Kees Cook, Gustavo A. R. Silva
In-Reply-To: <hjv4uuudhkueaotpyuzj3u3jg2rkr73jmrx2vxi37w3po5xk5x@3fhfebj6a3wt>
On Thu, 21 May 2026 14:48:30 +0100
Rodrigo Alencar <455.rodrigo.alencar@gmail.com> wrote:
> On 26/05/18 03:26PM, Rodrigo Alencar wrote:
> > On 26/05/17 06:56PM, sashiko-bot@kernel.org wrote:
> > > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> > > - [Medium] Exposing the hierarchical relationship via channel labels creates an ambiguous UAPI for userspace.
> > > --
> > >
> > > commit 64c6f961f1d7645c58f732e4bd4c11200b999e93
> > > Author: Rodrigo Alencar <rodrigo.alencar@analog.com>
> > >
> > > iio: core: add hierarchical channel relationships
> > >
> > > This commit introduces a parent-child relationship between IIO channels.
> > > It adds a parent pointer to the iio_chan_spec struct and exposes this
> > > relationship to userspace through a new "parent" sysfs attribute that
> > > returns the parent channel's label.
> > >
> > > > diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> > > > index 5c8404efd0a56..348ac7a597385 100644
> > > > --- a/drivers/iio/industrialio-core.c
> > > > +++ b/drivers/iio/industrialio-core.c
> > >
> > > [ ... ]
> > >
> > > > @@ -1263,6 +1271,31 @@ static int iio_device_add_channel_label(struct iio_dev *indio_dev,
> > > > return 1;
> > > > }
> > > >
> > > > +static int iio_device_add_channel_parent(struct iio_dev *indio_dev,
> > > > + struct iio_chan_spec const *chan)
> > > > +{
> > > > + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
> > > > + int ret;
> > > > +
> > > > + if (!chan->parent || (!indio_dev->info->read_label &&
> > > > + !chan->parent->extend_name))
> > > > + return 0;
> > >
> > > Is relying on channel labels robust enough for programmatic parent resolution?
> > >
> > > IIO channel labels are optional, human-readable descriptors and are not
> > > guaranteed by the core to be unique. If multiple channels within a device
> > > share the same label, how can userspace definitively resolve which specific
> > > channel is the parent?
> > >
> > > Also, if a driver establishes a hierarchy where chan->parent is set, but the
> > > parent channel lacks a label, this attribute is silently omitted, hiding the
> > > relationship entirely.
> > >
> > > Would it be more reliable to expose a definitive, unique identifier (such as
> > > the parent channel's sysfs prefix or index) rather than relying on an optional
> > > descriptive string?
> >
> > A bit impressive that sashiko can comment on that architecture level.
> >
> > Those are all good points. I suppose I went for this because otherwise it would
> > require refactoring core code to get the needed parts from __iio_device_attr_init()
> > that gets you the channel name without the attribute part.
> >
> > Maybe we should have a function that outputs a channel name into a buffer based on
> > __iio_device_attr_init() behavior, and that could be reused.
>
> This is the function with behavior extracted from __iio_device_attr_init():
>
> static int __iio_chan_prefix_emit(const struct iio_chan_spec *chan,
> enum iio_shared_by shared_by,
> char *buf, size_t len)
> {
> const char *dir = iio_direction[chan->output];
> const char *type = iio_chan_type_name_spec[chan->type];
> int n = 0;
>
> switch (shared_by) {
> case IIO_SHARED_BY_ALL:
> break;
> case IIO_SHARED_BY_DIR:
> n = scnprintf(buf, len, "%s", dir);
> break;
> case IIO_SHARED_BY_TYPE:
> n = scnprintf(buf, len, "%s_%s", dir, type);
> if (chan->differential)
> n += scnprintf(buf + n, len - n, "-%s", type);
> break;
> case IIO_SEPARATE:
> if (chan->indexed) {
> n = scnprintf(buf, len, "%s_%s%d", dir, type,
> chan->channel);
> if (chan->differential)
> n += scnprintf(buf + n, len - n, "-%s%d", type,
> chan->channel2);
> } else {
> if (chan->differential) {
> WARN(1, "Differential channels must be indexed\n");
> return -EINVAL;
> }
> n = scnprintf(buf, len, "%s_%s", dir, type);
> }
>
> if (chan->modified) {
> if (chan->differential) {
> WARN(1, "Differential channels can not have modifier\n");
> return -EINVAL;
> }
> n += scnprintf(buf + n, len - n, "_%s",
> iio_modifier_names[chan->channel2]);
> }
>
> if (chan->extend_name)
> n += scnprintf(buf + n, len - n, "_%s", chan->extend_name);
> break;
> }
>
> return n;
> }
>
> I think it is clear and reusable.
You only what the SEPARATE case but given the rest is much simpler anyway probably fine
to just use this function.
Jonathan
>
> > > > +
> > > > + ret = __iio_add_chan_devattr("parent",
> > > > + chan,
> > > > + &iio_read_channel_parent,
> > > > + NULL,
> > > > + 0,
> > > > + IIO_SEPARATE,
> > > > + &indio_dev->dev,
> > > > + NULL,
> > > > + &iio_dev_opaque->channel_attr_list);
> > > > + if (ret < 0)
> > > > + return ret;
> > > > +
> > > > + return 1;
> > > > +}
> > >
> > > --
> > > Sashiko AI review · https://sashiko.dev/#/patchset/20260517-ad9910-iio-driver-v5-0-31599c88314a@analog.com?part=3
>
^ permalink raw reply
* Re: [PATCH v2 4/4] arm64: dts: qcom: x1-dell-thena: bump linux,cma to 256 MiB
From: Rob Clark @ 2026-05-22 17:42 UTC (permalink / raw)
To: Val Packett
Cc: Michael Scott, linux-arm-msm, vkoul, neil.armstrong,
dmitry.baryshkov, wesley.cheng, abelvesa, faisal.hassan,
linux-phy, andersson, konradybcio, robh, krzk+dt, conor+dt,
devicetree, bryan.odonoghue, laurentiu.tudor1, alex.vinarskis,
linux-kernel
In-Reply-To: <e5b40f3c-25f6-401b-84d3-2fb96897d936@packett.cool>
On Wed, May 20, 2026 at 8:55 PM Val Packett <val@packett.cool> wrote:
>
>
> On 5/20/26 10:09 PM, Michael Scott wrote:
> > The 128 MiB linux,cma reserved-memory pool on dell-thena is too small
> > to support the camera pipeline in parallel with the normal Linux
> > desktop. On a freshly-booted system with GNOME running, the typical
> > runtime consumers — msm DRM framebuffers (Wayland triple buffering on
> > the eDP panel), qcom_iris video codec buffers, qcom_camss VFE
> > pre-allocated buffers — already occupy ~100 MiB of the pool, leaving
> > only ~25 MiB free.
>
> Huh, I'm surprised that drm framebuffers use CMA… IIRC, msm drm can work
> fine without a cma node present at all.
>
> Indeed, with a desktop on a 4K monitor I'm seeing..
>
> CmaTotal: 131072 kB
> CmaFree: 1704 kB
Is something in userspace allocating from dma-heap and importing into
drm/msm? We shouldn't otherwise be allocating from CMA, at least not
intentionally.
(I also dislike specifying CMA in dtb, since that seems more like
describing use-case than describing hw..)
BR,
-R
> > The libcamera "simple" pipeline handler used by /dev/media0 on
> > dell-thena allocates four ABGR8888 frames at 1920×1088 = 32 MiB total.
> > That request fails on the fourth frame:
> >
> > ERROR DmaBufAllocator: dma-heap allocation failure for frame-3
> > ERROR Allocator: Stream is not part of /base/.../camera@10 active configuration
> > Can't allocate buffers
> > Failed to start camera session
> >
> > resulting in gnome-snapshot's "Could not play camera stream" and any
> > other libcamera-mediated app being unable to actually stream.
>
> ..however I couldn't reproduce any failures, Snapshot started up just
> fine, lowering CmaFree to 300 kB.
>
> I have even launched both Snapshot and ffplay with a 4K AV1 video
> through av1_v4l2m2m, CmaFree went all the way down to zero but there
> were no errors whatsoever, both worked simultaneously just fine. o_0
>
> I think drm buffers might just get evicted from that area or something?
>
> > Bumping linux,cma to 256 MiB (a 0.9% reservation on these laptops'
> > typical 27 GiB RAM) leaves ~150 MiB free at runtime — sufficient for
> > the libcamera buffer set plus headroom for video playback or other
> > CMA-hungry workloads in parallel.
> >
> > Tested on Dell Latitude 7455: with the 256 MiB pool, CmaFree at
> > GNOME-desktop idle is ~150 MiB, gnome-snapshot streams the OV02E10
> > camera cleanly, and `cam -c 1 --capture=2` succeeds.
> >
> > The companion board files dell-inspiron-14-plus-7441 and the upstream
> > .dts variants inherit from x1-dell-thena.dtsi, so this changes the
> > pool size for every dell-thena-based laptop in one place.
>
>
> In any case, that's not an objection of course, just wondering why it's
> working fine for me and not for you..
>
> Acked-by: Val Packett <val@packett.cool>
>
> ~val
>
>
^ permalink raw reply
* Re: [PATCH v3 8/8] iio: temperature: ltc2983: Add support for ADT7604
From: Jonathan Cameron @ 2026-05-22 17:31 UTC (permalink / raw)
To: Stan, Liviu
Cc: David Lechner, Sa, Nuno, Andy Shevchenko, Hennerich, Michael,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Miclaus, Antoniu,
Francesco Lavra, linux-iio@vger.kernel.org,
linux-kernel@vger.kernel.org, linux, devicetree@vger.kernel.org
In-Reply-To: <LV9PR03MB8366C36D83A00FFCC166E333F60F2@LV9PR03MB8366.namprd03.prod.outlook.com>
On Fri, 22 May 2026 14:24:27 +0000
"Stan, Liviu" <Liviu.Stan@analog.com> wrote:
> On Fri, 22 May 2026 14:34:44 +0100 Jonathan Cameron <jic23@kernel.org> wrote:
>
> > On Thu, 21 May 2026 19:43:01 +0300
> > Liviu Stan <liviu.stan@analog.com> wrote:
> >
> ...
> >
> > The sashiko comment about the completion race looks real to me.
> > Can you take a look at that. Might be some odd reason why we can't
> > reinit_completion() before triggering the capture but that would
> > be very unusual.
> >
>
> I don't see any reason why we couldn't put it before the regmap_write,
> it has also already been done in ltc2983_eeprom_cmd(). So, I will change
> it in v4.
>
> > Otherwise just two really small things I missed in earlier reviews.
> > If everything else was ready to go I'd have tweaked these whilst
> > applying but seems you'll be doing a v4 so over to you!
>
> Understood, will change them in v4!:) Thanks!
>
> On Fri, 22 May 2026 09:09:33 -0500 David Lechner <dlechner@baylibre.com> wrote:
>
> > On 5/22/26 8:23 AM, Liviu Stan wrote:
> > > On Thu, 21 May 2026 19:18:28 +0000 sashiko-bot@kernel.org wrote:
> > >
> > >> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> ...
> > >> [Severity: High]
> > >> This is a pre-existing issue, but can this function experience spurious
> > >> read timeouts due to a race condition with the completion?
> > >>
> > >> Looking at the rest of this function:
> > >>
> > >> ret = regmap_write(st->regmap, LTC2983_STATUS_REG, start_conversion);
> > >> if (ret)
> > >> return ret;
> > >>
> > >> reinit_completion(&st->completion);
> > >>
> > >> If the hardware conversion finishes very quickly after regmap_write(),
> > >> could the interrupt fire and call complete() before the CPU executes
> > >> reinit_completion()? This would overwrite the completion event, causing the
> > >> subsequent wait_for_completion_timeout() to spuriously time out.
> > >>
> > >> Would it be safer to call reinit_completion() before initiating the hardware
> > >> action?
> > >
> > > This is theoretically valid but in practice, the conversion requires at minimum
> > > two 82ms cycles (167ms), so there is no realistic window for the interrupt to
> > > race with reinit_completion(). What do you guys think?
> >
> > I would still move it before the write so that it looks correct
> > and others can copy/paste the logic on other devices.
>
> That makes sense. Thanks!
>
> Would this be considered a fix?
Yes, though not an urgent one given no particular reports of it being hit.
Just put it at the start of the series and I'll apply it with the rest.
Can get backported after next merge window.
Thanks,
Jonathan
>
> Liviu
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox