* [PATCH v4 1/2] dt-bindings: display: bridge: Document Renesas RZ/G3L LVDS encoder
From: Biju @ 2026-06-19 10:10 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm
Cc: Biju Das, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Tommaso Merciai, dri-devel, devicetree,
linux-kernel, linux-renesas-soc, Prabhakar Mahadev Lad, Biju Das
In-Reply-To: <20260619101026.323633-1-biju.das.jz@bp.renesas.com>
From: Biju Das <biju.das.jz@bp.renesas.com>
Document the LVDS encoder IP found on the RZ/G3L SoC. It supports
single-link mode. LVDS and the DSI interface share a peripheral clock and
the MIPI_DSI_PRESET_N reset signal. However, the LVDS module cannot be
used at the same time as MIPI-DSI.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v3->v4:
* Dropped the tags as it is a rework dropping parent node that contains
simple-mfd and syscon.
v2->v3:
* Collected tag.
v2->v2[1]:
* No change.
[1] https://lore.kernel.org/all/20260524195829.960401F000E9@smtp.kernel.org/
v1->v2:
* Collected tag.
---
.../bridge/renesas,r9a08g046-lvds.yaml | 120 ++++++++++++++++++
1 file changed, 120 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/bridge/renesas,r9a08g046-lvds.yaml
diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,r9a08g046-lvds.yaml b/Documentation/devicetree/bindings/display/bridge/renesas,r9a08g046-lvds.yaml
new file mode 100644
index 000000000000..4cd7b688fbf7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/renesas,r9a08g046-lvds.yaml
@@ -0,0 +1,120 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/renesas,r9a08g046-lvds.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/G3L LVDS Encoder
+
+maintainers:
+ - Biju Das <biju.das.jz@bp.renesas.com>
+ - Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
+
+description: |
+ This binding describes the LVDS encoder embedded in the Renesas RZ/G3L
+ SoC. The encoder can operate in LVDS Single-link mode with 4 lanes
+ (Data) + 1 lane (Clock).
+
+properties:
+ compatible:
+ const: renesas,r9a08g046-lvds
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Peripheral clock
+ - description: PHY clock
+ - description: Dot clock
+
+ clock-names:
+ items:
+ - const: pclk
+ - const: phyclk
+ - const: dotclk
+
+ resets:
+ items:
+ - description: LVDS_RESET_N
+ - description: MIPI_DSI_PRESET_N
+ - description: MIPI_DSI_CMN_RSTB
+ - description: MIPI_DSI_ARESET_N
+
+ reset-names:
+ items:
+ - const: lvdrst
+ - const: prst
+ - const: rst
+ - const: arst
+
+ power-domains:
+ maxItems: 1
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Input channel, directly connected to the Display Unit.
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: |
+ Output channel, directly connected to the LVDS panel or bridge.
+
+ required:
+ - port@0
+ - port@1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+ - power-domains
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/renesas,r9a08g046-cpg.h>
+
+ lvds@108a0000 {
+ compatible = "renesas,r9a08g046-lvds";
+ reg = <0x108a0000 0x10000>;
+ clocks = <&cpg CPG_MOD R9A08G046_MIPI_DSI_PCLK>,
+ <&cpg CPG_MOD R9A08G046_LVDS_PLLCLK>,
+ <&cpg CPG_MOD R9A08G046_LVDS_CLK_DOT0>;
+ clock-names = "pclk", "phyclk", "dotclk";
+ resets = <&cpg R9A08G046_LVDS_RESET_N>,
+ <&cpg R9A08G046_MIPI_DSI_PRESET_N>,
+ <&cpg R9A08G046_MIPI_DSI_CMN_RSTB>,
+ <&cpg R9A08G046_MIPI_DSI_ARESET_N>;
+ reset-names = "lvdrst", "prst", "rst", "arst";
+ power-domains = <&cpg>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ lvds0_in: endpoint {
+ remote-endpoint = <&du_out_lvds0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ lvds0_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+ };
+...
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v4 1/2] arm64: dts: imx8mq-evk: Add OV5640 camera support via overlays
From: sashiko-bot @ 2026-06-19 10:16 UTC (permalink / raw)
To: robby.cai; +Cc: conor+dt, devicetree, Frank.Li, imx, robh
In-Reply-To: <20260619100532.3779934-2-robby.cai@oss.nxp.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Dual camera setup fails due to shared reset GPIO exclusivity causing `-EBUSY` and unexpected hardware resets.
- [Medium] Overlay-specific pinmux configurations and unconditional hogs pollute the base device tree.
--
commit d401c57ae9a7ef9c71733905b73812d521acf9a9
Author: Robby Cai <robby.cai@nxp.com>
arm64: dts: imx8mq-evk: Add OV5640 camera support via overlays
This patch adds device tree overlays for single and dual OV5640 camera
setups on the i.MX8MQ EVK board. It configures media pipelines for CSI1
and CSI2, noting that both sensors share a common reset GPIO and MCLK
source.
> diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi1.dtso b/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi1.dtso
> new file mode 100644
> index 0000000000000..1e9931802cdc4
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi1.dtso
[ ... ]
> + camera@3c {
> + compatible = "ovti,ov5640";
> + reg = <0x3c>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_camera1_pwdn>;
> + clocks = <&clk IMX8MQ_CLK_CLKO2>;
> + clock-names = "xclk";
> + assigned-clocks = <&clk IMX8MQ_CLK_CLKO2>;
> + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_200M>;
> + assigned-clock-rates = <20000000>;
> + powerdown-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
> + reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
[Severity: High]
Is it safe to assign this reset GPIO (&gpio1 6) when it is also assigned
identically in the CSI2 overlay?
Since the GPIO framework enforces exclusive access, won't the second camera
to probe fail with -EBUSY?
Additionally, when ov5640_powerup_sequence() toggles this shared reset line
during power-on, couldn't this silently hard-reset the other active camera
and break its stream?
> + DOVDD-supply = <&sw4_reg>;
> + AVDD-supply = <®_2v8>;
> + DVDD-supply = <®_1v5>;
[ ... ]
> diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi2.dtso b/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi2.dtso
> new file mode 100644
> index 0000000000000..fd247b3b59825
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi2.dtso
[ ... ]
> + camera@3c {
> + compatible = "ovti,ov5640";
> + reg = <0x3c>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_camera2_pwdn>;
> + clocks = <&clk IMX8MQ_CLK_CLKO2>;
> + clock-names = "xclk";
> + assigned-clocks = <&clk IMX8MQ_CLK_CLKO2>;
> + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_200M>;
> + assigned-clock-rates = <20000000>;
> + powerdown-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
> + reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
[Severity: High]
This assigns the exact same reset GPIO (&gpio1 6) as the CSI1 overlay,
which can cause probe contention and hardware state corruption as described
above.
> + DOVDD-supply = <&sw4_reg>;
> + AVDD-supply = <®_2v8>;
> + DVDD-supply = <®_1v5>;
[ ... ]
> diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
> index d48f901487d49..1260bb1d9069b 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
[ ... ]
> @@ -532,12 +546,34 @@ &wdog1 {
> };
>
> &iomuxc {
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_mclk>, <&pinctrl_camera_reset>;
[Severity: Medium]
Does unconditionally hogging these camera-specific pins in the base device
tree unnecessarily consume GPIOs when the optional camera overlays are not
applied?
> pinctrl_buck2: vddarmgrp {
> fsl,pins = <
> MX8MQ_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x19
> >;
> };
>
> + pinctrl_camera1_pwdn: camera1pwdngrp {
[Severity: Medium]
Could defining these overlay-specific pin groups in the base device tree,
rather than isolating them within their respective overlays, break the
modularity of the device tree overlays?
> + fsl,pins = <
> + MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x19
> + >;
> + };
> +
> + pinctrl_camera2_pwdn: camera2pwdngrp {
> + fsl,pins = <
> + MX8MQ_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x19
> + >;
> + };
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260619100532.3779934-1-robby.cai@oss.nxp.com?part=1
^ permalink raw reply
* Re: [PATCH v4 2/2] media: i2c: ov5640: Add reset controller support with GPIO fallback
From: sashiko-bot @ 2026-06-19 10:16 UTC (permalink / raw)
To: robby.cai; +Cc: robh, conor+dt, Frank.Li, devicetree, imx
In-Reply-To: <20260619100532.3779934-3-robby.cai@oss.nxp.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Misuse of the shared reset controller API violates hardware power-up sequencing, risking sensor damage via latch-up, and causes a power management resource leak.
- [Medium] Unbalanced shared reset control deassert_count triggers a kernel WARN_ON on the `ov5640_reset_deassert()` error path.
--
commit 08ff61c49c74c476ab99932a1e24e30024577ace
Author: Robby Cai <robby.cai@nxp.com>
media: i2c: ov5640: Add reset controller support with GPIO fallback
Add support for the reset controller framework by acquiring the reset
line using devm_reset_control_get_optional_shared_deasserted(). This
allows the driver to handle reset lines provided by a reset controller,
including shared ones, while avoiding unbalanced deassert counts.
> diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
> index 85ecc23b35877..5e6db8aacb118 100644
> --- a/drivers/media/i2c/ov5640.c
> +++ b/drivers/media/i2c/ov5640.c
[ ... ]
> @@ -2431,6 +2433,48 @@ static int ov5640_restore_mode(struct ov5640_dev *sensor)
> return ov5640_set_framefmt(sensor, &sensor->fmt);
> }
>
> +static int ov5640_get_reset(struct device *dev, struct ov5640_dev *sensor)
> +{
> + /* use deasserted version to avoid unbalanced deassert counts */
> + sensor->reset =
> + devm_reset_control_get_optional_shared_deasserted(dev, NULL);
[Severity: High]
Does acquiring the reset control in the deasserted state risk hardware
damage and cause a power management leak?
Because this API call deasserts the reset line during probe, it pulls the
reset IO line HIGH before VDD regulators are enabled in
ov5640_set_power_on(). Applying voltage to the reset pin while VDD is off
can cause a destructive latch-up condition.
Additionally, because devm_reset_control_get_optional_shared_deasserted()
acquires a base deassert vote, and the driver never explicitly asserts the
reset line during ov5640_set_power_off() on runtime PM suspend, does this
permanently prevent the reset controller and parent power domains from
suspending?
Also, the inline comment below claims GPIOD_OUT_HIGH ensures a deasserted
state for an ACTIVE_LOW reset, but GPIOD_OUT_HIGH sets the logical value
to 1, which drives an ACTIVE_LOW line physically LOW (asserted).
> + if (IS_ERR(sensor->reset))
> + return dev_err_probe(dev, PTR_ERR(sensor->reset),
> + "Failed to get reset\n");
> + else if (sensor->reset)
> + return 0;
> +
> + /*
> + * fallback to legacy reset-gpios
> + * GPIOD_OUT_HIGH ensures deasserted state for ACTIVE_LOW reset
> + */
> + sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
> + GPIOD_OUT_HIGH);
[ ... ]
> -static void ov5640_powerup_sequence(struct ov5640_dev *sensor)
> +static int ov5640_powerup_sequence(struct ov5640_dev *sensor)
> {
> + int ret;
> +
> if (sensor->pwdn_gpio) {
> - gpiod_set_value_cansleep(sensor->reset_gpio, 1);
> + ret = ov5640_reset_assert(sensor);
[Severity: High]
If the reset line is shared with an active device, will this actually
assert the reset line?
For shared reset controls, reset_control_assert() merely drops the local
vote. If another device is keeping the line deasserted, the physical pin
will remain HIGH.
Since the driver proceeds to power-cycle the OV5640's VDD regulators below:
> + if (ret) {
> + dev_err(&sensor->i2c_client->dev,
> + "Failed to assert reset: %d\n", ret);
> + return ret;
> + }
>
> /* camera power cycle */
> ov5640_power(sensor, false);
Doesn't power-cycling the sensor while the shared reset pin is driven HIGH
violate hardware sequencing and risk latch-up?
> usleep_range(5000, 10000); /* t2 */
> ov5640_power(sensor, true);
> usleep_range(1000, 2000); /* t3 */
>
> - gpiod_set_value_cansleep(sensor->reset_gpio, 0);
> + ret = ov5640_reset_deassert(sensor);
> + if (ret) {
> + dev_err(&sensor->i2c_client->dev,
> + "Failed to deassert reset: %d\n", ret);
> + ov5640_power(sensor, false);
> + return ret;
> + }
[Severity: Medium]
If ov5640_reset_deassert() fails here, does this cause a WARN_ON in the
reset core during cleanup?
The devm_reset_control_get_optional_shared_deasserted() call during probe
initializes the deassert_count to 1. The ov5640_reset_assert() call above
drops it to 0.
If this function returns an error without reclaiming the vote, the count
remains at 0. When probe subsequently fails, the devm framework will call
reset_control_assert() to balance the initial acquisition. Since the count
is already 0, this will underflow the counter and trigger a kernel warning
in drivers/reset/core.c.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260619100532.3779934-1-robby.cai@oss.nxp.com?part=2
^ permalink raw reply
* [PATCH v2] dt-bindings: thermal: qcom-tsens: Document the Maili Temperature Sensor
From: Haritha S K @ 2026-06-19 10:20 UTC (permalink / raw)
To: dipa.mantre, Amit Kucheria, Thara Gopinath, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Haritha S K, linux-pm, linux-arm-msm, devicetree, linux-kernel,
manaf.pallikunhi, gaurav.kohli, Krzysztof Kozlowski
Document the Temperature Sensor (TSENS) on the Qualcomm Maili SoC.
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Haritha S K <haritha.k@oss.qualcomm.com>
---
Changes in v2:
- Updated commit message.
- Link to v1: https://patch.msgid.link/20260617-b4-maili-upstream-3-v1-1-1b8cb7e425d8@oss.qualcomm.com
---
Documentation/devicetree/bindings/thermal/qcom-tsens.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
index f0efaa8349ee..5a8f7673e730 100644
--- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
@@ -58,6 +58,7 @@ properties:
- qcom,glymur-tsens
- qcom,hawi-tsens
- qcom,kaanapali-tsens
+ - qcom,maili-tsens
- qcom,milos-tsens
- qcom,nord-tsens
- qcom,msm8953-tsens
---
base-commit: a76326dca329a7a738ba367529868dfbafb4a403
change-id: 20260616-b4-maili-upstream-3-b198aaa8969f
Best regards,
--
Haritha S K <haritha.k@oss.qualcomm.com>
^ permalink raw reply related
* [PATCH 0/2] arm: dts: xilinx: Add MYIR MYS-7Z020-V2 board support
From: Liu Yu @ 2026-06-19 10:22 UTC (permalink / raw)
To: Michal Simek
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, devicetree,
linux-arm-kernel, Liu Yu
This series adds basic device tree and binding documentation support
for the MYIR MYS-7Z020-V2 development board, which is based on the
Xilinx Zynq-7000 (XC7Z020) SoC.
The first patch introduces the device tree file enabling essential
hardware support such as the serial console, MicroSD, Gigabit Ethernet,
QSPI flash, and user LEDs/buttons. The second patch adds the corresponding
compatible string to the Xilinx SoC bindings documentation.
Liu Yu (2):
dt-bindings: soc: xilinx: Add MYIR MYS-7Z020-V2 board
arm: dts: xilinx: Add support for MYIR MYS-7Z020-V2 board
.../bindings/soc/xilinx/xilinx.yaml | 1 +
arch/arm/boot/dts/xilinx/Makefile | 1 +
.../arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts | 228 ++++++++++++++++++
3 files changed, 230 insertions(+)
create mode 100644 arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts
--
2.43.0
^ permalink raw reply
* [PATCH 1/2] dt-bindings: soc: xilinx: Add MYIR MYS-7Z020-V2 board
From: Liu Yu @ 2026-06-19 10:22 UTC (permalink / raw)
To: Michal Simek
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, devicetree,
linux-arm-kernel, Liu Yu
In-Reply-To: <20260619102214.223121-1-f78fk@live.com>
Add compatible string for the MYIR MYS-7Z020-V2 board, based on
the Xilinx Zynq-7000 XC7Z020 SoC.
Signed-off-by: Liu Yu <f78fk@live.com>
---
Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml b/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml
index c9f99e0df2b3..72a84b628da3 100644
--- a/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml
+++ b/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml
@@ -23,6 +23,7 @@ properties:
- digilent,zynq-zybo
- digilent,zynq-zybo-z7
- ebang,ebaz4205
+ - myir,mys-7z020-v2
- myir,zynq-zturn-v5
- myir,zynq-zturn
- xlnx,zynq-cc108
--
2.43.0
^ permalink raw reply related
* [PATCH 2/2] arm: dts: xilinx: Add support for MYIR MYS-7Z020-V2 board
From: Liu Yu @ 2026-06-19 10:22 UTC (permalink / raw)
To: Michal Simek
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, devicetree,
linux-arm-kernel, Liu Yu
In-Reply-To: <20260619102214.223121-1-f78fk@live.com>
Add device tree support for the MYIR MYS-7Z020-V2 board based on
the Xilinx Zynq-7000 XC7Z020 SoC.
The board supports:
- UART serial console
- MicroSD card interface
- Gigabit Ethernet
- QSPI NOR flash
- GPIO-based user LEDs and push-button
Link: https://www.myirtech.com/list.asp?id=708
Signed-off-by: Liu Yu <f78fk@live.com>
---
arch/arm/boot/dts/xilinx/Makefile | 1 +
.../arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts | 228 ++++++++++++++++++
2 files changed, 229 insertions(+)
create mode 100644 arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts
diff --git a/arch/arm/boot/dts/xilinx/Makefile b/arch/arm/boot/dts/xilinx/Makefile
index 9233e539b192..6c59116013f1 100644
--- a/arch/arm/boot/dts/xilinx/Makefile
+++ b/arch/arm/boot/dts/xilinx/Makefile
@@ -3,6 +3,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \
zynq-cc108.dtb \
zynq-ebaz4205.dtb \
zynq-microzed.dtb \
+ zynq-mys-7z020-v2.dtb \
zynq-parallella.dtb \
zynq-zc702.dtb \
zynq-zc706.dtb \
diff --git a/arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts b/arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts
new file mode 100644
index 000000000000..39bd864ca358
--- /dev/null
+++ b/arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 Liu Yu <f78fk@live.com>
+ */
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "zynq-7000.dtsi"
+
+/ {
+ model = "MYIR MYS-7Z020-V2 Board";
+ compatible = "myir,mys-7z020-v2", "xlnx,zynq-7000";
+
+ aliases {
+ ethernet0 = &gem0;
+ mmc0 = &sdhci0;
+ serial0 = &uart1;
+ spi0 = &qspi;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ autorepeat;
+
+ key-user {
+ label = "USR";
+ gpios = <&gpio0 50 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led-blue {
+ label = "led_blue";
+ gpios = <&gpio0 115 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led-green {
+ label = "led_green";
+ gpios = <&gpio0 114 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led-red {
+ label = "led_red";
+ gpios = <&gpio0 116 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ usr-led1 {
+ label = "usr_led1";
+ gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ usr-led2 {
+ label = "usr_led2";
+ gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x40000000>;
+ };
+};
+
+&clkc {
+ ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+ phy-mode = "rgmii-id";
+ phy-handle = <ðernet_phy>;
+
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet_phy: ethernet-phy@7 {
+ reg = <0x7>;
+ };
+ };
+};
+
+&gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio0_default>;
+};
+
+&pinctrl0 {
+ pinctrl_gpio0_default: gpio0-default {
+ mux {
+ function = "gpio0";
+ groups = "gpio0_0_grp", "gpio0_9_grp", "gpio0_50_grp";
+ };
+ conf {
+ groups = "gpio0_0_grp", "gpio0_9_grp", "gpio0_50_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ conf-pull-up {
+ pins = "MIO0", "MIO9", "MIO50";
+ bias-pull-up;
+ };
+ };
+
+ pinctrl_sdhci0_default: sdhci0-default {
+ mux {
+ groups = "sdio0_2_grp";
+ function = "sdio0";
+ };
+ conf {
+ groups = "sdio0_2_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+ conf-cd {
+ pins = "MIO46";
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_uart1_default: uart1-default {
+ mux {
+ groups = "uart1_10_grp";
+ function = "uart1";
+ };
+ conf {
+ groups = "uart1_10_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ conf-rx {
+ pins = "MIO49";
+ bias-high-impedance;
+ };
+ conf-tx {
+ pins = "MIO48";
+ bias-disable;
+ };
+ };
+};
+
+&qspi {
+ num-cs = <1>;
+
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <50000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "qspi-boot";
+ reg = <0x0 0x80000>;
+ };
+
+ partition@80000 {
+ label = "qspi-bootenv";
+ reg = <0x80000 0x20000>;
+ };
+
+ partition@a0000 {
+ label = "qspi-bitstream";
+ reg = <0xa0000 0x460000>;
+ };
+
+ partition@500000 {
+ label = "qspi-kernel";
+ reg = <0x500000 0x480000>;
+ };
+
+ partition@980000 {
+ label = "qspi-devicetree";
+ reg = <0x980000 0x10000>;
+ };
+
+ partition@990000 {
+ label = "qspi-rootfs";
+ reg = <0x990000 0x600000>;
+ };
+
+ partition@f90000 {
+ label = "data";
+ reg = <0xf90000 0x70000>;
+ };
+ };
+ };
+};
+
+&sdhci0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhci0_default>;
+ disable-wp;
+
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_default>;
+
+ status = "okay";
+};
+
--
2.43.0
^ permalink raw reply related
* Re: [PATCH 2/2] arm: dts: xilinx: Add support for MYIR MYS-7Z020-V2 board
From: sashiko-bot @ 2026-06-19 10:32 UTC (permalink / raw)
To: Liu Yu; +Cc: robh, devicetree, conor+dt
In-Reply-To: <SY3PPF19552C607A65588339A2CED9E2AFDC7E22@SY3PPF19552C607.AUSP300.PROD.OUTLOOK.COM>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Missing function multiplexing for SD card detect (CD) pin, causing SD card detection to fail.
--
commit d502783eb06999075d769495567d3ef9a776e3f7
Author: Liu Yu <f78fk@live.com>
arm: dts: xilinx: Add support for MYIR MYS-7Z020-V2 board
Add device tree support for the MYIR MYS-7Z020-V2 board based on
the Xilinx Zynq-7000 XC7Z020 SoC.
Link: https://www.myirtech.com/list.asp?id=708
> diff --git a/arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts b/arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts
> new file mode 100644
> index 0000000000000..39bd864ca358d
> --- /dev/null
> +++ b/arch/arm/boot/dts/xilinx/zynq-mys-7z020-v2.dts
[ ... ]
> +&pinctrl0 {
[ ... ]
> + pinctrl_sdhci0_default: sdhci0-default {
> + mux {
> + groups = "sdio0_2_grp";
> + function = "sdio0";
> + };
> + conf {
> + groups = "sdio0_2_grp";
> + slew-rate = <0>;
> + io-standard = <1>;
> + bias-disable;
> + };
> + conf-cd {
> + pins = "MIO46";
> + bias-pull-up;
> + slew-rate = <0>;
> + io-standard = <1>;
> + };
[Severity: High]
Does this pin configuration properly route the SD card detect signal to the
SDHCI controller?
The conf-cd block sets the electrical properties for MIO46, but it appears
to lack the required multiplexing configuration. In the Zynq pinctrl driver,
routing the SD card detect signal requires explicitly requesting the
sdio0_cd function.
Without defining a mux node (such as adding a mux-cd block with
groups = "gpio0_46_grp" and function = "sdio0_cd"), the Linux pinctrl
driver will not route the internal SDHCI controller's CD line to MIO46.
Unless the bootloader pre-configures this mux and the configuration
survives suspend and resume cycles, the SD controller will likely fail
to detect card insertion or removal.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260619102214.223121-1-f78fk@live.com?part=2
^ permalink raw reply
* [PATCH v2 0/3] hwmon: emc1403: Convert to use OF bindings and add regulator support
From: Svyatoslav Ryhel @ 2026-06-19 10:31 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Svyatoslav Ryhel
Cc: linux-hwmon, devicetree, linux-kernel
Document, add OF and regulator support to EMC14XX thermal sensor family.
Schema file was separated from LM90 since according to Guenter Roeck[1]
these sensors are incompatible with LM90. Proposed schema has basic
hardware description. All registers Guenter Roeck mentioned may be added
later on, when/if driver would need to work with them. As for now driver
successfully works as is.
[1] https://lore.kernel.org/lkml/a0c5c1e8-9a36-4835-a5d9-7bafda79c36f@roeck-us.net/
---
Changes in v2:
- schema separated into a dedicated file
- dropped chip id check
- fixed match data casting
- adjusted regulator name
---
Jonas Schwöbel (1):
hwmon: (emc1403) Convert to use OF bindings
Svyatoslav Ryhel (2):
dt-bindings: hwmon: Document SMSC EMC1402/1403/1404/1428
hwmon: (emc1403) Add regulator support
.../bindings/hwmon/smsc,emc1403.yaml | 191 ++++++++++++++++++
drivers/hwmon/emc1403.c | 23 ++-
2 files changed, 212 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/hwmon/smsc,emc1403.yaml
--
2.53.0
^ permalink raw reply
* [PATCH v2 1/3] dt-bindings: hwmon: Document SMSC EMC1402/1403/1404/1428
From: Svyatoslav Ryhel @ 2026-06-19 10:31 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Svyatoslav Ryhel
Cc: linux-hwmon, devicetree, linux-kernel
In-Reply-To: <20260619103153.216444-1-clamor95@gmail.com>
Document the basic hardware layout of SMSC (now Microchip)
EMC1402/1403/1404/1428 thermal sensors.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
.../bindings/hwmon/smsc,emc1403.yaml | 191 ++++++++++++++++++
1 file changed, 191 insertions(+)
create mode 100644 Documentation/devicetree/bindings/hwmon/smsc,emc1403.yaml
diff --git a/Documentation/devicetree/bindings/hwmon/smsc,emc1403.yaml b/Documentation/devicetree/bindings/hwmon/smsc,emc1403.yaml
new file mode 100644
index 000000000000..bef07b599720
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/smsc,emc1403.yaml
@@ -0,0 +1,191 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/smsc,emc1403.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SMSC EMC1402/1403/1404/1428 thermal sensors
+
+maintainers:
+ - Svyatoslav Ryhel <clamor95@gmail.com>
+
+properties:
+ compatible:
+ oneOf:
+ - enum:
+ - smsc,emc1402
+ - smsc,emc1403
+ - smsc,emc1404
+ - smsc,emc1428
+
+ - items:
+ - enum:
+ - smsc,emc1412
+ - smsc,emc1422
+ - smsc,emc1442
+ - const: smsc,emc1402
+
+ - items:
+ - enum:
+ - smsc,emc1413
+ - smsc,emc1423
+ - const: smsc,emc1403
+
+ - items:
+ - enum:
+ - smsc,emc1414
+ - smsc,emc1424
+ - const: smsc,emc1404
+
+ - items:
+ - enum:
+ - smsc,emc1438
+ - const: smsc,emc1428
+
+ interrupts:
+ items:
+ - description: Sensors "ALERT" pin output.
+
+ reg:
+ maxItems: 1
+
+ "#thermal-sensor-cells":
+ const: 1
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ vdd-supply: true
+
+required:
+ - compatible
+ - reg
+
+patternProperties:
+ "^channel@([0-7])$":
+ type: object
+ description: Represents channels of the device and their specific configuration.
+
+ properties:
+ reg:
+ description: The channel number. 0 is local channel, 1-7 are remote channels.
+ items:
+ minimum: 0
+ maximum: 7
+
+ label:
+ description: A descriptive name for this channel, like "ambient" or "psu".
+
+ required:
+ - reg
+
+ additionalProperties: false
+
+allOf:
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - smsc,emc1404
+ - smsc,emc1428
+ then:
+ patternProperties:
+ "^channel@([0-7])$":
+ properties:
+ reg:
+ items:
+ maximum: 2
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - smsc,emc1404
+ then:
+ patternProperties:
+ "^channel@([0-7])$":
+ properties:
+ reg:
+ items:
+ maximum: 3
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sensor@4c {
+ compatible = "smsc,emc1412", "smsc,emc1402";
+ reg = <0x4c>;
+
+ interrupt-parent = <&gpio>;
+ interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+
+ vdd-supply = <&vdd_3v3_sys>;
+ #thermal-sensor-cells = <1>;
+ };
+ };
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sensor@29 {
+ compatible = "smsc,emc1428";
+ reg = <0x29>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@0 {
+ reg = <0x0>;
+ label = "local";
+ };
+
+ channel@1 {
+ reg = <0x1>;
+ label = "chan1";
+ };
+
+ channel@2 {
+ reg = <0x2>;
+ label = "chan2";
+ };
+
+ channel@3 {
+ reg = <0x3>;
+ label = "chan3";
+ };
+
+ channel@4 {
+ reg = <0x4>;
+ label = "chan4";
+ };
+
+ channel@5 {
+ reg = <0x5>;
+ label = "chan5";
+ };
+
+ channel@6 {
+ reg = <0x6>;
+ label = "chan6";
+ };
+
+ channel@7 {
+ reg = <0x7>;
+ label = "chan7";
+ };
+ };
+ };
--
2.53.0
^ permalink raw reply related
* [PATCH v2 2/3] hwmon: (emc1403) Convert to use OF bindings
From: Svyatoslav Ryhel @ 2026-06-19 10:31 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Svyatoslav Ryhel
Cc: linux-hwmon, devicetree, linux-kernel
In-Reply-To: <20260619103153.216444-1-clamor95@gmail.com>
From: Jonas Schwöbel <jonasschwoebel@yahoo.de>
Add OF match compatible table to be able to use this driver with Device
Trees.
Signed-off-by: Jonas Schwöbel <jonasschwoebel@yahoo.de>
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/hwmon/emc1403.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index 964a8cb278f1..ef1ccb40ed6c 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -16,6 +16,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
+#include <linux/mod_devicetable.h>
#include <linux/sysfs.h>
#include <linux/regmap.h>
#include <linux/util_macros.h>
@@ -659,14 +660,14 @@ static int emc1403_probe(struct i2c_client *client)
{
struct thermal_data *data;
struct device *hwmon_dev;
- const struct i2c_device_id *id = i2c_match_id(emc1403_idtable, client);
data = devm_kzalloc(&client->dev, sizeof(struct thermal_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
- data->chip = id->driver_data;
+ data->chip = (uintptr_t)i2c_get_match_data(client);
+
data->regmap = devm_regmap_init_i2c(client, &emc1403_regmap_config);
if (IS_ERR(data->regmap))
return PTR_ERR(data->regmap);
@@ -682,10 +683,21 @@ static const unsigned short emc1403_address_list[] = {
0x18, 0x1c, 0x29, 0x3c, 0x4c, 0x4d, 0x5c, I2C_CLIENT_END
};
+static const struct of_device_id emc1403_of_match[] = {
+ { .compatible = "smsc,emc1402", .data = (void *)emc1402 },
+ { .compatible = "smsc,emc1403", .data = (void *)emc1403 },
+ { .compatible = "smsc,emc1404", .data = (void *)emc1404 },
+ { .compatible = "smsc,emc1428", .data = (void *)emc1428 },
+ { }
+
+};
+MODULE_DEVICE_TABLE(of, emc1403_of_match);
+
static struct i2c_driver sensor_emc1403 = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "emc1403",
+ .of_match_table = emc1403_of_match,
},
.detect = emc1403_detect,
.probe = emc1403_probe,
--
2.53.0
^ permalink raw reply related
* [PATCH v2 3/3] hwmon: (emc1403) Add regulator support
From: Svyatoslav Ryhel @ 2026-06-19 10:31 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Svyatoslav Ryhel
Cc: linux-hwmon, devicetree, linux-kernel
In-Reply-To: <20260619103153.216444-1-clamor95@gmail.com>
Add support for VDD power supply for this sensor. It is required on some
devices for the sensor to start up and work properly.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/hwmon/emc1403.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index ef1ccb40ed6c..d14bd90ce424 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -19,6 +19,7 @@
#include <linux/mod_devicetable.h>
#include <linux/sysfs.h>
#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include <linux/util_macros.h>
#define THERMAL_PID_REG 0xfd
@@ -660,6 +661,12 @@ static int emc1403_probe(struct i2c_client *client)
{
struct thermal_data *data;
struct device *hwmon_dev;
+ int ret;
+
+ ret = devm_regulator_get_enable(&client->dev, "vdd");
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "Failed to enable regulator\n");
data = devm_kzalloc(&client->dev, sizeof(struct thermal_data),
GFP_KERNEL);
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v3 1/2] dt-bindings: iio: dac: Add AD5529R
From: Janani Sunil @ 2026-06-19 10:33 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Rodrigo Alencar, Janani Sunil, Lars-Peter Clausen,
Michael Hennerich, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
Jonathan Corbet, Shuah Khan, linux-iio, devicetree, linux-kernel,
linux-doc, Mark Brown
In-Reply-To: <20260614204455.408c4d40@jic23-huawei>
On 6/14/26 21:44, Jonathan Cameron wrote:
> On Tue, 9 Jun 2026 16:47:23 +0200
> Janani Sunil <jan.sun97@gmail.com> wrote:
>
>> On 5/26/26 15:11, Rodrigo Alencar wrote:
>>> On 26/05/19 05:42PM, Janani Sunil wrote:
>>>> Devicetree bindings for AD5529R 16 channel 12/16 bit high voltage,
>>>> buffered voltage output digital-to-analog converter (DAC) with an
>>>> integrated precision reference.
>>> ...
>>> Probably others may comment on that, but...
>>>
>>> This parent node may support device addressing for multi-device support through
>>> those ID pins. I suppose that each device may have its own power supplies or
>>> other resources like the toggle pins or reset and enable.
>>>
>>> That way I suppose that an example would look like...
>>>
>>>> +
>>>> +patternProperties:
>>>> + "^channel@([0-9]|1[0-5])$":
>>>> + type: object
>>>> + description: Child nodes for individual channel configuration
>>>> +
>>>> + properties:
>>>> + reg:
>>>> + description: Channel number.
>>>> + minimum: 0
>>>> + maximum: 15
>>>> +
>>>> + adi,output-range-microvolt:
>>>> + description: |
>>>> + Output voltage range for this channel as [min, max] in microvolts.
>>>> + If not specified, defaults to 0V to 5V range.
>>>> + oneOf:
>>>> + - items:
>>>> + - const: 0
>>>> + - enum: [5000000, 10000000, 20000000, 40000000]
>>>> + - items:
>>>> + - const: -5000000
>>>> + - const: 5000000
>>>> + - items:
>>>> + - const: -10000000
>>>> + - const: 10000000
>>>> + - items:
>>>> + - const: -15000000
>>>> + - const: 15000000
>>>> + - items:
>>>> + - const: -20000000
>>>> + - const: 20000000
>>>> +
>>>> + required:
>>>> + - reg
>>>> +
>>>> + additionalProperties: false
>>>> +
>>>> +required:
>>>> + - compatible
>>>> + - reg
>>>> + - vdd-supply
>>>> + - avdd-supply
>>>> + - hvdd-supply
>>>> +
>>>> +dependencies:
>>>> + spi-cpha: [ spi-cpol ]
>>>> + spi-cpol: [ spi-cpha ]
>>>> +
>>>> +allOf:
>>>> + - $ref: /schemas/spi/spi-peripheral-props.yaml#
>>>> +
>>>> +unevaluatedProperties: false
>>>> +
>>>> +examples:
>>>> + - |
>>>> + #include <dt-bindings/gpio/gpio.h>
>>>> +
>>>> + spi {
>>>> + #address-cells = <1>;
>>>> + #size-cells = <0>;
>>>> +
>>>> + dac@0 {
>>>> + compatible = "adi,ad5529r-16";
>>>> + reg = <0>;
>>>> + spi-max-frequency = <25000000>;
>>>> +
>>>> + vdd-supply = <&vdd_regulator>;
>>>> + avdd-supply = <&avdd_regulator>;
>>>> + hvdd-supply = <&hvdd_regulator>;
>>>> + hvss-supply = <&hvss_regulator>;
>>>> +
>>>> + reset-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
>>>> +
>>>> + #address-cells = <1>;
>>>> + #size-cells = <0>;
>>>> +
>>>> + channel@0 {
>>>> + reg = <0>;
>>>> + adi,output-range-microvolt = <0 5000000>;
>>>> + };
>>>> +
>>>> + channel@1 {
>>>> + reg = <1>;
>>>> + adi,output-range-microvolt = <(-10000000) 10000000>;
>>>> + };
>>>> +
>>>> + channel@2 {
>>>> + reg = <2>;
>>>> + adi,output-range-microvolt = <0 40000000>;
>>>> + };
>>>> + };
>>>> + };
>>> ...
>>>
>>> spi {
>>> #address-cells = <1>;
>>> #size-cells = <0>;
>>>
>>> multi-dac@0 {
>>> compatible = "adi,ad5529r-16";
>>> reg = <0>;
>>> spi-max-frequency = <25000000>;
>>>
>>> #address-cells = <1>;
>>> #size-cells = <0>;
>>>
>>> dac@0 {
>>> reg = <0>;
>>> vdd-supply = <&vdd_regulator>;
>>> avdd-supply = <&avdd_regulator>;
>>> hvdd-supply = <&hvdd_regulator>;
>>> hvss-supply = <&hvss_regulator>;
>>>
>>> reset-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
>>>
>>> #address-cells = <1>;
>>> #size-cells = <0>;
>>>
>>> channel@0 {
>>> reg = <0>;
>>> adi,output-range-microvolt = <0 5000000>;
>>> };
>>>
>>> channel@1 {
>>> reg = <1>;
>>> adi,output-range-microvolt = <(-10000000) 10000000>;
>>> };
>>>
>>> channel@2 {
>>> reg = <2>;
>>> adi,output-range-microvolt = <0 40000000>;
>>> };
>>> }
>>>
>>> dac@1 {
>>> reg = <1>;
>>> vdd-supply = <&vdd_regulator>;
>>> avdd-supply = <&avdd_regulator>;
>>> hvdd-supply = <&hvdd_regulator>;
>>> hvss-supply = <&hvss_regulator>;
>>>
>>> reset-gpios = <&gpio0 88 GPIO_ACTIVE_LOW>;
>>>
>>> #address-cells = <1>;
>>> #size-cells = <0>;
>>>
>>> channel@0 {
>>> reg = <0>;
>>> adi,output-range-microvolt = <0 5000000>;
>>> };
>>>
>>> channel@1 {
>>> reg = <1>;
>>> adi,output-range-microvolt = <(-10000000) 10000000>;
>>> };
>>> }
>>> };
>>> };
>>>
>>> then you might need something like:
>>>
>>> patternProperties:
>>> "^dac@[0-3]$":
>>>
>>> and put most of the things under this node pattern.
>>>
>>> So the main driver that you're putting together might need to handle up to four instances.
>>> Even if your current driver cannot handle this, the dt-bindings might need cover that.
>>>
>>> Need to double check if each dac node needs a separate compatible, so you would maybe populate
>>> a platform data to be shared with the child nodes, which would be a separate driver.
>>> (not sure if it would make sense to mix and match ad5529r-16 and ad5529r-12).
>> Hi Rodrigo,
>>
>> Thank you for looking at this.
>>
>> For now, I would prefer to keep the binding scoped to a single AD5529R device instance. The current
>> hardware/use case we have only needs one device node and the driver is written around that model as well.
>> While the device addressing pins could allow multi-device topology, we do not have an actual platform using
>> that configuration at the moment, so I would prefer not to introduce an extra parent/child binding structure
>> speculatively without a validating use case.
> Interesting feature - kind of similar to address control on a typical i2c bus device, or
> looking at it another way a kind of distributed SPI mux.
>
> Challenge of a binding is we need to anticipate the future. So I think we do need something
> like Rodrigo is suggesting even if we only (for now) support a single instance in the driver.
> That would leave the path open to supporting the addressing at a later date.
> An alternative might be to look at it like a chained device setup. In those we pretend there
> is just one device with a lot of channels etc. The snag is that here things are more loosely
> coupled whereas for those devices it tends to be you have to read / write the same register
> in all devices in the chain as one big SPI message.
>
> +CC Mark Brown as he may know of some precedence for this feature. For his reference..
> - Each of these device has 2 ID pins. The SPI transfers have to contain the 2 bit
> value that matches that or they are ignored. Thus a single bus + 1 chip select can
> be used to talk to 4 devices. Question is what that looks like in device tree + I guess
> longer term how to support it cleanly in SPI.
>
> Jonathan
Hi Jonathan, Rob, Krzysztof, Conor,
One possible model that would also allow mixing the 12-bit and 16-bit variants would be to treat the parent node
as the shared SPI transport only, and let each dac@N child carry its own compatible.
Rob, Krzysztof, Conor — wanted to get your input on whether this is an acceptable binding pattern.
properties:
compatible:
const: adi,ad5529r-bus
patternProperties:
"^dac@[0-3]$":
type: object
properties:
compatible:
enum:
- adi,ad5529r-16
- adi,ad5529r-12
reg:
minimum: 0
maximum: 3
With a DT example such as:
ad5529r@0 {
compatible = "adi,ad5529r-bus";
reg = <0>;
dac@0 {
compatible = "adi,ad5529r-16";
reg = <0>;
};
dac@1 {
compatible = "adi,ad5529r-12";
reg = <1>;
};
};
The downside is that it introduces adi,ad5529r-bus as a compatible that does not correspond to an actual
standalone device variant - it would require a parent driver to manage the shared SPI transport and enumerate the
child devices. The actual DAC functionality is handled by the matching per-child compatibles(12 or 16 bit).
Is this an acceptable pattern, or is there a preferred way to model this type of addressing scheme?
Regards,
Janani Sunil
^ permalink raw reply
* Re: [PATCH v2 1/3] dt-bindings: hwmon: Document SMSC EMC1402/1403/1404/1428
From: sashiko-bot @ 2026-06-19 10:40 UTC (permalink / raw)
To: Svyatoslav Ryhel; +Cc: devicetree, linux-hwmon, robh, conor+dt
In-Reply-To: <20260619103153.216444-2-clamor95@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The device tree binding schema fails to correctly restrict the maximum number of channels for the `smsc,emc1402` and its variants (emc1412, emc1422, emc1442). By grouping it alongside `emc1403` under the `not` condition for `emc1404`/`emc1428`, it inadvertently sets the channel `reg` maximum to 2 instead of 1.
--
commit 5a834c50ed998e304e4c00fb64e4e434cbd93896
Author: Svyatoslav Ryhel <clamor95@gmail.com>
dt-bindings: hwmon: Document SMSC EMC1402/1403/1404/1428
This commit documents the basic hardware layout of SMSC (now Microchip)
EMC1402/1403/1404/1428 thermal sensors.
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hwmon/smsc,emc1403.yaml
[ ... ]
> +allOf:
> + - if:
> + not:
> + properties:
> + compatible:
> + contains:
> + enum:
> + - smsc,emc1404
> + - smsc,emc1428
> + then:
> + patternProperties:
> + "^channel@([0-7])$":
> + properties:
> + reg:
> + items:
> + maximum: 2
[Severity: Low]
Does this conditional block correctly restrict the channel limits for the
smsc,emc1402 device and its variants (emc1412, emc1422, emc1442)?
By grouping the emc1402 variants with the emc1403 under the fallback
condition (not containing emc1404/emc1428), it applies a maximum reg value
of 2. This appears to allow up to 3 channels (0, 1, 2) to pass schema
validation.
Since the emc1402 hardware only supports 2 channels (local and 1 remote),
should there be a separate conditional for the emc1402 family setting the
maximum to 1?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260619103153.216444-1-clamor95@gmail.com?part=1
^ permalink raw reply
* Re: [PATCH v2 3/3] hwmon: (emc1403) Add regulator support
From: sashiko-bot @ 2026-06-19 10:41 UTC (permalink / raw)
To: Svyatoslav Ryhel; +Cc: robh, devicetree, linux-hwmon, conor+dt
In-Reply-To: <20260619103153.216444-4-clamor95@gmail.com>
> Add support for VDD power supply for this sensor. It is required on some
> devices for the sensor to start up and work properly.
>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260619103153.216444-1-clamor95@gmail.com?part=3
^ permalink raw reply
* Re: [PATCH v2 2/3] hwmon: (emc1403) Convert to use OF bindings
From: sashiko-bot @ 2026-06-19 10:45 UTC (permalink / raw)
To: Svyatoslav Ryhel; +Cc: conor+dt, robh, linux-hwmon, devicetree
In-Reply-To: <20260619103153.216444-3-clamor95@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Ambiguous OF match data value (0) prevents error handling for unsupported devices.
--
commit 7ef40c1ea161b005037b0b33a8e16b1f9bf6d41a
Author: Jonas Schwöbel <jonasschwoebel@yahoo.de>
hwmon: (emc1403) Convert to use OF bindings
This commit adds an OF match compatible table to the emc1403 driver
to enable device tree support.
> --- a/drivers/hwmon/emc1403.c
> +++ b/drivers/hwmon/emc1403.c
[ ... ]
> @@ -659,14 +660,14 @@ static int emc1403_probe(struct i2c_client *client)
[ ... ]
> - data->chip = id->driver_data;
> + data->chip = (uintptr_t)i2c_get_match_data(client);
> +
[Severity: Medium]
Will this cast silently hide error conditions?
If an unsupported device is manually bound via sysfs, i2c_get_match_data()
will return NULL (no match found). Since emc1402 evaluates to 0 in the
emc1403_chip enum, casting NULL to uintptr_t assigns 0 to data->chip. This
causes the driver to proceed as if an emc1402 device was found, rather than
safely aborting and returning -ENODEV.
[ ... ]
> @@ -682,10 +683,21 @@ static const unsigned short emc1403_address_list[] = {
[ ... ]
> +static const struct of_device_id emc1403_of_match[] = {
> + { .compatible = "smsc,emc1402", .data = (void *)emc1402 },
> + { .compatible = "smsc,emc1403", .data = (void *)emc1403 },
[Severity: Medium]
Does assigning 0 as the match data here cause ambiguity during device matching?
Because emc1402 is 0, when device_get_match_data() matches "smsc,emc1402",
it returns NULL. This forces i2c_get_match_data() to fall back to
i2c_match_id().
While this happens to succeed for valid DT nodes because the I2C core strips
the vendor prefix (allowing the id_table to match), it removes the ability
to distinguish between a successful emc1402 match and an error where no
match was found at all.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260619103153.216444-1-clamor95@gmail.com?part=2
^ permalink raw reply
* [PATCH v3 1/3] dt-bindings: add entry for qstcorp
From: Siratul Islam @ 2026-06-19 10:45 UTC (permalink / raw)
To: jic23, robh, krzk+dt, conor+dt
Cc: siratul.islam, dlechner, nuno.sa, andy, linux-iio, devicetree,
linux-kernel, Conor Dooley
In-Reply-To: <20260619104524.10172-1-siratul.islam@linux.dev>
Add an entry for QST Corporation Limited
Link: https://www.qstcorp.com/
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Siratul Islam <siratul.islam@linux.dev>
---
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..11aac47f90ce 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1355,6 +1355,8 @@ patternProperties:
description: Shenzhen QiShenglong Industrialist Co., Ltd.
"^qnap,.*":
description: QNAP Systems, Inc.
+ "^qstcorp,.*":
+ description: QST Corporation Limited
"^quanta,.*":
description: Quanta Computer Inc.
"^radxa,.*":
--
2.54.0
^ permalink raw reply related
* [PATCH v3 0/3] iio: magnetometer: add driver for QST QMC5883L Sensor
From: Siratul Islam @ 2026-06-19 10:45 UTC (permalink / raw)
To: jic23, robh, krzk+dt, conor+dt
Cc: siratul.islam, dlechner, nuno.sa, andy, linux-iio, devicetree,
linux-kernel
This patch series introduces the QST QMC5883L 3-Axis Magnetic Sensor
driver. It is a simple device with minimal magnetometer functionalities.
Commonly used as (software incompatible) replacement for the
Honeywell HMC5883L sensor.
This driver implements the basic functionalities of the QMC5883L sensor,
and intentionally leaves out some features like DRDY interrupt pin support
and power management for simplicity, both of which will be addressed
in future patches.
There was an attempt to introduce this device about an year ago but
the author seems to have abandoned the patch series. Since the device
is simple enough, I decided to start from scratch.
Note: I also noticed a patch for the QMC5883P variant. Despite similar
naming, the sensors are different including different register maps,
so these devices are not compatible with each other.
---
Changes in v3:
- Add trailing commas at list endings
- Rename regmap to map in multiple places
- Add and reorder header includes
- Update POR time comment
Changes in v2:
- Update commit message in binding.
- Reformat header includes.
- Remove iio_device_claim_direct()/iio_device_release_direct()
- Read the measurement registers before checking the OVL status bit
- Replace scoped_guard() with guard()
- Fix function parameter styling
- Replace FIELD_PREP_CONST() with FIELD_PREP()
- Replace qmc5883l_rng_avail[] with a 2D qmc5883l_scales[][2] array
- Update mutex comment
- Add a devm_add_action_or_reset() callback
- Use a named initializer in the i2c_device_id table
- Combine u8 rng, osr, odr; onto one line
- Various styling fixes
- Update maintainer email to siratul.islam@linux.dev
Link to v2: https://lore.kernel.org/linux-iio/20260616114942.37241-1-siratul.islam@linux.dev/
Link to v1: https://lore.kernel.org/linux-iio/20260612124557.13750-1-email@sirat.me/
Siratul Islam (3):
dt-bindings: add entry for qstcorp
dt-bindings: iio: magnetometer: add QST QMC5883L Sensor
iio: magnetometer: add driver for QST QMC5883L Sensor
.../iio/magnetometer/qstcorp,qmc5883l.yaml | 52 ++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
MAINTAINERS | 7 +
drivers/iio/magnetometer/Kconfig | 11 +
drivers/iio/magnetometer/Makefile | 2 +
drivers/iio/magnetometer/qmc5883l.c | 517 ++++++++++++++++++
6 files changed, 591 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/magnetometer/qstcorp,qmc5883l.yaml
create mode 100644 drivers/iio/magnetometer/qmc5883l.c
--
2.54.0
^ permalink raw reply
* [PATCH v3 2/3] dt-bindings: iio: magnetometer: add QST QMC5883L Sensor
From: Siratul Islam @ 2026-06-19 10:45 UTC (permalink / raw)
To: jic23, robh, krzk+dt, conor+dt
Cc: siratul.islam, dlechner, nuno.sa, andy, linux-iio, devicetree,
linux-kernel, Conor Dooley
In-Reply-To: <20260619104524.10172-1-siratul.islam@linux.dev>
Add devicetree binding for the QST QMC5883L 3-Axis Magnetic Sensor
connected via I2C.
Used enum so that more devices could use this binding
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Siratul Islam <siratul.islam@linux.dev>
---
.../iio/magnetometer/qstcorp,qmc5883l.yaml | 52 +++++++++++++++++++
MAINTAINERS | 6 +++
2 files changed, 58 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/magnetometer/qstcorp,qmc5883l.yaml
diff --git a/Documentation/devicetree/bindings/iio/magnetometer/qstcorp,qmc5883l.yaml b/Documentation/devicetree/bindings/iio/magnetometer/qstcorp,qmc5883l.yaml
new file mode 100644
index 000000000000..38abd083a4fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/magnetometer/qstcorp,qmc5883l.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/magnetometer/qstcorp,qmc5883l.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: QST QMC5883L 3-Axis Magnetic Sensor
+
+maintainers:
+ - Siratul Islam <siratul.islam@linux.dev>
+
+description: |
+ QST QMC5883L 3-Axis Magnetic Sensor on I2C bus.
+ https://www.qstcorp.com/upload/pdf/202512/13-52-04%20QMC5883L%20Datasheet%20Rev.%20B.pdf
+
+properties:
+ compatible:
+ enum:
+ - qstcorp,qmc5883l
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ vdd-supply: true
+
+ vddio-supply: true
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - vdd-supply
+ - vddio-supply
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ magnetometer@d {
+ compatible = "qstcorp,qmc5883l";
+ reg = <0x0d>;
+ vdd-supply = <&vdd_3v3_reg>;
+ vddio-supply = <&vdd_3v3_reg>;
+ };
+ };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index e035a3be797c..1127403c579b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21787,6 +21787,12 @@ F: Documentation/networking/device_drivers/ethernet/freescale/dpaa2/overview.rst
F: drivers/bus/fsl-mc/
F: include/uapi/linux/fsl_mc.h
+QST QMC5883L 3-Axis Magnetic Sensor
+M: Siratul Islam <siratul.islam@linux.dev>
+L: linux-iio@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/iio/magnetometer/qstcorp,qmc5883l.yaml
+
QT1010 MEDIA DRIVER
L: linux-media@vger.kernel.org
S: Orphan
--
2.54.0
^ permalink raw reply related
* [PATCH v3 3/3] iio: magnetometer: add driver for QST QMC5883L Sensor
From: Siratul Islam @ 2026-06-19 10:45 UTC (permalink / raw)
To: jic23, robh, krzk+dt, conor+dt
Cc: siratul.islam, dlechner, nuno.sa, andy, linux-iio, devicetree,
linux-kernel
In-Reply-To: <20260619104524.10172-1-siratul.islam@linux.dev>
Add driver for the QST QMC5883L 3-Axis Magnetic Sensor
connected via i2c.
Signed-off-by: Siratul Islam <siratul.islam@linux.dev>
---
MAINTAINERS | 1 +
drivers/iio/magnetometer/Kconfig | 11 +
drivers/iio/magnetometer/Makefile | 2 +
drivers/iio/magnetometer/qmc5883l.c | 517 ++++++++++++++++++++++++++++
4 files changed, 531 insertions(+)
create mode 100644 drivers/iio/magnetometer/qmc5883l.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 1127403c579b..0f9ad3b49a5d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21792,6 +21792,7 @@ M: Siratul Islam <siratul.islam@linux.dev>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/magnetometer/qstcorp,qmc5883l.yaml
+F: drivers/iio/magnetometer/qmc5883l.c
QT1010 MEDIA DRIVER
L: linux-media@vger.kernel.org
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index fb313e591e85..615564174086 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -198,6 +198,17 @@ config INFINEON_TLV493D
To compile this driver as a module, choose M here: the module
will be called tlv493d.
+config QMC5883L
+ tristate "QST QMC5883L 3-Axis Magnetic Sensor"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ Say Y here to add support driver for QST QMC5883L 3-Axis
+ Magnetic Sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called qmc5883l.
+
config SENSORS_HMC5843
tristate
select IIO_BUFFER
diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile
index 5bd227f8c120..552682555d86 100644
--- a/drivers/iio/magnetometer/Makefile
+++ b/drivers/iio/magnetometer/Makefile
@@ -26,6 +26,8 @@ obj-$(CONFIG_IIO_ST_MAGN_SPI_3AXIS) += st_magn_spi.o
obj-$(CONFIG_INFINEON_TLV493D) += tlv493d.o
+obj-$(CONFIG_QMC5883L) += qmc5883l.o
+
obj-$(CONFIG_SENSORS_HMC5843) += hmc5843_core.o
obj-$(CONFIG_SENSORS_HMC5843_I2C) += hmc5843_i2c.o
obj-$(CONFIG_SENSORS_HMC5843_SPI) += hmc5843_spi.o
diff --git a/drivers/iio/magnetometer/qmc5883l.c b/drivers/iio/magnetometer/qmc5883l.c
new file mode 100644
index 000000000000..b7fff3b63ca4
--- /dev/null
+++ b/drivers/iio/magnetometer/qmc5883l.c
@@ -0,0 +1,517 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Support for QST QMC5883L 3-Axis Magnetic Sensor on I2C bus.
+ *
+ * Copyright (C) 2026 Siratul Islam <siratul.islam@linux.dev>
+ *
+ * Datasheet available at
+ * <https://www.qstcorp.com/upload/pdf/202512/13-52-04%20QMC5883L%20Datasheet%20Rev.%20B.pdf>
+ *
+ */
+
+#include <linux/array_size.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/cleanup.h>
+#include <linux/delay.h>
+#include <linux/dev_printk.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+#include <asm/byteorder.h>
+
+#include <linux/iio/iio.h>
+
+#define QMC5883L_REG_X_LSB 0x00
+#define QMC5883L_REG_STATUS1 0x06
+#define QMC5883L_REG_CTRL1 0x09
+#define QMC5883L_REG_CTRL2 0x0A
+#define QMC5883L_REG_SET_RESET 0x0B
+#define QMC5883L_REG_ID 0x0D
+
+#define QMC5883L_CHIP_ID 0xFF
+
+#define QMC5883L_MODE_MASK GENMASK(1, 0)
+#define QMC5883L_ODR_MASK GENMASK(3, 2)
+#define QMC5883L_RNG_MASK GENMASK(5, 4)
+#define QMC5883L_OSR_MASK GENMASK(7, 6)
+
+#define QMC5883L_MODE_STANDBY 0x00
+#define QMC5883L_MODE_CONT 0x01
+
+#define QMC5883L_ODR_10HZ 0x00
+#define QMC5883L_ODR_50HZ 0x01
+#define QMC5883L_ODR_100HZ 0x02
+#define QMC5883L_ODR_200HZ 0x03
+
+#define QMC5883L_RNG_2G 0x00
+#define QMC5883L_RNG_8G 0x01
+
+#define QMC5883L_OSR_512 0x00
+#define QMC5883L_OSR_256 0x01
+#define QMC5883L_OSR_128 0x02
+#define QMC5883L_OSR_64 0x03
+
+#define QMC5883L_STATUS_DRDY BIT(0)
+#define QMC5883L_STATUS_OVL BIT(1)
+
+#define QMC5883L_SET_RESET_VAL BIT(0)
+#define QMC5883L_INT_DISABLE BIT(0)
+#define QMC5883L_SOFT_RESET BIT(7)
+
+#define QMC5883L_PORT_US 350
+
+struct qmc5883l_data {
+ struct regmap *regmap;
+ /*
+ * Protect data->range/odr/osr.
+ * Protect poll and read during measurement.
+ */
+ struct mutex mutex;
+ u8 range;
+ u8 odr;
+ u8 osr;
+};
+
+enum qmc5883l_chan {
+ QMC5883L_AXIS_X,
+ QMC5883L_AXIS_Y,
+ QMC5883L_AXIS_Z,
+};
+
+static const int qmc5883l_odr_avail[] = { 10, 50, 100, 200 };
+
+static const int qmc5883l_osr_avail[] = { 512, 256, 128, 64 };
+
+static const int qmc5883l_scales[][2] = {
+ [QMC5883L_RNG_2G] = { 0, 83333 },
+ [QMC5883L_RNG_8G] = { 0, 333333 },
+};
+
+static int qmc5883l_take_measurement(struct iio_dev *indio_dev, int index,
+ int *val)
+{
+ struct qmc5883l_data *data = iio_priv(indio_dev);
+ struct regmap *map = data->regmap;
+ unsigned int status;
+ __le16 buf[3];
+ int ret;
+
+ guard(mutex) (&data->mutex);
+
+ /* 50ms headroom over the slowest ODR (10Hz) */
+ ret = regmap_read_poll_timeout(map, QMC5883L_REG_STATUS1,
+ status, (status & QMC5883L_STATUS_DRDY),
+ 2 * USEC_PER_MSEC, 150 * USEC_PER_MSEC);
+ if (ret)
+ return ret;
+
+ ret = regmap_bulk_read(map, QMC5883L_REG_X_LSB, buf, sizeof(buf));
+ if (ret)
+ return ret;
+
+ if (status & QMC5883L_STATUS_OVL)
+ return -ERANGE;
+
+ *val = (s16)le16_to_cpu(buf[index]);
+
+ return 0;
+}
+
+static int qmc5883l_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long mask)
+{
+ struct qmc5883l_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = qmc5883l_take_measurement(indio_dev, chan->address, val);
+ if (ret)
+ return ret;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE: {
+ guard(mutex)(&data->mutex);
+
+ *val = qmc5883l_scales[data->range][0];
+ *val2 = qmc5883l_scales[data->range][1];
+
+ return IIO_VAL_INT_PLUS_NANO;
+ }
+ case IIO_CHAN_INFO_SAMP_FREQ: {
+ guard(mutex)(&data->mutex);
+
+ switch (data->odr) {
+ case QMC5883L_ODR_200HZ:
+ *val = 200;
+ break;
+ case QMC5883L_ODR_100HZ:
+ *val = 100;
+ break;
+ case QMC5883L_ODR_50HZ:
+ *val = 50;
+ break;
+ case QMC5883L_ODR_10HZ:
+ *val = 10;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return IIO_VAL_INT;
+ }
+ case IIO_CHAN_INFO_OVERSAMPLING_RATIO: {
+ guard(mutex)(&data->mutex);
+
+ switch (data->osr) {
+ case QMC5883L_OSR_64:
+ *val = 64;
+ break;
+ case QMC5883L_OSR_128:
+ *val = 128;
+ break;
+ case QMC5883L_OSR_256:
+ *val = 256;
+ break;
+ case QMC5883L_OSR_512:
+ *val = 512;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return IIO_VAL_INT;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static int qmc5883l_write_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int val, int val2, long mask)
+{
+ struct qmc5883l_data *data = iio_priv(indio_dev);
+ u8 rng, osr, odr;
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE: {
+ if (val != 0)
+ return -EINVAL;
+
+ if (val2 == qmc5883l_scales[QMC5883L_RNG_2G][1])
+ rng = QMC5883L_RNG_2G;
+ else if (val2 == qmc5883l_scales[QMC5883L_RNG_8G][1])
+ rng = QMC5883L_RNG_8G;
+ else
+ return -EINVAL;
+
+ guard(mutex)(&data->mutex);
+
+ ret = regmap_update_bits(data->regmap, QMC5883L_REG_CTRL1,
+ QMC5883L_RNG_MASK,
+ FIELD_PREP(QMC5883L_RNG_MASK, rng));
+ if (ret)
+ return ret;
+
+ data->range = rng;
+
+ return 0;
+ }
+ case IIO_CHAN_INFO_SAMP_FREQ: {
+ switch (val) {
+ case 200:
+ odr = QMC5883L_ODR_200HZ;
+ break;
+ case 100:
+ odr = QMC5883L_ODR_100HZ;
+ break;
+ case 50:
+ odr = QMC5883L_ODR_50HZ;
+ break;
+ case 10:
+ odr = QMC5883L_ODR_10HZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ guard(mutex)(&data->mutex);
+
+ ret = regmap_update_bits(data->regmap, QMC5883L_REG_CTRL1,
+ QMC5883L_ODR_MASK,
+ FIELD_PREP(QMC5883L_ODR_MASK, odr));
+ if (ret)
+ return ret;
+
+ data->odr = odr;
+
+ return 0;
+ }
+ case IIO_CHAN_INFO_OVERSAMPLING_RATIO: {
+ switch (val) {
+ case 64:
+ osr = QMC5883L_OSR_64;
+ break;
+ case 128:
+ osr = QMC5883L_OSR_128;
+ break;
+ case 256:
+ osr = QMC5883L_OSR_256;
+ break;
+ case 512:
+ osr = QMC5883L_OSR_512;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ guard(mutex)(&data->mutex);
+
+ ret = regmap_update_bits(data->regmap, QMC5883L_REG_CTRL1,
+ QMC5883L_OSR_MASK,
+ FIELD_PREP(QMC5883L_OSR_MASK, osr));
+ if (ret)
+ return ret;
+
+ data->osr = osr;
+
+ return 0;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static int qmc5883l_read_avail(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ const int **vals, int *type, int *length,
+ long mask)
+{
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *vals = qmc5883l_odr_avail;
+ *type = IIO_VAL_INT;
+ *length = ARRAY_SIZE(qmc5883l_odr_avail);
+ return IIO_AVAIL_LIST;
+ case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+ *vals = qmc5883l_osr_avail;
+ *type = IIO_VAL_INT;
+ *length = ARRAY_SIZE(qmc5883l_osr_avail);
+ return IIO_AVAIL_LIST;
+ case IIO_CHAN_INFO_SCALE:
+ *vals = (const int *)qmc5883l_scales;
+ *type = IIO_VAL_INT_PLUS_NANO;
+ *length = ARRAY_SIZE(qmc5883l_scales) * 2;
+ return IIO_AVAIL_LIST;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int qmc5883l_write_raw_get_fmt(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ long mask)
+{
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return IIO_VAL_INT;
+ }
+}
+
+static const struct iio_info qmc5883l_info = {
+ .read_raw = qmc5883l_read_raw,
+ .write_raw = qmc5883l_write_raw,
+ .read_avail = qmc5883l_read_avail,
+ .write_raw_get_fmt = qmc5883l_write_raw_get_fmt,
+};
+
+static int qmc5883l_init(struct qmc5883l_data *data)
+{
+ struct regmap *map = data->regmap;
+ unsigned int reg;
+ int ret;
+
+ ret = regmap_read(map, QMC5883L_REG_ID, ®);
+ if (ret)
+ return ret;
+
+ /* Not failing because rev 1.0 had this register reserved */
+ if (reg != QMC5883L_CHIP_ID)
+ dev_warn(regmap_get_device(map),
+ "Unknown chip id: 0x%02x, continuing\n", reg);
+
+ ret = regmap_write(map, QMC5883L_REG_CTRL2, QMC5883L_SOFT_RESET);
+ if (ret)
+ return ret;
+
+ /* Use POR completion time as a conservative bound */
+ fsleep(QMC5883L_PORT_US);
+
+ /* DRDY pin not used in this version of the driver */
+ ret = regmap_write(map, QMC5883L_REG_CTRL2, QMC5883L_INT_DISABLE);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(map, QMC5883L_REG_SET_RESET, QMC5883L_SET_RESET_VAL);
+ if (ret)
+ return ret;
+
+ data->odr = QMC5883L_ODR_50HZ;
+ data->range = QMC5883L_RNG_2G;
+ data->osr = QMC5883L_OSR_64;
+
+ return regmap_write(map, QMC5883L_REG_CTRL1,
+ FIELD_PREP(QMC5883L_MODE_MASK, QMC5883L_MODE_CONT) |
+ FIELD_PREP(QMC5883L_ODR_MASK, data->odr) |
+ FIELD_PREP(QMC5883L_RNG_MASK, data->range) |
+ FIELD_PREP(QMC5883L_OSR_MASK, data->osr));
+}
+
+static void qmc5883l_power_down_action(void *priv)
+{
+ struct qmc5883l_data *data = priv;
+
+ regmap_update_bits(data->regmap, QMC5883L_REG_CTRL1,
+ QMC5883L_MODE_MASK,
+ FIELD_PREP(QMC5883L_MODE_MASK, QMC5883L_MODE_STANDBY));
+}
+
+static bool qmc5883l_volatile_reg(struct device *dev, unsigned int reg)
+{
+ return reg <= QMC5883L_REG_STATUS1;
+}
+
+static bool qmc5883l_writable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case QMC5883L_REG_CTRL1:
+ case QMC5883L_REG_CTRL2:
+ case QMC5883L_REG_SET_RESET:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct regmap_config qmc5883l_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = QMC5883L_REG_ID,
+ .cache_type = REGCACHE_MAPLE,
+ .volatile_reg = qmc5883l_volatile_reg,
+ .writeable_reg = qmc5883l_writable_reg,
+};
+
+#define QMC5883L_CHANNEL(_axis) \
+ { \
+ .type = IIO_MAGN, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##_axis, \
+ .address = QMC5883L_AXIS_##_axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = \
+ BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
+ .info_mask_shared_by_type_available = \
+ BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
+ }
+
+static const struct iio_chan_spec qmc5883l_channels[] = {
+ QMC5883L_CHANNEL(X),
+ QMC5883L_CHANNEL(Y),
+ QMC5883L_CHANNEL(Z),
+};
+
+static int qmc5883l_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct qmc5883l_data *data;
+ struct iio_dev *indio_dev;
+ struct regmap *map;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ map = devm_regmap_init_i2c(client, &qmc5883l_regmap_config);
+ if (IS_ERR(map))
+ return dev_err_probe(dev, PTR_ERR(map),
+ "regmap initialization failed\n");
+
+ ret = devm_regulator_get_enable(dev, "vdd");
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to enable VDD regulator\n");
+
+ ret = devm_regulator_get_enable(dev, "vddio");
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to enable VDDIO regulator\n");
+
+ /* POR completion time max per datasheet Table 7 */
+ fsleep(QMC5883L_PORT_US);
+
+ data = iio_priv(indio_dev);
+ data->regmap = map;
+
+ ret = devm_mutex_init(dev, &data->mutex);
+ if (ret)
+ return ret;
+
+ indio_dev->name = "qmc5883l";
+ indio_dev->info = &qmc5883l_info;
+ indio_dev->channels = qmc5883l_channels;
+ indio_dev->num_channels = ARRAY_SIZE(qmc5883l_channels);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ ret = qmc5883l_init(data);
+ if (ret)
+ return dev_err_probe(dev, ret, "qmc5883l init failed\n");
+
+ ret = devm_add_action_or_reset(dev, qmc5883l_power_down_action, data);
+ if (ret)
+ return ret;
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct of_device_id qmc5883l_match[] = {
+ { .compatible = "qstcorp,qmc5883l" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, qmc5883l_match);
+
+static const struct i2c_device_id qmc5883l_id[] = {
+ { .name = "qmc5883l" },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, qmc5883l_id);
+
+static struct i2c_driver qmc5883l_driver = {
+ .driver = {
+ .name = "qmc5883l",
+ .of_match_table = qmc5883l_match,
+ },
+ .id_table = qmc5883l_id,
+ .probe = qmc5883l_probe,
+};
+module_i2c_driver(qmc5883l_driver);
+
+MODULE_DESCRIPTION("QST QMC5883L 3-Axis Magnetic Sensor driver");
+MODULE_AUTHOR("Siratul Islam <siratul.islam@linux.dev>");
+MODULE_LICENSE("Dual BSD/GPL");
--
2.54.0
^ permalink raw reply related
* [RFC PATCH 0/3] dt-bindings: riscv: Add RISC-V Worlds and SiFive WorldGuard DT bindings
From: Yu-Chien Peter Lin @ 2026-06-19 10:58 UTC (permalink / raw)
To: devicetree, linux-riscv, linux-kernel
Cc: robh, krzk+dt, conor+dt, pjw, palmer, aou, alex, samuel.holland,
dlan, guodong, dfustini, michal.simek, junhui.liu,
darshan.prajapati, akpm, zhangchunyan, luxu.kernel, pincheng.plct,
nick.hu, jim.shu, zong.li, greentime.hu, robin.randhawa, scott,
dave.patel, raymond.mao, Yu-Chien Peter Lin
Add device tree bindings for RISC-V Worlds, a standard extension that tags
every transaction with a World ID for fine-grained isolation. SiFive's
WorldGuard Checker is a hardware firewall in the system interconnect that
inspects transaction WIDs and enforces per-World access policies on memory
and MMIO devices.
The three patches add: Worlds ISA extension properties (riscv,nworlds and
sifive,trustedwid on /cpus), per-hart World ID constraints (riscv,pmwid,
riscv,pmwidlist, riscv,pmlwidlist on cpu@X nodes), and the wgchecker2
binding with access-controller specifiers.
The access-controllers specifier carries range, permission and config fields
to support three use cases:
1. single range device protection
2. discontiguous range device protection
3. sub-range memory partitioning.
Link: https://github.com/riscvarchive/security/blob/main/papers/worldguard%20proposal.pdf
Yu-Chien Peter Lin (3):
dt-bindings: riscv: Add Worlds ISA extensions
dt-bindings: riscv: Add Worlds per-hart properties
dt-bindings: sifive: Add WorldGuard Checker
.../devicetree/bindings/riscv/cpus.yaml | 21 ++
.../devicetree/bindings/riscv/extensions.yaml | 29 +++
.../devicetree/bindings/riscv/worlds.yaml | 86 +++++++
.../bindings/sifive/sifive,wgchecker2.yaml | 237 ++++++++++++++++++
4 files changed, 373 insertions(+)
create mode 100644 Documentation/devicetree/bindings/riscv/worlds.yaml
create mode 100644 Documentation/devicetree/bindings/sifive/sifive,wgchecker2.yaml
--
2.43.7
^ permalink raw reply
* [RFC PATCH 1/3] dt-bindings: riscv: Add Worlds ISA extensions
From: Yu-Chien Peter Lin @ 2026-06-19 10:58 UTC (permalink / raw)
To: devicetree, linux-riscv, linux-kernel
Cc: robh, krzk+dt, conor+dt, pjw, palmer, aou, alex, samuel.holland,
dlan, guodong, dfustini, michal.simek, junhui.liu,
darshan.prajapati, akpm, zhangchunyan, luxu.kernel, pincheng.plct,
nick.hu, jim.shu, zong.li, greentime.hu, robin.randhawa, scott,
dave.patel, raymond.mao, Yu-Chien Peter Lin
In-Reply-To: <20260619105834.1277302-1-peter.lin@sifive.com>
Add DT bindings for RISC-V Worlds ISA extensions to tag
transactions with World IDs that hardware uses to enforce
world-based isolation across execution contexts.
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
.../devicetree/bindings/riscv/extensions.yaml | 29 +++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
index 2b0a8a93bb21..1bc8b1aa67c0 100644
--- a/Documentation/devicetree/bindings/riscv/extensions.yaml
+++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
@@ -193,12 +193,35 @@ properties:
ratified at commit d70011dde6c2 ("Update to ratified state")
of riscv-j-extension.
+ - const: smlwid
+ description: |
+ The standard Smlwid extension for M-mode control of lower
+ privilege World ID via the mlwid CSR as ratified at commit
+ TBD ("TBD") of riscv-worlds.
+
+ - const: smlwidlist
+ description: |
+ The standard Smlwidlist extension for M-mode control of lower
+ privilege World IDs via the mlwidlist CSR as ratified at commit
+ TBD ("TBD") of riscv-worlds.
+
- const: smstateen
description: |
The standard Smstateen extension for controlling access to CSRs
added by other RISC-V extensions in H/S/VS/U/VU modes and as
ratified at commit a28bfae (Ratified (#7)) of riscv-state-enable.
+ - const: smwdeleg
+ description: |
+ The standard Smwdeleg extension for M-mode delegation of lower
+ privilege World ID control to S-mode via the mwiddeleg CSR, as
+ ratified at commit TBD ("TBD") of riscv-worlds.
+
+ - const: smwid
+ description: |
+ The standard Smwid extension for M-mode World ID control via the
+ mwid CSR as ratified at commit TBD ("TBD") of riscv-worlds.
+
- const: ssaia
description: |
The standard Ssaia supervisor-level extension for the advanced
@@ -262,6 +285,12 @@ properties:
ratified in RISC-V Profiles Version 1.0, with commit b1d806605f87
("Updated to ratified state.")
+ - const: sswid
+ description: |
+ The standard Sswid extension for S-mode control of lower
+ privilege World IDs via the slwid CSR as ratified at commit
+ TBD ("TBD") of riscv-worlds.
+
- const: supm
description: |
The standard Supm extension for pointer masking support in user
--
2.43.7
^ permalink raw reply related
* [RFC PATCH 2/3] dt-bindings: riscv: Add Worlds per-hart properties
From: Yu-Chien Peter Lin @ 2026-06-19 10:58 UTC (permalink / raw)
To: devicetree, linux-riscv, linux-kernel
Cc: robh, krzk+dt, conor+dt, pjw, palmer, aou, alex, samuel.holland,
dlan, guodong, dfustini, michal.simek, junhui.liu,
darshan.prajapati, akpm, zhangchunyan, luxu.kernel, pincheng.plct,
nick.hu, jim.shu, zong.li, greentime.hu, robin.randhawa, scott,
dave.patel, raymond.mao, Yu-Chien Peter Lin
In-Reply-To: <20260619105834.1277302-1-peter.lin@sifive.com>
Add per-hart DT properties for RISC-V Worlds architecture:
riscv,pmwid, riscv,pmwidlist, and riscv,pmlwidlist. These
platform-defined values are primarily used by M-mode firmware
to configure World ID CSRs and restrict WID usage across
privilege levels.
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
.../devicetree/bindings/riscv/cpus.yaml | 21 +++++
.../devicetree/bindings/riscv/worlds.yaml | 77 +++++++++++++++++++
2 files changed, 98 insertions(+)
create mode 100644 Documentation/devicetree/bindings/riscv/worlds.yaml
diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml
index 5feeb2203050..4b5778b6d3e7 100644
--- a/Documentation/devicetree/bindings/riscv/cpus.yaml
+++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
@@ -26,6 +26,7 @@ description: |
allOf:
- $ref: /schemas/cpu.yaml#
- $ref: extensions.yaml
+ - $ref: worlds.yaml
- if:
not:
properties:
@@ -120,11 +121,31 @@ properties:
thead systems where the vector register length is not identical on all harts, or
the vlenb CSR is not available.
+ riscv,pmwid:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Platform-defined M-mode World ID (WID) assigned to this hart.
+ minimum: 0
+ maximum: 63
+
+ riscv,pmwidlist:
+ $ref: /schemas/types.yaml#/definitions/uint64
+ description:
+ Platform-defined bitmap of M-mode World IDs (WIDs) that this hart may use.
+
+ riscv,pmlwidlist:
+ $ref: /schemas/types.yaml#/definitions/uint64
+ description:
+ Platform-defined bitmap of World IDs (WIDs) that S-mode and U-mode may use
+ on this hart.
+
# RISC-V has multiple properties for cache op block sizes as the sizes
# differ between individual CBO extensions
cache-op-block-size: false
# RISC-V requires 'timebase-frequency' in /cpus, so disallow it here
timebase-frequency: false
+ # RISC-V requires 'riscv,nworlds' in /cpus, so disallow it here
+ riscv,nworlds: false
interrupt-controller:
type: object
diff --git a/Documentation/devicetree/bindings/riscv/worlds.yaml b/Documentation/devicetree/bindings/riscv/worlds.yaml
new file mode 100644
index 000000000000..cc8b3747591e
--- /dev/null
+++ b/Documentation/devicetree/bindings/riscv/worlds.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0 OR MIT)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/riscv/worlds.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Worlds Extension
+
+maintainers:
+ - Yu-Chien Peter Lin <peter.lin@sifive.com>
+
+description: |
+ The RISC-V Worlds ISA extension, as described in the RISC-V Privileged
+ Specification, adds World ID tagging for context isolation.
+
+ This binding describes the system-wide Worlds configuration for the /cpus node
+ and is used alongside per-hart Worlds-related properties such as riscv,pmwid in
+ the RISC-V CPU binding and Worlds-related ISA extensions enumerated via
+ riscv,isa-extensions.
+
+select:
+ properties:
+ $nodename:
+ pattern: "^cpus$"
+
+properties:
+ riscv,nworlds:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Number of World IDs (WIDs) supported by the platform. This is a system-wide
+ property that describes the total number of isolation contexts available.
+ Hardware components such as the WorldGuard Checker use this to determine
+ the valid range of WID values.
+ minimum: 2
+ maximum: 64
+
+additionalProperties: true
+
+examples:
+ - |
+ // Example: System with 4 World IDs
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <1000000>;
+ riscv,nworlds = <4>;
+
+ cpu@0 {
+ device_type = "cpu";
+ reg = <0>;
+ compatible = "sifive,bullet0", "riscv";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c";
+ riscv,pmwid = <0>;
+
+ interrupt-controller {
+ #interrupt-cells = <1>;
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ };
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ reg = <1>;
+ compatible = "sifive,bullet0", "riscv";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c";
+ riscv,pmwid = <1>;
+
+ interrupt-controller {
+ #interrupt-cells = <1>;
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ };
+ };
+ };
--
2.43.7
^ permalink raw reply related
* [RFC PATCH 3/3] dt-bindings: sifive: Add WorldGuard Checker
From: Yu-Chien Peter Lin @ 2026-06-19 10:58 UTC (permalink / raw)
To: devicetree, linux-riscv, linux-kernel
Cc: robh, krzk+dt, conor+dt, pjw, palmer, aou, alex, samuel.holland,
dlan, guodong, dfustini, michal.simek, junhui.liu,
darshan.prajapati, akpm, zhangchunyan, luxu.kernel, pincheng.plct,
nick.hu, jim.shu, zong.li, greentime.hu, robin.randhawa, scott,
dave.patel, raymond.mao, Yu-Chien Peter Lin
In-Reply-To: <20260619105834.1277302-1-peter.lin@sifive.com>
Add DT binding for SiFive wgChecker2, a hardware firewall enforcing
WID-based access control in RISC-V Worlds. Provides checker slots to
program per-WID permissions for downstream resources, with optional
sub-range partitioning.
Link: https://github.com/riscvarchive/security/blob/main/papers/worldguard%20proposal.pdf
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
Reviewed-by: Zong Li <zong.li@sifive.com>
Reviewed-by: Jim Shu <jim.shu@sifive.com>
---
.../devicetree/bindings/riscv/worlds.yaml | 9 +
.../bindings/sifive/sifive,wgchecker2.yaml | 237 ++++++++++++++++++
2 files changed, 246 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sifive/sifive,wgchecker2.yaml
diff --git a/Documentation/devicetree/bindings/riscv/worlds.yaml b/Documentation/devicetree/bindings/riscv/worlds.yaml
index cc8b3747591e..c39a06c2dd8d 100644
--- a/Documentation/devicetree/bindings/riscv/worlds.yaml
+++ b/Documentation/devicetree/bindings/riscv/worlds.yaml
@@ -34,6 +34,14 @@ properties:
minimum: 2
maximum: 64
+ sifive,trustedwid:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 31
+ description: |
+ The World ID (WID) designated as the trusted WID for this platform.
+ Transactions tagged with this WID are authorized to access and configure
+ WorldGuard blocks, including wgCheckers and wgMarkers.
+
additionalProperties: true
examples:
@@ -44,6 +52,7 @@ examples:
#size-cells = <0>;
timebase-frequency = <1000000>;
riscv,nworlds = <4>;
+ sifive,trustedwid = <3>;
cpu@0 {
device_type = "cpu";
diff --git a/Documentation/devicetree/bindings/sifive/sifive,wgchecker2.yaml b/Documentation/devicetree/bindings/sifive/sifive,wgchecker2.yaml
new file mode 100644
index 000000000000..043c748385ed
--- /dev/null
+++ b/Documentation/devicetree/bindings/sifive/sifive,wgchecker2.yaml
@@ -0,0 +1,237 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2026 SiFive, Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sifive/sifive,wgchecker2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive WorldGuard Checker
+
+maintainers:
+ - Yu-Chien Peter Lin <peter.lin@sifive.com>
+
+description: |
+ The RISC-V Worlds ISA extension defines World IDs (WIDs) as architectural
+ identifiers that tag each system transaction with its originating context.
+ System integrators assign WIDs to execution contexts such as privilege modes,
+ trusted execution environments, or other isolation boundaries.
+
+ The SiFive WorldGuard Checker is a hardware firewall positioned in the
+ system interconnect fabric. It inspects every transaction, evaluating the
+ WID against access control policies encoded in checker slots for each
+ protected resource. Transactions from unauthorized WIDs are blocked and
+ reported as bus errors, interrupts, or both.
+
+ This enables spatial partitioning of memory regions and memory-mapped devices
+ across execution contexts. Different address ranges can enforce distinct
+ policies, allowing isolated workloads to coexist with hardware-enforced
+ protection.
+
+ The wgChecker acts as an access-controller provider as defined in the
+ access-controllers framework. Protected devices are consumers that declare
+ their access policy via the access-controllers property. The hardware
+ supports up to 32 World IDs.
+
+ The World ID authorized to configure WorldGuard blocks is specified by the
+ sifive,trustedwid property in the /cpus node.
+
+allOf:
+ - $ref: /schemas/access-controllers/access-controllers.yaml#
+
+properties:
+ compatible:
+ const: sifive,wgchecker2
+
+ reg:
+ maxItems: 1
+ description:
+ Base address and size of the wgChecker memory-mapped I/O registers.
+
+ interrupts:
+ maxItems: 1
+ description:
+ Interrupt line asserted when a WID access violation is detected and
+ interrupt reporting is enabled in the slot configuration (IR or IW
+ bits set).
+
+ '#access-controller-cells':
+ const: 7
+ description: |
+ Specifier for one access-control rule, encoded as seven u32 cells:
+ <addr-hi addr-lo size-hi size-lo perm-hi perm-lo config>
+
+ where:
+ - addr-hi, addr-lo: 64-bit base address of the protected region.
+ - size-hi, size-lo: 64-bit size of the protected region in bytes.
+ - perm-hi: Permission bitmap for WIDs 16..31. Two bits per WID:
+ bit 2*(WID-16) = Read permission
+ bit 2*(WID-16)+1 = Write permission
+ Set bits grant access. Use 0x0 for systems with
+ riscv,nworlds <= 16.
+ - perm-lo: Permission bitmap for WIDs 0..15. Two bits per WID:
+ bit 2*WID = Read permission
+ bit 2*WID+1 = Write permission
+ Set bits grant access.
+ - config: Slot configuration bits:
+ Bit 0 (ER): Report read violations as bus errors
+ Bit 1 (EW): Report write violations as bus errors
+ Bit 2 (IR): Report read violations via interrupt
+ Bit 3 (IW): Report write violations via interrupt
+ Bit 4 (L): Lock bit - prevents further modification
+ Bits 5..31 are reserved and must be zero.
+
+ Multiple entries may be listed to apply different policies to
+ different address ranges, including sub-ranges within a single
+ physical resource.
+
+required:
+ - compatible
+ - reg
+ - '#access-controller-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ // Example 1: Single device protection
+ // WID 0 and WID 3 have RW access to UART; errors and IRQs reported.
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <1000000>;
+ riscv,nworlds = <4>;
+ sifive,trustedwid = <3>;
+
+ cpu@0 {
+ device_type = "cpu";
+ reg = <0>;
+ compatible = "riscv";
+ riscv,isa = "rv64imac";
+ };
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ uart: uart@1c1000 {
+ compatible = "ns16550a";
+ reg = <0x0 0x001c1000 0x0 0x1000>;
+ reg-names = "control";
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
+ // WID 0,3 RW; report errors+IRQs
+ access-controllers = <&wgchecker0
+ 0x0 0x001c1000 0x0 0x00001000
+ 0x0 0x000000c3 0x0f>;
+ };
+
+ wgchecker0: wgchecker@1c2000 {
+ compatible = "sifive,wgchecker2";
+ reg = <0x0 0x001c2000 0x0 0x1000>;
+ #access-controller-cells = <7>;
+ interrupts = <80 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&aplic_m>;
+ };
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ // Example 2: Multi-reg device with separate per-range rules
+ // m_mode: WID 3 only; s_mode: WID 0,3 RW.
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <1000000>;
+ riscv,nworlds = <16>;
+ sifive,trustedwid = <3>;
+
+ cpu@0 {
+ device_type = "cpu";
+ reg = <0>;
+ compatible = "riscv";
+ riscv,isa = "rv64imac";
+ };
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ device: device@10000 {
+ compatible = "vendor,soc1-ip";
+ reg = <0x0 0x00010000 0x0 0x8000>,
+ <0x0 0x00a00000 0x0 0x4000>;
+ reg-names = "m_mode", "s_mode";
+ // m_mode: WID 3 only; s_mode: WID 0,3 RW
+ access-controllers = <&wgchecker1
+ 0x0 0x00010000 0x0 0x00008000
+ 0x0 0x000000c0 0x0f>,
+ <&wgchecker1
+ 0x0 0x00a00000 0x0 0x00004000
+ 0x0 0x000000c3 0x0f>;
+ };
+
+ wgchecker1: wgchecker@35000 {
+ compatible = "sifive,wgchecker2";
+ reg = <0x0 0x00035000 0x0 0x1000>;
+ #access-controller-cells = <7>;
+ interrupts = <81 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&aplic_m>;
+ };
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ // Example 3: DRAM partitioning with secure enclave
+ // Sub-range 1 [0x80000000, 0xC0000000): WID 0,1,3 RW
+ // Sub-range 2 [0xC0000000, 0xC1000000): WID 1,3 only (secure enclave)
+ // Sub-range 3 [0xC1000000, 0x100000000): WID 0,1,3 RW
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <1000000>;
+ riscv,nworlds = <4>;
+ sifive,trustedwid = <3>;
+
+ cpu@0 {
+ device_type = "cpu";
+ reg = <0>;
+ compatible = "riscv";
+ riscv,isa = "rv64imac";
+ };
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ddr: memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x80000000>;
+ access-controllers =
+ <&wgchecker2
+ 0x0 0x80000000 0x0 0x40000000
+ 0x0 0x000000cf 0x0f>,
+ <&wgchecker2
+ 0x0 0xc0000000 0x0 0x01000000
+ 0x0 0x000000cc 0x0f>,
+ <&wgchecker2
+ 0x0 0xc1000000 0x0 0x3f000000
+ 0x0 0x000000cf 0x0f>;
+ };
+
+ wgchecker2: wgchecker@40000000 {
+ compatible = "sifive,wgchecker2";
+ reg = <0x0 0x40000000 0x0 0x1000>;
+ #access-controller-cells = <7>;
+ interrupts = <82 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&aplic_m>;
+ };
+ };
--
2.43.7
^ permalink raw reply related
* Re: [PATCH v2 2/6] iommu/arm-smmu: Add interconnect bandwidth voting support
From: Bibek Kumar Patro @ 2026-06-19 10:54 UTC (permalink / raw)
To: Konrad Dybcio, Dmitry Baryshkov
Cc: Will Deacon, Robin Murphy, Joerg Roedel, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
linux-arm-kernel, iommu, devicetree, linux-kernel, linux-arm-msm
In-Reply-To: <299d54c5-fb93-47ee-9495-fbf48a3204fd@oss.qualcomm.com>
On 6/18/2026 2:58 PM, Konrad Dybcio wrote:
> On 6/17/26 4:26 PM, Bibek Kumar Patro wrote:
>>
>>
>> On 6/16/2026 5:51 AM, Dmitry Baryshkov wrote:
>>> On Mon, Jun 15, 2026 at 06:36:51PM +0530, Bibek Kumar Patro wrote:
>>>>
>>>>
>>>> On 6/8/2026 7:25 PM, Dmitry Baryshkov wrote:
>>>>> On Tue, May 26, 2026 at 08:12:03PM +0530, Bibek Kumar Patro wrote:
>>>>>> On some SoCs the SMMU registers require an active interconnect
>>>>>> bandwidth vote to be accessible. While other clients typically
>>>>>> satisfy this requirement implicitly, certain corner cases (e.g.
>>>>>> during sleep/wakeup transitions) can leave the SMMU without a
>>>>>> vote, causing intermittent register access failures.
>>>>>>
>>>>>> Add support for an optional interconnect path to the arm-smmu
>>>>>> driver and vote for bandwidth while the SMMU is active. The path
>>>>>> is acquired from DT if present and ignored otherwise.
>>>>>>
>>>>>> The bandwidth vote is enabled before accessing SMMU registers
>>>>>> during probe and runtime resume, and released during runtime
>>>>>> suspend and on error paths.
>>>>>>
>>>>>> Generally, from an architectural perspective, GEM_NOC and DDR are
>>>>>> expected to have an active vote whenever the adreno_smmu block is
>>>>>> powered on. In most common use cases, this requirement is implicitly
>>>>>> satisfied because other GPU-related clients (for example, the GMU
>>>>>> device) already hold a GEM_NOC vote when adreno_smmu is enabled.
>>>>>>
>>>>>> However, there are certain corner cases, such as during sleep/wakeup
>>>>>> transitions, where the GEM_NOC vote can be removed before adreno_smmu
>>>>>> is powered down. If adreno_smmu is then accessed while the interconnect
>>>>>> vote is missing, it can lead to the observed failures. Because of the
>>>>>> precise ordering involved, this scenario is difficult to reproduce
>>>>>> consistently.
>>>>>> (also GDSC is involved in adreno usecases can have an independent vote)
>>>>>>
>>>>>> Signed-off-by: Bibek Kumar Patro <bibek.patro@oss.qualcomm.com>
>>>>>> ---
>>>>>> drivers/iommu/arm/arm-smmu/arm-smmu.c | 57 +++++++++++++++++++++++++++++++++--
>>>>>> drivers/iommu/arm/arm-smmu/arm-smmu.h | 2 ++
>>>>>> 2 files changed, 57 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>>>>>> index 0bd21d206eb3e75c3b9fb1364cdc92e82c5aa499..07c7e44ec6a5bd1488f00f87d859a20495e46601 100644
>>>>>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
>>>>>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>>>>>> @@ -53,6 +53,11 @@
>>>>>> #define MSI_IOVA_BASE 0x8000000
>>>>>> #define MSI_IOVA_LENGTH 0x100000
>>>>>> +/* Interconnect bandwidth vote values for the SMMU register access path */
>>>>>> +#define ARM_SMMU_ICC_AVG_BW 0
>>>>>> +#define ARM_SMMU_ICC_PEAK_BW_HIGH 1000
>>>>>
>>>>> totally random numbers, which might be different for non-Qualcomm platform.
>>>>>
>>>>
>>>> Ideally, any non-zero value would be enough to keep the path active.
>>>
>>> This is true for Qualcomm devices. However, you are adding this to a
>>> generic code.
>>>
>>>> Here 1 Would be enough to keep the path active, but might be too small to
>>>> reliably keep the bus active.
>>>> Other is UINT_MAX, which will reliably keep the bus active but might cause a
>>>> power penalty.
>>>>
>>>> #define ARM_SMMU_ICC_PEAK_BW_HIGH UINT_MAX
>>>>
>>>> seems to be suitable here to reliably keep the bus active by BCM
>>>> for both Qualcomm and non-Qualcomm platforms (with some power penalty).
>>>>
>>>> LMK, if you feel otherwise.
>>>
>>> Shift it to the qcom instance or provide platform-specific values? (My
>>> preference would be towards the first solution).
>>>
>>
>>
>> To support platform-specific values, we may need to introduce a LUT-based approach in the driver. (Bandwidth voting values cannot be placed in device-tree property IIRC ?)
>>
>> Currently, all Qualcomm platforms use 0x1000 for SMMU ICC voting. I
>
> (you used decimal 1000)
>
It's my bad, i meant 1000 only
(I'll check on the icc_bw calculation to get clarity on the values)
>> can evaluate if this could be moved to a Qualcomm-specific
>> implementation.
>
> Add a vendor hook to arm_smmu_runtime_suspend/resume and handle it within
> the QC driver
>
Just curious, wouldn't this apply for all the arm-smmu users in addition
to Qualcomm devices as i mentioned here [1].
Vendor hook would make it Qualcomm specific.
[1]:
https://lore.kernel.org/all/984ff9c7-3eef-463c-a330-bf7acd063667@oss.qualcomm.com/
Thanks & regards,
Bibek
> Konrad
^ 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