Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v3 8/9] ASoC: loongson: Add headphone jack detection and DAPM routing
From: sashiko-bot @ 2026-06-26  2:44 UTC (permalink / raw)
  To: Binbin Zhou; +Cc: devicetree, conor+dt, robh
In-Reply-To: <c4b1503220b6fb433ecdcb881556827579041c3d.1782439646.git.zhoubinbin@loongson.cn>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Double-free of the hp-det GPIO descriptor on probe failure or driver unbind.
- [High] Global state mutation via static global instance structures.
- [Low] Misleading DAPM event handler name and widget array typos due to copy-pasting.
--

commit 96bfdeee5a35a70f217e0f245943a82eb9a7ce3b
Author: Binbin Zhou <zhoubinbin@loongson.cn>

ASoC: loongson: Add headphone jack detection and DAPM routing

Extend the Loongson audio machine driver with jack detection, DAPM
widgets support, enabling proper switching between headphones and
speakers on the Loongson-2K0300 ATK-DL2K0300B board.

> diff --git a/sound/soc/loongson/loongson_card.c b/sound/soc/loongson/loongson_card.c
> index 0e63cbcad57ac..25cd12eab4b1f 100644
> --- a/sound/soc/loongson/loongson_card.c
> +++ b/sound/soc/loongson/loongson_card.c

[ ... ]

> +static int tegra_machine_event(struct snd_soc_dapm_widget *w,
> +			       struct snd_kcontrol *k, int event)
> +{

[Severity: Low]
This isn't a bug, but should this function be renamed to match the loongson
namespace instead of keeping the tegra_ prefix from a copied driver?

> +	struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm);
> +	struct loongson_card_data *priv = snd_soc_card_get_drvdata(card);
> +
> +	if (!snd_soc_dapm_widget_name_cmp(w, "Speaker"))
> +		gpiod_set_value_cansleep(priv->gpiod_spkr_en,
> +					 SND_SOC_DAPM_EVENT_ON(event));

[ ... ]

> +static const struct snd_soc_dapm_widget loongson_aosc_dapm_widgets[] = {

[Severity: Low]
This isn't a bug, but there is a typo here (aosc instead of asoc).

> +	SND_SOC_DAPM_HP("Headphone", tegra_machine_event),
> +	SND_SOC_DAPM_SPK("Speaker", tegra_machine_event),
> +};
> +
> +/* Headphones Jack */
> +
> +static struct snd_soc_jack loongson_asoc_hp_jack;
> +
> +static struct snd_soc_jack_pin loongson_asoc_hp_jack_pins[] = {

[ ... ]

> +static struct snd_soc_jack_gpio loongson_asoc_hp_jack_gpio = {
> +	.name = "Headphones detection",
> +	.report = SND_JACK_HEADPHONE,
> +	.debounce_time = 150,
> +};

[Severity: High]
Will using a static global instance for snd_soc_jack_gpio cause cross-device
state corruption?

The ASoC core function snd_soc_jack_add_gpios() takes ownership of this
struct and initializes a delayed_work structure inside it. If multiple
instances of this driver probe concurrently or across unbind/rebind cycles,
multiple driver instances might mutate and re-initialize the same global
static struct and its workqueue list head.

Could this be moved to the instance-specific loongson_card_data instead?

> +
> +static int loongson_asoc_machine_init(struct snd_soc_pcm_runtime *rtd)
> +{
> +	struct snd_soc_card *card = rtd->card;
> +	struct loongson_card_data *ls_priv = snd_soc_card_get_drvdata(card);
> +	int ret = 0;

[ ... ]

> @@ -135,16 +229,35 @@ static int loongson_card_parse_acpi(struct loongson_card_data *data)
>  
>  static int loongson_card_parse_of(struct loongson_card_data *data)
>  {
> -	struct device_node *cpu, *codec;
>  	struct snd_soc_card *card = &data->snd_card;
> +	struct device_node *cpu, *codec;
>  	struct device *dev = card->dev;
>  	int ret, i;
>  
> +	data->gpiod_hp_det = devm_gpiod_get_optional(dev, "hp-det", GPIOD_IN);

[Severity: High]
Will this devm-managed GPIO descriptor trigger a double-free on driver unbind
or probe deferral?

When devm_gpiod_get_optional() requests the GPIO, it registers a devres
cleanup action. Later in loongson_asoc_machine_init():

loongson_asoc_machine_init() {
    ...
    loongson_asoc_hp_jack_gpio.desc = ls_priv->gpiod_hp_det;
    ret = snd_soc_jack_add_gpios(&loongson_asoc_hp_jack, 1,
                                 &loongson_asoc_hp_jack_gpio);
    ...
}

The snd_soc_jack_add_gpios() call registers a second overlapping devres action
that unconditionally frees the GPIO descriptor. When the device is unbound,
won't both cleanup actions attempt to free the same gpio_device, leading to
a Use-After-Free?

> +	if (IS_ERR(data->gpiod_hp_det))
> +		return PTR_ERR(data->gpiod_hp_det);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1782439646.git.zhoubinbin@loongson.cn?part=8

^ permalink raw reply

* [PATCH 1/2] dt-bindings: arm: tegra: Add lenovo,thinkedge-se70 compatible string
From: Jiqi Li @ 2026-06-26  3:34 UTC (permalink / raw)
  To: linux-tegra
  Cc: devicetree, robh+dt, krzk+dt, conor+dt, jonathanh, thierry.reding,
	mpearson-lenovo, Jiqi Li
In-Reply-To: <20260626033418.520762-1-lijq9@lenovo.com>

Lenovo ThinkEdge SE70 is a fanless industrial edge gateway carrier
board based on NVIDIA Tegra194 (Xavier NX) SOM.
Add the corresponding compatible string for device tree validation.

Signed-off-by: Jiqi Li <lijq9@lenovo.com>
---
 Documentation/devicetree/bindings/arm/tegra.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/tegra.yaml b/Documentation/devicetree/bindings/arm/tegra.yaml
index 033a63f6c068..960c604ef9a3 100644
--- a/Documentation/devicetree/bindings/arm/tegra.yaml
+++ b/Documentation/devicetree/bindings/arm/tegra.yaml
@@ -268,6 +268,10 @@ properties:
         items:
           - const: nvidia,p3509-0000+p3668-0001
           - const: nvidia,tegra194
+      - description: Lenovo ThinkEdge SE70
+        items:
+          - const: lenovo,thinkedge-se70
+          - const: nvidia,tegra194
       - items:
           - const: nvidia,tegra234-vdk
           - const: nvidia,tegra234
-- 
2.43.0


^ permalink raw reply related

* [PATCH 2/2] arm64: tegra: Add Lenovo ThinkEdge SE70 carrier board DTS
From: Jiqi Li @ 2026-06-26  3:34 UTC (permalink / raw)
  To: linux-tegra
  Cc: devicetree, robh+dt, krzk+dt, conor+dt, jonathanh, thierry.reding,
	mpearson-lenovo, Jiqi Li
In-Reply-To: <20260626033418.520762-1-lijq9@lenovo.com>

ThinkEdge SE70 is a fanless industrial edge gateway built around
NVIDIA Tegra194 Xavier NX SOM. This patch adds a standalone device
tree file describing core carrier board peripherals:
- Custom 40-pin header pinmux configuration
- External SD card slot with dedicated 3.3V fixed regulator

No fan, PWM, tachometer, extra camera/spi peripherals are present
on this passively cooled platform, so unused nodes are explicitly
disabled following mainline device tree best practices.

Static verification passed: dt_binding_check and dtbs compilation
complete without errors.

Signed-off-by: Jiqi Li <lijq9@lenovo.com>
---
 arch/arm64/boot/dts/nvidia/Makefile           |   1 +
 .../nvidia/tegra194-lenovo-thinkedge-se70.dts | 164 ++++++++++++++++++
 2 files changed, 165 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts

diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile
index 72c0cb5efa47..736a3f8a923f 100644
--- a/arch/arm64/boot/dts/nvidia/Makefile
+++ b/arch/arm64/boot/dts/nvidia/Makefile
@@ -29,6 +29,7 @@ dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p3509-0000+p3636-0001.dtb
 dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p2972-0000.dtb
 dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p3509-0000+p3668-0000.dtb
 dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p3509-0000+p3668-0001.dtb
+dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-lenovo-thinkedge-se70.dtb
 dtb-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-sim-vdk.dtb
 dtb-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-p3737-0000+p3701-0000.dtb
 dtb-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-p3737-0000+p3701-0008.dtb
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts b/arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts
new file mode 100644
index 000000000000..d44eb7c9b474
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "tegra194-p3668-0001.dtsi"
+#include "tegra194-p3509-0000.dtsi"
+
+/ {
+	model = "Lenovo ThinkEdge SE70";
+	compatible = "lenovo,thinkedge-se70", "nvidia,tegra194";
+
+	chosen {
+		bootargs = "console=ttyTCU0,115200";
+	};
+
+	/* Fixed 3.3V regulator for external SD card slot */
+	fixed-regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ap2306gn_3v3_sd: ap2306gn-3v3-sd {
+			compatible = "regulator-fixed";
+			regulator-name = "ap2306gn-3v3-sd";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio TEGRA194_MAIN_GPIO(Q, 5) GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+			status = "okay";
+		};
+	};
+
+	bus@0 {
+
+		/* Custom pinmux configurations for 40-pin expansion header */
+		pinmux@c302000 {
+			status = "okay";
+			touch-clk-pcc4 {
+				nvidia,pins = "touch_clk_pcc4";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_UP>;
+				nvidia,tristate = <TEGRA_PIN_ENABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
+		};
+
+		pinmux@2430028 {
+			status = "okay";
+			soc-gpio41-pq5 {
+				nvidia,pins = "soc_gpio41_pq5";
+				nvidia,function = "rsvd2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+		};
+
+		pinmux@2430000 {
+			status = "okay";
+			pinctrl-names = "default";
+			pinctrl-0 = <&hdr40_pinmux>;
+
+			hdr40_pinmux: header-40pin-pinmux {
+				pin7 {
+					nvidia,pins = "aud_mclk_ps4";
+					nvidia,function = "aud";
+					nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+					nvidia,tristate = <TEGRA_PIN_DISABLE>;
+					nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+				};
+				pin11 {
+					nvidia,pins = "uart1_rts_pr4";
+					nvidia,function = "uarta";
+					nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+					nvidia,tristate = <TEGRA_PIN_DISABLE>;
+					nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+				};
+				pin12 {
+					nvidia,pins = "dap5_sclk_pt5";
+					nvidia,function = "i2s5";
+					nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+					nvidia,tristate = <TEGRA_PIN_DISABLE>;
+					nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				};
+				pin35 {
+					nvidia,pins = "dap5_fs_pu0";
+					nvidia,function = "i2s5";
+					nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+					nvidia,tristate = <TEGRA_PIN_DISABLE>;
+					nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				};
+				pin36 {
+					nvidia,pins = "uart1_cts_pr5";
+					nvidia,function = "uarta";
+					nvidia,pull = <TEGRA_PIN_PULL_UP>;
+					nvidia,tristate = <TEGRA_PIN_ENABLE>;
+					nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				};
+				pin38 {
+					nvidia,pins = "dap5_din_pt7";
+					nvidia,function = "i2s5";
+					nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+					nvidia,tristate = <TEGRA_PIN_ENABLE>;
+					nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				};
+				pin40 {
+					nvidia,pins = "dap5_dout_pt6";
+					nvidia,function = "i2s5";
+					nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+					nvidia,tristate = <TEGRA_PIN_DISABLE>;
+					nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+				};
+			};
+		};
+
+		/* Configure i2c bus clock to 400kHz for carrier board peripherals */
+		i2c@3160000 {
+			clock-frequency = <400000>;
+			status = "okay";
+		};
+
+		/* SDMMC3 for external user SD card slot with dedicated 3.3V power */
+		sdhci@3440000 {
+			vmmc-supply = <&ap2306gn_3v3_sd>;
+			cd-gpios = <&gpio_aon TEGRA194_AON_GPIO(CC, 4) GPIO_ACTIVE_HIGH>;
+			status = "okay";
+		};
+
+		/* Disable fan and tachometer hardware not populated on SE70 carrier board */
+		pwm-fan {
+			status = "disabled";
+		};
+		thermal-fan-est {
+			status = "disabled";
+		};
+		tachometer@39c0000 {
+			status = "disabled";
+		};
+		pwm@c340000 {
+			status = "disabled";
+		};
+		pwm@3280000 {
+			status = "disabled";
+		};
+		pwm@32c0000 {
+			status = "disabled";
+		};
+		pwm@32d0000 {
+			status = "disabled";
+		};
+		pwm@32f0000 {
+			status = "disabled";
+		};
+		generic-pwm-tachometer {
+			status = "disabled";
+		};
+
+		/* Disable unused SPI interfaces on 40-pin header */
+		spi@3210000 {
+			status = "disabled";
+		};
+		spi@3230000 {
+			status = "disabled";
+		};
+	};
+};
-- 
2.43.0


^ permalink raw reply related

* [RFC v2 PATCH 0/2] Add Lenovo ThinkEdge SE70 carrier board support
From: Jiqi Li @ 2026-06-26  3:34 UTC (permalink / raw)
  To: linux-tegra
  Cc: devicetree, robh+dt, krzk+dt, conor+dt, jonathanh, thierry.reding,
	mpearson-lenovo, Jiqi Li

This series adds device tree bindings and standalone DTS for the Lenovo
ThinkEdge SE70 fanless industrial edge gateway based on NVIDIA Tegra194
Xavier NX SOM.

Patch 1 adds the board compatible string to tegra.yaml for dt-schema
validation.
Patch 2 introduces the carrier board DTS with 40-pin header pinmux and
external SD card power regulator, disables unused fan/PWM/spi peripherals.

Static verification passed: dt_binding_check and dtbs compilation
complete without errors.

We maintain downstream DTS for mass-deployed SE70 hardware internally.
Upstreaming aligns with existing OEM board contributions (Google/Xiaomi)
in the Tegra tree, cuts long-term out-of-tree patch maintenance overhead.
This industrial platform has a full 7-year support lifecycle until 2028;
Lenovo will keep backporting DT fixes throughout its service window.
All peripherals use generic upstream drivers with no proprietary extensions.


Changes in v2:
- Wrap all memory-mapped peripherals under root bus@0 node to match upstream
  tegra194.dtsi hardware topology
- Add missing tegra194.dtsi include to resolve undefined GPIO/pinctrl macros
- Fix regulator label syntax error (illegal hyphens replaced with underscores),
  sync supply reference in sdhci node
- Remove downstream L4T-only nvidia,lpdr pinmux property which lacks upstream binding
- Fix SD card detect double inversion logic: drop cd-inverted property,
  set cd-gpios to GPIO_ACTIVE_HIGH
- Add required simple-bus properties (#address-cells, #size-cells) to fixed-regulators
- Unify all node labels to underscore naming per devicetree specification
- Correct mismatched 2.3V -> 3.3V regulator comment
- Trim compound SOM compatible string to eliminate un-documented binding warning

Jiqi Li (2):
  dt-bindings: arm: tegra: Add lenovo,thinkedge-se70 compatible string
  arm64: tegra: Add Lenovo ThinkEdge SE70 carrier board DTS

 .../devicetree/bindings/arm/tegra.yaml        |   4 +
 arch/arm64/boot/dts/nvidia/Makefile           |   1 +
 .../nvidia/tegra194-lenovo-thinkedge-se70.dts | 164 ++++++++++++++++++
 3 files changed, 169 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts

-- 
2.43.0


^ permalink raw reply

* [PATCH v2 0/2] rtq2208: Remove the unnecessary MTP_SEL property
From: cy_huang @ 2026-06-26  3:38 UTC (permalink / raw)
  To: Mark Brown, Krzysztof Kozlowski
  Cc: Rob Herring, Conor Dooley, Liam Girdwood, ChiYuan Huang,
	Yoon Dong Min, edward_kim, devicetree, linux-kernel

From: ChiYuan Huang <cy_huang@richtek.com>

This patch series remove the 'richtek,mtp-sel-high' property usage.

v2:
- Remove'richtek,mtp-sel-high' from yaml example block

ChiYuan Huang (2):
  regulator: dt-bindings: rtq2208: Label mtp-sel-high property as
    deprecated
  regualtor: rtq2208: Initiate the default MTP_SEL state by hardware
    register

 .../devicetree/bindings/regulator/richtek,rtq2208.yaml     | 4 +++-
 drivers/regulator/rtq2208-regulator.c                      | 7 ++++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

-- 
2.43.0


^ permalink raw reply

* [PATCH v2 1/2] regulator: dt-bindings: rtq2208: Label mtp-sel-high property as deprecated
From: cy_huang @ 2026-06-26  3:38 UTC (permalink / raw)
  To: Mark Brown, Krzysztof Kozlowski
  Cc: Rob Herring, Conor Dooley, Liam Girdwood, ChiYuan Huang,
	Yoon Dong Min, edward_kim, devicetree, linux-kernel
In-Reply-To: <cover.1782444299.git.cy_huang@richtek.com>

From: ChiYuan Huang <cy_huang@richtek.com>

Since it can be identified by hardware register, label the unnecessary
property 'richtek,mtp-sel-high' as deprecated.

Signed-off-by: ChiYuan Huang <cy_huang@richtek.com>
---
v2
- Following by AI Robot suggestion
  https://sashiko.dev/#/patchset/cover.1782353659.git.cy_huang@richtek.com?part=1

  Remove'richtek,mtp-sel-high' from yaml example block
---
 .../devicetree/bindings/regulator/richtek,rtq2208.yaml        | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml b/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml
index 022c1f197364..25b0865d4c04 100644
--- a/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml
+++ b/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml
@@ -42,11 +42,14 @@ properties:
 
   richtek,mtp-sel-high:
     type: boolean
+    deprecated: true
     description:
       vout register selection based on this boolean value.
       false - Using DVS0 register setting to adjust vout
       true - Using DVS1 register setting to adjust vout
 
+      The property is now deprecated. Will be identified by RG HW register.
+
   regulators:
     type: object
     additionalProperties: false
@@ -100,7 +103,6 @@ examples:
         compatible = "richtek,rtq2208";
         reg = <0x10>;
         interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;
-        richtek,mtp-sel-high;
 
         regulators {
           buck-a {
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 2/2] regualtor: rtq2208: Initiate the default MTP_SEL state by hardware register
From: cy_huang @ 2026-06-26  3:38 UTC (permalink / raw)
  To: Mark Brown, Krzysztof Kozlowski
  Cc: Rob Herring, Conor Dooley, Liam Girdwood, ChiYuan Huang,
	Yoon Dong Min, edward_kim, devicetree, linux-kernel
In-Reply-To: <cover.1782444299.git.cy_huang@richtek.com>

From: ChiYuan Huang <cy_huang@richtek.com>

Read the initial MTP_SEL state by hardware register to prevent the wrong
specified property value from the conflict of hardware pin assignment.

Signed-off-by: ChiYuan Huang <cy_huang@richtek.com>
---
 drivers/regulator/rtq2208-regulator.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/regulator/rtq2208-regulator.c b/drivers/regulator/rtq2208-regulator.c
index f669a562f036..7fe082def494 100644
--- a/drivers/regulator/rtq2208-regulator.c
+++ b/drivers/regulator/rtq2208-regulator.c
@@ -12,6 +12,7 @@
 #include <linux/mod_devicetable.h>
 
 /* Register */
+#define RTQ2208_REG_FSOUTB_CNTL			0x11
 #define RTQ2208_REG_GLOBAL_INT1			0x12
 #define RTQ2208_REG_FLT_RECORDBUCK_CB		0x18
 #define RTQ2208_REG_GLOBAL_INT1_MASK		0x1D
@@ -34,6 +35,7 @@
 #define RTQ2208_REG_HIDDEN1			0xFF
 
 /* Mask */
+#define RTQ2208_MTP_SEL_RO_MASK			BIT(7)
 #define RTQ2208_BUCK_NR_MTP_SEL_MASK		GENMASK(7, 0)
 #define RTQ2208_BUCK_EN_NR_MTP_SEL0_MASK	BIT(0)
 #define RTQ2208_BUCK_EN_NR_MTP_SEL1_MASK	BIT(1)
@@ -465,10 +467,13 @@ static int rtq2208_parse_regulator_dt_data(int n_regulator, const unsigned int *
 		struct rtq2208_regulator_desc *rdesc[RTQ2208_LDO_MAX], struct device *dev,
 		unsigned int ldo1_fixed, unsigned int ldo2_fixed)
 {
+	struct regmap *regmap = dev_get_regmap(dev, NULL);
 	int mtp_sel, i, idx;
 
 	/* get mtp_sel0 or mtp_sel1 */
-	mtp_sel = device_property_read_bool(dev, "richtek,mtp-sel-high");
+	mtp_sel = regmap_test_bits(regmap, RTQ2208_REG_FSOUTB_CNTL, RTQ2208_MTP_SEL_RO_MASK);
+	if (mtp_sel < 0)
+		return dev_err_probe(dev, mtp_sel, "Failed to init mtp_sel state\n");
 
 	for (i = 0; i < n_regulator; i++) {
 		idx = regulator_idx_table[i];
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH 1/2] dt-bindings: arm: tegra: Add lenovo,thinkedge-se70 compatible string
From: sashiko-bot @ 2026-06-26  3:43 UTC (permalink / raw)
  To: Jiqi Li; +Cc: conor+dt, devicetree, robh
In-Reply-To: <20260626033418.520762-2-lijq9@lenovo.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The compatible string array for the Lenovo ThinkEdge SE70 omits the underlying Xavier NX SOM compatible string.
--

commit bdfb0a0b8f7c5312dd01ccd7b35c0e589b16d8f5
Author: Jiqi Li <lijq9@lenovo.com>

dt-bindings: arm: tegra: Add lenovo,thinkedge-se70 compatible string

This commit adds the compatible string for the Lenovo ThinkEdge SE70 carrier
board, which is based on the NVIDIA Tegra194 (Xavier NX) SOM, to the ARM
Tegra device tree bindings schema.

> diff --git a/Documentation/devicetree/bindings/arm/tegra.yaml b/Documentation/devicetree/bindings/arm/tegra.yaml
> index 033a63f6c0687..960c604ef9a3a 100644
> --- a/Documentation/devicetree/bindings/arm/tegra.yaml
> +++ b/Documentation/devicetree/bindings/arm/tegra.yaml
> @@ -268,6 +268,10 @@ properties:
>          items:
>            - const: nvidia,p3509-0000+p3668-0001
>            - const: nvidia,tegra194
> +      - description: Lenovo ThinkEdge SE70
> +        items:
> +          - const: lenovo,thinkedge-se70
> +          - const: nvidia,tegra194

[Severity: Low]
Since the Lenovo ThinkEdge SE70 is a carrier board based on the NVIDIA
Tegra194 (Xavier NX) SOM, should this items list also require the underlying
SOM compatible string (nvidia,p3668-0001)?

Restricting the array to exactly two elements here implies the corresponding
device tree will omit the SOM fallback string. Omitting the intermediate SOM
string prevents the OS from natively identifying the underlying module and
could cause drivers or quirks targeting the Xavier NX SOM to fail to match
on this board.

>        - items:
>            - const: nvidia,tegra234-vdk
>            - const: nvidia,tegra234

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260626033418.520762-1-lijq9@lenovo.com?part=1

^ permalink raw reply

* Re: [PATCH v2 1/2] regulator: dt-bindings: rtq2208: Label mtp-sel-high property as deprecated
From: sashiko-bot @ 2026-06-26  3:46 UTC (permalink / raw)
  To: cy_huang; +Cc: devicetree, robh, conor+dt
In-Reply-To: <594ebe167b33ca885c040984624e4b5d1382c0e2.1782444299.git.cy_huang@richtek.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Missing block scalar indicator (`|`) in the `description` property causes a fatal YAML parsing error.
--

commit 5c227b25d25e534f0fd83cfc25a3a064d6084614
Author: ChiYuan Huang <cy_huang@richtek.com>

regulator: dt-bindings: rtq2208: Label mtp-sel-high property as deprecated

This commit marks the richtek,mtp-sel-high property as deprecated in the
rtq2208 device tree binding schema. It adds the deprecated flag and updates
the description to indicate that the property can now be identified by a
hardware register.

> diff --git a/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml b/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml
> --- a/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml
> +++ b/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml
> @@ -42,11 +42,14 @@ properties:
>  
>    richtek,mtp-sel-high:
>      type: boolean
> +    deprecated: true
>      description:
>        vout register selection based on this boolean value.
>        false - Using DVS0 register setting to adjust vout
>        true - Using DVS1 register setting to adjust vout
>  
> +      The property is now deprecated. Will be identified by RG HW register.

[Severity: Low]
Does the addition of this blank line break the YAML syntax?

Because the description field lacks a block scalar indicator (| or >), it is
parsed as a plain scalar. Plain scalars cannot contain blank lines, which
causes a parsing error during make dt_binding_check. Adding a block scalar
indicator to the description field would resolve the issue.

> +
>    regulators:
>      type: object
>      additionalProperties: false

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1782444299.git.cy_huang@richtek.com?part=1

^ permalink raw reply

* Re: [PATCH 2/2] arm64: tegra: Add Lenovo ThinkEdge SE70 carrier board DTS
From: sashiko-bot @ 2026-06-26  3:47 UTC (permalink / raw)
  To: Jiqi Li; +Cc: conor+dt, robh, devicetree
In-Reply-To: <20260626033418.520762-3-lijq9@lenovo.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] Pin configurations are instantiated as standalone dummy nodes instead of subnodes of the pinctrl controllers.
- [High] SD card controller override fails due to a node name mismatch (`sdhci` vs `mmc`).
- [High] The pwm-fan status override fails because it is incorrectly nested under bus@0.
- [Medium] Device tree contains dead overrides for non-existent downstream nodes.
- [Medium] The fixed-regulators node incorrectly uses simple-bus with `#address-cells = <1>` for a sizeless child.
--

commit 124a29c4818b88a33b77f6bc336c64c7bd9a06ec
Author: Jiqi Li <lijq9@lenovo.com>

arm64: tegra: Add Lenovo ThinkEdge SE70 carrier board DTS

ThinkEdge SE70 is a fanless industrial edge gateway built around
NVIDIA Tegra194 Xavier NX SOM. This patch adds a standalone device
tree file describing core carrier board peripherals.

> diff --git a/arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts b/arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts
> new file mode 100644
> index 0000000000000..d44eb7c9b4742
> --- /dev/null
> +++ b/arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts

[ ... ]

> +	/* Fixed 3.3V regulator for external SD card slot */
> +	fixed-regulators {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		ap2306gn_3v3_sd: ap2306gn-3v3-sd {

[Severity: Medium]
The fixed-regulators node is marked as compatible = "simple-bus" and sets
#address-cells = <1>, but its child ap2306gn-3v3-sd does not have a unit
address or a reg property.

Since the simple-bus binding requires children to have a reg or ranges
property, will this cause dtbs_check validation to fail?

[ ... ]

> +	bus@0 {
> +
> +		/* Custom pinmux configurations for 40-pin expansion header */
> +		pinmux@c302000 {
> +			status = "okay";
> +			touch-clk-pcc4 {
> +				nvidia,pins = "touch_clk_pcc4";
> +				nvidia,function = "rsvd2";
> +				nvidia,pull = <TEGRA_PIN_PULL_UP>;
> +				nvidia,tristate = <TEGRA_PIN_ENABLE>;
> +				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
> +			};
> +		};
> +
> +		pinmux@2430028 {
> +			status = "okay";
> +			soc-gpio41-pq5 {

[Severity: High]
Is it intended to create standalone nodes at the exact register offsets of
the individual pins (pinmux@c302000 and pinmux@2430028), instead of placing
them as subnodes under the main pinctrl controllers (which reside at
pinmux@c300000 and pinmux@2430000 in tegra194.dtsi)?

Because they are standalone nodes and lack a pinctrl-0 reference, the pinctrl
driver won't parse them, which will cause these pinmux configurations to be
ignored.

[ ... ]

> +		/* SDMMC3 for external user SD card slot with dedicated 3.3V power */
> +		sdhci@3440000 {
> +			vmmc-supply = <&ap2306gn_3v3_sd>;
> +			cd-gpios = <&gpio_aon TEGRA194_AON_GPIO(CC, 4) GPIO_ACTIVE_HIGH>;
> +			status = "okay";
> +		};

[Severity: High]
In the upstream tegra194.dtsi, the SDMMC3 controller is defined as
mmc@3440000.

Does using sdhci@3440000 here create a new, inert dummy node instead of
overriding the existing mmc@3440000 node? This would leave the actual
controller in its default disabled state.

> +
> +		/* Disable fan and tachometer hardware not populated on SE70 carrier board */
> +		pwm-fan {
> +			status = "disabled";
> +		};

[Severity: High]
In tegra194-p3509-0000.dtsi, the pwm-fan node is located at the root of the
device tree (/pwm-fan).

Since this override is nested inside /bus@0/, doesn't this create a new dummy
node at /bus@0/pwm-fan while leaving the actual root /pwm-fan node enabled?

> +		thermal-fan-est {
> +			status = "disabled";
> +		};
> +		tachometer@39c0000 {
> +			status = "disabled";
> +		};

[Severity: Medium]
It looks like nodes such as thermal-fan-est, tachometer@39c0000,
generic-pwm-tachometer, spi@3210000, and spi@3230000 do not exist in the
upstream tegra194 device tree sources.

Does overriding them here just create new dummy disabled nodes instead of
affecting real hardware?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260626033418.520762-1-lijq9@lenovo.com?part=2

^ permalink raw reply

* Re: [PATCH v6 5/8] clk: qcom: tcsrcc-glymur: Add Mahua QREF regulator support
From: Qiang Yu @ 2026-06-26  3:53 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Bjorn Andersson, Michael Turquette, Stephen Boyd, Brian Masney,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Taniya Das,
	Konrad Dybcio, linux-arm-msm, linux-clk, devicetree, linux-kernel,
	krishna.chundru
In-Reply-To: <cd7619b6-a428-4ad3-9926-52b846953634@oss.qualcomm.com>

On Mon, Jun 22, 2026 at 03:03:39PM +0200, Konrad Dybcio wrote:
> On 6/22/26 2:49 PM, Qiang Yu wrote:
> > On Mon, Jun 22, 2026 at 01:35:45PM +0200, Konrad Dybcio wrote:
> >> On 6/22/26 7:11 AM, Qiang Yu wrote:
> >>> Mahua is based on Glymur but uses a different QREF topology, requiring
> >>> distinct regulator lists and clock descriptors for its PCIe clock
> >>> references.
> >>>
> >>> Add mahua-specific regulator arrays and clk descriptor table, and use
> >>> match_data to select the correct descriptor table per compatible string at
> >>> probe time.
> >>>
> >>> Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
> >>> ---
> 
> [...]
> 
> >> You're also missing PCIe_1_CLKREF_EN (+0x48) (for PCIe5)
> >> which goes through CXO1_>TX->RPT0->RPT1->RPT2->RX2
> > 
> > I have removed PCIe_1_CLKREF_EN in dts node because PCIe5 PHY doesn't
> > require QREF. So I didn't provide its structure here.
> 
> I don't quite get what you mean. I see that it is there in the graph

I double-checked with the HW team — QREF is not required for CXO0. In TCSR
HPG, I think the QREF components you are seeing are in an old version
diagram, but it says the QREF for CXO0 will be removed. In the updated
diagram, PCIe5, USB2_0, USB2_1, USB4_0 and USB4_1 PHYs get refclk directly
from CXO0.

In theory, we don't need to vote clkref_en and QREF LDOs for these PHY
instances, and I got confirmation from the PCIe HW team for PCIe5 PHY.

I also compared the description of the TCSR_CLKREF_EN register between
glymur and mahua on ipcatlog. Unfortunately, only
TCSR_USB4_1_CLKREF_EN_USB4_ENABLE is marked as "not in use". I believe
this is because these registers are not documented well in ipcatlog.

So I think part of the regulator lists you commented for USB instances is
not required, and their dts node also can to be changed to use CXO as
refclk instead of TCSR_CLKREF_EN. But the mapping between the USB instance
names in the QREF diagram and the TCSR_CLKREF_EN registers is not clear —
I cannot find TCSR_USB4_0_CLKREF_EN_USB4_ENABLE, but there is a USB4_0 PHY
in the diagram. Can we leave the USB regulator list as NULL or we just
add them as it is harmless?

- Qaing Yu


^ permalink raw reply

* Re: [PATCH] arm64: dts: qcom: eliza: Add PCIe PHY and controller nodes
From: Krishna Chaitanya Chundru @ 2026-06-26  4:16 UTC (permalink / raw)
  To: Abel Vesa
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <rnwgxeuz6t6cpbcrmcggqtzsfjnur6kmkttgymp6cbglzjva5v@q4cyoq62p3yp>



On 6/25/2026 3:42 PM, Abel Vesa wrote:
> On 26-06-10 17:40:09, Krishna Chaitanya Chundru wrote:
>> Eliza supports two PCIe instances: one 8GT/s x1 (PCIe0) and one 8GT/s x2
>> (PCIe1). Add PCIe controller and PHY nodes for both instances, and update
>> the GCC clock references to use the newly added PHY nodes instead of
>> placeholder zeros.
>>
>> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
>> ---
>> This patch depends on https://lore.kernel.org/all/20260608-eliza-v3-0-9bdeb7434b28@oss.qualcomm.com/
>> ---
>>  arch/arm64/boot/dts/qcom/eliza.dtsi | 359 +++++++++++++++++++++++++++++++++++-
>>  1 file changed, 357 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/eliza.dtsi b/arch/arm64/boot/dts/qcom/eliza.dtsi
>> index 7e97361a5dc5..2a51da62270d 100644
>> --- a/arch/arm64/boot/dts/qcom/eliza.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/eliza.dtsi
>> @@ -610,8 +610,8 @@ gcc: clock-controller@100000 {
>>  
>>  			clocks = <&bi_tcxo_div2>,
>>  				 <&sleep_clk>,
>> -				 <0>,
>> -				 <0>,
>> +				 <&pcie0_phy>,
>> +				 <&pcie1_phy>,
>>  				 <&ufs_mem_phy 0>,
>>  				 <&ufs_mem_phy 1>,
>>  				 <&ufs_mem_phy 2>,
>> @@ -716,6 +716,361 @@ mmss_noc: interconnect@1780000 {
>>  			#interconnect-cells = <2>;
>>  		};
>>  
>> +		pcie0: pcie@1c00000 {
>> +			device_type = "pci";
>> +			compatible = "qcom,eliza-pcie", "qcom,pcie-sm8550";
>> +			reg = <0 0x01c00000 0 0x3000>,
>> +			      <0 0x40000000 0 0xf1d>,
>> +			      <0 0x40000f20 0 0xa8>,
>> +			      <0 0x40001000 0 0x1000>,
>> +			      <0 0x40100000 0 0x100000>,
>> +			      <0 0x01c03000 0 0x1000>;
>> +			reg-names = "parf",
>> +				    "dbi",
>> +				    "elbi",
>> +				    "atu",
>> +				    "config",
>> +				    "mhi";
>> +			#address-cells = <3>;
>> +			#size-cells = <2>;
>> +			ranges = <0x01000000 0 0x00000000 0 0x40200000 0 0x100000>,
>> +				 <0x02000000 0 0x40300000 0 0x40300000 0 0x3d00000>;
>> +
>> +			interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 537 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 540 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 653 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
>> +			interrupt-names = "msi0",
>> +					  "msi1",
>> +					  "msi2",
>> +					  "msi3",
>> +					  "msi4",
>> +					  "msi5",
>> +					  "msi6",
>> +					  "msi7",
>> +					  "global";
>> +
>> +			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
>> +				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
>> +				 <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
>> +				 <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
>> +				 <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>,
>> +				 <&gcc GCC_DDRSS_PCIE_SF_QTB_CLK>,
>> +				 <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>,
>> +				 <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>;
>> +			clock-names = "aux",
>> +				      "cfg",
>> +				      "bus_master",
>> +				      "bus_slave",
>> +				      "slave_q2a",
>> +				      "ddrss_sf_tbu",
>> +				      "noc_aggr",
>> +				      "cnoc_sf_axi";
>> +
>> +			resets = <&gcc GCC_PCIE_0_BCR>,
>> +				 <&gcc GCC_PCIE_0_LINK_DOWN_BCR>;
>> +			reset-names = "pci",
>> +				      "link_down";
>> +
>> +			interconnects = <&pcie_noc MASTER_PCIE_0 QCOM_ICC_TAG_ALWAYS
>> +					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
>> +					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
>> +					 &cnoc_main SLAVE_PCIE_0 QCOM_ICC_TAG_ACTIVE_ONLY>;
>> +			interconnect-names = "pcie-mem",
>> +					     "cpu-pcie";
>> +
>> +			power-domains = <&gcc GCC_PCIE_0_GDSC>;
>> +
>> +			operating-points-v2 = <&pcie0_opp_table>;
>> +
>> +			iommu-map = <0 &apps_smmu 0x1480 0x1>,
>> +				    <0x100 &apps_smmu 0x1481 0x1>;
>> +
>> +			interrupt-map = <0 0 0 1 &intc 0 0 0 564 IRQ_TYPE_LEVEL_HIGH>,
>> +					<0 0 0 2 &intc 0 0 0 565 IRQ_TYPE_LEVEL_HIGH>,
>> +					<0 0 0 3 &intc 0 0 0 566 IRQ_TYPE_LEVEL_HIGH>,
>> +					<0 0 0 4 &intc 0 0 0 567 IRQ_TYPE_LEVEL_HIGH>;
>> +			interrupt-map-mask = <0 0 0 0x7>;
>> +			#interrupt-cells = <1>;
>> +
>> +			linux,pci-domain = <0>;
>> +			num-lanes = <1>;
>> +			bus-range = <0 0xff>;
>> +
>> +			dma-coherent;
>> +
> No pinctrl states?
>
>> +
>> +		pcie1: pcie@1c08000 {
>> +			device_type = "pci";
>> +			compatible = "qcom,eliza-pcie", "qcom,pcie-sm8550";
>> +			reg = <0 0x01c08000 0 0x3000>,
>> +			      <0 0x44000000 0 0xf1d>,
>> +			      <0 0x44000f20 0 0xa8>,
>> +			      <0 0x44001000 0 0x1000>,
>> +			      <0 0x44100000 0 0x100000>,
>> +			      <0 0x01c0b000 0 0x1000>;
>> +			reg-names = "parf",
>> +				    "dbi",
>> +				    "elbi",
>> +				    "atu",
>> +				    "config",
>> +				    "mhi";
>> +			#address-cells = <3>;
>> +			#size-cells = <2>;
>> +			ranges = <0x01000000 0 0x00000000 0 0x44200000 0 0x100000>,
>> +				 <0x02000000 0 0x44300000 0 0x44300000 0 0x3d00000>;
>> +
>> +			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
>> +			interrupt-names = "msi0",
>> +					  "msi1",
>> +					  "msi2",
>> +					  "msi3",
>> +					  "msi4",
>> +					  "msi5",
>> +					  "msi6",
>> +					  "msi7",
>> +					  "global";
>> +
>> +			clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
>> +				 <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
>> +				 <&gcc GCC_PCIE_1_MSTR_AXI_CLK>,
>> +				 <&gcc GCC_PCIE_1_SLV_AXI_CLK>,
>> +				 <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>,
>> +				 <&gcc GCC_DDRSS_PCIE_SF_QTB_CLK>,
>> +				 <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>,
>> +				 <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>;
>> +			clock-names = "aux",
>> +				      "cfg",
>> +				      "bus_master",
>> +				      "bus_slave",
>> +				      "slave_q2a",
>> +				      "ddrss_sf_tbu",
>> +				      "noc_aggr",
>> +				      "cnoc_sf_axi";
>> +
>> +			resets = <&gcc GCC_PCIE_1_BCR>,
>> +				 <&gcc GCC_PCIE_1_LINK_DOWN_BCR>;
>> +			reset-names = "pci",
>> +				      "link_down";
>> +
>> +			interconnects = <&pcie_noc MASTER_PCIE_1 QCOM_ICC_TAG_ALWAYS
>> +					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
>> +					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
>> +					 &cnoc_main SLAVE_PCIE_1 QCOM_ICC_TAG_ACTIVE_ONLY>;
>> +			interconnect-names = "pcie-mem",
>> +					     "cpu-pcie";
>> +
>> +			power-domains = <&gcc GCC_PCIE_1_GDSC>;
>> +
>> +			operating-points-v2 = <&pcie1_opp_table>;
>> +
>> +			iommu-map = <0 &apps_smmu 0x1400 0x1>,
>> +				    <0x100 &apps_smmu 0x1401 0x1>;
>> +
>> +			interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>,
>> +					<0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>,
>> +					<0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>,
>> +					<0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>;
>> +			interrupt-map-mask = <0 0 0 0x7>;
>> +			#interrupt-cells = <1>;
>> +
>> +			linux,pci-domain = <1>;
>> +			num-lanes = <2>;
>> +			bus-range = <0 0xff>;
>> +
>> +			dma-coherent;
> No pinctrl states?
As we are adding perst & wake gpio's in board specific file, it is better to
add the pincntrl also
there only.

- Krishna Chaitanya.

^ permalink raw reply

* [RFC PATCH 0/2] Add Lenovo ThinkEdge SE70 carrier board support
From: Jiqi Li @ 2026-06-26  1:09 UTC (permalink / raw)
  To: linux-tegra
  Cc: devicetree, robh+dt, krzk+dt, conor+dt, jonathanh, thierry.reding,
	mpearson-lenovo, Jiqi Li

This series adds device tree bindings and standalone DTS for the Lenovo
ThinkEdge SE70 fanless industrial edge gateway based on NVIDIA Tegra194
Xavier NX SOM.

Patch 1 adds the board compatible string to tegra.yaml for dt-schema
validation.
Patch 2 introduces the carrier board DTS with 40-pin header pinmux and
external SD card power regulator, disables unused fan/PWM/spi peripherals.

Static verification passed: dt_binding_check and dtbs compilation
complete without errors.

We maintain downstream DTS for mass-deployed SE70 hardware internally.
Upstreaming aligns with existing OEM board contributions (Google/Xiaomi)
in the Tegra tree, cuts long-term out-of-tree patch maintenance overhead.
This industrial platform has a full 7-year support lifecycle until 2028;
Lenovo will keep backporting DT fixes throughout its service window.
All peripherals use generic upstream drivers with no proprietary extensions.

Jiqi Li (2):
  dt-bindings: arm: tegra: Add lenovo,thinkedge-se70 compatible string
  arm64: tegra: Add Lenovo ThinkEdge SE70 carrier board DTS

 .../devicetree/bindings/arm/tegra.yaml        |   4 +
 arch/arm64/boot/dts/nvidia/Makefile           |   1 +
 .../nvidia/tegra194-lenovo-thinkedge-se70.dts | 167 ++++++++++++++++++
 3 files changed, 172 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts

-- 
2.43.0


^ permalink raw reply

* [PATCH 1/2] dt-bindings: net: altr,socfpga-stmmac: add more interrupts for Agilex5
From: Dinh Nguyen @ 2026-06-26  4:25 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt
  Cc: dinguyen, devicetree, muhammad.nazim.amirul.nazle.asmade

The stmmac hardware on Agilex5 supports 8 TX/RX queue pairs and is
dma-coherent. Update the schema to handle the hardware differences
between SoC variants.

Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
---
 .../bindings/net/altr,socfpga-stmmac.yaml     | 51 +++++++++++++++++--
 1 file changed, 46 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml b/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
index fc445ad5a1f1..9bae17688992 100644
--- a/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
+++ b/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
@@ -62,12 +62,28 @@ properties:
       - const: stmmaceth
       - const: ptp_ref
 
-  interrupts:
-    maxItems: 1
-
   interrupt-names:
-    items:
-      - const: macirq
+    oneOf:
+      - items:
+          - const: macirq
+      - items:
+          - const: macirq
+          - const: tx-queue-0
+          - const: tx-queue-1
+          - const: tx-queue-2
+          - const: tx-queue-3
+          - const: tx-queue-4
+          - const: tx-queue-5
+          - const: tx-queue-6
+          - const: tx-queue-7
+          - const: rx-queue-0
+          - const: rx-queue-1
+          - const: rx-queue-2
+          - const: rx-queue-3
+          - const: rx-queue-4
+          - const: rx-queue-5
+          - const: rx-queue-6
+          - const: rx-queue-7
 
   iommus:
     minItems: 1
@@ -149,10 +165,35 @@ required:
   - clocks
   - clock-names
   - altr,sysmgr-syscon
+  - interrupts
+  - interrupt-names
 
 allOf:
   - $ref: snps,dwmac.yaml#
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: altr,socfpga-stmmac-agilex5
+    then:
+      properties:
+        interrupts:
+          minItems: 17
+          maxItems: 17
+
+        interrupt-names:
+          minItems: 17
+          maxItems: 17
+
+        dma-coherent: true
+    else:
+      properties:
+        interrupts:
+          minItems: 1
+
+        dma-coherent: false
+
 unevaluatedProperties: false
 
 examples:
-- 
2.42.0.411.g813d9a9188


^ permalink raw reply related

* [PATCH 2/2] arm64: dts: socfpga: agilex5: update channel interrupts for gmac1 and gmac2
From: Dinh Nguyen @ 2026-06-26  4:25 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt
  Cc: dinguyen, devicetree, muhammad.nazim.amirul.nazle.asmade
In-Reply-To: <20260626042541.1091774-1-dinguyen@kernel.org>

Populate the gmac1 and gmac2 interrupt list to support 8 TX/RX queue
pairs.

Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
---
 .../arm64/boot/dts/intel/socfpga_agilex5.dtsi | 72 +++++++++++++++++--
 1 file changed, 68 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi b/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
index 2096decb5655..f54767d1526e 100644
--- a/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
@@ -702,8 +702,40 @@ gmac1: ethernet@10820000 {
 			compatible = "altr,socfpga-stmmac-agilex5",
 				     "snps,dwxgmac-2.10";
 			reg = <0x10820000 0x3500>;
-			interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "macirq";
+			interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq",
+					  "tx-queue-0",
+					  "tx-queue-1",
+					  "tx-queue-2",
+					  "tx-queue-3",
+					  "tx-queue-4",
+					  "tx-queue-5",
+					  "tx-queue-6",
+					  "tx-queue-7",
+					  "rx-queue-0",
+					  "rx-queue-1",
+					  "rx-queue-2",
+					  "rx-queue-3",
+					  "rx-queue-4",
+					  "rx-queue-5",
+					  "rx-queue-6",
+					  "rx-queue-7";
 			resets = <&rst EMAC1_RESET>, <&rst EMAC1_OCP_RESET>;
 			reset-names = "stmmaceth", "ahb";
 			clocks = <&clkmgr AGILEX5_EMAC1_CLK>,
@@ -816,8 +848,40 @@ gmac2: ethernet@10830000 {
 			compatible = "altr,socfpga-stmmac-agilex5",
 				     "snps,dwxgmac-2.10";
 			reg = <0x10830000 0x3500>;
-			interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "macirq";
+			interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq",
+					  "tx-queue-0",
+					  "tx-queue-1",
+					  "tx-queue-2",
+					  "tx-queue-3",
+					  "tx-queue-4",
+					  "tx-queue-5",
+					  "tx-queue-6",
+					  "tx-queue-7",
+					  "rx-queue-0",
+					  "rx-queue-1",
+					  "rx-queue-2",
+					  "rx-queue-3",
+					  "rx-queue-4",
+					  "rx-queue-5",
+					  "rx-queue-6",
+					  "rx-queue-7";
 			resets = <&rst EMAC2_RESET>, <&rst EMAC2_OCP_RESET>;
 			reset-names = "stmmaceth", "ahb";
 			clocks = <&clkmgr AGILEX5_EMAC2_CLK>,
-- 
2.42.0.411.g813d9a9188


^ permalink raw reply related

* Re: [PATCH 1/2] dt-bindings: net: altr,socfpga-stmmac: add more interrupts for Agilex5
From: sashiko-bot @ 2026-06-26  4:31 UTC (permalink / raw)
  To: Dinh Nguyen; +Cc: conor+dt, devicetree, robh
In-Reply-To: <20260626042541.1091774-1-dinguyen@kernel.org>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Removing the top-level constraints for `interrupts` and `interrupt-names` without restoring them in the `else` block allows older variants to incorrectly pass schema validation with up to 17 interrupts.
--

commit b9bb703e842480b5efde889d362af4d3e53520cb
Author: Dinh Nguyen <dinguyen@kernel.org>

dt-bindings: net: altr,socfpga-stmmac: add more interrupts for Agilex5

The stmmac hardware on Agilex5 supports 8 TX/RX queue pairs and is
dma-coherent. This commit updates the schema to handle the hardware
differences between SoC variants.

> diff --git a/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml b/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
> index fc445ad5a1f1a..9bae17688992c 100644
> --- a/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
> +++ b/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
[ ... ]
> @@ -62,12 +62,28 @@ properties:
>        - const: stmmaceth
>        - const: ptp_ref
>  
> -  interrupts:
> -    maxItems: 1
> -
>    interrupt-names:
[ ... ]
> @@ -149,10 +165,35 @@ required:
[ ... ]
>  allOf:
>    - $ref: snps,dwmac.yaml#
>  
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: altr,socfpga-stmmac-agilex5
> +    then:
> +      properties:
> +        interrupts:
> +          minItems: 17
> +          maxItems: 17
> +
> +        interrupt-names:
> +          minItems: 17
> +          maxItems: 17
> +
> +        dma-coherent: true
> +    else:
> +      properties:
> +        interrupts:
> +          minItems: 1

[Severity: Medium]
Does this missing maxItems constraint allow older variants to incorrectly pass
schema validation with up to 17 interrupts?

Since the top-level maxItems: 1 constraint was removed for interrupts, this
else block applies to all non-Agilex5 variants but only enforces minItems: 1.
Because there are no top-level restrictions stopping it, device trees for
older variants (e.g., altr,socfpga-stmmac-a10-s10) could specify multiple
interrupts and matching interrupt-names without triggering a schema validation
error.

Should maxItems: 1 for interrupts and a matching constraint for
interrupt-names be added to this else block to enforce the original strict
hardware constraints for prior generations?

> +
> +        dma-coherent: false
> +
>  unevaluatedProperties: false

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260626042541.1091774-1-dinguyen@kernel.org?part=1

^ permalink raw reply

* Re: [PATCH 2/2] arm64: dts: socfpga: agilex5: update channel interrupts for gmac1 and gmac2
From: sashiko-bot @ 2026-06-26  4:31 UTC (permalink / raw)
  To: Dinh Nguyen; +Cc: devicetree, robh, conor+dt
In-Reply-To: <20260626042541.1091774-2-dinguyen@kernel.org>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Incomplete DT update: gmac0 is left with an invalid interrupt count that will fail dtbs validation.
--

commit ce31f4c657e3508e9aef68e6da54a09c1d243026
Author: Dinh Nguyen <dinguyen@kernel.org>

arm64: dts: socfpga: agilex5: update channel interrupts for gmac1 and gmac2

Populate the gmac1 and gmac2 interrupt list to support 8 TX/RX queue
pairs.

> diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi b/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
> index 02e62d954e949..140e4bf9fb155 100644
> --- a/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
> +++ b/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
> @@ -670,8 +670,40 @@ gmac1: ethernet@10820000 {
>  			compatible = "altr,socfpga-stmmac-agilex5",
>  				     "snps,dwxgmac-2.10";
>  			reg = <0x10820000 0x3500>;

[Severity: Medium]
Should gmac0 also be updated to include 17 interrupts?

Looking earlier in the same file, gmac0 uses the exact same
"altr,socfpga-stmmac-agilex5" compatible string, but this patch
leaves it configured with only a single interrupt:

arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi:
	gmac0: ethernet@10810000 {
		compatible = "altr,socfpga-stmmac-agilex5",
			     "snps,dwxgmac-2.10";
		reg = <0x10810000 0x3500>;
		interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
		interrupt-names = "macirq";
                ...
	}

Since the device tree binding strictly requires 17 interrupts for this
specific compatible string, won't skipping gmac0 result in dtbs_check
validation errors and leave its queues without dedicated interrupts at
runtime?

> -			interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
> -			interrupt-names = "macirq";
> +			interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260626042541.1091774-1-dinguyen@kernel.org?part=2

^ permalink raw reply

* Re: [PATCH v5 1/7] dt-bindings: display: verisilicon,dc: generalize for single-output variants
From: Icenowy Zheng @ 2026-06-26  5:27 UTC (permalink / raw)
  To: Conor Dooley, Joey Lu
  Cc: maarten.lankhorst, mripard, tzimmermann, airlied, simona, robh,
	krzk+dt, conor+dt, ychuang3, schung, yclu4, dri-devel, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20260625-bobbing-annotate-d1c4d6874ee2@spud>

在 2026-06-25四的 17:33 +0100,Conor Dooley写道:
> On Thu, Jun 25, 2026 at 05:44:43PM +0800, Joey Lu wrote:
> > The verisilicon,dc binding was originally written for the T-Head
> > TH1520
> > SoC carrying a DC8200, and hard-codes five clocks, three resets and
> > two
> > output ports.
> > 
> > Add the Nuvoton MA35D1 DCUltraLite (nuvoton,ma35d1-dcu) to the
> > binding.
> > The DCUltraLite uses only two clocks (core, pix0) and one reset
> > (core),
> > with a single output port.
> > 
> > Use allOf/if blocks to express per-variant constraints rather than
> > hard-coding the DC8200 topology at the top level.  Each
> > compatible's
> > block constrains the clock and reset item counts; the nuvoton block
> > additionally overrides clock-names to the two names it actually
> > uses.
> > 
> > Signed-off-by: Joey Lu <a0987203069@gmail.com>
> > ---
> >  .../bindings/display/verisilicon,dc.yaml      | 57
> > +++++++++++++++++++
> >  1 file changed, 57 insertions(+)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> > b/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> > index 9dc35ab973f2..1e751f3c7ce8 100644
> > --- a/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> > +++ b/Documentation/devicetree/bindings/display/verisilicon,dc.yaml
> > @@ -17,6 +17,7 @@ properties:
> >      items:
> >        - enum:
> >            - thead,th1520-dc8200
> > +          - nuvoton,ma35d1-dcu
> >        - const: verisilicon,dc # DC IPs have discoverable
> > ID/revision registers
> >  
> >    reg:
> > @@ -77,6 +78,62 @@ required:
> >    - clock-names
> >    - ports
> >  
> > +allOf:
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: thead,th1520-dc8200
> > +    then:
> > +      properties:
> > +        clocks:
> > +          minItems: 5
> > +          maxItems: 5
> > +
> > +        clock-names:
> > +          minItems: 5
> > +          maxItems: 5
> 
> All the maxItems here repeat the maximum constraint and do nothing.
> 
> Since you didn't change the minimum constraint at the top level, your
> minItems also do nothing.
> 
> > +
> > +        resets:
> > +          minItems: 3
> > +          maxItems: 3
> > +
> > +        reset-names:
> > +          minItems: 3
> > +          maxItems: 3
> > +
> > +      required:
> > +        - resets
> > +        - reset-names
> 
> Both conditional sections have this, but the original binding doesn't
> require these for the thead device. This is a functional change
> therefore and shouldn't be in a patch calling itself "generalise for
> single ended variants".

Well yes they're required.

Should I send a patch adding the `thead,th1520-dc8200` part of the
schema?

> 
> FWIW, adding your new compatible shouldn't really be in a patch with
> that subject either, it really should say "add support for nuvoton
> ma35d1" or something.
> 
> > +
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: nuvoton,ma35d1-dcu
> > +    then:
> > +      properties:
> > +        clocks:
> > +          minItems: 2
> 
> Anything that updates the minimum constraint should be done at the
> top
> level of this schema. The conditional section should then tighten the
> constraint, in this case that means only having maxItems.
> 
> > +          maxItems: 2
> > +
> > +        clock-names:
> > +          items:
> > +            - const: core
> > +            - const: pix0
> 
> Does this even work when the top level schema thinks clock 2 should
> be
> called axi?
> 
> > +
> > +        resets:
> > +          minItems: 1
> > +          maxItems: 1
> > +
> > +        reset-names:
> > +          items:
> > +            - const: core
> 
> This is just maxItems: 1.

Well the implicit rules of DT binding schemas are quite weird...

Thanks,
Icenowy

> 
> pw-bot: changes-requested
> 
> Thanks,
> Conor.
> 
> > +
> > +      required:
> > +        - resets
> > +        - reset-names
> > +
> >  additionalProperties: false
> >  
> >  examples:
> > -- 
> > 2.43.0
> > 

^ permalink raw reply

* Re: [PATCH v2 1/2] dt-bindings: input: syna,rmi4: Document syna,rmi4-s3706b
From: Dmitry Torokhov @ 2026-06-26  5:37 UTC (permalink / raw)
  To: david
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jason A. Donenfeld, Matthias Schiffer, Vincent Huang,
	Bjorn Andersson, Konrad Dybcio, linux-input, devicetree,
	linux-kernel, linux-arm-msm, phone-devel, Krzysztof Kozlowski
In-Reply-To: <20260523-synaptics-rmi4-dt-v2-1-0645122babdc@ixit.cz>

On Sat, May 23, 2026 at 11:45:34AM +0200, David Heidelberg via B4 Relay wrote:
> From: David Heidelberg <david@ixit.cz>
> 
> Mostly irrelevant for authentic Synaptics touchscreens, but very important
> for applying workarounds to cheap TS knockoffs.
> 
> These knockoffs work well with the downstream driver, and since the user
> has no way to distinguish them, later in this patch set, we introduce
> workarounds to ensure they function as well as possible.
> 
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Signed-off-by: David Heidelberg <david@ixit.cz>

Applied, thank you.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v2 2/2] arm64: dts: qcom: sdm845-oneplus: Update compatible to include model
From: Dmitry Torokhov @ 2026-06-26  5:38 UTC (permalink / raw)
  To: David Heidelberg
  Cc: Krzysztof Kozlowski, Krzysztof Kozlowski, Konrad Dybcio,
	Rob Herring, Conor Dooley, Jason A. Donenfeld, Matthias Schiffer,
	Vincent Huang, Bjorn Andersson, Konrad Dybcio, linux-input,
	devicetree, linux-kernel, linux-arm-msm, phone-devel
In-Reply-To: <32affded-bae2-46c4-a702-2054fbfe46a8@ixit.cz>

On Thu, Jun 25, 2026 at 08:39:15PM +0200, David Heidelberg wrote:
> On 25/06/2026 18:57, Dmitry Torokhov wrote:
> > Hi Krzysztof,
> > 
> > On Thu, Jun 25, 2026 at 10:23:54AM +0200, Krzysztof Kozlowski wrote:
> > > On 25/06/2026 06:53, Dmitry Torokhov wrote:
> > > > On Wed, Jun 24, 2026 at 04:37:25PM +0200, David Heidelberg wrote:
> > > > > On 24/06/2026 06:28, Dmitry Torokhov wrote:
> > > > > > Hi David,
> > > > > > 
> > > > > > On Sun, Jun 21, 2026 at 07:11:45PM +0200, David Heidelberg wrote:
> > > > > > > On 28/05/2026 00:13, David Heidelberg wrote:
> > > > > > > > On 27/05/2026 23:56, Dmitry Torokhov wrote:
> > > > > > > > > Hi David,
> > > > > > > > > 
> > > > > > > > > On Sat, May 23, 2026 at 11:45:35AM +0200, David Heidelberg via B4 Relay wrote:
> > > > > > > > > > From: David Heidelberg <david@ixit.cz>
> > > > > > > > > > 
> > > > > > > > > > We know the driver is reporting s3706b, introduce the compatible so we
> > > > > > > > > > can more easily introduce quirks for weird touchscreen replacements in
> > > > > > > > > > followup series.
> > > > > > > > > > 
> > > > > > > > > > Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> > > > > > > > > > Signed-off-by: David Heidelberg <david@ixit.cz>
> > > > > > > > > > ---
> > > > > > > > > >     arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 2 +-
> > > > > > > > > >     1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > > > > > > 
> > > > > > > > > > diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
> > > > > > > > > > b/arch/ arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
> > > > > > > > > > index 6b7378cf4d493..148164d456a5a 100644
> > > > > > > > > > --- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
> > > > > > > > > > +++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
> > > > > > > > > > @@ -475,17 +475,17 @@ bq27441_fg: bq27441-battery@55 {
> > > > > > > > > >         };
> > > > > > > > > >     };
> > > > > > > > > >     &i2c12 {
> > > > > > > > > >         status = "okay";
> > > > > > > > > >         clock-frequency = <400000>;
> > > > > > > > > >         synaptics-rmi4-i2c@20 {
> > > > > > > > > > -        compatible = "syna,rmi4-i2c";
> > > > > > > > > > +        compatible = "syna,rmi4-s3706b", "syna,rmi4-i2c";
> > > > > > > > > 
> > > > > > > > > So I believe we established that this device (s3706b) does not in fact
> > > > > > > > > implement rmi4 protocol properly. Why do we have "syna,rmi4-i2c" as a
> > > > > > > > > fallback? Shouldn't it be just "syna,rmi4-s3706b"?
> > > > > > > > 
> > > > > > > > The vendor supplies s3706b which does implement the RMI4 properly.
> > > > > > > > 
> > > > > > > > The 3rd party replacement impersonating original parts may not implement
> > > > > > > > it properly, but I don't address this issue in this initial submission.
> > > > > > > > 
> > > > > > > > With this compatible we know which original part is used by the vendor
> > > > > > > > and installed in the phones, so later we can deduct specific sequences
> > > > > > > > for the replacement aftermarket parts to keep phone touchscreen working
> > > > > > > > same as they do on Android without affecting other devices.
> > > > > > > 
> > > > > > > Hello Dmitry.
> > > > > > > 
> > > > > > > May I ask what is currently preventing this series from moving forward?
> > > > > > > 
> > > > > > > The first version was posted in 2023 [1]. I picked it up again in 2025 [2]
> > > > > > > and am now on the 9th iteration (this patchset). At this point, the series
> > > > > > > has been under discussion for well over a year, with relatively little
> > > > > > > feedback and increasingly long gaps between review rounds.
> > > > > > > 
> > > > > > > The current approach is based on the guidance I have received so far,
> > > > > > > including suggestions from the device-tree maintainers. When concerns were
> > > > > > > raised, I tried to address them and rework the series accordingly.
> > > > > > > 
> > > > > > > What I am struggling with is understanding what specific issue still needs
> > > > > > > to be resolved before these patches can be accepted. If there are remaining
> > > > > > > requirements, objections to the approach, or technical concerns that I have
> > > > > > > not addressed, I would appreciate having them stated explicitly so I can
> > > > > > > work on them.
> > > > > > > 
> > > > > > > I also split out the straightforward, self-contained changes in the hope
> > > > > > > that at least those could progress independently while I continued working
> > > > > > > on any follow-up requirements. However, even those patches do not appear to
> > > > > > > be moving forward.
> > > > > > > 
> > > > > > > Could you please clarify what outcome you would like to see from this
> > > > > > > series, and what concrete changes would be required to get it accepted?
> > > > > > 
> > > > > > I am still confused about how you want to differentiate between the full
> > > > > > RMI4 support vs the OnePlus flavor. The "syna,rmi4-s3706b", as you
> > > > > > mentioned, implements RMI4 protocol properly, so we do not need to
> > > > > > actually have it documented neither in binding nor in DTS.
> > > > > 
> > > > > --- part 1 ---
> > > > > 
> > > > > This series addresses identification within device-tree. It's normal
> > > > > recommended practice.
> > > > > 
> > > > > If we know, the device ships specific, but **compliant** variant, we just
> > > > > put it as compatible = "more-specific", "less-specific"; in this case
> > > > > "syna,rmi4-s3706b", "syna,rmi4-i2c"
> > > > > 
> > > > > This approach is used everywhere. This has nothing to do with after-market parts.
> > > > 
> > > > We do this in many cases, sometimes when a part has different timings or
> > > > maybe additional functionality compared to the base model.
> > > 
> > > Generic expectation is to have always dedicated front compatible for
> > > every device. rmi4-i2c is not really specific enough, more like a
> > > family, thus a specific device compatible is essential by the DT rules.
> > 
> > Essential in what way? What will break if such compatible is not there?
> > We have lived without it for many years and will continue live happily
> > without it for years to come.
> 
> Hi Dmitry, Krzystof,
> 
> Device tree should describe the hardware, rmi4-i2c isn't the exact model of
> hardware used, the real hardware is Synaptics S3706B. Device-tree should,
> where possible, describe the actual hardware used.
> 
> > 
> > We keep having this conversation each time there is self-describing
> > protocol that does not require knowledge of a specific part number:
> > i2c-hid, rmi4, spi-hid coming over soon.
> 
> While the protocol doesn't require this knowledge, where is the issue
> provide the model, at least in the places where we know it?
> 
> Does it making things worse to describe hardware in more detail?

OK, I applied the binding change, the dts change should go through some
other tree.

Thanks.

-- 
Dmitry

^ permalink raw reply

* [PATCH v9 1/3] dt-bindings: dma: Add Amlogic A9 SoC DMA
From: Xianwei Zhao via B4 Relay @ 2026-06-26  5:39 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Kees Cook, Gustavo A. R. Silva, Frank Li
  Cc: linux-amlogic, dmaengine, devicetree, linux-kernel,
	linux-hardening, Xianwei Zhao, Krzysztof Kozlowski
In-Reply-To: <20260626-amlogic-dma-v9-0-558d672c4a95@amlogic.com>

From: Xianwei Zhao <xianwei.zhao@amlogic.com>

Add documentation describing the Amlogic A9 SoC DMA. And add
the properties specific values defines into a new include file.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
 .../devicetree/bindings/dma/amlogic,a9-dma.yaml    | 65 ++++++++++++++++++++++
 include/dt-bindings/dma/amlogic,a9-dma.h           |  8 +++
 2 files changed, 73 insertions(+)

diff --git a/Documentation/devicetree/bindings/dma/amlogic,a9-dma.yaml b/Documentation/devicetree/bindings/dma/amlogic,a9-dma.yaml
new file mode 100644
index 000000000000..efd7b2602c33
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/amlogic,a9-dma.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/amlogic,a9-dma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic general DMA controller
+
+description:
+  This is a general-purpose peripheral DMA controller. It currently supports
+  major peripherals including I2C, I3C, PIO, and CAN-BUS. Transmit and receive
+  for the same peripheral use two separate channels, controlled by different
+  register sets. I2C and I3C transfer data in 1-byte units, while PIO and
+  CAN-BUS transfer data in 4-byte units. From the controller’s perspective,
+  there is no significant difference.
+
+maintainers:
+  - Xianwei Zhao <xianwei.zhao@amlogic.com>
+
+properties:
+  compatible:
+    const: amlogic,a9-dma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: sys
+
+  '#dma-cells':
+    const: 2
+
+  dma-channels:
+    maximum: 64
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - '#dma-cells'
+  - dma-channels
+
+allOf:
+  - $ref: dma-controller.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    dma-controller@fe400000{
+        compatible = "amlogic,a9-dma";
+        reg = <0xfe400000 0x4000>;
+        interrupts = <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>;
+        clocks = <&clkc 45>;
+        #dma-cells = <2>;
+        dma-channels = <28>;
+    };
diff --git a/include/dt-bindings/dma/amlogic,a9-dma.h b/include/dt-bindings/dma/amlogic,a9-dma.h
new file mode 100644
index 000000000000..c59c2fd4b956
--- /dev/null
+++ b/include/dt-bindings/dma/amlogic,a9-dma.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+
+#ifndef __DT_BINDINGS_DMA_AMLOGIC_DMA_H__
+#define __DT_BINDINGS_DMA_AMLOGIC_DMA_H__
+
+#define DMA_TX			0
+#define DMA_RX			1
+#endif /* __DT_BINDINGS_DMA_AMLOGIC_DMA_H__ */

-- 
2.52.0



^ permalink raw reply related

* [PATCH v9 0/3] Add Amlogic general DMA
From: Xianwei Zhao via B4 Relay @ 2026-06-26  5:39 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Kees Cook, Gustavo A. R. Silva, Frank Li
  Cc: linux-amlogic, dmaengine, devicetree, linux-kernel,
	linux-hardening, Xianwei Zhao, Krzysztof Kozlowski, Frank Li

Add DMA driver and bindigns for the Amlogic SoCs.

Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
Changes in v9:
- Use each transmission request sg_link mem instead of the loop mem get.
- Fix some hidden issues which reviewed by ai robot.
- Link to v8: https://lore.kernel.org/r/20260521-amlogic-dma-v8-0-86cc2ce94142@amlogic.com

Changes in v8:
- Use kzalloc instead of kmalloc.
- Initialize the temporary variable and fix a spelling mistake.
- Link to v7: https://lore.kernel.org/r/20260324-amlogic-dma-v7-0-f8b91ee192c1@amlogic.com

Changes in v7:
- Take use vchan to support mltiple txns.
- Link to v6: https://lore.kernel.org/r/20260309-amlogic-dma-v6-0-63349d23bd4b@amlogic.com

Changes in v6:
- Some minor modifications according to Frank's suggestion.
- Link to v5: https://lore.kernel.org/r/20260304-amlogic-dma-v5-0-aa453d14fd43@amlogic.com

Changes in v5:
- Rename head file and rename macro definition.
- Rename the subject in [2/3] from "dma" to "dmaengine".
- Link to v4: https://lore.kernel.org/r/20260227-amlogic-dma-v4-0-f25e4614e9b7@amlogic.com

Changes in v4:
- Support split transfer when data len > MAX_LEN.
- When a module fails or exits, perform de-initialization.
- Some other minor modifications.
- Link to v3: https://lore.kernel.org/r/20260206-amlogic-dma-v3-0-56fb9f59ed22@amlogic.com

Changes in v3:
- Adjust the format of binding according to Frank's suggestion.
- Some code format modified according to Frank's suggestion.
- Support one prep_sg and one submit, drop multi prep_sg and one submit.
- Keep pre state when resume from pause status.
- Link to v2: https://lore.kernel.org/r/20260127-amlogic-dma-v2-0-4525d327d74d@amlogic.com

Changes in v2:
- Introduce what the DMA is used for in the A9 SoC.
- Some minor modifications were made according to Krzysztof's suggestions.
- Some modifications were made according to Neil's suggestions.
- Fix a build error.
- Link to v1: https://lore.kernel.org/r/20251216-amlogic-dma-v1-0-e289e57e96a7@amlogic.com

---
Xianwei Zhao (3):
      dt-bindings: dma: Add Amlogic A9 SoC DMA
      dmaengine: amlogic: Add general DMA driver for A9
      MAINTAINERS: Add an entry for Amlogic DMA driver

 .../devicetree/bindings/dma/amlogic,a9-dma.yaml    |  65 ++
 MAINTAINERS                                        |   7 +
 drivers/dma/Kconfig                                |  10 +
 drivers/dma/Makefile                               |   1 +
 drivers/dma/amlogic-dma.c                          | 708 +++++++++++++++++++++
 include/dt-bindings/dma/amlogic,a9-dma.h           |   8 +
 6 files changed, 799 insertions(+)
---
base-commit: 4e01d2f7809240ed63a44889386635921c0627b1
change-id: 20251215-amlogic-dma-79477d5cd264

Best regards,
-- 
Xianwei Zhao <xianwei.zhao@amlogic.com>



^ permalink raw reply

* [PATCH v9 3/3] MAINTAINERS: Add an entry for Amlogic DMA driver
From: Xianwei Zhao via B4 Relay @ 2026-06-26  5:39 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Kees Cook, Gustavo A. R. Silva, Frank Li
  Cc: linux-amlogic, dmaengine, devicetree, linux-kernel,
	linux-hardening, Xianwei Zhao
In-Reply-To: <20260626-amlogic-dma-v9-0-558d672c4a95@amlogic.com>

From: Xianwei Zhao <xianwei.zhao@amlogic.com>

Add Amlogic DMA controller entry to MAINTAINERS to clarify
the maintainers.

Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3e7b2d9e9c24..b4ef8d3f52cb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1307,6 +1307,13 @@ F:	Documentation/devicetree/bindings/perf/amlogic,g12-ddr-pmu.yaml
 F:	drivers/perf/amlogic/
 F:	include/soc/amlogic/
 
+AMLOGIC DMA DRIVER
+M:	Xianwei Zhao <xianwei.zhao@amlogic.com>
+L:	linux-amlogic@lists.infradead.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/dma/amlogic,a9-dma.yaml
+F:	drivers/dma/amlogic-dma.c
+
 AMLOGIC ISP DRIVER
 M:	Keke Li <keke.li@amlogic.com>
 L:	linux-media@vger.kernel.org

-- 
2.52.0



^ permalink raw reply related

* [PATCH v9 2/3] dmaengine: amlogic: Add general DMA driver for A9
From: Xianwei Zhao via B4 Relay @ 2026-06-26  5:39 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Kees Cook, Gustavo A. R. Silva, Frank Li
  Cc: linux-amlogic, dmaengine, devicetree, linux-kernel,
	linux-hardening, Xianwei Zhao, Frank Li
In-Reply-To: <20260626-amlogic-dma-v9-0-558d672c4a95@amlogic.com>

From: Xianwei Zhao <xianwei.zhao@amlogic.com>

Amlogic A9 SoCs include a general-purpose DMA controller that can be used
by multiple peripherals, such as I2C PIO and I3C. Each peripheral group
is associated with a dedicated DMA channel in hardware.

Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
 drivers/dma/Kconfig       |  10 +
 drivers/dma/Makefile      |   1 +
 drivers/dma/amlogic-dma.c | 708 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 719 insertions(+)

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index ae6a682c9f76..01f96a8257e5 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -85,6 +85,16 @@ config AMCC_PPC440SPE_ADMA
 	help
 	  Enable support for the AMCC PPC440SPe RAID engines.
 
+config AMLOGIC_DMA
+	tristate "Amlogic general DMA support"
+	depends on ARCH_MESON || COMPILE_TEST
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+	select REGMAP_MMIO
+	help
+	  Enable support for the Amlogic general DMA engines. THis DMA
+	  controller is used some Amlogic SoCs, such as A9.
+
 config APPLE_ADMAC
 	tristate "Apple ADMAC support"
 	depends on ARCH_APPLE || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 14aa086629d5..f62d12b08e15 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_DMATEST) += dmatest.o
 obj-$(CONFIG_ALTERA_MSGDMA) += altera-msgdma.o
 obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
 obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/
+obj-$(CONFIG_AMLOGIC_DMA) += amlogic-dma.o
 obj-$(CONFIG_APPLE_ADMAC) += apple-admac.o
 obj-$(CONFIG_ARM_DMA350) += arm-dma350.o
 obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
diff --git a/drivers/dma/amlogic-dma.c b/drivers/dma/amlogic-dma.c
new file mode 100644
index 000000000000..bce6932f3a12
--- /dev/null
+++ b/drivers/dma/amlogic-dma.c
@@ -0,0 +1,708 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright (C) 2025 Amlogic, Inc. All rights reserved
+ * Author: Xianwei Zhao <xianwei.zhao@amlogic.com>
+ */
+
+#include <dt-bindings/dma/amlogic,a9-dma.h>
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "virt-dma.h"
+
+#define RCH_REG_BASE		0x0
+#define WCH_REG_BASE		0x2000
+/*
+ * Each rch (read from memory) REG offset  Rch_offset 0x0 each channel total 0x40
+ * rch addr = DMA_base + Rch_offset+ chan_id * 0x40 + reg_offset
+ */
+#define RCH_READY		0x0
+#define RCH_STATUS		0x4
+#define RCH_CFG			0x8
+#define CFG_CLEAR		BIT(25)
+#define CFG_PAUSE		BIT(26)
+#define CFG_ENABLE		BIT(27)
+#define CFG_DONE		BIT(28)
+#define RCH_ADDR		0xc
+#define RCH_LEN			0x10
+#define RCH_RD_LEN		0x14
+#define RCH_PRT			0x18
+#define RCH_SYCN_STAT		0x1c
+#define RCH_ADDR_LOW		0x20
+#define RCH_ADDR_HIGH		0x24
+/* if work on 64, it work with RCH_PRT */
+#define RCH_PTR_HIGH		0x28
+
+/*
+ * Each wch (write to memory) REG offset  Wch_offset 0x2000 each channel total 0x40
+ * wch addr = DMA_base + Wch_offset+ chan_id * 0x40 + reg_offset
+ */
+#define WCH_READY		0x0
+#define WCH_TOTAL_LEN		0x4
+#define WCH_CFG			0x8
+#define WCH_ADDR		0xc
+#define WCH_LEN			0x10
+#define WCH_RD_LEN		0x14
+#define WCH_PRT			0x18
+#define WCH_CMD_CNT		0x1c
+#define WCH_ADDR_LOW		0x20
+#define WCH_ADDR_HIGH		0x24
+/* if work on 64, it work with RCH_PRT */
+#define WCH_PTR_HIGH		0x28
+
+/* DMA controller reg */
+#define RCH_INT_MASK		0x1000
+#define WCH_INT_MASK		0x1004
+#define CLEAR_W_BATCH		0x1014
+#define CLEAR_RCH		0x1024
+#define CLEAR_WCH		0x1028
+#define RCH_ACTIVE		0x1038
+#define WCH_ACTIVE		0x103c
+#define RCH_DONE		0x104c
+#define WCH_DONE		0x1050
+#define RCH_ERR			0x1060
+#define RCH_LEN_ERR		0x1064
+#define WCH_ERR			0x1068
+#define DMA_BATCH_END		0x1078
+#define WCH_EOC_DONE		0x1088
+#define WDMA_RESP_ERR		0x1098
+#define UPT_PKT_SYNC		0x10a8
+#define RCHN_CFG		0x10ac
+#define WCHN_CFG		0x10b0
+#define MEM_PD_CFG		0x10b4
+#define MEM_BUS_CFG		0x10b8
+#define DMA_GMV_CFG		0x10bc
+#define DMA_GMR_CFG		0x10c0
+
+#define MAX_CHAN_ID		32
+#define SG_MAX_LEN		GENMASK(26, 0)
+
+struct aml_dma_sg_link {
+#define LINK_LEN		GENMASK(26, 0)
+#define LINK_IRQ		BIT(27)
+#define LINK_EOC		BIT(28)
+#define LINK_LOOP		BIT(29)
+#define LINK_ERR		BIT(30)
+#define LINK_OWNER		BIT(31)
+	u32 ctl;
+	u32 addr_low;
+	u32 addr_high;
+	u32 revered;
+} __packed;
+
+/* 1 page for link 256*16 */
+#define DMA_MAX_LINK		256
+/* sizeof(struct aml_dma_sg_link) */
+#define DMA_LINK_SIZE		16
+#define DMA_LINK_MAX_SIZE	(DMA_LINK_SIZE * DMA_MAX_LINK)
+
+struct aml_dma_desc {
+	struct virt_dma_desc		vd;
+	struct aml_dma_sg_link		*sg_link;
+	struct dma_device		*dma_device;
+	dma_addr_t			sg_link_phys;
+	size_t				sg_link_size;
+	u32				data_len;
+};
+
+struct aml_dma_chan {
+	struct virt_dma_chan		vchan;
+	struct aml_dma_dev		*aml_dma;
+	struct aml_dma_desc		*cur_desc;
+	enum dma_status			pre_status;
+	enum dma_status			status;
+	enum dma_transfer_direction	direction;
+	int				chan_id;
+	/* reg_base (direction + chan_id) */
+	int				reg_offs;
+	/* When there are multiple consecutive transmission errors, this chanel halt */
+	int				err_num;
+};
+
+struct aml_dma_dev {
+	struct dma_device		dma_device;
+	void __iomem			*base;
+	struct regmap			*regmap;
+	struct clk			*clk;
+	int				irq;
+	struct platform_device		*pdev;
+	struct aml_dma_chan		*aml_rch[MAX_CHAN_ID];
+	struct aml_dma_chan		*aml_wch[MAX_CHAN_ID];
+	unsigned int			chan_nr;
+	unsigned int			chan_used;
+	struct aml_dma_chan		aml_chans[]__counted_by(chan_nr);
+};
+
+static inline struct aml_dma_chan *to_aml_dma_chan(struct dma_chan *chan)
+{
+	return container_of(chan, struct aml_dma_chan, vchan.chan);
+}
+
+static inline struct aml_dma_desc *to_aml_dma_desc(struct virt_dma_desc *vd)
+{
+	return container_of(vd, struct aml_dma_desc, vd);
+}
+
+static void aml_dma_free_desc(struct virt_dma_desc *vd)
+{
+	struct aml_dma_desc *aml_desc = to_aml_dma_desc(vd);
+
+	dma_free_coherent(aml_desc->dma_device->dev,
+			  aml_desc->sg_link_size,
+			  aml_desc->sg_link,
+			  aml_desc->sg_link_phys);
+	kfree(aml_desc);
+}
+
+static int aml_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct aml_dma_chan *aml_chan = to_aml_dma_chan(chan);
+	struct aml_dma_dev *aml_dma = aml_chan->aml_dma;
+
+	/* offset is the same RCH_CFG and WCH_CFG */
+	regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEAR);
+	regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE);
+	regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEAR);
+
+	aml_chan->status = DMA_COMPLETE;
+	aml_chan->cur_desc = NULL;
+	aml_chan->err_num = 0;
+
+	return 0;
+}
+
+static void aml_dma_free_chan_resources(struct dma_chan *chan)
+{
+	struct aml_dma_chan *aml_chan = to_aml_dma_chan(chan);
+	struct aml_dma_dev *aml_dma = aml_chan->aml_dma;
+	struct virt_dma_desc *cur_vd = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&aml_chan->vchan.lock, flags);
+	regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE);
+	regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEAR);
+	if (aml_chan->cur_desc)
+		cur_vd = &aml_chan->cur_desc->vd;
+	aml_chan->cur_desc = NULL;
+	spin_unlock_irqrestore(&aml_chan->vchan.lock, flags);
+	if (cur_vd)
+		aml_dma_free_desc(cur_vd);
+
+	vchan_free_chan_resources(&aml_chan->vchan);
+}
+
+/* DMA transfer state  update how many data reside it */
+static enum dma_status aml_dma_tx_status(struct dma_chan *chan,
+					 dma_cookie_t cookie,
+					 struct dma_tx_state *txstate)
+{
+	struct aml_dma_chan *aml_chan = to_aml_dma_chan(chan);
+	struct aml_dma_dev *aml_dma = aml_chan->aml_dma;
+	struct aml_dma_desc *aml_desc = NULL;
+	struct virt_dma_desc *vd;
+	u32 residue = 0, done;
+	unsigned long flags;
+	enum dma_status ret;
+
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret == DMA_COMPLETE || !txstate)
+		return ret;
+
+	spin_lock_irqsave(&aml_chan->vchan.lock, flags);
+	vd = vchan_find_desc(&aml_chan->vchan, cookie);
+	if (vd) {
+		aml_desc = to_aml_dma_desc(vd);
+		residue = aml_desc->data_len;
+	} else if (aml_chan->cur_desc && aml_chan->cur_desc->vd.tx.cookie == cookie) {
+		aml_desc = aml_chan->cur_desc;
+		regmap_read(aml_dma->regmap, aml_chan->reg_offs + RCH_RD_LEN, &done);
+		residue = aml_desc->data_len - done;
+	} else {
+		dev_err(aml_dma->dma_device.dev, "cookie error\n");
+	}
+	spin_unlock_irqrestore(&aml_chan->vchan.lock, flags);
+
+	dma_set_residue(txstate, residue);
+
+	return ret;
+}
+
+static struct dma_async_tx_descriptor *aml_dma_prep_slave_sg
+		(struct dma_chan *chan, struct scatterlist *sgl,
+		unsigned int sg_len, enum dma_transfer_direction direction,
+		unsigned long flags, void *context)
+{
+	struct aml_dma_chan *aml_chan = to_aml_dma_chan(chan);
+	struct aml_dma_dev *aml_dma = aml_chan->aml_dma;
+	struct aml_dma_desc *aml_desc = NULL;
+	struct aml_dma_sg_link *sg_link = NULL;
+	struct scatterlist *sg = NULL;
+	u64 paddr;
+	u32 link_count, avail;
+	u32 i;
+
+	if (aml_chan->direction != direction) {
+		dev_err(aml_dma->dma_device.dev, "direction not support\n");
+		return NULL;
+	}
+
+	link_count = sg_nents_for_dma(sgl, sg_len, SG_MAX_LEN);
+	if (link_count == 0)
+		return NULL;
+
+	aml_desc = kzalloc_obj(*aml_desc, GFP_NOWAIT);
+	if (!aml_desc)
+		return NULL;
+	aml_desc->sg_link_size = link_count * sizeof(*sg_link);
+	aml_desc->sg_link = dma_alloc_coherent(aml_dma->dma_device.dev, aml_desc->sg_link_size,
+					       &aml_desc->sg_link_phys, GFP_NOWAIT);
+	if (!aml_desc->sg_link) {
+		kfree(aml_desc);
+		return NULL;
+	}
+	aml_desc->dma_device = &aml_dma->dma_device;
+
+	sg_link = aml_desc->sg_link;
+	for_each_sg(sgl, sg, sg_len, i) {
+		avail = sg_dma_len(sg);
+		paddr = sg->dma_address;
+		while (avail > SG_MAX_LEN) {
+			/* set dma address and len to sglink*/
+			sg_link->addr_low = lower_32_bits(paddr);
+			sg_link->addr_high = upper_32_bits(paddr);
+			sg_link->ctl = FIELD_PREP(LINK_LEN, SG_MAX_LEN);
+			paddr = paddr + SG_MAX_LEN;
+			avail = avail - SG_MAX_LEN;
+			sg_link++;
+		}
+		/* set dma address and len to sglink*/
+		sg_link->addr_low = lower_32_bits(paddr);
+		sg_link->addr_high = upper_32_bits(paddr);
+		sg_link->ctl = FIELD_PREP(LINK_LEN, avail);
+
+		aml_desc->data_len += sg_dma_len(sg);
+		sg_link++;
+	}
+
+	/* the last sg set eoc flag */
+	sg_link--;
+	sg_link->ctl |= LINK_EOC;
+
+	return vchan_tx_prep(&aml_chan->vchan, &aml_desc->vd, flags);
+}
+
+static int aml_dma_chan_pause(struct dma_chan *chan)
+{
+	struct aml_dma_chan *aml_chan = to_aml_dma_chan(chan);
+	struct aml_dma_dev *aml_dma = aml_chan->aml_dma;
+	unsigned long flags;
+
+	spin_lock_irqsave(&aml_chan->vchan.lock, flags);
+	regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE);
+	aml_chan->pre_status = aml_chan->status;
+	aml_chan->status = DMA_PAUSED;
+	spin_unlock_irqrestore(&aml_chan->vchan.lock, flags);
+
+	return 0;
+}
+
+static int aml_dma_chan_resume(struct dma_chan *chan)
+{
+	struct aml_dma_chan *aml_chan = to_aml_dma_chan(chan);
+	struct aml_dma_dev *aml_dma = aml_chan->aml_dma;
+	unsigned long flags;
+
+	spin_lock_irqsave(&aml_chan->vchan.lock, flags);
+	regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE);
+	aml_chan->status = aml_chan->pre_status;
+	spin_unlock_irqrestore(&aml_chan->vchan.lock, flags);
+
+	return 0;
+}
+
+static int aml_dma_terminate_all(struct dma_chan *chan)
+{
+	struct aml_dma_chan *aml_chan = to_aml_dma_chan(chan);
+	struct aml_dma_dev *aml_dma = aml_chan->aml_dma;
+	int chan_id = aml_chan->chan_id;
+	struct virt_dma_desc *cur_vd;
+	unsigned long flags;
+	LIST_HEAD(head);
+
+	spin_lock_irqsave(&aml_chan->vchan.lock, flags);
+	regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE);
+	regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEAR);
+
+	if (aml_chan->direction == DMA_MEM_TO_DEV)
+		regmap_set_bits(aml_dma->regmap, RCH_INT_MASK, BIT(chan_id));
+	else if (aml_chan->direction == DMA_DEV_TO_MEM)
+		regmap_set_bits(aml_dma->regmap, WCH_INT_MASK, BIT(chan_id));
+
+	vchan_get_all_descriptors(&aml_chan->vchan, &head);
+	cur_vd = &aml_chan->cur_desc->vd;
+	aml_chan->cur_desc = NULL;
+	spin_unlock_irqrestore(&aml_chan->vchan.lock, flags);
+	if (cur_vd)
+		aml_dma_free_desc(cur_vd);
+
+	vchan_dma_desc_free_list(&aml_chan->vchan, &head);
+
+	regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE);
+	regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEAR);
+
+	return 0;
+}
+
+static void aml_dma_start(struct aml_dma_chan *aml_chan)
+{
+	struct virt_dma_desc *vd = vchan_next_desc(&aml_chan->vchan);
+	struct aml_dma_dev *aml_dma = aml_chan->aml_dma;
+	struct aml_dma_desc *aml_desc = NULL;
+	int chan_id = aml_chan->chan_id;
+
+	if (aml_chan->status == DMA_ERROR) {
+		if (aml_chan->err_num > 5) {
+			dev_err(aml_dma->dma_device.dev, "hw error\n");
+			return;
+		}
+		regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE);
+		regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEAR);
+		aml_chan->err_num++;
+		regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE);
+		regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEAR);
+		aml_chan->status = DMA_COMPLETE;
+	} else {
+		aml_chan->err_num = 0;
+	}
+
+	if (!vd)
+		return;
+
+	if (aml_chan->status != DMA_COMPLETE)
+		return;
+
+	list_del(&vd->node);
+	aml_desc = to_aml_dma_desc(vd);
+	aml_chan->cur_desc = aml_desc;
+
+	if (aml_chan->direction == DMA_MEM_TO_DEV) {
+		regmap_write(aml_dma->regmap, aml_chan->reg_offs + RCH_ADDR,
+			     lower_32_bits(aml_desc->sg_link_phys));
+		regmap_write(aml_dma->regmap, aml_chan->reg_offs + RCH_ADDR_HIGH,
+			     upper_32_bits(aml_desc->sg_link_phys));
+		regmap_write(aml_dma->regmap, aml_chan->reg_offs + RCH_LEN, aml_desc->data_len);
+		regmap_clear_bits(aml_dma->regmap, RCH_INT_MASK, BIT(chan_id));
+		/* for rch (tx) need set cfg 0 to trigger start */
+		regmap_write(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, 0);
+	} else if (aml_chan->direction == DMA_DEV_TO_MEM) {
+		regmap_write(aml_dma->regmap, aml_chan->reg_offs + WCH_ADDR,
+			     lower_32_bits(aml_desc->sg_link_phys));
+		regmap_write(aml_dma->regmap, aml_chan->reg_offs + WCH_ADDR_HIGH,
+			     upper_32_bits(aml_desc->sg_link_phys));
+		regmap_write(aml_dma->regmap, aml_chan->reg_offs + WCH_LEN, aml_desc->data_len);
+		regmap_clear_bits(aml_dma->regmap, WCH_INT_MASK, BIT(chan_id));
+	}
+}
+
+static void aml_dma_issue_pending(struct dma_chan *chan)
+{
+	struct aml_dma_chan *aml_chan = to_aml_dma_chan(chan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&aml_chan->vchan.lock, flags);
+	if (vchan_issue_pending(&aml_chan->vchan) && !aml_chan->cur_desc)
+		aml_dma_start(aml_chan);
+	spin_unlock_irqrestore(&aml_chan->vchan.lock, flags);
+}
+
+static irqreturn_t aml_dma_interrupt_handler(int irq, void *dev_id)
+{
+	struct aml_dma_dev *aml_dma = dev_id;
+	struct aml_dma_chan *aml_chan;
+	struct aml_dma_desc *aml_desc;
+	u32 done, eoc_done, err, err_l, end;
+	u32 cpl_data;
+	int i = 0;
+
+	/* deal with rch normal complete and error */
+	regmap_read(aml_dma->regmap, RCH_DONE, &done);
+	regmap_read(aml_dma->regmap, RCH_ERR, &err);
+	regmap_read(aml_dma->regmap, RCH_LEN_ERR, &err_l);
+	err = err | err_l;
+
+	done = done | err;
+
+	while (done) {
+		i = ffs(done) - 1;
+		regmap_write(aml_dma->regmap, CLEAR_RCH, BIT(i));
+		done &= ~BIT(i);
+		aml_chan = aml_dma->aml_rch[i];
+		if (!aml_chan) {
+			dev_err(aml_dma->dma_device.dev, "idx %d rch not initialized\n", i);
+			continue;
+		}
+		spin_lock(&aml_chan->vchan.lock);
+		aml_chan->status = (err & BIT(i)) ? DMA_ERROR : DMA_COMPLETE;
+		aml_desc = aml_chan->cur_desc;
+		if (!aml_desc) {
+			spin_unlock(&aml_chan->vchan.lock);
+			continue;
+		}
+		if (aml_chan->status == DMA_ERROR) {
+			aml_desc->vd.tx_result.result = DMA_TRANS_READ_FAILED;
+			regmap_read(aml_dma->regmap, aml_chan->reg_offs + RCH_RD_LEN, &cpl_data);
+			aml_desc->vd.tx_result.residue = aml_desc->data_len - cpl_data;
+		}
+		vchan_cookie_complete(&aml_desc->vd);
+		aml_chan->cur_desc = NULL;
+		aml_dma_start(aml_chan);
+		spin_unlock(&aml_chan->vchan.lock);
+	}
+
+	/* deal with wch normal complete and error */
+	regmap_read(aml_dma->regmap, DMA_BATCH_END, &end);
+	if (end)
+		regmap_write(aml_dma->regmap, CLEAR_W_BATCH, end);
+
+	regmap_read(aml_dma->regmap, WCH_DONE, &done);
+	regmap_read(aml_dma->regmap, WCH_EOC_DONE, &eoc_done);
+	done = done | eoc_done;
+
+	regmap_read(aml_dma->regmap, WCH_ERR, &err);
+	regmap_read(aml_dma->regmap, WDMA_RESP_ERR, &err_l);
+	err = err | err_l;
+
+	done = done | err;
+	i = 0;
+	while (done) {
+		i = ffs(done) - 1;
+		done &= ~BIT(i);
+		regmap_write(aml_dma->regmap, CLEAR_WCH, BIT(i));
+		aml_chan = aml_dma->aml_wch[i];
+		if (!aml_chan) {
+			dev_err(aml_dma->dma_device.dev, "idx %d wch not initialized\n", i);
+			continue;
+		}
+		spin_lock(&aml_chan->vchan.lock);
+		aml_chan->status = (err & BIT(i)) ? DMA_ERROR : DMA_COMPLETE;
+		aml_desc = aml_chan->cur_desc;
+		if (!aml_desc) {
+			spin_unlock(&aml_chan->vchan.lock);
+			continue;
+		}
+		if (aml_chan->status == DMA_ERROR) {
+			aml_desc->vd.tx_result.result = DMA_TRANS_WRITE_FAILED;
+			regmap_read(aml_dma->regmap, aml_chan->reg_offs + RCH_RD_LEN, &cpl_data);
+			aml_desc->vd.tx_result.residue = aml_desc->data_len - cpl_data;
+		}
+		vchan_cookie_complete(&aml_desc->vd);
+		aml_chan->cur_desc = NULL;
+		aml_dma_start(aml_chan);
+		spin_unlock(&aml_chan->vchan.lock);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct dma_chan *aml_of_dma_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma)
+{
+	struct aml_dma_dev *aml_dma = (struct aml_dma_dev *)ofdma->of_dma_data;
+	struct aml_dma_chan *aml_chan = NULL;
+	u32 type;
+	u32 phy_chan_id;
+
+	if (dma_spec->args_count != 2)
+		return NULL;
+
+	type = dma_spec->args[0];
+	phy_chan_id = dma_spec->args[1];
+
+	if (phy_chan_id >= MAX_CHAN_ID)
+		return NULL;
+
+	if (type == DMA_TX) {
+		aml_chan = aml_dma->aml_rch[phy_chan_id];
+		if (!aml_chan) {
+			if (aml_dma->chan_used >= aml_dma->chan_nr) {
+				dev_err(aml_dma->dma_device.dev, "some dma clients err used\n");
+				return NULL;
+			}
+			aml_chan = &aml_dma->aml_chans[aml_dma->chan_used];
+			aml_dma->chan_used++;
+			aml_chan->direction = DMA_MEM_TO_DEV;
+			aml_chan->chan_id = phy_chan_id;
+			aml_chan->reg_offs = RCH_REG_BASE + 0x40 * aml_chan->chan_id;
+			aml_dma->aml_rch[phy_chan_id] = aml_chan;
+		}
+	} else if (type == DMA_RX) {
+		aml_chan = aml_dma->aml_wch[phy_chan_id];
+		if (!aml_chan) {
+			if (aml_dma->chan_used >= aml_dma->chan_nr) {
+				dev_err(aml_dma->dma_device.dev, "some dma clients err used\n");
+				return NULL;
+			}
+			aml_chan = &aml_dma->aml_chans[aml_dma->chan_used];
+			aml_dma->chan_used++;
+			aml_chan->direction = DMA_DEV_TO_MEM;
+			aml_chan->chan_id = phy_chan_id;
+			aml_chan->reg_offs = WCH_REG_BASE + 0x40 * aml_chan->chan_id;
+			aml_dma->aml_wch[phy_chan_id] = aml_chan;
+		}
+	} else {
+		dev_err(aml_dma->dma_device.dev, "type %d not supported\n", type);
+		return NULL;
+	}
+
+	return dma_get_slave_channel(&aml_chan->vchan.chan);
+}
+
+static int aml_dma_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct dma_device *dma_dev;
+	struct aml_dma_dev *aml_dma;
+	int ret, i, len;
+	u32 chan_nr;
+
+	const struct regmap_config aml_regmap_config = {
+		.reg_bits = 32,
+		.val_bits = 32,
+		.reg_stride = 4,
+		.max_register = 0x3000,
+	};
+
+	ret = of_property_read_u32(np, "dma-channels", &chan_nr);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to read dma-channels\n");
+	if (chan_nr > (MAX_CHAN_ID * 2))
+		return dev_err_probe(&pdev->dev, -EINVAL, "dma-channels unusual\n");
+
+	len = sizeof(struct aml_dma_dev) + sizeof(struct aml_dma_chan) * chan_nr;
+	aml_dma = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
+	if (!aml_dma)
+		return -ENOMEM;
+
+	aml_dma->chan_nr = chan_nr;
+
+	aml_dma->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(aml_dma->base))
+		return PTR_ERR(aml_dma->base);
+
+	aml_dma->regmap = devm_regmap_init_mmio(&pdev->dev, aml_dma->base,
+						&aml_regmap_config);
+	if (IS_ERR_OR_NULL(aml_dma->regmap))
+		return PTR_ERR(aml_dma->regmap);
+
+	aml_dma->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+	if (IS_ERR(aml_dma->clk))
+		return PTR_ERR(aml_dma->clk);
+
+	aml_dma->irq = platform_get_irq(pdev, 0);
+
+	aml_dma->pdev = pdev;
+	aml_dma->dma_device.dev = &pdev->dev;
+
+	dma_dev = &aml_dma->dma_device;
+	INIT_LIST_HEAD(&dma_dev->channels);
+
+	/* Initialize channel parameters */
+	for (i = 0; i < chan_nr; i++) {
+		struct aml_dma_chan *aml_chan = &aml_dma->aml_chans[i];
+
+		aml_chan->aml_dma = aml_dma;
+		aml_chan->vchan.desc_free = aml_dma_free_desc;
+		vchan_init(&aml_chan->vchan, &aml_dma->dma_device);
+	}
+	aml_dma->chan_used = 0;
+
+	dma_set_max_seg_size(dma_dev->dev, SG_MAX_LEN);
+	dma_cap_set(DMA_SLAVE, dma_dev->cap_mask);
+	dma_dev->device_alloc_chan_resources = aml_dma_alloc_chan_resources;
+	dma_dev->device_free_chan_resources = aml_dma_free_chan_resources;
+	dma_dev->device_tx_status = aml_dma_tx_status;
+	dma_dev->device_prep_slave_sg = aml_dma_prep_slave_sg;
+	dma_dev->device_pause = aml_dma_chan_pause;
+	dma_dev->device_resume = aml_dma_chan_resume;
+	dma_dev->device_terminate_all = aml_dma_terminate_all;
+	dma_dev->device_issue_pending = aml_dma_issue_pending;
+	/* PIO 4 bytes and I2C 1 byte */
+	dma_dev->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | BIT(DMA_SLAVE_BUSWIDTH_1_BYTE);
+	dma_dev->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+	dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+
+	regmap_write(aml_dma->regmap, RCH_INT_MASK, 0xffffffff);
+	regmap_write(aml_dma->regmap, WCH_INT_MASK, 0xffffffff);
+
+	ret = devm_request_irq(&pdev->dev, aml_dma->irq, aml_dma_interrupt_handler,
+			       0, dev_name(&pdev->dev), aml_dma);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to register irq\n");
+
+	ret = dmaenginem_async_device_register(dma_dev);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to register dmaenginem\n");
+
+	ret = of_dma_controller_register(np, aml_of_dma_xlate, aml_dma);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to register xlate\n");
+
+	platform_set_drvdata(pdev, aml_dma);
+
+	return 0;
+}
+
+static void aml_dma_remove(struct platform_device *pdev)
+{
+	struct aml_dma_dev *aml_dma = platform_get_drvdata(pdev);
+	struct aml_dma_chan *aml_chan = NULL;
+	int i;
+
+	of_dma_controller_free((&pdev->dev)->of_node);
+
+	regmap_write(aml_dma->regmap, RCH_INT_MASK, 0xffffffff);
+	regmap_write(aml_dma->regmap, WCH_INT_MASK, 0xffffffff);
+
+	for (i = 0; i < MAX_CHAN_ID; i++) {
+		aml_chan = aml_dma->aml_rch[i];
+		if (aml_chan)
+			tasklet_kill(&aml_chan->vchan.task);
+		aml_chan = aml_dma->aml_wch[i];
+		if (aml_chan)
+			tasklet_kill(&aml_chan->vchan.task);
+	}
+}
+
+static const struct of_device_id aml_dma_ids[] = {
+	{ .compatible = "amlogic,a9-dma", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, aml_dma_ids);
+
+static struct platform_driver aml_dma_driver = {
+	.probe		= aml_dma_probe,
+	.remove		= aml_dma_remove,
+	.driver		= {
+		.name	= "aml-dma",
+		.of_match_table = aml_dma_ids,
+	},
+};
+
+module_platform_driver(aml_dma_driver);
+
+MODULE_DESCRIPTION("GENERAL DMA driver for Amlogic");
+MODULE_AUTHOR("Xianwei Zhao <xianwei.zhao@amlogic.com>");
+MODULE_LICENSE("GPL");

-- 
2.52.0



^ permalink raw reply related

* [PATCH v2 0/3] X2 Elite HP EliteBook X G2q support
From: Jason Pettit @ 2026-06-26  5:47 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: linux-arm-msm, devicetree, linux-kernel, Akhil P Oommen,
	Mahadevan P, Sibi Sankar, Jingyi Wang, Ananthu C V, Jason Pettit

This series adds initial device-tree support for the HP EliteBook X G2q
14" Next Gen AI PC (product SKU C4JG0AV, board 8E91), a Snapdragon X2
Elite (Glymur) laptop.

The board was brought up and validated on real hardware. The electrical
description (PMIC rails, PHY supplies, the HDMI bridge wiring) was
verified against the live unit rather than copied from a Glymur CRD.

Working on this laptop with this series applied:

  - Internal eDP panel (samsung,atna33xc20)
  - 2x USB Type-C with DisplayPort alt-mode and USB
  - Chassis HDMI output
  - Chassis USB-A host port
  - Fingerprint reader
  - NVMe SSD on PCIe5
  - Wi-Fi, Bluetooth
  - Keyboard, touchpad, touchscreen, lid switch
  - Adreno GPU and GMU (Freedreno GL on Mesa)
  - Audio playback and capture
  - Real-time clock
  - Compute DSP (cDSP)

This patch series builds upon the recent work of Qualcomm engineers to
enable another Glymur-based laptop.

Like its peer submissions, the camera support is missing today.

This has the same known dependencies as other boards on this
platform (audio, GPU, SoCCP series).

The GPU device-tree patches come from the partially merged Glymur GPU DT
v5 series at
https://lore.kernel.org/all/20260522-glymur-gpu-dt-v5-0-562c406b210c@oss.qualcomm.com/

SCMI on this configuration needs CONFIG_QCOM_CPUCP_MBOX built in (=y).

The bindings patch is independent and can be reviewed/applied on its own.
The board patch can be reviewed in parallel with the GPU, LPASS and SoCCP
SoC series. Until those land in the target tree, it will trip the expected
"Label or path ... not found" dtc error. As with the X2 Elite Lenovo Yoga
Slim 7x submission, this v1 is expected to trigger some dt-bindings warnings
that come from the in-flight dependency series, not from the board patch
itself.

Signed-off-by: Jason Pettit <jason.pettit@oss.qualcomm.com>
---
Changes in v2:
- Enable the PMIC RTC (qcom,no-alarm + qcom,uefi-rtc-info)
- Add the SMB2370 eUSB2 repeaters on usb_0/usb_1
- Enable the compute DSP (remoteproc_cdsp / fastrpc)
- Addressed comments from reviewers on v1
- Link to v1: https://lore.kernel.org/linux-arm-msm/20260620-glymur-send-v1-0-fc4a2cfd107c@oss.qualcomm.com

---
Jason Pettit (3):
      dt-bindings: arm: qcom: Add HP EliteBook X G2q 14 AI
      arm64: dts: qcom: Add HP EliteBook X G2q 14 AI
      firmware: qcom: scm: Allow QSEECOM on HP EliteBook X G2q 14 AI

 Documentation/devicetree/bindings/arm/qcom.yaml    |    1 +
 arch/arm64/boot/dts/qcom/Makefile                  |    1 +
 .../boot/dts/qcom/glymur-hp-elitebook-x-g2q.dts    | 1019 ++++++++++++++++++++
 drivers/firmware/qcom/qcom_scm.c                   |    1 +
 4 files changed, 1022 insertions(+)
---
base-commit: dd60bcf0ad17dd15d6d4d677315c4cf9827445f9
change-id: 20260619-glymur-send-1136d243a120
prerequisite-patch-id: 36f4bb7740fd65d808fa6685bce4b03798a547ff
prerequisite-patch-id: 054631082c45d3ab3117f541f0d4d90b660dac73
prerequisite-patch-id: af18aef027c45213c11b436746fa31b3b6ebe46b
prerequisite-message-id: <20260419-glymur_dp-v1-1-ad1067a8e8ae@oss.qualcomm.com>
prerequisite-patch-id: 7cb9a168c33491bf91ece900a2218aa7b4b68ddd
prerequisite-message-id: <20260523085511.2532669-1-sibi.sankar@oss.qualcomm.com>
prerequisite-patch-id: 43e96d8a5063f51e2b5ee75fc8c9e10682e5670c
prerequisite-patch-id: 2e71d345f84a821d89da2a6064954409fdb1277d
prerequisite-patch-id: 0b9f5995044bb3d3ffda227ac986b755fa118c63
prerequisite-message-id: <20260623-knp-soccp-v7-0-1ec7bb5c9fec@oss.qualcomm.com>
prerequisite-patch-id: 8459bcae98ac156f6576657fe9233badcd385218
prerequisite-patch-id: b5182f879cdd23c5a0c64bf09b40213b71059b51
prerequisite-patch-id: c962e3f24c435e91ae563bbba9e396bf277ff0ad
prerequisite-patch-id: b9cd65895f55e9d76ba28ef8f9aaf6cdefe1b9d3
prerequisite-patch-id: 6484d1056e30f2027e81eee375d979197754bc12
prerequisite-patch-id: fa7954f6fd2d27a6f0e805c9643b70e7e201c503
prerequisite-message-id: <20260403-glymur-soccp-v3-1-f0e8d57f11ba@oss.qualcomm.com>
prerequisite-patch-id: 48c26c428cbeaa674a615704d1abeb87e4e965c8

Best regards,
--  
Jason Pettit <jason.pettit@oss.qualcomm.com>


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox