Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v5 0/3] spmi-pmic-arb: Add support for PMIC arbiter v8 for Glymur and Kaanapali
From: Stephen Boyd @ 2026-01-16  2:20 UTC (permalink / raw)
  To: Conor Dooley, David Collins, Jishnu Prakash, Krzysztof Kozlowski,
	Rob Herring, konrad.dybcio
  Cc: linux-arm-msm, linux-kernel, devicetree, Jishnu Prakash, aiqun.yu,
	kamal.wadhwa, Pankaj Patil, Jingyi Wang
In-Reply-To: <20251126-pmic_arb_v8-v5-0-4dd8dc5dc5a1@oss.qualcomm.com>

Quoting Jishnu Prakash (2025-11-25 23:12:52)
> This patch series updates the SPMI dt-bindings and driver to add
> support for PMIC arbiter v8, targeting Qualcomm SoCs Glymur and
> Kaanapali.
> 
> SPMI PMIC Arbiter version 8 builds upon version 7 with support for
> up to four SPMI buses.  To achieve this, the register map was
> slightly rearranged.
> 
> Device tree changes are not included in this series and will be
> posted separately.
> 
> Signed-off-by: Jishnu Prakash <jishnu.prakash@oss.qualcomm.com>
> ---

Applied to spmi-next

^ permalink raw reply

* Re: [PATCH v4 0/5] SPMI: MediaTek: Add support for multi-bus
From: Stephen Boyd @ 2026-01-16  2:19 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: robh, krzk+dt, conor+dt, matthias.bgg, angelogioacchino.delregno,
	hsin-hsiung.wang, linux-kernel, devicetree, linux-arm-kernel,
	linux-mediatek, kernel
In-Reply-To: <20251024083247.25814-1-angelogioacchino.delregno@collabora.com>

Quoting AngeloGioacchino Del Regno (2025-10-24 03:32:42)
> Changes in v4:
>  - Refactored IRQ domain handling due to deprecation of function
>    irq_domain_add_tree() to use the new irq_domain_create_tree()
>  - Added .irq_eoi() callback for rcs_irq as that better reflects
>    the actual functionality of this interrupt controller (as its
>    SLV_x_y_EINT registers are really signaling "EOI", not "ACK")
>  - Fixed to use generic_handle_domain_irq_safe() to avoid races
>  - Tested again on MT8196 Chromebook
> 
> Changes in v3:
>  - Added Fixes tag to commit 3, collected R-b tag from wenst
> 
> Changes in v2:
>  - Fixed indentation error in dt-bindings
> 
> This series adds basic support for multi-bus (multi-master) SPMI
> controllers, as found in the MediaTek MT8196 Chromebook SoC and
> the MediaTek MT6991 Dimensity 9400 Smartphone SoC, including RCS
> interrupt handling and per-bus registration.
> 

Applied to spmi-next

^ permalink raw reply

* Re: [PATCH] dt-bindings: spmi: spmi-mtk-pmif: Add compatible for MT8189 SoC
From: Stephen Boyd @ 2026-01-16  2:19 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Conor Dooley, Hsin-Hsiung Wang,
	Krzysztof Kozlowski, Louis-Alexis Eyraud, Matthias Brugger,
	Rob Herring
  Cc: kernel, linux-kernel, devicetree, linux-arm-kernel,
	linux-mediatek, Louis-Alexis Eyraud
In-Reply-To: <20251029-mt8189-dt-bindings-spmi-v1-1-fbea12a4ed5e@collabora.com>

Quoting Louis-Alexis Eyraud (2025-10-29 08:31:16)
> Add compatible string for the SPMI block on MT8189 SoC, which is
> compatible with the one used on MT8195.
> 
> Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
> ---

Applied to spmi-next

^ permalink raw reply

* [PATCH 3/3] riscv: cpufeature: Clarify ISA spec version for canonical order
From: Guodong Xu @ 2026-01-16  2:10 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Samuel Holland,
	Heinrich Schuchardt, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Evan Green, Andrew Jones
  Cc: Paul Walmsley, Conor Dooley, devicetree, linux-riscv,
	linux-kernel, Guodong Xu
In-Reply-To: <20260116-supm-ext-id-v1-0-5fcf778ba4a6@riscstar.com>

Specify that chapter 27 refers to version 20191213 of the RISC-V ISA
Unprivileged Architecture. The chapter numbering differs across
specification versions - for example, in version 20250508, the ISA
Extension Naming Conventions is chapter 36, not chapter 27.

Historical versions of the RISC-V specification can be found via Link [1].

Link: https://riscv.org/specifications/ratified/ [1]
Fixes: 8135ade32c0db ("RISC-V: shunt isa_ext_arr to cpufeature.c")
Signed-off-by: Guodong Xu <guodong@riscstar.com>
---
 arch/riscv/kernel/cpufeature.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 39680280f858..629984df1e7b 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -461,7 +461,8 @@ static const unsigned int riscv_supm_exts[] = {
 
 /*
  * The canonical order of ISA extension names in the ISA string is defined in
- * chapter 27 of the unprivileged specification.
+ * Chapter 27 of the RISC-V Instruction Set Manual Volume I Unprivileged ISA
+ * (Document Version 20191213).
  *
  * Ordinarily, for in-kernel data structures, this order is unimportant but
  * isa_ext_arr defines the order of the ISA string in /proc/cpuinfo.

-- 
2.43.0


^ permalink raw reply related

* [PATCH 2/3] riscv: cpufeature: Add ISA extension parsing for Supm
From: Guodong Xu @ 2026-01-16  2:10 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Samuel Holland,
	Heinrich Schuchardt, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Evan Green, Andrew Jones
  Cc: Paul Walmsley, Conor Dooley, devicetree, linux-riscv,
	linux-kernel, Guodong Xu
In-Reply-To: <20260116-supm-ext-id-v1-0-5fcf778ba4a6@riscstar.com>

Supm has been ratified in the RISC-V Pointer Masking specification
(Version 1.0, 10/2024) and is mandated in RVA23 Profiles (Version 1.0,
2024-10-17) for RVA23U64. Supm indicates userspace pointer masking
support.

Remove the previous macro aliasing of Supm to Ssnpm/Smnpm in hwcap.h,
treating Supm as a distinct RISC-V ISA extension ID.

Add ISA parsing logic for Supm, and implement a validator to ensure
that Supm is only reported as available if Kconfig allows it and the
underlying Ssnpm (for supervisor mode) or Smnpm (for machine mode)
extension is present. Supm relies on Ssnpm or Smnpm to provide the
underlying hardware implementation.

With this change, "supm" will be reported (when available) in
/proc/cpuinfo as part of the "isa" and "hart isa" string.

Link: https://lore.kernel.org/lkml/20260101-legume-engraved-0fae8282cfbe@spud/#r [1]
Link: https://lore.kernel.org/all/4ebbe14b-2579-4ba6-808d-d50c24641d04@sifive.com/#r [2]
Signed-off-by: Guodong Xu <guodong@riscstar.com>
---
 arch/riscv/include/asm/hwcap.h |  3 +--
 arch/riscv/kernel/cpufeature.c | 35 +++++++++++++++++++++++++++++++++--
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index 4369a2338541..7653e5cff9ae 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -110,6 +110,7 @@
 #define RISCV_ISA_EXT_ZALASR		101
 #define RISCV_ISA_EXT_ZILSD		102
 #define RISCV_ISA_EXT_ZCLSD		103
+#define RISCV_ISA_EXT_SUPM		104
 
 #define RISCV_ISA_EXT_XLINUXENVCFG	127
 
@@ -118,10 +119,8 @@
 
 #ifdef CONFIG_RISCV_M_MODE
 #define RISCV_ISA_EXT_SxAIA		RISCV_ISA_EXT_SMAIA
-#define RISCV_ISA_EXT_SUPM		RISCV_ISA_EXT_SMNPM
 #else
 #define RISCV_ISA_EXT_SxAIA		RISCV_ISA_EXT_SSAIA
-#define RISCV_ISA_EXT_SUPM		RISCV_ISA_EXT_SSNPM
 #endif
 
 #endif /* _ASM_RISCV_HWCAP_H */
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index fa591aff9d33..39680280f858 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -296,6 +296,27 @@ static int riscv_ext_svadu_validate(const struct riscv_isa_ext_data *data,
 	return 0;
 }
 
+static int riscv_ext_supm_validate(const struct riscv_isa_ext_data *data,
+				   const unsigned long *isa_bitmap)
+{
+	if (!IS_ENABLED(CONFIG_RISCV_ISA_SUPM))
+		return -EINVAL;
+
+	/*
+	 * Supm requires Ssnpm for S-mode or Smnpm for M-mode to provide
+	 * pointer masking for the U-mode execution environment.
+	 */
+	if (IS_ENABLED(CONFIG_RISCV_M_MODE)) {
+		if (__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_SMNPM))
+			return 0;
+	} else {
+		if (__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_SSNPM))
+			return 0;
+	}
+
+	return -EPROBE_DEFER;
+}
+
 static const unsigned int riscv_a_exts[] = {
 	RISCV_ISA_EXT_ZAAMO,
 	RISCV_ISA_EXT_ZALRSC,
@@ -429,6 +450,15 @@ static const unsigned int riscv_c_exts[] = {
 	RISCV_ISA_EXT_ZCD,
 };
 
+/*
+ * Smnpm and Ssnpm provide pointer masking for the next lower privilege mode
+ * (U-mode), thus enabling Supm. Both extensions imply the same subset.
+ */
+static const unsigned int riscv_supm_exts[] = {
+	RISCV_ISA_EXT_XLINUXENVCFG,
+	RISCV_ISA_EXT_SUPM
+};
+
 /*
  * The canonical order of ISA extension names in the ISA string is defined in
  * chapter 27 of the unprivileged specification.
@@ -552,12 +582,13 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 	__RISCV_ISA_EXT_DATA_VALIDATE(zvkt, RISCV_ISA_EXT_ZVKT, riscv_ext_vector_crypto_validate),
 	__RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA),
 	__RISCV_ISA_EXT_DATA(smmpm, RISCV_ISA_EXT_SMMPM),
-	__RISCV_ISA_EXT_SUPERSET(smnpm, RISCV_ISA_EXT_SMNPM, riscv_xlinuxenvcfg_exts),
+	__RISCV_ISA_EXT_SUPERSET(smnpm, RISCV_ISA_EXT_SMNPM, riscv_supm_exts),
 	__RISCV_ISA_EXT_DATA(smstateen, RISCV_ISA_EXT_SMSTATEEN),
 	__RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA),
 	__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
-	__RISCV_ISA_EXT_SUPERSET(ssnpm, RISCV_ISA_EXT_SSNPM, riscv_xlinuxenvcfg_exts),
+	__RISCV_ISA_EXT_SUPERSET(ssnpm, RISCV_ISA_EXT_SSNPM, riscv_supm_exts),
 	__RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
+	__RISCV_ISA_EXT_DATA_VALIDATE(supm, RISCV_ISA_EXT_SUPM, riscv_ext_supm_validate),
 	__RISCV_ISA_EXT_DATA(svade, RISCV_ISA_EXT_SVADE),
 	__RISCV_ISA_EXT_DATA_VALIDATE(svadu, RISCV_ISA_EXT_SVADU, riscv_ext_svadu_validate),
 	__RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL),

-- 
2.43.0


^ permalink raw reply related

* [PATCH 1/3] dt-bindings: riscv: Add Supm extension description
From: Guodong Xu @ 2026-01-16  2:10 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Samuel Holland,
	Heinrich Schuchardt, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Evan Green, Andrew Jones
  Cc: Paul Walmsley, Conor Dooley, devicetree, linux-riscv,
	linux-kernel, Guodong Xu
In-Reply-To: <20260116-supm-ext-id-v1-0-5fcf778ba4a6@riscstar.com>

Add description for the Supm extension. Supm indicates support for pointer
masking in user mode. Supm is mandatory for RVA23S64.

The Supm extension is ratified in commit d70011dde6c2 ("Update to ratified
state") of riscv-j-extension.

Signed-off-by: Guodong Xu <guodong@riscstar.com>
---
 Documentation/devicetree/bindings/riscv/extensions.yaml | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
index 4ffd61926505..1922dff03787 100644
--- a/Documentation/devicetree/bindings/riscv/extensions.yaml
+++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
@@ -262,6 +262,23 @@ properties:
             ratified in RISC-V Profiles Version 1.0, with commit b1d806605f87
             ("Updated to ratified state.")
 
+        - const: supm
+          description: |
+            The standard Supm extension for pointer masking support in user
+            mode (U-mode) as ratified at commit d70011dde6c2 ("Update to
+            ratified state") of riscv-j-extension.
+
+            Supm represents a combination of underlying hardware capability
+            (Smnpm or Ssnpm), U-mode consumer privilege level, and M/S-mode
+            software configuration that enables pointer masking for U-mode.
+
+            DO NOT include this property in device trees targeting privileged
+            system software (S-mode or M-mode).
+
+            This property is only appropriate in device trees provided to
+            U-mode software where the next-higher-privilege-mode supports
+            Smnpm or Ssnpm and enables it for U-mode.
+
         - const: svade
           description: |
             The standard Svade supervisor-level extension for SW-managed PTE A/D

-- 
2.43.0


^ permalink raw reply related

* [PATCH 0/3] riscv: cpufeature: Add Supm extension id and validation
From: Guodong Xu @ 2026-01-16  2:10 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Samuel Holland,
	Heinrich Schuchardt, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Evan Green, Andrew Jones
  Cc: Paul Walmsley, Conor Dooley, devicetree, linux-riscv,
	linux-kernel, Guodong Xu

Supm as an extension indicates pointer-masking support for user mode
(U-mode). It relies on Ssnpm or Smnpm for the underlying hardware
implementation.

As a ratified feature, define a dedicated RISCV_ISA_EXT_ id for Supm.
However, since Supm is targeting U-mode, it should not be added into
devicetrees that describe hardware running privileged system softwares.

Supm is implied by Ssnpm (S-mode) or Smnpm (M-mode). Add parsing logic
and validation to ensure this dependency.

When CONFIG_RISCV_ISA_SUPM is disabled, Supm validation will fail
regardless of whether Ssnpm or Smnpm exist. This patchset doesn't change
this behavior.

Prior discussions about how Supm should be handled can be found in Links
[1] and [2].

Link: https://lore.kernel.org/lkml/20260101-legume-engraved-0fae8282cfbe@spud/#r [1]
Link: https://lore.kernel.org/all/4ebbe14b-2579-4ba6-808d-d50c24641d04@sifive.com/#r [2]

Signed-off-by: Guodong Xu <guodong@riscstar.com>
---
Guodong Xu (3):
      dt-bindings: riscv: Add Supm extension description
      riscv: cpufeature: Add ISA extension parsing for Supm
      riscv: cpufeature: Clarify ISA spec version for canonical order

 .../devicetree/bindings/riscv/extensions.yaml      | 17 ++++++++++
 arch/riscv/include/asm/hwcap.h                     |  3 +-
 arch/riscv/kernel/cpufeature.c                     | 38 ++++++++++++++++++++--
 3 files changed, 53 insertions(+), 5 deletions(-)
---
base-commit: ef41e6187f77b52e4b17ab9637be8f878e1f7a5b
change-id: 20260116-supm-ext-id-826e8da4c4b5

Best regards,
-- 
Guodong Xu <guodong@riscstar.com>


^ permalink raw reply

* Re: [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver
From: Brian Masney @ 2026-01-16  2:05 UTC (permalink / raw)
  To: Anirudh Srinivasan
  Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
	linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
	mpe, mpe, npiggin, agross, agross
In-Reply-To: <20260115-atlantis-clocks-v1-3-7356e671f28b@oss.tenstorrent.com>

Hi Anirudh,

Thanks for the patch!

On Thu, Jan 15, 2026 at 05:42:02PM -0600, Anirudh Srinivasan wrote:
> Add driver for syscon block in Tenstorrent Atlantis SoC. This version of
> the driver coves clocks from RCPU syscon.
> 
> 5 types of clocks generated by this controller: PLLs (PLLs
> with bypass functionality and an additional Gate clk at output), Shared
> Gates (Multiple Gate clks that share an enable bit), standard Muxes,
> Dividers and Gates. All clocks are derived from a 24 Mhz oscillator.
> 
> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> ---
> diff --git a/drivers/clk/tenstorrent/atlantis-ccu.c b/drivers/clk/tenstorrent/atlantis-ccu.c
> new file mode 100644
> index 000000000000..f3a2ea49a82e
> --- /dev/null
> +++ b/drivers/clk/tenstorrent/atlantis-ccu.c
> @@ -0,0 +1,932 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2026 Tenstorrent
> + */
> +
> +#include <linux/array_size.h>
> +#include <linux/auxiliary_bus.h>
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/idr.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/minmax.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#include <soc/tenstorrent/atlantis-syscon.h>
> +
> +#include <dt-bindings/clock/tenstorrent,atlantis-syscon.h>
> +#include <linux/regmap.h>
> +#include <linux/clk-provider.h>
> +#include <linux/math.h>
> +#include <linux/bitfield.h>

Please sort the headers. clk-provider.h is listed twice. Remove the
unnecessary newlines.

> +static void atlantis_ccu_lock(void *_lock)
> +{
> +	spinlock_t *lock = _lock;
> +
> +	spin_lock(lock);
> +}
> +
> +static void atlantis_ccu_unlock(void *_lock)
> +{
> +	spinlock_t *lock = _lock;
> +
> +	spin_unlock(lock);
> +}

Are these abstractions really needed? Why not just call spin_lock/unlock
directly?

> +static int atlantis_ccu_clocks_register(struct device *dev,
> +					struct atlantis_ccu *ccu,
> +					const struct atlantis_ccu_data *data)
> +{
> +	struct regmap *regmap = ccu->regmap;
> +	struct clk_hw_onecell_data *clk_data;
> +	int i, ret;
> +	size_t num_clks = data->num;
> +
> +	clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num),
> +				GFP_KERNEL);
> +	if (!clk_data)
> +		return -ENOMEM;
> +
> +	ccu->clk_data = clk_data;
> +
> +	for (i = 0; i < data->num; i++) {
> +		struct clk_hw *hw = data->hws[i];
> +		const char *name = hw->init->name;
> +		struct atlantis_clk_common *common =
> +			hw_to_atlantis_clk_common(hw);
> +		common->regmap = regmap;
> +
> +		/* Fixup missing handle to parent for gates/muxes/dividers */
> +		if (hw->init->parent_hws && hw->init->num_parents == 1) {
> +			const struct atlantis_clk_common *parent =
> +				hw_to_atlantis_clk_common(
> +					hw->init->parent_hws[0]);
> +			hw->init->parent_hws[0] = clk_data->hws[parent->clkid];
> +		}
> +
> +		switch (common->clk_type) {
> +		case ATLANTIS_CLK_MUX:
> +			struct atlantis_clk_mux *mux =
> +				hw_to_atlantis_clk_mux(hw);
> +
> +			hw = devm_clk_hw_register_mux_parent_data_table(
> +				ccu->dev, name, hw->init->parent_data,
> +				hw->init->num_parents, hw->init->flags,
> +				ccu->base + mux->config.reg_offset,
> +				mux->config.shift, mux->config.width, 0, NULL,
> +				&lock);
> +
> +			if (IS_ERR(hw)) {
> +				dev_err(dev, "Cannot register clock %d - %s\n",
> +					i, name);
> +				return ret;

return PTR_ERR(hw);

> +			}
> +
> +			if (data == &atlantis_ccu_rcpu_data) {
> +				switch (common->clkid) {
> +				case CLK_RCPU_ROOT:
> +					ret = clk_hw_set_parent(
> +						hw,
> +						clk_data->hws[CLK_RCPU_PLL]);

Should the parent be defined in device tree instead of statically in the
driver? devm_of_clk_add_hw_provider() is called below, and it calls
of_clk_set_defaults(), which will allow the use of the
assigned-clock-parents and assigned-clocks properties.

> +					if (ret)
> +						dev_err(ccu->dev,
> +							"Failed to set RCPU ROOT MUX parent: %d\n",
> +							ret);
> +					break;
> +				case CLK_NOCC_CLK:
> +					ret = clk_hw_set_parent(
> +						hw, clk_data->hws[CLK_NOC_PLL]);
> +					if (ret)
> +						dev_err(ccu->dev,
> +							"Failed to set NOCC Mux parent: %d\n",
> +							ret);
> +					break;
> +				}
> +			}
> +			break;
> +		case ATLANTIS_CLK_DIVIDER:
> +			struct atlantis_clk_divider *div =
> +				hw_to_atlantis_clk_divider(hw);
> +
> +			hw = devm_clk_hw_register_divider_parent_hw(
> +				ccu->dev, name, common->hw.init->parent_hws[0],
> +				div->common.hw.init->flags,
> +				ccu->base + div->config.reg_offset,
> +				div->config.shift, div->config.width,
> +				div->config.flags, &lock);
> +
> +			if (IS_ERR(hw)) {
> +				dev_err(dev, "Cannot register clock %d - %s\n",
> +					i, name);
> +				return ret;
> +			}
> +
> +			break;
> +		case ATLANTIS_CLK_GATE:
> +			struct atlantis_clk_gate *gate =
> +				hw_to_atlantis_clk_gate(hw);
> +
> +			hw = devm_clk_hw_register_gate_parent_hw(
> +				ccu->dev, name, common->hw.init->parent_hws[0],
> +				hw->init->flags,
> +				ccu->base + gate->config.reg_offset,
> +				ffs(gate->config.enable) - 1, 0, &lock);
> +
> +			if (IS_ERR(hw)) {
> +				dev_err(dev, "Cannot register clock %d - %s\n",
> +					i, name);
> +				return ret;

return PTR_ERR(hw);

> +			}
> +
> +			break;
> +		case ATLANTIS_CLK_FIXED_FACTOR:
> +			struct atlantis_clk_fixed_factor *factor =
> +				hw_to_atlantis_clk_fixed_factor(hw);
> +
> +			if (hw->init->parent_data) {
> +				hw = devm_clk_hw_register_fixed_factor_index(
> +					dev, name,
> +					hw->init->parent_data[0].index,
> +					hw->init->flags, factor->config.mult,
> +					factor->config.div);
> +			} else {
> +				hw = devm_clk_hw_register_fixed_factor_parent_hw(
> +					dev, name, hw->init->parent_hws[0],
> +					hw->init->flags, factor->config.mult,
> +					factor->config.div);
> +			}
> +			if (IS_ERR(hw)) {
> +				dev_err(dev, "Cannot register clock %d - %s\n",
> +					i, name);
> +				return ret;

return PTR_ERR(hw);

> +			}
> +			break;
> +		case ATLANTIS_CLK_GATE_SHARED:
> +			struct atlantis_clk_gate_shared *gate_shared =
> +				hw_to_atlantis_clk_gate_shared(hw);
> +			gate_shared->config.refcount_lock = &refcount_lock;
> +
> +			ret = devm_clk_hw_register(dev, hw);
> +

Unnecessary newline

> +			if (ret) {
> +				dev_err(dev, "Cannot register clock %d - %s\n",
> +					i, name);
> +				return ret;
> +			}
> +
> +			break;
> +		default:
> +
> +			ret = devm_clk_hw_register(dev, hw);
> +

Unnecessary newline

Brian


^ permalink raw reply

* Re: [PATCH] dt-bindings: net: wireless: ath11k: Combine two if:then: clauses
From: Jeff Johnson @ 2026-01-16  1:26 UTC (permalink / raw)
  To: Johannes Berg, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jeff Johnson, linux-wireless, devicetree, ath11k, linux-kernel,
	Krzysztof Kozlowski
In-Reply-To: <20251230114835.52504-2-krzysztof.kozlowski@oss.qualcomm.com>


On Tue, 30 Dec 2025 12:48:36 +0100, Krzysztof Kozlowski wrote:
> Simplify the binding by combining two if:then: clauses which have
> exactly the same conditional part.
> 
> 

Applied, thanks!

[1/1] dt-bindings: net: wireless: ath11k: Combine two if:then: clauses
      commit: 2125381d60c572684cc4ca61a2b1cf44c7eab059

Best regards,
-- 
Jeff Johnson <jeff.johnson@oss.qualcomm.com>


^ permalink raw reply

* Re: [PATCH 8/8] riscv: dts: sophgo: add Milk-V Duo 256M board dts
From: Inochi Amaoto @ 2026-01-15 23:35 UTC (permalink / raw)
  To: Anton D. Stavinskii, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Chen Wang, Inochi Amaoto,
	Jaroslav Kysela, Takashi Iwai, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexandre Ghiti
  Cc: linux-sound, devicetree, sophgo, linux-kernel, linux-riscv
In-Reply-To: <20260115-cv1800b-i2s-driver-v1-8-e8b22b8578ab@gmail.com>

On Thu, Jan 15, 2026 at 11:17:45PM +0400, Anton D. Stavinskii wrote:
> Example of usage internal dac/adc and external I2S mic
> The example shows how to use the card and
> will actually work other boards.
> Fixed clocks needed to make simple card make
> initial .set_sysclk with proper clock rates.
> Same for DAC. I2S3 has to be started not only
> for DAC but for the ADC also because it
> provides mclk for both.
> 
> dai-link@2 will only work if registers
> are set according to this issue
> https://github.com/sophgo/sophgo-doc/issues/174#event-21395297524
> in other case i2s2 will not output clocks and data.
> Those changes are not connected to the driver itself,
> but for another subsystem which is not yet ipmlemented.
> The following config properly works for MilkV Duo/256Mm, Module.
> Basically everything with sg2000/sg2002 but on some boards
> i2s2 output pins are soldered to Ethernet module.
> In Milk 256M they are free to use as external DAC/ADC.
> 
> Signed-off-by: Anton D. Stavinskii <stavinsky@gmail.com>
> ---
>  arch/riscv/boot/dts/sophgo/Makefile                |   1 +
>  .../boot/dts/sophgo/sg2002-milkv-duo-256m.dts      | 231 +++++++++++++++++++++
>  2 files changed, 232 insertions(+)
> 
> diff --git a/arch/riscv/boot/dts/sophgo/Makefile b/arch/riscv/boot/dts/sophgo/Makefile
> index 6f65526d4193..c8901ff680cb 100644
> --- a/arch/riscv/boot/dts/sophgo/Makefile
> +++ b/arch/riscv/boot/dts/sophgo/Makefile
> @@ -6,3 +6,4 @@ dtb-$(CONFIG_ARCH_SOPHGO) += sg2042-milkv-pioneer.dtb
>  dtb-$(CONFIG_ARCH_SOPHGO) += sg2042-evb-v1.dtb
>  dtb-$(CONFIG_ARCH_SOPHGO) += sg2042-evb-v2.dtb
>  dtb-$(CONFIG_ARCH_SOPHGO) += sg2044-sophgo-srd3-10.dtb
> +dtb-$(CONFIG_ARCH_SOPHGO) += sg2002-milkv-duo-256m.dtb
> diff --git a/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo-256m.dts b/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo-256m.dts
> new file mode 100644
> index 000000000000..cc33c4355969
> --- /dev/null
> +++ b/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo-256m.dts
> @@ -0,0 +1,231 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (C) 2024 Thomas Bonnefille <thomas.bonnefille@bootlin.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "sg2002.dtsi"
> +
> +/ {
> +	model = "Milk-V duo 256M";
> +	compatible = "milkv,duo-256m",
> +	"sipeed,licheerv-nano",
> +	"sophgo,sg2002";
> +
> +	aliases {
> +		gpio0 = &gpio0;
> +		gpio1 = &gpio1;
> +		gpio2 = &gpio2;
> +		gpio3 = &gpio3;
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +		serial2 = &uart2;
> +		serial3 = &uart3;
> +		serial4 = &uart4;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +};
> +
> +&osc {
> +	clock-frequency = <25000000>;
> +};
> +
> +&pinctrl {
> +	uart0_cfg: uart0-cfg {
> +		uart0-pins {
> +			pinmux = <PINMUX(PIN_UART0_TX, 0)>,
> +			<PINMUX(PIN_UART0_RX, 0)>;
> +			bias-pull-up;
> +			drive-strength-microamp = <10800>;
> +			power-source = <3300>;
> +		};
> +	};
> +
> +	sdhci0_cfg: sdhci0-cfg {
> +		sdhci0-clk-pins {
> +			pinmux = <PINMUX(PIN_SD0_CLK, 0)>;
> +			bias-pull-up;
> +			drive-strength-microamp = <16100>;
> +			power-source = <3300>;
> +		};
> +
> +		sdhci0-cmd-pins {
> +			pinmux = <PINMUX(PIN_SD0_CMD, 0)>;
> +			bias-pull-up;
> +			drive-strength-microamp = <10800>;
> +			power-source = <3300>;
> +		};
> +
> +		sdhci0-data-pins {
> +			pinmux = <PINMUX(PIN_SD0_D0, 0)>,
> +			<PINMUX(PIN_SD0_D1, 0)>,
> +			<PINMUX(PIN_SD0_D2, 0)>,
> +			<PINMUX(PIN_SD0_D3, 0)>;
> +			bias-pull-up;
> +			drive-strength-microamp = <10800>;
> +			power-source = <3300>;
> +		};
> +
> +		sdhci0-cd-pins {
> +			pinmux = <PINMUX(PIN_SD0_CD, 0)>;
> +			bias-pull-up;
> +			drive-strength-microamp = <10800>;
> +			power-source = <3300>;
> +		};
> +	};
> +};
> +
> +&sdhci0 {
> +	pinctrl-0 = <&sdhci0_cfg>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +	bus-width = <4>;
> +	no-1-8-v;
> +	no-mmc;
> +	no-sdio;
> +	disable-wp;
> +};
> +
> +&usb {
> +	dr_mode = "peripheral";
> +	status = "okay";
> +	g-rx-fifo-size = <1536>;
> +	g-tx-fifo-size = <128 128 64 64 64 64 32 32>;
> +};
> +
> +&uart0 {
> +	pinctrl-0 = <&uart0_cfg>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +};
> +
> +&dmac {
> +	status = "okay";
> +};
> +
> +&dmamux {
> +	status = "okay";
> +};
> +
> +&pinctrl {
> +	i2s2_cfg: i2s2-cfg {
> +		i2s2-out-pins {
> +			pinmux = <PINMUX(PIN_ETH_TXM, 7)>,
> +			<PINMUX(PIN_ETH_RXP,  7)>,
> +			<PINMUX(PIN_ETH_RXM,  7)>;
> +
> +			drive-strength-microamp = <15700>;
> +			power-source = <1800>;
> +		};
> +
> +		i2s2-in-pins {
> +			pinmux = <PINMUX(PIN_ETH_TXP, 7)>;
> +			power-source = <1800>;
> +		};
> +	};
> +};
> +
> +&i2s0 {
> +	#sound-dai-cells = <0>;
> +	status = "okay";
> +};
> +
> +&i2s2 {
> +	pinctrl-0 = <&i2s2_cfg>;
> +	pinctrl-names = "default";
> +	#sound-dai-cells = <0>;
> +	status = "okay";
> +};
> +
> +&i2s3 {
> +	#sound-dai-cells = <0>;
> +	status = "okay";
> +};
> +
> +/ {

> +	int_adc: codec@300a100 {
> +		compatible = "sophgo,cv1800b-sound-adc";
> +		#sound-dai-cells = <0>;
> +		reg = <0x300a100 0x100>;
> +	};
> +
> +	int_dac: codec@300a000 {
> +		compatible = "sophgo,cv1800b-sound-dac";
> +		#sound-dai-cells = <0>;
> +		reg = <0x300a000 0x100>;
> +	};
> +

Move these two nodes into cv180x.dtsi, others are not allowed
in this patch series, use a separate patch instead.

Regards,
Inochi


> +	ext_adc: my-ext-adc {
> +		compatible = "invensense,ics43432";
> +		#sound-dai-cells = <0>;
> +	};
> +
> +	sound {
> +		compatible = "simple-audio-card";
> +		simple-audio-card,name = "cv1800b card";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		simple-audio-card,dai-link@0 {
> +			reg = <0>;
> +			format = "i2s";
> +			bitclock-master = <&clock_master0>;
> +			frame-master = <&clock_master0>;
> +
> +			codec {
> +				sound-dai = <&int_dac>;
> +			};
> +
> +			clock_master0: cpu {
> +				system-clock-frequency = <12288000>;
> +				system-clock-fixed;
> +				system-clock-direction-out;
> +				mclk-fs = <256>;
> +				sound-dai = <&i2s3>;
> +			};
> +		};
> +
> +		simple-audio-card,dai-link@1 {
> +			reg = <1>;
> +			format = "i2s";
> +			bitclock-master = <&clock_master1>;
> +			frame-master = <&clock_master1>;
> +
> +			clock_master1: codec {
> +				mclk-fs = <256>;
> +				system-clock-frequency = <12288000>;
> +				system-clock-fixed;
> +				sound-dai = <&int_adc>;
> +			};
> +
> +			cpu {
> +				mclk-fs = <256>;
> +				system-clock-frequency = <12288000>;
> +				system-clock-fixed;
> +				sound-dai = <&i2s0>;
> +			};
> +		};
> +
> +		simple-audio-card,dai-link@2 {
> +			reg = <2>;
> +			format = "i2s";
> +			bitclock-master = <&clock_master2>;
> +			frame-master = <&clock_master2>;
> +
> +			codec {
> +				sound-dai = <&ext_adc>;
> +			};
> +
> +			clock_master2: cpu {
> +				mclk-fs = <256>;
> +				system-clock-frequency = <12288000>;
> +				system-clock-fixed;
> +				sound-dai = <&i2s2>;
> +			};
> +		};
> +	};
> +};
> 
> -- 
> 2.43.0
> 

^ permalink raw reply

* Re: [PATCH v2 2/3] dt-binding: rtc: loongson: Document Loongson-2K0300 compatible
From: Binbin Zhou @ 2026-01-16  1:14 UTC (permalink / raw)
  To: Rob Herring
  Cc: Binbin Zhou, Huacai Chen, Krzysztof Kozlowski, Conor Dooley,
	Alexandre Belloni, linux-rtc, Xiaochuang Mao, Huacai Chen,
	Xuerui Wang, loongarch, devicetree, linux-mips, Keguang Zhang
In-Reply-To: <CAL_JsqJVD3o41Zch6fMY6s-qmyd9cQg6CJ+iya+3kdtuqvNMoA@mail.gmail.com>

Hi Rob:

Thanks for your reply.

On Fri, Jan 16, 2026 at 1:00 AM Rob Herring <robh@kernel.org> wrote:
>
> On Thu, Jan 15, 2026 at 1:39 AM Binbin Zhou <zhoubb.aaron@gmail.com> wrote:
> >
> > Hi Rob:
> >
> > Thanks for your reply.
> >
> > On Thu, Jan 15, 2026 at 4:58 AM Rob Herring <robh@kernel.org> wrote:
> > >
> > > On Wed, Jan 07, 2026 at 09:22:41AM +0800, Binbin Zhou wrote:
> > > > Hi Rob:
> > > >
> > > > Thanks for your review.
> > > >
> > > > On Wed, Jan 7, 2026 at 3:13 AM Rob Herring <robh@kernel.org> wrote:
> > > > >
> > > > > On Tue, Jan 06, 2026 at 09:33:32AM +0800, Binbin Zhou wrote:
> > > > > > Add "loongson,ls2k0300-rtc" dedicated compatible to represent the RTC
> > > > > > interface of the Loongson-2K0300 chip.
> > > > > >
> > > > > > Its hardware design is similar to that of the Loongson-1B, but it does
> > > > > > not support the alarm feature.
> > > > >
> > > > > But you are requiring the interrupt property for it? Isn't it no alarm
> > > > > feature means no interrupt?
> > > >
> > > > Yes, the `interrupts` attribute is not required without the alarm feature.
> > > >
> > > > But my judgment condition is `not contains` (added in patch-1[1]).
> > > > There are only a few SoCs on the Loongson platform that don't support
> > > > the RTC alarm feature, so I think `not contains` looks cleaner and
> > > > simpler.
> > >
> > > I should have said allowing rather than requiring.
> > >
> > > You are allowing (though not requiring) 'interrupts' for Loongson-1B and
> > > Loongson-2K0300. In patch 1, you made it required for other platforms
> > > which is an ABI change. That's fine if it was a mistake and is truly
> > > required.
> >
> > Emm, it's true that for the binding interface, Patch-1 is indeed an
> > ABI change, but it's more of a fixed patch.
> >
> > Throughout all existing Loongson DTS{i}, RTC nodes decide whether to
> > include the `interrupts` property or not based on the alarm feature.
> > Loongson-1c rtc nodes do not include the `interrupts` attribute [1],
> > while all other Loongson chip rtc nodes do [2].
> >
> > So, while this is an ABI change, I don't think it affects existing
> > Loongson DTS{i} rtc nodes. Also, it more accurately describes the
> > features of the corresponding RTC device.
> >
> > Therefore, I would like to clarify it in the Patch-1 commit message of
> > the next patch version and fix the error in the commit title:
> > dt-binding -> dt-bindings.
> >
> > How do you feel about that?
>
> That's fine, but you also need:
>
> else:
>   properties:
>     interrupts: false
>
> So that on the 2 platforms without an interrupt(alarm), 'interrupts'
> is not allowed.
>
> With that, you might as well just drop the 'not' and flip the 'then'
> and 'else' schemas around.

OK, I'll fall back to the writeup in the v1 patchset as follows:

if:
  properties:
    compatible:
      contains:
        enum:
          - loongson,ls1c-rtc
          - loongson,ls2k0300-rtc

then:
  properties:
    interrupts: false

>
> Rob

-- 
Thanks.
Binbin

^ permalink raw reply

* [PATCH v4 0/5] Fix sd card support for RK3576 platform
From: Shawn Lin @ 2026-01-16  0:55 UTC (permalink / raw)
  To: Heiko Stuebner, Ulf Hansson
  Cc: linux-rockchip, linux-mmc, devicetree, FUKAUMI Naoki,
	Marco Schirrmeister, John Clark, Tianling Shen, Detlev Casanova,
	Shawn Lin


Marco reported a problem[1] for his FriendlyElec NanoPi R76S board. The problem
is becuase after runtime suspend, the associated power domain is powered off, which
resets the registers including power control bit, card detection logic and internal
phase registers. This leads to three problems need to be solved.

1. hot-plug broken:

SD card hot-plug support for RK3576 boards is broken, because sd slot should try to
use slot-gpio(cd-gpios) instead of function IO for supporting runtime PM. In order
to support slot-gpio detection method, we should disable jtag switching for RK3576.

But the rockchip_grf_init fails to handle this because it couldn't handle
multiple grf nodes. In this case, iocgrf is in behind of sysgrf, so only
sysgrf is handled. We should scan all possible nodes.

Moreover, the offset is wrong as well. Per the TRM, the address of
TOP_IOC_IOC_MISC_CON is 0x260440F0, which means the offset if 0x40F0
instead of 0x040F.

2. cards lost power:

When powering off the power domain during runtime suspend, the controller fails to
maintain the power control status as all the registers is cleared. This results in
power lost for cards during runtime suspend and have to reset the card each time
exiting from runtime supended state. Should use gpio-based regulator for vmmc-suppy
for the boards.

3. controller lost internal phases/mem-clock settings

As the same reason mentioned above, should invent rockchip specific runtime PM
callbacks to save and restore internal phase related settings.

Note: An examination of the RK3576 related dts files suggests that several other boards
may also not function correctly, because I noticed signs of copy-pasting, but I don't have
the schematics to confirm it, I've cc'ed the users of these boards. I hope they can verify
their own boards and submit separate patches if fixes are needed.

Please help review and test.

[1] https://lore.kernel.org/all/20260110010715.1610159-1-mschirrmeister@gmail.com/T/#t


Changes in v4
- add fix patches for RK3576 EVB1 and NanoPi R76S

Changes in v3:
- remove of_node_put() (Heiko)

Changes in v2:
- use for_each_matching_node_and_match(Heiko)

Shawn Lin (5):
  soc: rockchip: grf: Fix wrong RK3576_IOCGRF_MISC_CON definition
  soc: rockchip: grf: Support multiple grf to be handled
  mmc: dw_mmc-rockchip: Fix runtime PM support for internal phase
    support
  arm64: dts: rockchip: Fix SD card support for RK3576 EVB1
  arm64: dts: rockchip: Fix SD card support for RK3576 Nanopi R76s

 arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts   | 22 +++++++++
 .../arm64/boot/dts/rockchip/rk3576-nanopi-r76s.dts | 23 ++++++++-
 drivers/mmc/host/dw_mmc-rockchip.c                 | 38 ++++++++++++++-
 drivers/soc/rockchip/grf.c                         | 57 +++++++++++-----------
 4 files changed, 109 insertions(+), 31 deletions(-)

-- 
2.7.4


^ permalink raw reply

* Re: [PATCH 0/8] ASoC: sophgo: add CV1800 AIAO mux and I2S support
From: Inochi Amaoto @ 2026-01-15 23:34 UTC (permalink / raw)
  To: Anton D. Stavinskii, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Chen Wang, Inochi Amaoto,
	Jaroslav Kysela, Takashi Iwai, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexandre Ghiti
  Cc: linux-sound, devicetree, sophgo, linux-kernel, linux-riscv
In-Reply-To: <20260115-cv1800b-i2s-driver-v1-0-e8b22b8578ab@gmail.com>

On Thu, Jan 15, 2026 at 11:17:37PM +0400, Anton D. Stavinskii wrote:
> This patch series adds basic audio support for Sophgo CV1800B, 
> as used on boards such as the Milk-V Duo. 
> The series introduces an AIAO audio mux driver, 
> an I2S controller driver, corresponding DT bindings, 
> and DTS updates to wire the components together.
> 

I haven't see your mux driver, is it missed?

> The implementation is based on vendor documentation 
> and testing on real hardware.  This series relies on 
> recent fixes in the DesignWare AXI DMA support; 
> in particular, correct operation depends on 
> the DMA changes discussed at:
> https://lore.kernel.org/all/20251214224601.598358-1-inochiama@gmail.com/ 
> The current driver implementation supports a fixed audio configuration 
> of 48 kHz sample rate.  The series has been tested on the 
> Milk-V Duo 256M board using the Sophgo SG2002 SoC. 
> The implementation is expected to also work on Milk-V Duo and Milk-V Module 
> boards based on the SG2000 SoC, as the audio 
> and DMA blocks are closely related.
> 
> Known hardware limitation:
> On CV1800B / SG2002, the I2S2 output pins cannot be enabled via pinctrl alone.
> Due to SoC design constraints, the output path becomes functional only after 
> additional vendor-specific register programming. 
> This series makes the limitation explicit and does not attempt to work around 
> it implicitly via pinctrl or undocumented behavior.
> 
> Signed-off-by: Anton D. Stavinskii <stavinsky@gmail.com>
> ---
> Anton D. Stavinskii (8):
>       dt-bindings: sound: sophgo: add CV1800B I2S/TDM controller binding
>       ASoC: sophgo: add CV1800B I2S/TDM controller driver
>       dt-bindings: sound: sophgo: add CV1800B internal ADC codec
>       ASoC: sophgo: add CV1800B internal ADC codec driver
>       dt-bindings: sound: sophgo: add CV1800B internal DAC codec
>       ASoC: sophgo: add CV1800B internal DAC codec driver
>       riscv: dts: sophgo: dts nodes for i2s tdm modules
>       riscv: dts: sophgo: add Milk-V Duo 256M board dts
> 
>  .../bindings/sound/sophgo,cv1800b-i2s.yaml         |  75 +++
>  .../bindings/sound/sophgo,cv1800b-sound-adc.yaml   |  43 ++
>  .../bindings/sound/sophgo,cv1800b-sound-dac.yaml   |  43 ++
>  arch/riscv/boot/dts/sophgo/Makefile                |   1 +
>  arch/riscv/boot/dts/sophgo/cv180x-dmamux.h         |  57 ++
>  arch/riscv/boot/dts/sophgo/cv180x.dtsi             |  49 ++
>  .../boot/dts/sophgo/sg2002-milkv-duo-256m.dts      | 231 +++++++
>  sound/soc/Kconfig                                  |   1 +
>  sound/soc/Makefile                                 |   1 +
>  sound/soc/sophgo/Kconfig                           |  41 ++
>  sound/soc/sophgo/Makefile                          |   5 +
>  sound/soc/sophgo/cv1800b-sound-adc.c               | 322 ++++++++++
>  sound/soc/sophgo/cv1800b-sound-dac.c               | 204 ++++++
>  sound/soc/sophgo/cv1800b-tdm.c                     | 714 +++++++++++++++++++++
>  14 files changed, 1787 insertions(+)
> ---
> base-commit: 7a52965b6976c936f413eebeee3f78c6faf09012
> change-id: 20260115-cv1800b-i2s-driver-4f17836dec56
> 
> Best regards,
> -- 
> Anton D. Stavinskii <stavinsky@gmail.com>
> 

Thanks for your patch, for all the patchs, I hope you write a
meaningful comment for the patch, at least for now I found it
is nothing in your comment.

Also, the patch 8 should not in this patch and should be a
separate patch.

Regards,
Inochi

^ permalink raw reply

* [PATCH v4 4/5] arm64: dts: rockchip: Fix SD card support for RK3576 EVB1
From: Shawn Lin @ 2026-01-16  0:55 UTC (permalink / raw)
  To: Heiko Stuebner, Ulf Hansson
  Cc: linux-rockchip, linux-mmc, devicetree, FUKAUMI Naoki,
	Marco Schirrmeister, John Clark, Tianling Shen, Detlev Casanova,
	Shawn Lin
In-Reply-To: <1768524932-163929-1-git-send-email-shawn.lin@rock-chips.com>

When runtime suspend is enabled, the associated power domain is powered
off, which resets the registers, including the power control bit. As a result,
the card loses power during runtime suspend. The card should still be able
to process I/O with the help of mmc_blk_mq_rw_recovery(), which is suboptimal.
To address this issue, we must use vmmc-supply with a GPIO based method to
maintain power to the card. Also, add cd-gpios method to make hot-plug work
correctly during idle periods.

Fixes: f135a1a07352 ("arm64: dts: rockchip: Add rk3576 evb1 board")
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---

Changes in v3: None
Changes in v2: None

 arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts
index 0789733..f5746bc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts
@@ -223,6 +223,18 @@
 		vin-supply = <&vcc_3v3_s3>;
 	};
 
+	vcc3v3_sd: regulator-vcc-3v3-sd {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdmmc_pwren>;
+		regulator-name = "vcc3v3_sd";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_3v3_s0>;
+	};
+
 	vcc_ufs_s0: regulator-vcc-ufs-s0 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc_ufs_s0";
@@ -904,6 +916,12 @@
 		};
 	};
 
+	sdmmc {
+		sdmmc_pwren: sdmmc-pwren {
+			rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	usb {
 		usb_host_pwren: usb-host-pwren {
 			rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -958,11 +976,15 @@
 	bus-width = <4>;
 	cap-mmc-highspeed;
 	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
 	disable-wp;
 	max-frequency = <200000000>;
 	no-sdio;
 	no-mmc;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_det &sdmmc0_bus4>;
 	sd-uhs-sdr104;
+	vmmc-supply = <&vcc3v3_sd>;
 	vqmmc-supply = <&vccio_sd_s0>;
 	status = "okay";
 };
-- 
2.7.4


^ permalink raw reply related

* [PATCH v4 3/5] mmc: dw_mmc-rockchip: Fix runtime PM support for internal phase support
From: Shawn Lin @ 2026-01-16  0:55 UTC (permalink / raw)
  To: Heiko Stuebner, Ulf Hansson
  Cc: linux-rockchip, linux-mmc, devicetree, FUKAUMI Naoki,
	Marco Schirrmeister, John Clark, Tianling Shen, Detlev Casanova,
	Shawn Lin
In-Reply-To: <1768524932-163929-1-git-send-email-shawn.lin@rock-chips.com>

RK3576 is the first platform to introduce internal phase support, and
subsequent platforms are expected to adopt a similar design. In this
architecture, runtime suspend powers off the attached power domain, which
resets registers, including vendor-specific ones such as SDMMC_TIMING_CON0,
SDMMC_TIMING_CON1, and SDMMC_MISC_CON. These registers must be saved and
restored, a requirement that falls outside the scope of the dw_mmc core.

Fixes: 59903441f5e4 ("mmc: dw_mmc-rockchip: Add internal phase support")
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Tested-by: Marco Schirrmeister <mschirrmeister@gmail.com>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/host/dw_mmc-rockchip.c | 38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index 879188f..2fe0896 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -36,6 +36,8 @@ struct dw_mci_rockchip_priv_data {
 	int			default_sample_phase;
 	int			num_phases;
 	bool			internal_phase;
+	int                     sample_phase;
+	int                     drv_phase;
 };
 
 /*
@@ -573,9 +575,43 @@ static void dw_mci_rockchip_remove(struct platform_device *pdev)
 	dw_mci_pltfm_remove(pdev);
 }
 
+static int dw_mci_rockchip_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_mci *host = platform_get_drvdata(pdev);
+	struct dw_mci_rockchip_priv_data *priv = host->priv;
+
+	if (priv->internal_phase) {
+		priv->sample_phase = rockchip_mmc_get_phase(host, true);
+		priv->drv_phase = rockchip_mmc_get_phase(host, false);
+	}
+
+	return dw_mci_runtime_suspend(dev);
+}
+
+static int dw_mci_rockchip_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_mci *host = platform_get_drvdata(pdev);
+	struct dw_mci_rockchip_priv_data *priv = host->priv;
+	int ret;
+
+	ret = dw_mci_runtime_resume(dev);
+	if (ret)
+		return ret;
+
+	if (priv->internal_phase) {
+		rockchip_mmc_set_phase(host, true, priv->sample_phase);
+		rockchip_mmc_set_phase(host, false, priv->drv_phase);
+		mci_writel(host, MISC_CON, MEM_CLK_AUTOGATE_ENABLE);
+	}
+
+	return ret;
+}
+
 static const struct dev_pm_ops dw_mci_rockchip_dev_pm_ops = {
 	SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
-	RUNTIME_PM_OPS(dw_mci_runtime_suspend, dw_mci_runtime_resume, NULL)
+	RUNTIME_PM_OPS(dw_mci_rockchip_runtime_suspend, dw_mci_rockchip_runtime_resume, NULL)
 };
 
 static struct platform_driver dw_mci_rockchip_pltfm_driver = {
-- 
2.7.4


^ permalink raw reply related

* [PATCH v4 2/5] soc: rockchip: grf: Support multiple grf to be handled
From: Shawn Lin @ 2026-01-16  0:55 UTC (permalink / raw)
  To: Heiko Stuebner, Ulf Hansson
  Cc: linux-rockchip, linux-mmc, devicetree, FUKAUMI Naoki,
	Marco Schirrmeister, John Clark, Tianling Shen, Detlev Casanova,
	Shawn Lin
In-Reply-To: <1768524932-163929-1-git-send-email-shawn.lin@rock-chips.com>

Currently, only the first matched node will be handled. This leads
to jtag switching broken for RK3576, as rk3576-sys-grf is found before
rk3576-ioc-grf. Change the code to scan all the possible node to fix
the problem.

Fixes: e1aaecacfa13 ("soc: rockchip: grf: Add rk3576 default GRF values")
Cc: Detlev Casanova <detlev.casanova@collabora.com>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Tested-by: Marco Schirrmeister <mschirrmeister@gmail.com>
---

Changes in v4:
- none

Changes in v3:
- remove of_node_put() (Heiko)

Changes in v2:
- use for_each_matching_node_and_match(Heiko)

 drivers/soc/rockchip/grf.c | 55 +++++++++++++++++++++++-----------------------
 1 file changed, 27 insertions(+), 28 deletions(-)

diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c
index 8974d1c..04937c4 100644
--- a/drivers/soc/rockchip/grf.c
+++ b/drivers/soc/rockchip/grf.c
@@ -217,34 +217,33 @@ static int __init rockchip_grf_init(void)
 	struct regmap *grf;
 	int ret, i;
 
-	np = of_find_matching_node_and_match(NULL, rockchip_grf_dt_match,
-					     &match);
-	if (!np)
-		return -ENODEV;
-	if (!match || !match->data) {
-		pr_err("%s: missing grf data\n", __func__);
-		of_node_put(np);
-		return -EINVAL;
-	}
-
-	grf_info = match->data;
-
-	grf = syscon_node_to_regmap(np);
-	of_node_put(np);
-	if (IS_ERR(grf)) {
-		pr_err("%s: could not get grf syscon\n", __func__);
-		return PTR_ERR(grf);
-	}
-
-	for (i = 0; i < grf_info->num_values; i++) {
-		const struct rockchip_grf_value *val = &grf_info->values[i];
-
-		pr_debug("%s: adjusting %s in %#6x to %#10x\n", __func__,
-			val->desc, val->reg, val->val);
-		ret = regmap_write(grf, val->reg, val->val);
-		if (ret < 0)
-			pr_err("%s: write to %#6x failed with %d\n",
-			       __func__, val->reg, ret);
+	for_each_matching_node_and_match(np, rockchip_grf_dt_match, &match) {
+		if (!of_device_is_available(np))
+			continue;
+		if (!match || !match->data) {
+			pr_err("%s: missing grf data\n", __func__);
+			of_node_put(np);
+			return -EINVAL;
+		}
+
+		grf_info = match->data;
+
+		grf = syscon_node_to_regmap(np);
+		if (IS_ERR(grf)) {
+			pr_err("%s: could not get grf syscon\n", __func__);
+			return PTR_ERR(grf);
+		}
+
+		for (i = 0; i < grf_info->num_values; i++) {
+			const struct rockchip_grf_value *val = &grf_info->values[i];
+
+			pr_debug("%s: adjusting %s in %#6x to %#10x\n", __func__,
+				val->desc, val->reg, val->val);
+			ret = regmap_write(grf, val->reg, val->val);
+			if (ret < 0)
+				pr_err("%s: write to %#6x failed with %d\n",
+					__func__, val->reg, ret);
+		}
 	}
 
 	return 0;
-- 
2.7.4


^ permalink raw reply related

* [PATCH net-next v3 6/6] net: dsa: mxl-gsw1xx: add support for Intel GSW150
From: Daniel Golle @ 2026-01-16  0:08 UTC (permalink / raw)
  To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Russell King, netdev,
	devicetree, linux-kernel
  Cc: Chen Minqiang, Xinfa Deng
In-Reply-To: <cover.1768519376.git.daniel@makrotopia.org>

Add support for the Intel GSW150 (aka. Lantiq PEB7084) switch IC to
the mxl-gsw1xx driver. This switch comes with 5 Gigabit Ethernet
copper ports (Intel XWAY PHY11G (xRX v1.2 integrated) PHYs) as well as
one GMII/RGMII and one RGMII port.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: enclose the gswip_hw_info initializers in compiler diag exception
    to prevent triggering -Woverride-init

v2: clean-up phylink_get_caps

 drivers/net/dsa/lantiq/mxl-gsw1xx.c | 61 ++++++++++++++++++++++++++---
 drivers/net/dsa/lantiq/mxl-gsw1xx.h |  2 +
 2 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/drivers/net/dsa/lantiq/mxl-gsw1xx.c b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
index 54cf7aab3bfe4..0d18b79647064 100644
--- a/drivers/net/dsa/lantiq/mxl-gsw1xx.c
+++ b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
@@ -503,6 +503,14 @@ static const struct phylink_pcs_ops gsw1xx_pcs_ops = {
 	.pcs_link_up = gsw1xx_pcs_link_up,
 };
 
+static void gsw1xx_phylink_get_lpi_caps(struct phylink_config *config)
+{
+	config->lpi_capabilities = MAC_100FD | MAC_1000FD;
+	config->lpi_timer_default = 20;
+	memcpy(config->lpi_interfaces, config->supported_interfaces,
+	       sizeof(config->lpi_interfaces));
+}
+
 static void gsw1xx_phylink_get_caps(struct dsa_switch *ds, int port,
 				    struct phylink_config *config)
 {
@@ -536,10 +544,32 @@ static void gsw1xx_phylink_get_caps(struct dsa_switch *ds, int port,
 		break;
 	}
 
-	config->lpi_capabilities = MAC_100FD | MAC_1000FD;
-	config->lpi_timer_default = 20;
-	memcpy(config->lpi_interfaces, config->supported_interfaces,
-	       sizeof(config->lpi_interfaces));
+	gsw1xx_phylink_get_lpi_caps(config);
+}
+
+static void gsw150_phylink_get_caps(struct dsa_switch *ds, int port,
+				    struct phylink_config *config)
+{
+	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+				   MAC_10 | MAC_100 | MAC_1000;
+
+	switch (port) {
+	case 0 ... 4: /* built-in PHYs */
+		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
+			  config->supported_interfaces);
+		break;
+
+	case 5: /* GMII or RGMII */
+		__set_bit(PHY_INTERFACE_MODE_GMII,
+			  config->supported_interfaces);
+		fallthrough;
+
+	case 6: /* RGMII */
+		phy_interface_set_rgmii(config->supported_interfaces);
+		break;
+	}
+
+	gsw1xx_phylink_get_lpi_caps(config);
 }
 
 static struct phylink_pcs *gsw1xx_phylink_mac_select_pcs(struct phylink_config *config,
@@ -768,6 +798,25 @@ static const struct gswip_hw_info gsw141_data = {
 	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
 };
 
+static const struct gswip_hw_info gsw150_data = {
+	.max_ports		= GSW150_PORTS,
+	.allowed_cpu_ports	= BIT(5) | BIT(6),
+	.mii_cfg = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[5] = 0,
+		[6] = 10,
+	},
+	.mii_pcdu = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[5] = 1,
+		[6] = 11,
+	},
+	.phylink_get_caps	= gsw150_phylink_get_caps,
+	.pce_microcode		= &gsw1xx_pce_microcode,
+	.pce_microcode_size	= ARRAY_SIZE(gsw1xx_pce_microcode),
+	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
+};
+
 __diag_pop();
 
 /*
@@ -775,6 +824,8 @@ __diag_pop();
  * GSW145 is the industrial temperature version of GSW140.
  */
 static const struct of_device_id gsw1xx_of_match[] = {
+	{ .compatible = "intel,gsw150", .data = &gsw150_data },
+	{ .compatible = "lantiq,peb7084", .data = &gsw150_data },
 	{ .compatible = "maxlinear,gsw120", .data = &gsw12x_data },
 	{ .compatible = "maxlinear,gsw125", .data = &gsw12x_data },
 	{ .compatible = "maxlinear,gsw140", .data = &gsw140_data },
@@ -798,5 +849,5 @@ static struct mdio_driver gsw1xx_driver = {
 mdio_module_driver(gsw1xx_driver);
 
 MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
-MODULE_DESCRIPTION("Driver for MaxLinear GSW1xx ethernet switch");
+MODULE_DESCRIPTION("Driver for Intel/MaxLinear GSW1xx Ethernet switch");
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/lantiq/mxl-gsw1xx.h b/drivers/net/dsa/lantiq/mxl-gsw1xx.h
index 38e03c048a26c..087587f62e5e1 100644
--- a/drivers/net/dsa/lantiq/mxl-gsw1xx.h
+++ b/drivers/net/dsa/lantiq/mxl-gsw1xx.h
@@ -10,6 +10,8 @@
 #include <linux/bitfield.h>
 
 #define GSW1XX_PORTS				6
+#define GSW150_PORTS				7
+
 /* Port used for RGMII or optional RMII */
 #define GSW1XX_MII_PORT				5
 /* Port used for SGMII */
-- 
2.52.0

^ permalink raw reply related

* [PATCH net-next v3 5/6] net: dsa: mxl-gsw1xx: only setup SerDes PCS if it exists
From: Daniel Golle @ 2026-01-16  0:07 UTC (permalink / raw)
  To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Russell King, netdev,
	devicetree, linux-kernel
  Cc: Chen Minqiang, Xinfa Deng
In-Reply-To: <cover.1768519376.git.daniel@makrotopia.org>

Older Intel GSW150 chip doesn't have a SGMII/1000Base-X/2500Base-X PCS.
Prepare for supporting Intel GSW150 by skipping PCS reset and
initialization in case no .mac_select_pcs operation is defined.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: no changes
v2: new patch

 drivers/net/dsa/lantiq/mxl-gsw1xx.c | 37 ++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/drivers/net/dsa/lantiq/mxl-gsw1xx.c b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
index 0267196f98464..54cf7aab3bfe4 100644
--- a/drivers/net/dsa/lantiq/mxl-gsw1xx.c
+++ b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
@@ -579,6 +579,28 @@ static struct regmap *gsw1xx_regmap_init(struct gsw1xx_priv *priv,
 				priv, &config);
 }
 
+static int gsw1xx_serdes_pcs_init(struct gsw1xx_priv *priv)
+{
+	/* do nothing if the chip doesn't have a SerDes PCS */
+	if (!priv->gswip.hw_info->mac_select_pcs)
+		return 0;
+
+	priv->pcs.ops = &gsw1xx_pcs_ops;
+	priv->pcs.poll = true;
+	__set_bit(PHY_INTERFACE_MODE_SGMII,
+		  priv->pcs.supported_interfaces);
+	__set_bit(PHY_INTERFACE_MODE_1000BASEX,
+		  priv->pcs.supported_interfaces);
+	if (priv->gswip.hw_info->supports_2500m)
+		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
+			  priv->pcs.supported_interfaces);
+	priv->tbi_interface = PHY_INTERFACE_MODE_NA;
+
+	/* assert SGMII reset to power down SGMII unit */
+	return regmap_set_bits(priv->shell, GSW1XX_SHELL_RST_REQ,
+			       GSW1XX_RST_REQ_SGMII_SHELL);
+}
+
 static int gsw1xx_probe(struct mdio_device *mdiodev)
 {
 	struct device *dev = &mdiodev->dev;
@@ -631,20 +653,7 @@ static int gsw1xx_probe(struct mdio_device *mdiodev)
 	if (IS_ERR(priv->shell))
 		return PTR_ERR(priv->shell);
 
-	priv->pcs.ops = &gsw1xx_pcs_ops;
-	priv->pcs.poll = true;
-	__set_bit(PHY_INTERFACE_MODE_SGMII,
-		  priv->pcs.supported_interfaces);
-	__set_bit(PHY_INTERFACE_MODE_1000BASEX,
-		  priv->pcs.supported_interfaces);
-	if (priv->gswip.hw_info->supports_2500m)
-		__set_bit(PHY_INTERFACE_MODE_2500BASEX,
-			  priv->pcs.supported_interfaces);
-	priv->tbi_interface = PHY_INTERFACE_MODE_NA;
-
-	/* assert SGMII reset to power down SGMII unit */
-	ret = regmap_set_bits(priv->shell, GSW1XX_SHELL_RST_REQ,
-			      GSW1XX_RST_REQ_SGMII_SHELL);
+	ret = gsw1xx_serdes_pcs_init(priv);
 	if (ret < 0)
 		return ret;
 
-- 
2.52.0

^ permalink raw reply related

* [PATCH net-next v3 4/6] net: dsa: lantiq: clean up phylink_get_caps switch statement
From: Daniel Golle @ 2026-01-16  0:07 UTC (permalink / raw)
  To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Russell King, netdev,
	devicetree, linux-kernel
  Cc: Chen Minqiang, Xinfa Deng
In-Reply-To: <cover.1768519376.git.daniel@makrotopia.org>

Use case ranges for phylink_get_caps and remove the redundant "port N:"
from the comments.

Suggested-by: Vladimir Oltean <olteanv@gmail.com>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: no changes
v2: new patch

 drivers/net/dsa/lantiq/lantiq_gswip.c | 12 +++---------
 drivers/net/dsa/lantiq/mxl-gsw1xx.c   | 11 +++++------
 2 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/net/dsa/lantiq/lantiq_gswip.c b/drivers/net/dsa/lantiq/lantiq_gswip.c
index b36bc1416d7ff..68d5a282800d9 100644
--- a/drivers/net/dsa/lantiq/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq/lantiq_gswip.c
@@ -34,8 +34,7 @@ static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
 					  struct phylink_config *config)
 {
 	switch (port) {
-	case 0:
-	case 1:
+	case 0 ... 1:
 		phy_interface_set_rgmii(config->supported_interfaces);
 		__set_bit(PHY_INTERFACE_MODE_MII,
 			  config->supported_interfaces);
@@ -45,9 +44,7 @@ static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
 			  config->supported_interfaces);
 		break;
 
-	case 2:
-	case 3:
-	case 4:
+	case 2 ... 4:
 	case 6:
 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 			  config->supported_interfaces);
@@ -76,10 +73,7 @@ static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port,
 			  config->supported_interfaces);
 		break;
 
-	case 1:
-	case 2:
-	case 3:
-	case 4:
+	case 1 ... 4:
 	case 6:
 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 			  config->supported_interfaces);
diff --git a/drivers/net/dsa/lantiq/mxl-gsw1xx.c b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
index acf9e2465b934..0267196f98464 100644
--- a/drivers/net/dsa/lantiq/mxl-gsw1xx.c
+++ b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
@@ -512,14 +512,12 @@ static void gsw1xx_phylink_get_caps(struct dsa_switch *ds, int port,
 				   MAC_10 | MAC_100 | MAC_1000;
 
 	switch (port) {
-	case 0:
-	case 1:
-	case 2:
-	case 3:
+	case 0 ... 3: /* built-in PHYs */
 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 			  config->supported_interfaces);
 		break;
-	case 4: /* port 4: SGMII */
+
+	case 4: /* SGMII */
 		__set_bit(PHY_INTERFACE_MODE_SGMII,
 			  config->supported_interfaces);
 		__set_bit(PHY_INTERFACE_MODE_1000BASEX,
@@ -530,7 +528,8 @@ static void gsw1xx_phylink_get_caps(struct dsa_switch *ds, int port,
 			config->mac_capabilities |= MAC_2500FD;
 		}
 		return; /* no support for EEE on SGMII port */
-	case 5: /* port 5: RGMII or RMII */
+
+	case 5: /* RGMII or RMII */
 		__set_bit(PHY_INTERFACE_MODE_RMII,
 			  config->supported_interfaces);
 		phy_interface_set_rgmii(config->supported_interfaces);
-- 
2.52.0

^ permalink raw reply related

* [PATCH net-next v3 3/6] net: dsa: lantiq: allow arbitrary MII registers
From: Daniel Golle @ 2026-01-16  0:07 UTC (permalink / raw)
  To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Russell King, netdev,
	devicetree, linux-kernel
  Cc: Chen Minqiang, Xinfa Deng
In-Reply-To: <cover.1768519376.git.daniel@makrotopia.org>

The Lantiq GSWIP and MaxLinear GSW1xx drivers are currently relying on a
hard-coded mapping of MII ports to their respective MII_CFG and MII_PCDU
registers and only allow applying an offset to the port index.

While this is sufficient for the currently supported hardware, the very
similar Intel GSW150 (aka. Lantiq PEB7084) cannot be described using
this arrangement.

Introduce two arrays to specify the MII_CFG and MII_PCDU registers for
each port, replacing the current bitmap used to safeguard MII ports as
well as the port index offset.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: enclose the gswip_hw_info initializers in compiler diag exception
    to prevent triggering -Woverride-init

v2: introduce GSWIP_MAX_PORTS macro

 drivers/net/dsa/lantiq/lantiq_gswip.c        | 37 ++++++++++++++++----
 drivers/net/dsa/lantiq/lantiq_gswip.h        |  6 ++--
 drivers/net/dsa/lantiq/lantiq_gswip_common.c | 27 +++-----------
 drivers/net/dsa/lantiq/mxl-gsw1xx.c          | 37 ++++++++++++++++----
 4 files changed, 70 insertions(+), 37 deletions(-)

diff --git a/drivers/net/dsa/lantiq/lantiq_gswip.c b/drivers/net/dsa/lantiq/lantiq_gswip.c
index b094001a7c805..b36bc1416d7ff 100644
--- a/drivers/net/dsa/lantiq/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq/lantiq_gswip.c
@@ -12,6 +12,7 @@
 #include "lantiq_pce.h"
 
 #include <linux/clk.h>
+#include <linux/compiler.h>
 #include <linux/delay.h>
 #include <linux/firmware.h>
 #include <linux/mfd/syscon.h>
@@ -462,11 +463,25 @@ static void gswip_shutdown(struct platform_device *pdev)
 	platform_set_drvdata(pdev, NULL);
 }
 
+__diag_push();
+__diag_ignore_all("-Woverride-init",
+		  "logic to initialize all and then override some is OK");
+
 static const struct gswip_hw_info gswip_xrx200 = {
-	.max_ports = 7,
+	.max_ports = GSWIP_MAX_PORTS,
 	.allowed_cpu_ports = BIT(6),
-	.mii_ports = BIT(0) | BIT(1) | BIT(5),
-	.mii_port_reg_offset = 0,
+	.mii_cfg = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[0] = GSWIP_MII_CFGp(0),
+		[1] = GSWIP_MII_CFGp(1),
+		[5] = GSWIP_MII_CFGp(5),
+	},
+	.mii_pcdu = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[0] = GSWIP_MII_PCDU0,
+		[1] = GSWIP_MII_PCDU1,
+		[5] = GSWIP_MII_PCDU5,
+	},
 	.phylink_get_caps = gswip_xrx200_phylink_get_caps,
 	.pce_microcode = &gswip_pce_microcode,
 	.pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
@@ -474,16 +489,26 @@ static const struct gswip_hw_info gswip_xrx200 = {
 };
 
 static const struct gswip_hw_info gswip_xrx300 = {
-	.max_ports = 7,
+	.max_ports = GSWIP_MAX_PORTS,
 	.allowed_cpu_ports = BIT(6),
-	.mii_ports = BIT(0) | BIT(5),
-	.mii_port_reg_offset = 0,
+	.mii_cfg = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[0] = GSWIP_MII_CFGp(0),
+		[5] = GSWIP_MII_CFGp(5),
+	},
+	.mii_pcdu = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[0] = GSWIP_MII_PCDU0,
+		[5] = GSWIP_MII_PCDU5,
+	},
 	.phylink_get_caps = gswip_xrx300_phylink_get_caps,
 	.pce_microcode = &gswip_pce_microcode,
 	.pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode),
 	.tag_protocol = DSA_TAG_PROTO_GSWIP,
 };
 
+__diag_pop();
+
 static const struct of_device_id gswip_of_match[] = {
 	{ .compatible = "lantiq,xrx200-gswip", .data = &gswip_xrx200 },
 	{ .compatible = "lantiq,xrx300-gswip", .data = &gswip_xrx300 },
diff --git a/drivers/net/dsa/lantiq/lantiq_gswip.h b/drivers/net/dsa/lantiq/lantiq_gswip.h
index 2e0f2afbadbbc..524289db7c213 100644
--- a/drivers/net/dsa/lantiq/lantiq_gswip.h
+++ b/drivers/net/dsa/lantiq/lantiq_gswip.h
@@ -243,6 +243,8 @@
 
 #define GSWIP_VLAN_UNAWARE_PVID	0
 
+#define GSWIP_MAX_PORTS		7
+
 struct gswip_pce_microcode {
 	u16 val_3;
 	u16 val_2;
@@ -253,8 +255,8 @@ struct gswip_pce_microcode {
 struct gswip_hw_info {
 	int max_ports;
 	unsigned int allowed_cpu_ports;
-	unsigned int mii_ports;
-	int mii_port_reg_offset;
+	s16 mii_cfg[GSWIP_MAX_PORTS];
+	s16 mii_pcdu[GSWIP_MAX_PORTS];
 	bool supports_2500m;
 	const struct gswip_pce_microcode (*pce_microcode)[];
 	size_t pce_microcode_size;
diff --git a/drivers/net/dsa/lantiq/lantiq_gswip_common.c b/drivers/net/dsa/lantiq/lantiq_gswip_common.c
index e790f2ef75884..05b28b540661a 100644
--- a/drivers/net/dsa/lantiq/lantiq_gswip_common.c
+++ b/drivers/net/dsa/lantiq/lantiq_gswip_common.c
@@ -118,15 +118,11 @@ static u32 gswip_switch_r_timeout(struct gswip_priv *priv, u32 offset,
 static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 mask, u32 set,
 			       int port)
 {
-	int reg_port;
-
 	/* MII_CFG register only exists for MII ports */
-	if (!(priv->hw_info->mii_ports & BIT(port)))
+	if (priv->hw_info->mii_cfg[port] == -1)
 		return;
 
-	reg_port = port + priv->hw_info->mii_port_reg_offset;
-
-	regmap_write_bits(priv->mii, GSWIP_MII_CFGp(reg_port), mask,
+	regmap_write_bits(priv->mii, priv->hw_info->mii_cfg[port], mask,
 			  set);
 }
 
@@ -604,28 +600,13 @@ static void gswip_mii_delay_setup(struct gswip_priv *priv, struct dsa_port *dp,
 	u32 tx_delay = GSWIP_MII_PCDU_TXDLY_DEFAULT;
 	u32 rx_delay = GSWIP_MII_PCDU_RXDLY_DEFAULT;
 	struct device_node *port_dn = dp->dn;
-	u16 mii_pcdu_reg;
 
 	/* As MII_PCDU registers only exist for MII ports, silently return
 	 * unless the port is an MII port
 	 */
-	if (!(priv->hw_info->mii_ports & BIT(dp->index)))
+	if (priv->hw_info->mii_pcdu[dp->index] == -1)
 		return;
 
-	switch (dp->index + priv->hw_info->mii_port_reg_offset) {
-	case 0:
-		mii_pcdu_reg = GSWIP_MII_PCDU0;
-		break;
-	case 1:
-		mii_pcdu_reg = GSWIP_MII_PCDU1;
-		break;
-	case 5:
-		mii_pcdu_reg = GSWIP_MII_PCDU5;
-		break;
-	default:
-		return;
-	}
-
 	/* legacy code to set default delays according to the interface mode */
 	switch (interface) {
 	case PHY_INTERFACE_MODE_RGMII_ID:
@@ -646,7 +627,7 @@ static void gswip_mii_delay_setup(struct gswip_priv *priv, struct dsa_port *dp,
 	of_property_read_u32(port_dn, "rx-internal-delay-ps", &rx_delay);
 	of_property_read_u32(port_dn, "tx-internal-delay-ps", &tx_delay);
 
-	regmap_write_bits(priv->mii, mii_pcdu_reg,
+	regmap_write_bits(priv->mii, priv->hw_info->mii_pcdu[dp->index],
 			  GSWIP_MII_PCDU_TXDLY_MASK |
 			  GSWIP_MII_PCDU_RXDLY_MASK,
 			  GSWIP_MII_PCDU_TXDLY(tx_delay) |
diff --git a/drivers/net/dsa/lantiq/mxl-gsw1xx.c b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
index f8ff8a604bf53..acf9e2465b934 100644
--- a/drivers/net/dsa/lantiq/mxl-gsw1xx.c
+++ b/drivers/net/dsa/lantiq/mxl-gsw1xx.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/bits.h>
+#include <linux/compiler.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
@@ -699,11 +700,21 @@ static void gsw1xx_shutdown(struct mdio_device *mdiodev)
 	cancel_delayed_work_sync(&gsw1xx_priv->clear_raneg);
 }
 
+__diag_push();
+__diag_ignore_all("-Woverride-init",
+		  "logic to initialize all and then override some is OK");
+
 static const struct gswip_hw_info gsw12x_data = {
 	.max_ports		= GSW1XX_PORTS,
 	.allowed_cpu_ports	= BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT),
-	.mii_ports		= BIT(GSW1XX_MII_PORT),
-	.mii_port_reg_offset	= -GSW1XX_MII_PORT,
+	.mii_cfg = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[GSW1XX_MII_PORT] = GSWIP_MII_CFGp(0),
+	},
+	.mii_pcdu = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[GSW1XX_MII_PORT] = GSWIP_MII_PCDU0,
+	},
 	.mac_select_pcs		= gsw1xx_phylink_mac_select_pcs,
 	.phylink_get_caps	= &gsw1xx_phylink_get_caps,
 	.supports_2500m		= true,
@@ -715,8 +726,14 @@ static const struct gswip_hw_info gsw12x_data = {
 static const struct gswip_hw_info gsw140_data = {
 	.max_ports		= GSW1XX_PORTS,
 	.allowed_cpu_ports	= BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT),
-	.mii_ports		= BIT(GSW1XX_MII_PORT),
-	.mii_port_reg_offset	= -GSW1XX_MII_PORT,
+	.mii_cfg = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[GSW1XX_MII_PORT] = GSWIP_MII_CFGp(0),
+	},
+	.mii_pcdu = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[GSW1XX_MII_PORT] = GSWIP_MII_PCDU0,
+	},
 	.mac_select_pcs		= gsw1xx_phylink_mac_select_pcs,
 	.phylink_get_caps	= &gsw1xx_phylink_get_caps,
 	.supports_2500m		= true,
@@ -728,8 +745,14 @@ static const struct gswip_hw_info gsw140_data = {
 static const struct gswip_hw_info gsw141_data = {
 	.max_ports		= GSW1XX_PORTS,
 	.allowed_cpu_ports	= BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT),
-	.mii_ports		= BIT(GSW1XX_MII_PORT),
-	.mii_port_reg_offset	= -GSW1XX_MII_PORT,
+	.mii_cfg = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[GSW1XX_MII_PORT] = GSWIP_MII_CFGp(0),
+	},
+	.mii_pcdu = {
+		[0 ... GSWIP_MAX_PORTS - 1] = -1,
+		[GSW1XX_MII_PORT] = GSWIP_MII_PCDU0,
+	},
 	.mac_select_pcs		= gsw1xx_phylink_mac_select_pcs,
 	.phylink_get_caps	= gsw1xx_phylink_get_caps,
 	.pce_microcode		= &gsw1xx_pce_microcode,
@@ -737,6 +760,8 @@ static const struct gswip_hw_info gsw141_data = {
 	.tag_protocol		= DSA_TAG_PROTO_MXL_GSW1XX,
 };
 
+__diag_pop();
+
 /*
  * GSW125 is the industrial temperature version of GSW120.
  * GSW145 is the industrial temperature version of GSW140.
-- 
2.52.0

^ permalink raw reply related

* [PATCH net-next v3 2/6] dt-bindings: net: dsa: lantiq,gswip: add Intel GSW150
From: Daniel Golle @ 2026-01-16  0:07 UTC (permalink / raw)
  To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Russell King, netdev,
	devicetree, linux-kernel
  Cc: Chen Minqiang, Xinfa Deng
In-Reply-To: <cover.1768519376.git.daniel@makrotopia.org>

Add compatible strings for the Intel GSW150 which is apparently
identical or at least compatible with the Lantiq PEB7084 Ethernet
switch IC.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
---
v3: no changes
v2: no changes

 Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml b/Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml
index 9c0de536bae97..97842523772f4 100644
--- a/Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml
+++ b/Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml
@@ -19,6 +19,8 @@ maintainers:
 properties:
   compatible:
     enum:
+      - intel,gsw150
+      - lantiq,peb7084
       - lantiq,xrx200-gswip
       - lantiq,xrx300-gswip
       - lantiq,xrx330-gswip
-- 
2.52.0

^ permalink raw reply related

* [PATCH net-next v3 1/6] dt-bindings: net: dsa: lantiq,gswip: use correct node name
From: Daniel Golle @ 2026-01-16  0:07 UTC (permalink / raw)
  To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Russell King, netdev,
	devicetree, linux-kernel
  Cc: Chen Minqiang, Xinfa Deng
In-Reply-To: <cover.1768519376.git.daniel@makrotopia.org>

Ethernet PHYs should use nodes named 'ethernet-phy@'.
Rename the Ethernet PHY nodes in the example to comply.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
---
v3: no changes
v2: new patch

 Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml b/Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml
index 205b683849a53..9c0de536bae97 100644
--- a/Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml
+++ b/Documentation/devicetree/bindings/net/dsa/lantiq,gswip.yaml
@@ -316,7 +316,7 @@ examples:
                 #address-cells = <1>;
                 #size-cells = <0>;
 
-                switchphy0: switchphy@0 {
+                switchphy0: ethernet-phy@0 {
                     reg = <0>;
 
                     leds {
@@ -331,7 +331,7 @@ examples:
                     };
                 };
 
-                switchphy1: switchphy@1 {
+                switchphy1: ethernet-phy@1 {
                     reg = <1>;
 
                     leds {
-- 
2.52.0

^ permalink raw reply related

* [PATCH net-next v3 0/6] net: dsa: lantiq: add support for Intel GSW150
From: Daniel Golle @ 2026-01-16  0:06 UTC (permalink / raw)
  To: Hauke Mehrtens, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Russell King, netdev,
	devicetree, linux-kernel
  Cc: Chen Minqiang, Xinfa Deng

The Intel GSW150 Ethernet Switch (aka. Lantiq PEB7084) is the predecessor of
MaxLinear's GSW1xx series of switches. It shares most features, but has a
slightly different port layout and different MII interfaces.
Adding support for this switch to the mxl-gsw1xx driver is quite trivial.
---
Changes since v2:
 * enclose the gswip_hw_info initializers in compiler diag exception
   to prevent triggering -Woverride-init

Changes since initial submission:
 * add patch fixing node naming convention for dt-bindings
 * introduce GSWIP_MAX_PORTS macro
 * don't assert SGMII PCS reset in case chip doesn't have SGMII
 * use case ranges in phylink_get_caps


Daniel Golle (6):
  dt-bindings: net: dsa: lantiq,gswip: use correct node name
  dt-bindings: net: dsa: lantiq,gswip: add Intel GSW150
  net: dsa: lantiq: allow arbitrary MII registers
  net: dsa: lantiq: clean up phylink_get_caps switch statement
  net: dsa: mxl-gsw1xx: only setup SerDes PCS if it exists
  net: dsa: mxl-gsw1xx: add support for Intel GSW150

 .../bindings/net/dsa/lantiq,gswip.yaml        |   6 +-
 drivers/net/dsa/lantiq/lantiq_gswip.c         |  49 ++++--
 drivers/net/dsa/lantiq/lantiq_gswip.h         |   6 +-
 drivers/net/dsa/lantiq/lantiq_gswip_common.c  |  27 +---
 drivers/net/dsa/lantiq/mxl-gsw1xx.c           | 146 ++++++++++++++----
 drivers/net/dsa/lantiq/mxl-gsw1xx.h           |   2 +
 6 files changed, 163 insertions(+), 73 deletions(-)

-- 
2.52.0

^ permalink raw reply

* [PATCH 8/8] clk: tenstorrent: Add reset controller to Atlantis clock controller probe
From: Anirudh Srinivasan @ 2026-01-15 23:42 UTC (permalink / raw)
  To: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Turquette, Stephen Boyd, Anirudh Srinivasan,
	Philipp Zabel
  Cc: linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
	mpe, mpe, npiggin, agross, agross
In-Reply-To: <20260115-atlantis-clocks-v1-0-7356e671f28b@oss.tenstorrent.com>

Create a reset auxiliary device during probe of clock controller

Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
 drivers/clk/tenstorrent/atlantis-ccu.c | 59 ++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/drivers/clk/tenstorrent/atlantis-ccu.c b/drivers/clk/tenstorrent/atlantis-ccu.c
index f3a2ea49a82e..e4f56018907f 100644
--- a/drivers/clk/tenstorrent/atlantis-ccu.c
+++ b/drivers/clk/tenstorrent/atlantis-ccu.c
@@ -491,6 +491,7 @@ struct atlantis_ccu {
 struct atlantis_ccu_data {
 	struct clk_hw **hws;
 	size_t num;
+	const char *reset_name;
 };
 
 static const struct clk_parent_data osc_24m_clk[] = {
@@ -706,6 +707,7 @@ static struct clk_hw *atlantis_rcpu_clks[] = {
 static const struct atlantis_ccu_data atlantis_ccu_rcpu_data = {
 	.hws = atlantis_rcpu_clks,
 	.num = ARRAY_SIZE(atlantis_rcpu_clks),
+	.reset_name = "rcpu-reset"
 };
 
 static int atlantis_ccu_clocks_register(struct device *dev,
@@ -875,6 +877,59 @@ static int atlantis_ccu_clocks_register(struct device *dev,
 	return ret;
 }
 
+static void atlantis_cadev_release(struct device *dev)
+{
+	struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+	kfree(to_atlantis_ccu_adev(adev));
+}
+
+static void atlantis_adev_unregister(void *data)
+{
+	struct auxiliary_device *adev = data;
+
+	auxiliary_device_delete(adev);
+	auxiliary_device_uninit(adev);
+}
+
+static int atlantis_ccu_adev_register(struct device *dev,
+				      struct atlantis_ccu *ccu,
+				      const struct atlantis_ccu_data *data,
+				      const char *adev_name)
+{
+	struct atlantis_ccu_adev *cadev;
+	struct auxiliary_device *adev;
+	int ret;
+
+	cadev = kzalloc(sizeof(*cadev), GFP_KERNEL);
+	if (!cadev)
+		return -ENOMEM;
+
+	cadev->regmap = ccu->regmap;
+
+	adev = &cadev->adev;
+	adev->name = adev_name;
+	adev->dev.parent = dev;
+	adev->dev.release = atlantis_cadev_release;
+	adev->dev.of_node = dev->of_node;
+
+	ret = auxiliary_device_init(adev);
+	if (ret)
+		goto err_free_cadev;
+
+	ret = auxiliary_device_add(adev);
+	if (ret) {
+		auxiliary_device_uninit(adev);
+		return ret;
+	}
+
+	return devm_add_action_or_reset(dev, atlantis_adev_unregister, adev);
+
+err_free_cadev:
+	kfree(cadev);
+
+	return ret;
+}
 static int atlantis_ccu_probe(struct platform_device *pdev)
 {
 	const struct atlantis_ccu_data *data;
@@ -905,6 +960,10 @@ static int atlantis_ccu_probe(struct platform_device *pdev)
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to register clocks\n");
 
+	ret = atlantis_ccu_adev_register(dev, ccu, data, data->reset_name);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to register resets\n");
+
 	return 0;
 }
 

-- 
2.43.0


^ permalink raw reply related

* [PATCH 7/8] reset: tenstorrent: Add reset controller for Atlantis
From: Anirudh Srinivasan @ 2026-01-15 23:42 UTC (permalink / raw)
  To: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Turquette, Stephen Boyd, Anirudh Srinivasan,
	Philipp Zabel
  Cc: linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
	mpe, mpe, npiggin, agross, agross
In-Reply-To: <20260115-atlantis-clocks-v1-0-7356e671f28b@oss.tenstorrent.com>

Implement reset controller as an auxiliary device of the clock
controller, sharing the same regmap interface. This version of the
driver covers resets from the RCPU syscon.

Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
 MAINTAINERS                                |   1 +
 drivers/reset/Kconfig                      |  11 ++
 drivers/reset/Makefile                     |   1 +
 drivers/reset/reset-tenstorrent-atlantis.c | 164 +++++++++++++++++++++++++++++
 4 files changed, 177 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 93d941d2886b..31c3e5bcb32d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22538,6 +22538,7 @@ F:	Documentation/devicetree/bindings/riscv/tenstorrent.yaml
 F:	Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
 F:	arch/riscv/boot/dts/tenstorrent/
 F:	drivers/clk/tenstorrent/
+F:	drivers/reset/reset-tenstorrent-atlantis.c
 F:	include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
 F:	include/soc/tenstorrent/
 
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 6e5d6deffa7d..cade77717492 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -324,6 +324,17 @@ config RESET_SUNXI
 	help
 	  This enables the reset driver for Allwinner SoCs.
 
+config RESET_TENSTORRENT_ATLANTIS
+	tristate "Tenstorrent atlantis reset driver"
+	depends on ARCH_TENSTORRENT || COMPILE_TEST
+	select AUXILIARY_BUS
+	default ARCH_TENSTORRENT
+	help
+	  This enables the driver for the reset controller
+	  present in the Tenstorrent Atlantis SoC.
+	  Enable this option to be able to use hardware
+	  resets on Atalantis based systems.
+
 config RESET_TH1520
 	tristate "T-HEAD TH1520 reset controller"
 	depends on ARCH_THEAD || COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 9c3e484dfd81..a31959da0a88 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
 obj-$(CONFIG_RESET_SPACEMIT) += reset-spacemit.o
 obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
 obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
+obj-$(CONFIG_RESET_TENSTORRENT_ATLANTIS) += reset-tenstorrent-atlantis.o
 obj-$(CONFIG_RESET_TH1520) += reset-th1520.o
 obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
 obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
diff --git a/drivers/reset/reset-tenstorrent-atlantis.c b/drivers/reset/reset-tenstorrent-atlantis.c
new file mode 100644
index 000000000000..b1e934a5b054
--- /dev/null
+++ b/drivers/reset/reset-tenstorrent-atlantis.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2026 Tenstorrent
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/reset-controller.h>
+#include <linux/regmap.h>
+
+#include <soc/tenstorrent/atlantis-syscon.h>
+#include <dt-bindings/clock/tenstorrent,atlantis-syscon.h>
+
+struct atlantis_reset_data {
+	u8 bit;
+	u16 reg;
+	bool active_low;
+};
+
+struct atlantis_reset_controller_data {
+	const struct atlantis_reset_data *reset_data;
+	size_t count;
+};
+
+struct atlantis_reset_controller {
+	struct reset_controller_dev rcdev;
+	const struct atlantis_reset_controller_data *data;
+	struct regmap *regmap;
+};
+
+#define to_atlantis_reset_controller(_rcdev) \
+	container_of((_rcdev), struct atlantis_reset_controller, rcdev)
+
+#define RESET_DATA(_reg, _bit, _active_low)                          \
+	{                                                            \
+		.bit = _bit, .reg = _reg, .active_low = _active_low, \
+	}
+
+static const struct atlantis_reset_data atlantis_rcpu_resets[] = {
+	[RST_SMNDMA0] = RESET_DATA(RCPU_BLK_RST_REG, 0, true),
+	[RST_SMNDMA1] = RESET_DATA(RCPU_BLK_RST_REG, 1, true),
+	[RST_WDT0] = RESET_DATA(RCPU_BLK_RST_REG, 2, true),
+	[RST_WDT1] = RESET_DATA(RCPU_BLK_RST_REG, 3, true),
+	[RST_TMR] = RESET_DATA(RCPU_BLK_RST_REG, 4, true),
+	[RST_PVTC] = RESET_DATA(RCPU_BLK_RST_REG, 12, true),
+	[RST_PMU] = RESET_DATA(RCPU_BLK_RST_REG, 13, true),
+	[RST_MAILBOX] = RESET_DATA(RCPU_BLK_RST_REG, 14, true),
+	[RST_SPACC] = RESET_DATA(RCPU_BLK_RST_REG, 26, true),
+	[RST_OTP] = RESET_DATA(RCPU_BLK_RST_REG, 28, true),
+	[RST_TRNG] = RESET_DATA(RCPU_BLK_RST_REG, 29, true),
+	[RST_CRC] = RESET_DATA(RCPU_BLK_RST_REG, 30, true),
+
+	[RST_QSPI] = RESET_DATA(LSIO_BLK_RST_REG, 0, true),
+	[RST_I2C0] = RESET_DATA(LSIO_BLK_RST_REG, 1, true),
+	[RST_I2C1] = RESET_DATA(LSIO_BLK_RST_REG, 2, true),
+	[RST_I2C2] = RESET_DATA(LSIO_BLK_RST_REG, 3, true),
+	[RST_I2C3] = RESET_DATA(LSIO_BLK_RST_REG, 4, true),
+	[RST_I2C4] = RESET_DATA(LSIO_BLK_RST_REG, 5, true),
+	[RST_UART0] = RESET_DATA(LSIO_BLK_RST_REG, 6, true),
+	[RST_UART1] = RESET_DATA(LSIO_BLK_RST_REG, 7, true),
+	[RST_UART2] = RESET_DATA(LSIO_BLK_RST_REG, 8, true),
+	[RST_UART3] = RESET_DATA(LSIO_BLK_RST_REG, 9, true),
+	[RST_UART4] = RESET_DATA(LSIO_BLK_RST_REG, 10, true),
+	[RST_SPI0] = RESET_DATA(LSIO_BLK_RST_REG, 11, true),
+	[RST_SPI1] = RESET_DATA(LSIO_BLK_RST_REG, 12, true),
+	[RST_SPI2] = RESET_DATA(LSIO_BLK_RST_REG, 13, true),
+	[RST_SPI3] = RESET_DATA(LSIO_BLK_RST_REG, 14, true),
+	[RST_GPIO] = RESET_DATA(LSIO_BLK_RST_REG, 15, true),
+	[RST_CAN0] = RESET_DATA(LSIO_BLK_RST_REG, 17, true),
+	[RST_CAN1] = RESET_DATA(LSIO_BLK_RST_REG, 18, true),
+	[RST_I2S0] = RESET_DATA(LSIO_BLK_RST_REG, 19, true),
+	[RST_I2S1] = RESET_DATA(LSIO_BLK_RST_REG, 20, true),
+
+};
+
+static const struct atlantis_reset_controller_data atlantis_rcpu_reset_data = {
+	.reset_data = atlantis_rcpu_resets,
+	.count = ARRAY_SIZE(atlantis_rcpu_resets),
+};
+
+static int atlantis_reset_update(struct reset_controller_dev *rcdev,
+				 unsigned long id, bool assert)
+{
+	unsigned int val;
+	struct atlantis_reset_controller *rst =
+		to_atlantis_reset_controller(rcdev);
+	const struct atlantis_reset_data *data = &rst->data->reset_data[id];
+	unsigned int mask = BIT(data->bit);
+	struct regmap *regmap = rst->regmap;
+
+	if (data->active_low ^ assert)
+		val = mask;
+	else
+		val = ~mask;
+
+	return regmap_update_bits(regmap, data->reg, mask, val);
+}
+
+static int atlantis_reset_assert(struct reset_controller_dev *rcdev,
+				 unsigned long id)
+{
+	return atlantis_reset_update(rcdev, id, true);
+}
+
+static int atlantis_reset_deassert(struct reset_controller_dev *rcdev,
+				   unsigned long id)
+{
+	return atlantis_reset_update(rcdev, id, false);
+}
+
+static const struct reset_control_ops atlantis_reset_control_ops = {
+	.assert = atlantis_reset_assert,
+	.deassert = atlantis_reset_deassert,
+};
+
+static int
+atlantis_reset_controller_register(struct device *dev,
+				   struct atlantis_reset_controller *controller)
+{
+	struct reset_controller_dev *rcdev = &controller->rcdev;
+
+	rcdev->ops = &atlantis_reset_control_ops;
+	rcdev->owner = THIS_MODULE;
+	rcdev->of_node = dev->of_node;
+	rcdev->nr_resets = controller->data->count;
+
+	return devm_reset_controller_register(dev, &controller->rcdev);
+}
+static int atlantis_reset_probe(struct auxiliary_device *adev,
+				const struct auxiliary_device_id *id)
+{
+	struct atlantis_ccu_adev *rdev = to_atlantis_ccu_adev(adev);
+	struct atlantis_reset_controller *controller;
+	struct device *dev = &adev->dev;
+
+	controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
+	if (!controller)
+		return -ENOMEM;
+	controller->data =
+		(const struct atlantis_reset_controller_data *)id->driver_data;
+	controller->regmap = rdev->regmap;
+
+	return atlantis_reset_controller_register(dev, controller);
+}
+
+static const struct auxiliary_device_id atlantis_reset_ids[] = {
+	{ .name = "atlantis_ccu.rcpu-reset",
+	  .driver_data = (kernel_ulong_t)&atlantis_rcpu_reset_data },
+	{},
+};
+MODULE_DEVICE_TABLE(auxiliary, atlantis_reset_ids);
+
+static struct auxiliary_driver atlantis_reset_driver = {
+	.probe = atlantis_reset_probe,
+	.id_table = atlantis_reset_ids,
+};
+module_auxiliary_driver(atlantis_reset_driver);
+
+MODULE_AUTHOR("Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>");
+MODULE_DESCRIPTION("Atlantis reset controller driver");
+MODULE_LICENSE("GPL");

-- 
2.43.0


^ permalink raw reply related


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