Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* RE: [RFC PATCH 3/6] arm64: hyperv: Add per-CPU RSI host call infrastructure for CCA Realms
From: Michael Kelley @ 2026-06-18 17:46 UTC (permalink / raw)
  To: Kameron Carr, kys@microsoft.com, haiyangz@microsoft.com,
	wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com
  Cc: catalin.marinas@arm.com, will@kernel.org, mark.rutland@arm.com,
	lpieralisi@kernel.org, sudeep.holla@kernel.org, arnd@arndb.de,
	thuth@redhat.com, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	Michael Kelley
In-Reply-To: <20260609181030.2378391-4-kameroncarr@linux.microsoft.com>

From: Kameron Carr <kameroncarr@linux.microsoft.com> Sent: Tuesday, June 9, 2026 11:10 AM
> 
> Arm CCA Realms cannot issue Hyper-V hypercalls via HVC; the guest must
> route them through the RSI_HOST_CALL interface, which takes the IPA of a
> per-CPU rsi_host_call structure as its argument.
> 
> Add hyperv_pcpu_hostcall_struct as a per-CPU pointer to that buffer and
> allocate it for the boot CPU during hyperv_init() and for each secondary
> CPU in hv_cpu_init(). The allocation is gated on is_realm_world() so
> non-Realm arm64 Hyper-V guests pay no memory cost.

I wonder if there's a simpler approach here. What about calculating the
total size of struct rsi_host_call needed for all CPUs, then doing a single
dynamic allocation to effectively create an array of entries? Each CPU
would just index into the array with its processor ID. You could still have
a per-cpu pointer that points to the correct array entry to avoid the need
to get the processor ID, but I wonder if even that is worth the trouble. Since
struct rsi_host_call size is a power of 2, the indexing is just a simple shift.

The hyperv_pcpu_input_page is allocated the way it is because it's much
bigger. But 16 struct rsi_host_call fit into a single 4 KiB, so there's no
danger of hitting a memory allocation limit at boot time. Even with 8192
CPUs the allocation is only 2 MiB. 

Michael

> 
> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
> ---
>  arch/arm64/hyperv/mshyperv.c      | 78 ++++++++++++++++++++++++++++++-
>  arch/arm64/include/asm/mshyperv.h |  3 ++
>  2 files changed, 79 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> index 4fdc26ade1d74..08fec82691683 100644
> --- a/arch/arm64/hyperv/mshyperv.c
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -15,10 +15,16 @@
>  #include <linux/errno.h>
>  #include <linux/version.h>
>  #include <linux/cpuhotplug.h>
> +#include <linux/slab.h>
> +#include <linux/percpu.h>
>  #include <asm/mshyperv.h>
> +#include <asm/rsi.h>
> 
>  static bool hyperv_initialized;
> 
> +void * __percpu *hyperv_pcpu_hostcall_struct;
> +EXPORT_SYMBOL_GPL(hyperv_pcpu_hostcall_struct);
> +
>  int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
>  {
>  	hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
> @@ -60,6 +66,46 @@ static bool __init hyperv_detect_via_acpi(void)
> 
>  #endif
> 
> +static void hv_hostcall_free(void)
> +{
> +	int cpu;
> +
> +	if (!hyperv_pcpu_hostcall_struct)
> +		return;
> +
> +	for_each_possible_cpu(cpu)
> +		kfree(*per_cpu_ptr(hyperv_pcpu_hostcall_struct, cpu));
> +	free_percpu(hyperv_pcpu_hostcall_struct);
> +	hyperv_pcpu_hostcall_struct = NULL;
> +}
> +
> +static int hv_cpu_init(unsigned int cpu)
> +{
> +	void **hostcall_struct;
> +	gfp_t flags;
> +	void *mem;
> +
> +	if (hyperv_pcpu_hostcall_struct) {
> +		/* hv_cpu_init() can be called with IRQs disabled from hv_resume() */
> +		flags = irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL;
> +
> +		hostcall_struct = (void **)this_cpu_ptr(hyperv_pcpu_hostcall_struct);
> +		/*
> +		 * The hostcall_struct memory is not freed when the CPU
> +		 * goes offline. If a previously offlined CPU is brought
> +		 * back online, the memory is reused here.
> +		 */
> +		if (!*hostcall_struct) {
> +			mem = kzalloc_obj(struct rsi_host_call, flags);
> +			if (!mem)
> +				return -ENOMEM;
> +			*hostcall_struct = mem;
> +		}
> +	}
> +
> +	return hv_common_cpu_init(cpu);
> +}
> +
>  static bool __init hyperv_detect_via_smccc(void)
>  {
>  	uuid_t hyperv_uuid = UUID_INIT(
> @@ -73,6 +119,8 @@ static bool __init hyperv_detect_via_smccc(void)
>  static int __init hyperv_init(void)
>  {
>  	struct hv_get_vp_registers_output	result;
> +	void **hostcall_struct;
> +	void *mem;
>  	u64	guest_id;
>  	int	ret;
> 
> @@ -85,6 +133,27 @@ static int __init hyperv_init(void)
>  	if (!hyperv_detect_via_acpi() && !hyperv_detect_via_smccc())
>  		return 0;
> 
> +	/*
> +	 * The RSI host-call buffer is only ever used when
> +	 * is_realm_world() is true. Skip the per-CPU allocation on
> +	 * non-Realm guests.
> +	 */
> +	if (is_realm_world()) {
> +		hyperv_pcpu_hostcall_struct = alloc_percpu(void *);
> +		if (!hyperv_pcpu_hostcall_struct)
> +			return -ENOMEM;
> +
> +		hostcall_struct = (void **)this_cpu_ptr(hyperv_pcpu_hostcall_struct);
> +		if (!*hostcall_struct) {
> +			mem = kzalloc_obj(struct rsi_host_call);
> +			if (!mem) {
> +				ret = -ENOMEM;
> +				goto free_hostcall_mem;
> +			}
> +			*hostcall_struct = mem;
> +		}
> +	}
> +
>  	/* Setup the guest ID */
>  	guest_id = hv_generate_guest_id(LINUX_VERSION_CODE);
>  	hv_set_vpreg(HV_REGISTER_GUEST_OS_ID, guest_id);
> @@ -106,12 +175,13 @@ static int __init hyperv_init(void)
> 
>  	ret = hv_common_init();
>  	if (ret)
> -		return ret;
> +		goto free_hostcall_mem;
> 
>  	ret = cpuhp_setup_state(CPUHP_AP_HYPERV_ONLINE,
> "arm64/hyperv_init:online",
> -				hv_common_cpu_init, hv_common_cpu_die);
> +				hv_cpu_init, hv_common_cpu_die);
>  	if (ret < 0) {
>  		hv_common_free();
> +		hv_hostcall_free();
>  		return ret;
>  	}
> 
> @@ -125,6 +195,10 @@ static int __init hyperv_init(void)
> 
>  	hyperv_initialized = true;
>  	return 0;
> +
> +free_hostcall_mem:
> +	hv_hostcall_free();
> +	return ret;
>  }
> 
>  early_initcall(hyperv_init);
> diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
> index b721d3134ab66..65a00bd14c6cb 100644
> --- a/arch/arm64/include/asm/mshyperv.h
> +++ b/arch/arm64/include/asm/mshyperv.h
> @@ -63,4 +63,7 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg)
> 
>  #include <asm-generic/mshyperv.h>
> 
> +/* Per-CPU RSI host call structure for CCA Realms */
> +extern void *__percpu *hyperv_pcpu_hostcall_struct;
> +
>  #endif
> --
> 2.45.4
> 



^ permalink raw reply

* RE: [RFC PATCH 5/6] arm64: hyperv: Route hypercalls through RSI host call in CCA Realms
From: Michael Kelley @ 2026-06-18 17:46 UTC (permalink / raw)
  To: Kameron Carr, kys@microsoft.com, haiyangz@microsoft.com,
	wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com
  Cc: catalin.marinas@arm.com, will@kernel.org, mark.rutland@arm.com,
	lpieralisi@kernel.org, sudeep.holla@kernel.org, arnd@arndb.de,
	thuth@redhat.com, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	Michael Kelley
In-Reply-To: <20260609181030.2378391-6-kameroncarr@linux.microsoft.com>

From: Kameron Carr <kameroncarr@linux.microsoft.com> Sent: Tuesday, June 9, 2026 11:10 AM
> 
> Modify the five hypercall wrapper functions to check is_realm_world()
> and use the per-CPU rsi_host_call structure when inside a Realm.
> 
> Signed-off-by: Kameron Carr <kameroncarr@linux.microsoft.com>
> ---
>  arch/arm64/hyperv/hv_core.c | 175 +++++++++++++++++++++++++++++-------
>  1 file changed, 141 insertions(+), 34 deletions(-)
> 
> diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
> index e33a9e3c366a1..1759998ef2667 100644
> --- a/arch/arm64/hyperv/hv_core.c
> +++ b/arch/arm64/hyperv/hv_core.c
> @@ -16,6 +16,7 @@
>  #include <asm-generic/bug.h>
>  #include <hyperv/hvhdk.h>
>  #include <asm/mshyperv.h>
> +#include <asm/rsi.h>
> 
>  /*
>   * hv_do_hypercall- Invoke the specified hypercall
> @@ -25,12 +26,32 @@ u64 hv_do_hypercall(u64 control, void *input, void *output)
>  	struct arm_smccc_res	res;
>  	u64			input_address;
>  	u64			output_address;
> +	struct rsi_host_call *hostcall;
> +	unsigned long flags;
> +	u64 ret;
> 
>  	input_address = input ? virt_to_phys(input) : 0;
>  	output_address = output ? virt_to_phys(output) : 0;
> 
> -	arm_smccc_1_1_hvc(HV_FUNC_ID, control,
> -			  input_address, output_address, &res);
> +	if (is_realm_world()) {
> +		local_irq_save(flags);
> +		hostcall = *this_cpu_ptr(hyperv_pcpu_hostcall_struct);
> +		memset(hostcall, 0, sizeof(*hostcall));
> +		hostcall->gprs[0] = HV_FUNC_ID;
> +		hostcall->gprs[1] = control;
> +		hostcall->gprs[2] = input_address;
> +		hostcall->gprs[3] = output_address;
> +
> +		if (rsi_host_call(virt_to_phys(hostcall)) == RSI_SUCCESS)
> +			ret = hostcall->gprs[0];
> +		else
> +			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
> +		local_irq_restore(flags);
> +		return ret;

This code sequence for handling the realm case is almost exactly
duplicated for the three hypercall variants. The only difference is
how gprs[2] and gprs[3] are populated. So I think the code
sequence could go into a helper routine with the appropriate
values for gprs[2] and gprs[3] passed in. 

> +	}
> +
> +	arm_smccc_1_1_hvc(HV_FUNC_ID, control, input_address,
> +			  output_address, &res);
>  	return res.a0;
>  }
>  EXPORT_SYMBOL_GPL(hv_do_hypercall);
> @@ -45,9 +66,28 @@ u64 hv_do_fast_hypercall8(u16 code, u64 input)
>  {
>  	struct arm_smccc_res	res;
>  	u64			control;
> +	struct rsi_host_call *hostcall;
> +	unsigned long flags;
> +	u64 ret;
> 
>  	control = (u64)code | HV_HYPERCALL_FAST_BIT;
> 
> +	if (is_realm_world()) {
> +		local_irq_save(flags);
> +		hostcall = *this_cpu_ptr(hyperv_pcpu_hostcall_struct);
> +		memset(hostcall, 0, sizeof(*hostcall));
> +		hostcall->gprs[0] = HV_FUNC_ID;
> +		hostcall->gprs[1] = control;
> +		hostcall->gprs[2] = input;
> +
> +		if (rsi_host_call(virt_to_phys(hostcall)) == RSI_SUCCESS)
> +			ret = hostcall->gprs[0];
> +		else
> +			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
> +		local_irq_restore(flags);
> +		return ret;
> +	}
> +
>  	arm_smccc_1_1_hvc(HV_FUNC_ID, control, input, &res);
>  	return res.a0;
>  }
> @@ -62,9 +102,29 @@ u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2)
>  {
>  	struct arm_smccc_res	res;
>  	u64			control;
> +	struct rsi_host_call *hostcall;
> +	unsigned long flags;
> +	u64 ret;
> 
>  	control = (u64)code | HV_HYPERCALL_FAST_BIT;
> 
> +	if (is_realm_world()) {
> +		local_irq_save(flags);
> +		hostcall = *this_cpu_ptr(hyperv_pcpu_hostcall_struct);
> +		memset(hostcall, 0, sizeof(*hostcall));
> +		hostcall->gprs[0] = HV_FUNC_ID;
> +		hostcall->gprs[1] = control;
> +		hostcall->gprs[2] = input1;
> +		hostcall->gprs[3] = input2;
> +
> +		if (rsi_host_call(virt_to_phys(hostcall)) == RSI_SUCCESS)
> +			ret = hostcall->gprs[0];
> +		else
> +			ret = HV_STATUS_INVALID_HYPERCALL_INPUT;
> +		local_irq_restore(flags);
> +		return ret;
> +	}
> +
>  	arm_smccc_1_1_hvc(HV_FUNC_ID, control, input1, input2, &res);
>  	return res.a0;
>  }
> @@ -76,24 +136,44 @@ EXPORT_SYMBOL_GPL(hv_do_fast_hypercall16);
>  void hv_set_vpreg(u32 msr, u64 value)
>  {
>  	struct arm_smccc_res res;
> +	struct rsi_host_call *hostcall;
> +	unsigned long flags;
> +	u64 status;
> +
> +	if (is_realm_world()) {
> +		local_irq_save(flags);
> +		hostcall = *this_cpu_ptr(hyperv_pcpu_hostcall_struct);
> +		memset(hostcall, 0, sizeof(*hostcall));
> +		hostcall->gprs[0] = HV_FUNC_ID;
> +		hostcall->gprs[1] = HVCALL_SET_VP_REGISTERS |
> +				    HV_HYPERCALL_FAST_BIT |
> +				    HV_HYPERCALL_REP_COMP_1;
> +		hostcall->gprs[2] = HV_PARTITION_ID_SELF;
> +		hostcall->gprs[3] = HV_VP_INDEX_SELF;
> +		hostcall->gprs[4] = msr;
> +		hostcall->gprs[6] = value;
> 
> -	arm_smccc_1_1_hvc(HV_FUNC_ID,
> -		HVCALL_SET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
> -			HV_HYPERCALL_REP_COMP_1,
> -		HV_PARTITION_ID_SELF,
> -		HV_VP_INDEX_SELF,
> -		msr,
> -		0,
> -		value,
> -		0,
> -		&res);
> +		if (rsi_host_call(virt_to_phys(hostcall)) == RSI_SUCCESS)
> +			status = hostcall->gprs[0];
> +		else
> +			status = HV_STATUS_INVALID_HYPERCALL_INPUT;
> +		local_irq_restore(flags);
> +	} else {
> +		arm_smccc_1_1_hvc(HV_FUNC_ID,
> +				  HVCALL_SET_VP_REGISTERS |
> +					  HV_HYPERCALL_FAST_BIT |
> +					  HV_HYPERCALL_REP_COMP_1,
> +				  HV_PARTITION_ID_SELF, HV_VP_INDEX_SELF, msr,
> +				  0, value, 0, &res);
> +		status = res.a0;
> +	}
> 
>  	/*
> -	 * Something is fundamentally broken in the hypervisor if
> -	 * setting a VP register fails. There's really no way to
> -	 * continue as a guest VM, so panic.
> +	 * Something is fundamentally broken in the hypervisor (or, in a
> +	 * Realm, the RMM denied the host call) if setting a VP register
> +	 * fails. There's really no way to continue as a guest VM, so panic.
>  	 */
> -	BUG_ON(!hv_result_success(res.a0));
> +	BUG_ON(!hv_result_success(status));
>  }
>  EXPORT_SYMBOL_GPL(hv_set_vpreg);
> 
> @@ -108,29 +188,56 @@ void hv_get_vpreg_128(u32 msr, struct
> hv_get_vp_registers_output *result)
>  {
>  	struct arm_smccc_1_2_regs args;
>  	struct arm_smccc_1_2_regs res;
> +	struct rsi_host_call *hostcall;
> +	u64 status;
> 
> -	args.a0 = HV_FUNC_ID;
> -	args.a1 = HVCALL_GET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
> -			HV_HYPERCALL_REP_COMP_1;
> -	args.a2 = HV_PARTITION_ID_SELF;
> -	args.a3 = HV_VP_INDEX_SELF;
> -	args.a4 = msr;
> +	if (is_realm_world()) {
> +		unsigned long flags;
> 
> -	/*
> -	 * Use the SMCCC 1.2 interface because the results are in registers
> -	 * beyond X0-X3.
> -	 */
> -	arm_smccc_1_2_hvc(&args, &res);
> +		local_irq_save(flags);
> +		hostcall = *this_cpu_ptr(hyperv_pcpu_hostcall_struct);
> +		memset(hostcall, 0, sizeof(*hostcall));
> +
> +		hostcall->gprs[0] = HV_FUNC_ID;
> +		hostcall->gprs[1] = HVCALL_GET_VP_REGISTERS |
> +				    HV_HYPERCALL_FAST_BIT |
> +				    HV_HYPERCALL_REP_COMP_1;
> +		hostcall->gprs[2] = HV_PARTITION_ID_SELF;
> +		hostcall->gprs[3] = HV_VP_INDEX_SELF;
> +		hostcall->gprs[4] = msr;
> +
> +		if (rsi_host_call(virt_to_phys(hostcall)) == RSI_SUCCESS) {
> +			status = hostcall->gprs[0];
> +			result->as64.low = hostcall->gprs[6];
> +			result->as64.high = hostcall->gprs[7];
> +		} else {
> +			status = HV_STATUS_INVALID_HYPERCALL_INPUT;
> +		}
> +		local_irq_restore(flags);
> +	} else {
> +		args.a0 = HV_FUNC_ID;
> +		args.a1 = HVCALL_GET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
> +			  HV_HYPERCALL_REP_COMP_1;
> +		args.a2 = HV_PARTITION_ID_SELF;
> +		args.a3 = HV_VP_INDEX_SELF;
> +		args.a4 = msr;
> +
> +		/*
> +		 * Use the SMCCC 1.2 interface because the results are in
> +		 * registers beyond X0-X3.
> +		 */
> +		arm_smccc_1_2_hvc(&args, &res);
> +		status = res.a0;
> +		result->as64.low = res.a6;
> +		result->as64.high = res.a7;
> +	}
> 
>  	/*
> -	 * Something is fundamentally broken in the hypervisor if
> -	 * getting a VP register fails. There's really no way to
> -	 * continue as a guest VM, so panic.
> +	 * Something is fundamentally broken in the hypervisor (or, in a
> +	 * Realm, the RMM denied the host call) if getting a VP register
> +	 * fails. There's really no way to continue as a guest VM, so panic.
>  	 */
> -	BUG_ON(!hv_result_success(res.a0));
> -
> -	result->as64.low = res.a6;
> -	result->as64.high = res.a7;
> +	BUG_ON(!hv_result_success(status));
>  }
>  EXPORT_SYMBOL_GPL(hv_get_vpreg_128);
> 
> --
> 2.45.4
> 



^ permalink raw reply

* Re: [PATCH v2 1/2] module: add SCMI device table alias support
From: Frank Li @ 2026-06-18 18:16 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Sudeep Holla, Cristian Marussi, Nathan Chancellor, Nicolas Schier,
	Michael Turquette, arm-scmi, linux-arm-kernel, linux-kernel,
	linux-kbuild, Hans de Goede, Stephen Boyd, Brian Masney,
	Rafael J. Wysocki, Viresh Kumar, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Guenter Roeck,
	Jyoti Bhayana, Jonathan Cameron, David Lechner, Nuno Sá,
	Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, Liam Girdwood,
	Mark Brown, Philipp Zabel, Alexandre Belloni, linux-clk, linux-pm,
	imx, linux-hwmon, linux-iio, linux-input, linux-rtc
In-Reply-To: <20260618-scmi-modalias-v2-1-8c7547c1be21@oss.qualcomm.com>

On Thu, Jun 18, 2026 at 03:56:34PM +0000, Bjorn Andersson wrote:
>
> SCMI client drivers already describe their bus match data with
> MODULE_DEVICE_TABLE(scmi, ...), but modpost does not know how to consume
> SCMI device tables. As a result, SCMI modules do not get generated module
> aliases from their id tables.
>
> Move struct scmi_device_id to mod_devicetable.h so it has a fixed layout
> visible to modpost, add the corresponding generated offsets and teach
> file2alias to emit scmi:<protocol>:<name> aliases.
>
> Use the same stable alias format for SCMI device uevents and sysfs
> modaliases. The previous string included the instance-specific device
> name, which is not useful for matching modules.
>
> Assisted-by: Codex:GPT-5.5
> Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>


^ permalink raw reply

* Re: [PATCH 08/11] dmaengine: ste_dma40: Use power domain for LCLA SRAM
From: Frank Li @ 2026-06-18 18:23 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ulf Hansson,
	Mark Brown, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Simona Vetter, Vinod Koul, Frank Li, Lee Jones,
	linux-arm-kernel, devicetree, linux-pm, dri-devel, dmaengine
In-Reply-To: <20260618-ux500-power-domains-v7-1-v1-8-eb5e50b1a588@kernel.org>

On Thu, Jun 18, 2026 at 07:00:54AM +0200, Linus Walleij wrote:
> Replace the LCLA ESRAM regulator with runtime PM.
>
> Use the SRAM device that owns the ESRAM34 power domain.
>
> Hold that domain while DMA transfers are active.
>
> Assisted-by: Codex:gpt-5-5
> Signed-off-by: Linus Walleij <linusw@kernel.org>
> ---
>  drivers/dma/ste_dma40.c | 97 ++++++++++++++++++++++++++++---------------------
>  1 file changed, 55 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
> index 9b803c0aec25..6ca67ec446dc 100644
> --- a/drivers/dma/ste_dma40.c
> +++ b/drivers/dma/ste_dma40.c
> @@ -21,8 +21,8 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/of_dma.h>
> +#include <linux/of_platform.h>
>  #include <linux/amba/bus.h>
> -#include <linux/regulator/consumer.h>
>
>  #include "dmaengine.h"
>  #include "ste_dma40.h"
> @@ -571,7 +571,8 @@ struct d40_gen_dmac {
>   * to phy_chans entries.
>   * @plat_data: Pointer to provided platform_data which is the driver
>   * configuration.
> - * @lcpa_regulator: Pointer to hold the regulator for the esram bank for lcla.
> + * @lcla_dev: SRAM device for the ESRAM bank used by LCLA.
> + * @lcla_pm_enabled: Whether runtime PM was enabled for LCLA by this driver.
>   * @phy_res: Vector containing all physical channels.
>   * @lcla_pool: lcla pool settings and data.
>   * @lcpa_base: The virtual mapped address of LCPA.
> @@ -607,7 +608,8 @@ struct d40_base {
>  	struct d40_chan			**lookup_log_chans;
>  	struct d40_chan			**lookup_phy_chans;
>  	struct stedma40_platform_data	 *plat_data;
> -	struct regulator		 *lcpa_regulator;
> +	struct device			 *lcla_dev;
> +	bool				  lcla_pm_enabled;
>  	/* Physical half channels */
>  	struct d40_phy_res		 *phy_res;
>  	struct d40_lcla_pool		  lcla_pool;
> @@ -628,6 +630,22 @@ static struct device *chan2dev(struct d40_chan *d40c)
>  	return &d40c->chan.dev->device;
>  }
>
> +static void d40_transfer_runtime_get(struct d40_base *base)
> +{
> +	if (base->lcla_dev)
> +		pm_runtime_get_sync(base->lcla_dev);
> +
> +	pm_runtime_get_sync(base->dev);

Suggest create device link between base->dev and base->lcla_dev, so run
time pm framework will auto do it for you

Ref: https://lore.kernel.org/imx/20260513-b4-b4-edma-runtime-opt-v5-4-1e595bfb8423@nxp.com/

Frank


^ permalink raw reply

* Re: [PATCH 3/8] Bluetooth: btnxpuart: Add M.2 Bluetooth device support using pwrseq
From: Frank Li @ 2026-06-18 18:27 UTC (permalink / raw)
  To: Sherry Sun (OSS)
  Cc: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl, imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun
In-Reply-To: <20260618101047.4185497-4-sherry.sun@oss.nxp.com>

On Thu, Jun 18, 2026 at 06:10:42PM +0800, Sherry Sun (OSS) wrote:
> From: Sherry Sun <sherry.sun@nxp.com>
>
> Power supply to the M.2 Bluetooth device attached to the host using M.2
> connector is controlled using the 'uart' pwrseq device. So add support for
> getting the pwrseq device if the OF graph link is present. Once obtained,
> the existing pwrseq APIs can be used to control the power supplies of the
> M.2 card.
>
> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> ---
>  drivers/bluetooth/btnxpuart.c | 33 ++++++++++++++++++++++++++++++---
>  1 file changed, 30 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
> index e7036a48ce48..1aa8972f0dab 100644
> --- a/drivers/bluetooth/btnxpuart.c
> +++ b/drivers/bluetooth/btnxpuart.c
> @@ -9,6 +9,8 @@
>
>  #include <linux/serdev.h>
>  #include <linux/of.h>
> +#include <linux/of_graph.h>
> +#include <linux/pwrseq/consumer.h>
>  #include <linux/skbuff.h>
>  #include <linux/unaligned.h>
>  #include <linux/firmware.h>
> @@ -211,6 +213,7 @@ struct btnxpuart_dev {
>
>  	struct ps_data psdata;
>  	struct btnxpuart_data *nxp_data;
> +	struct pwrseq_desc *pwrseq;
>  	struct reset_control *pdn;
>  	struct hci_uart hu;
>  };
> @@ -1866,11 +1869,27 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
>  		return err;
>  	}
>
> +	if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
> +		struct pwrseq_desc *pwrseq;
> +
> +		pwrseq = devm_pwrseq_get(&serdev->ctrl->dev, "uart");
> +		if (IS_ERR(pwrseq))
> +			return PTR_ERR(pwrseq);
> +
> +		nxpdev->pwrseq = pwrseq;
> +		err = pwrseq_power_on(pwrseq);
> +		if (err) {
> +			dev_err(&serdev->dev, "Failed to power on pwrseq\n");
> +			return err;
> +		}

Can you provide helper function like devm clk get and enabled?
like devm_pwrsq_get_on()

So simple below error handle.

Frank

> +	}
> +
>  	/* Initialize and register HCI device */
>  	hdev = hci_alloc_dev();
>  	if (!hdev) {
>  		dev_err(&serdev->dev, "Can't allocate HCI device\n");
> -		return -ENOMEM;
> +		err = -ENOMEM;
> +		goto err_pwrseq_power_off;
>  	}
>
>  	reset_control_deassert(nxpdev->pdn);
> @@ -1903,11 +1922,14 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
>
>  	if (hci_register_dev(hdev) < 0) {
>  		dev_err(&serdev->dev, "Can't register HCI device\n");
> +		err = -ENODEV;
>  		goto probe_fail;
>  	}
>
> -	if (ps_setup(hdev))
> +	if (ps_setup(hdev)) {
> +		err = -ENODEV;
>  		goto probe_fail;
> +	}
>
>  	hci_devcd_register(hdev, nxp_coredump, nxp_coredump_hdr,
>  			   nxp_coredump_notify);
> @@ -1917,7 +1939,10 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
>  probe_fail:
>  	reset_control_assert(nxpdev->pdn);
>  	hci_free_dev(hdev);
> -	return -ENODEV;
> +err_pwrseq_power_off:
> +	if (nxpdev->pwrseq)
> +		pwrseq_power_off(nxpdev->pwrseq);
> +	return err;
>  }
>
>  static void nxp_serdev_remove(struct serdev_device *serdev)
> @@ -1944,6 +1969,8 @@ static void nxp_serdev_remove(struct serdev_device *serdev)
>  	ps_cleanup(nxpdev);
>  	hci_unregister_dev(hdev);
>  	reset_control_assert(nxpdev->pdn);
> +	if (nxpdev->pwrseq)
> +		pwrseq_power_off(nxpdev->pwrseq);
>  	hci_free_dev(hdev);
>  }
>
> --
> 2.50.1
>
>


^ permalink raw reply

* Re: [PATCH 2/8] power: sequencing: pcie-m2: Add PCI ID for NXP 88W9098 and AW693 Bluetooth
From: Frank Li @ 2026-06-18 18:29 UTC (permalink / raw)
  To: Sherry Sun (OSS)
  Cc: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl, imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun
In-Reply-To: <20260618101047.4185497-3-sherry.sun@oss.nxp.com>

On Thu, Jun 18, 2026 at 06:10:41PM +0800, Sherry Sun (OSS) wrote:
> From: Sherry Sun <sherry.sun@nxp.com>
>
> 88W9098 is a NXP Wi-Fi/BT combo chip with PCI device ID 0x2b43 under
> Marvell Extended vendor ID. AW693 is a NXP Wi-Fi/BT combo chip with
> PCI device ID 0x3003 under NXP/Philips vendor ID.
>
> Add both chips to pwrseq_m2_pci_ids[] so that the pwrseq-pcie-m2 driver
> can create the Bluetooth serdev device when these cards are inserted into
> a PCIe M.2 Key E connector.
>
> Both chips use "nxp,88w8987-bt" as the serdev compatible string, which
> is the entry point for the btnxpuart driver. The driver identifies the
> actual chip variant at runtime via chip ID auto-detection and loads the
> appropriate firmware accordingly.
>
> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/power/sequencing/pwrseq-pcie-m2.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
> index 94c3f4b7ee36..9217ffcfa6e5 100644
> --- a/drivers/power/sequencing/pwrseq-pcie-m2.c
> +++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
> @@ -186,6 +186,10 @@ static int pwrseq_pcie_m2_match(struct pwrseq_device *pwrseq,
>  }
>
>  static const struct pci_device_id pwrseq_m2_pci_ids[] = {
> +	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x2b43),
> +	  .driver_data = (kernel_ulong_t)"nxp,88w8987-bt" },
> +	{ PCI_DEVICE(PCI_VENDOR_ID_PHILIPS, 0x3003),
> +	  .driver_data = (kernel_ulong_t)"nxp,88w8987-bt" },
>  	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x1107),
>  	  .driver_data = (kernel_ulong_t)"qcom,wcn7850-bt" },
>  	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x1103),
> --
> 2.50.1
>
>


^ permalink raw reply

* Re: [PATCH 1/8] PCI: imx6: Add skip_pwrctrl_off flag support
From: Frank Li @ 2026-06-18 18:37 UTC (permalink / raw)
  To: Sherry Sun (OSS)
  Cc: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl, imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun
In-Reply-To: <20260618101047.4185497-2-sherry.sun@oss.nxp.com>

On Thu, Jun 18, 2026 at 06:10:40PM +0800, Sherry Sun (OSS) wrote:
> From: Sherry Sun <sherry.sun@nxp.com>
>
> Use dw_pcie::skip_pwrctrl_off to avoid powering off devices during suspend
> to preserve wakeup capability of the devices and also not to power on the
> devices in the init path.
> This allows controller power-off to be skipped when some devices(e.g. M.2
> cards key E without auxiliary power) required to support PCIe L2 link state
> and wake-up mechanisms.
>
> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 36 +++++++++++++++++----------
>  1 file changed, 23 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 0fa716d1ed75..ff5a9565dbbf 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -1382,16 +1382,20 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
>  		}
>  	}
>
> -	ret = pci_pwrctrl_create_devices(dev);
> -	if (ret) {
> -		dev_err(dev, "failed to create pwrctrl devices\n");
> -		goto err_reg_disable;
> +	if (!pci->suspended) {
> +		ret = pci_pwrctrl_create_devices(dev);
> +		if (ret) {
> +			dev_err(dev, "failed to create pwrctrl devices\n");
> +			goto err_reg_disable;
> +		}

supposed create_devices only do once.

pci_pwrctrl_power_on_devices() controller on and off for difference case.

Frank
>  	}
>
> -	ret = pci_pwrctrl_power_on_devices(dev);
> -	if (ret) {
> -		dev_err(dev, "failed to power on pwrctrl devices\n");
> -		goto err_pwrctrl_destroy;
> +	if (!pp->skip_pwrctrl_off) {
> +		ret = pci_pwrctrl_power_on_devices(dev);
> +		if (ret) {
> +			dev_err(dev, "failed to power on pwrctrl devices\n");
> +			goto err_pwrctrl_destroy;
> +		}
>  	}
>
>  	ret = imx_pcie_clk_enable(imx_pcie);
> @@ -1460,9 +1464,10 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
>  err_clk_disable:
>  	imx_pcie_clk_disable(imx_pcie);
>  err_pwrctrl_power_off:
> -	pci_pwrctrl_power_off_devices(dev);
> +	if (!pp->skip_pwrctrl_off)
> +		pci_pwrctrl_power_off_devices(dev);
>  err_pwrctrl_destroy:
> -	if (ret != -EPROBE_DEFER)
> +	if (ret != -EPROBE_DEFER && !pci->suspended)
>  		pci_pwrctrl_destroy_devices(dev);
>  err_reg_disable:
>  	if (imx_pcie->vpcie)
> @@ -1482,7 +1487,8 @@ static void imx_pcie_host_exit(struct dw_pcie_rp *pp)
>  	}
>  	imx_pcie_clk_disable(imx_pcie);
>
> -	pci_pwrctrl_power_off_devices(pci->dev);
> +	if (!pci->pp.skip_pwrctrl_off)
> +		pci_pwrctrl_power_off_devices(pci->dev);
>  	if (imx_pcie->vpcie)
>  		regulator_disable(imx_pcie->vpcie);
>  }
> @@ -1990,12 +1996,16 @@ static int imx_pcie_probe(struct platform_device *pdev)
>  static void imx_pcie_shutdown(struct platform_device *pdev)
>  {
>  	struct imx_pcie *imx_pcie = platform_get_drvdata(pdev);
> +	struct dw_pcie *pci = imx_pcie->pci;
> +	struct dw_pcie_rp *pp = &pci->pp;
>
>  	/* bring down link, so bootloader gets clean state in case of reboot */
>  	imx_pcie_assert_core_reset(imx_pcie);
>  	imx_pcie_assert_perst(imx_pcie, true);
> -	pci_pwrctrl_power_off_devices(&pdev->dev);
> -	pci_pwrctrl_destroy_devices(&pdev->dev);
> +	if (!pp->skip_pwrctrl_off)
> +		pci_pwrctrl_power_off_devices(&pdev->dev);
> +	if (!pci->suspended)
> +		pci_pwrctrl_destroy_devices(&pdev->dev);
>  }
>
>  static const struct imx_pcie_drvdata drvdata[] = {
> --
> 2.50.1
>
>


^ permalink raw reply

* Re: [PATCH v10 1/4] dt-bindings: clock: imx95-blk-ctl: Use single quotes consistently
From: Frank Li @ 2026-06-18 18:40 UTC (permalink / raw)
  To: guoniu.zhou
  Cc: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
	Michael Turquette, Stephen Boyd, imx, linux-media, devicetree,
	linux-arm-kernel, linux-kernel, linux-clk, Guoniu Zhou
In-Reply-To: <20260618-csi_formatter-v10-1-f23830312ba5@oss.nxp.com>

On Thu, Jun 18, 2026 at 05:41:35PM +0800, guoniu.zhou@oss.nxp.com wrote:
> From: Guoniu Zhou <guoniu.zhou@nxp.com>
>
> Change "clocks" to 'clocks' in the description to match the quote style
> used for property names like '#clock-cells' throughout the file.
>
> Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

> Changes in v10:
> - New patch to fix inconsistent quote usage (Krzysztof Kozlowski)
> ---
>  Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> index 27403b4c52d6..534fa219d9f9 100644
> --- a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> +++ b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> @@ -36,7 +36,7 @@ properties:
>      const: 1
>      description:
>        The clock consumer should specify the desired clock by having the clock
> -      ID in its "clocks" phandle cell. See
> +      ID in its 'clocks' phandle cell. See
>        include/dt-bindings/clock/nxp,imx95-clock.h
>
>  required:
>
> --
> 2.34.1
>
>


^ permalink raw reply

* Re: [PATCH v10 2/4] media: dt-bindings: Add CSI Pixel Formatter DT bindings
From: Frank Li @ 2026-06-18 18:41 UTC (permalink / raw)
  To: guoniu.zhou
  Cc: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
	Michael Turquette, Stephen Boyd, imx, linux-media, devicetree,
	linux-arm-kernel, linux-kernel, linux-clk, Guoniu Zhou
In-Reply-To: <20260618-csi_formatter-v10-2-f23830312ba5@oss.nxp.com>

On Thu, Jun 18, 2026 at 05:41:36PM +0800, guoniu.zhou@oss.nxp.com wrote:
> From: Guoniu Zhou <guoniu.zhou@nxp.com>
>
> The i.MX95 CSI pixel formatting module uses packet info, pixel and
> non-pixel data from the CSI-2 host controller and reformat them to
> match Pixel Link(PL) definition.
>
> Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>

Reviewed-by: Frank Li <Frank.Li@nxp.com>

> ---
> Changes in v10:
> - Drop syscon parent node from example
> - Drop Reviewed-by tags from Frank and Krzysztof due to binding changes
> - Add description for reg property
> - Add space after formatter@20 before opening brace in example
> - Enhance the port description with more detailed information
> - Delete the blank line immediately following the endpoint in example
>
> Changes in v9:
> - Use direct node instead of syscon wrapper in example
>
> Changes in v8:
> - Use standard port reference instead of video-interfaces.yaml
> - Add parent syscon node in example to show device integration
> - Add required constraints for port@0 and port@1 in ports node
>
> Changes in v7:
> - Change compatible to imx95-csi-formatter as IP is i.MX95 specific per Marco's suggestion
>   Link: https://lore.kernel.org/linux-media/20260511-csi_formatter-v6-0-01028e312e2b@oss.nxp.com/T/#mcd135b3de179b3cb69daa1fd6e0e8e27c85b3332
> ---
>  .../bindings/media/fsl,imx95-csi-formatter.yaml    | 88 ++++++++++++++++++++++
>  1 file changed, 88 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/fsl,imx95-csi-formatter.yaml b/Documentation/devicetree/bindings/media/fsl,imx95-csi-formatter.yaml
> new file mode 100644
> index 000000000000..58c4e1cc056b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/fsl,imx95-csi-formatter.yaml
> @@ -0,0 +1,88 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/fsl,imx95-csi-formatter.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: i.MX95 CSI Pixel Formatter
> +
> +maintainers:
> +  - Guoniu Zhou <guoniu.zhou@nxp.com>
> +
> +description:
> +  The CSI pixel formatting module found on i.MX95 uses packet info, pixel
> +  and non-pixel data from the CSI-2 host controller and reformat them to
> +  match Pixel Link(PL) definition.
> +
> +properties:
> +  compatible:
> +    const: fsl,imx95-csi-formatter
> +
> +  reg:
> +    maxItems: 1
> +    description: Register offset and size within the parent syscon
> +
> +  clocks:
> +    maxItems: 1
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port@0:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description:
> +          Input port, connects to MIPI CSI-2 receiver output (IDI interface)
> +
> +      port@1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description:
> +          Output port, connects to ISI input via Pixel Link (PL)
> +
> +    required:
> +      - port@0
> +      - port@1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - power-domains
> +  - ports
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/nxp,imx95-clock.h>
> +
> +    formatter@20 {
> +        compatible = "fsl,imx95-csi-formatter";
> +        reg = <0x20 0x100>;
> +        clocks = <&cameramix_csr IMX95_CLK_CAMBLK_CSI2_FOR0>;
> +        power-domains = <&scmi_devpd 3>;
> +
> +        ports {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            port@0 {
> +                reg = <0>;
> +
> +                endpoint {
> +                    remote-endpoint = <&mipi_csi_0_out>;
> +                };
> +            };
> +
> +            port@1 {
> +                reg = <1>;
> +
> +                endpoint {
> +                    remote-endpoint = <&isi_in_2>;
> +                };
> +            };
> +        };
> +    };
>
> --
> 2.34.1
>
>


^ permalink raw reply

* Re: [PATCH v10 3/4] dt-bindings: clock: imx95-blk-ctl: Define formatter child node schema
From: Frank Li @ 2026-06-18 18:45 UTC (permalink / raw)
  To: guoniu.zhou
  Cc: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
	Michael Turquette, Stephen Boyd, imx, linux-media, devicetree,
	linux-arm-kernel, linux-kernel, linux-clk, Guoniu Zhou
In-Reply-To: <20260618-csi_formatter-v10-3-f23830312ba5@oss.nxp.com>

On Thu, Jun 18, 2026 at 05:41:37PM +0800, guoniu.zhou@oss.nxp.com wrote:
> From: Guoniu Zhou <guoniu.zhou@nxp.com>
>
> The Camera CSR contains control registers for multiple CSI formatter IPs
> at different register offsets. Each formatter is an independent hardware
> block with its own clock input and media pipeline connection.
>
> Define schema to allow formatter child nodes under nxp,imx95-camera-csr,
> with 'reg' property specifying the formatter's register offset within the
> CSR address space.
>
> Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
> ---
> Changes in v10:
> - Use single quotes for regex pattern to be consistent (Krzysztof Kozlowski)
> - Add formatter subnode binding and camera-csr syscon example
> - Update commit title and message
>
> Changes in v9:
> - New patch to address the issue of formatter acting as a child node of syscon
> ---
>  .../bindings/clock/nxp,imx95-blk-ctl.yaml          | 64 +++++++++++++++++++++-
>  1 file changed, 63 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> index 534fa219d9f9..b4d0a7670fac 100644
> --- a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> +++ b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> @@ -46,7 +46,27 @@ required:
>    - power-domains
>    - clocks
>
> -additionalProperties: false
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: nxp,imx95-camera-csr
> +    then:
> +      properties:
> +        '#address-cells':
> +          const: 1
> +        '#size-cells':
> +          const: 1
> +      required:
> +        - '#address-cells'
> +        - '#size-cells'
> +      patternProperties:
> +        '^formatter@[0-9a-f]+$':
> +          type: object
> +          $ref: /schemas/media/fsl,imx95-csi-formatter.yaml#

suppose      "unevaluatedProperties:" false should under '^formatter@[0-9a-f]+$':

> +
> +unevaluatedProperties: false

here should keep original additionalProperties: false

Frank

>
>  examples:
>    - |
> @@ -57,4 +77,46 @@ examples:
>        clocks = <&scmi_clk 114>;
>        power-domains = <&scmi_devpd 21>;
>      };
> +
> +  - |
> +    #include <dt-bindings/clock/nxp,imx95-clock.h>
> +
> +    syscon@4ac10000 {
> +      compatible = "nxp,imx95-camera-csr", "syscon";
> +      reg = <0x4ac10000 0x10000>;
> +      #address-cells = <1>;
> +      #size-cells = <1>;
> +      #clock-cells = <1>;
> +      clocks = <&scmi_clk 62>;
> +      power-domains = <&scmi_devpd 3>;
> +
> +      formatter@20 {
> +        compatible = "fsl,imx95-csi-formatter";
> +        reg = <0x20 0x100>;
> +        clocks = <&cameramix_csr IMX95_CLK_CAMBLK_CSI2_FOR0>;
> +        power-domains = <&scmi_devpd 3>;
> +
> +        ports {
> +          #address-cells = <1>;
> +          #size-cells = <0>;
> +
> +          port@0 {
> +            reg = <0>;
> +
> +            endpoint {
> +              remote-endpoint = <&mipi_csi_0_out>;
> +            };
> +
> +          };
> +
> +          port@1 {
> +            reg = <1>;
> +
> +            endpoint {
> +              remote-endpoint = <&isi_in_2>;
> +            };
> +          };
> +        };
> +      };
> +    };
>  ...
>
> --
> 2.34.1
>
>


^ permalink raw reply

* Re: [PATCH V2 2/3] dmaengine: zynqmp_dma: Add per-channel reset support
From: Frank Li @ 2026-06-18 18:52 UTC (permalink / raw)
  To: Golla Nagendra
  Cc: vkoul, Frank.Li, michal.simek, robh, krzk+dt, conor+dt,
	jay.buddhabhatti, harini.katakam, m.tretter, radhey.shyam.pandey,
	abin.joseph, kees, sakari.ailus, git, dmaengine, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20260618071056.2024286-3-nagendra.golla@amd.com>

On Thu, Jun 18, 2026 at 12:40:55PM +0530, Golla Nagendra wrote:
> [You don't often get email from nagendra.golla@amd.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> Versal Gen 2 and Versal Net SoCs expose a dedicated reset line per
> ZDMA channel, replacing the earlier approach where a single reset
> was shared across all channels. Add reset handling in the channel
> probe path using device_reset_optional() to trigger a reset pulse
> on the channel during initialization.
>
> Platforms without per-channel reset continue to work unaffected
> since device_reset_optional() returns 0 when no reset is specified.
>
> add pm_runtime_put_noidle() in the probe error path before
> pm_runtime_disable() to balance the usage counter incremented by
> pm_runtime_resume_and_get(). This is particularly important since
> device_reset_optional() can return -EPROBE_DEFER, causing the
> kernel to retry probe() and leak one PM usage count per retry
> without the put.

Use sperate patch to fix this problem

Frank
>
> Signed-off-by: Golla Nagendra <nagendra.golla@amd.com>
> ---
>  drivers/dma/xilinx/zynqmp_dma.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
> index f6a812e49ddc..a9dfec3c0ca3 100644
> --- a/drivers/dma/xilinx/zynqmp_dma.c
> +++ b/drivers/dma/xilinx/zynqmp_dma.c
> @@ -18,6 +18,7 @@
>  #include <linux/clk.h>
>  #include <linux/io-64-nonatomic-lo-hi.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/reset.h>
>
>  #include "../dmaengine.h"
>
> @@ -916,6 +917,11 @@ static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev,
>         if (IS_ERR(chan->regs))
>                 return PTR_ERR(chan->regs);
>
> +       err = device_reset_optional(&pdev->dev);
> +       if (err)
> +               return dev_err_probe(&pdev->dev, err,
> +                                    "failed to reset channel\n");
> +
>         chan->bus_width = ZYNQMP_DMA_BUS_WIDTH_64;
>         chan->dst_burst_len = ZYNQMP_DMA_MAX_DST_BURST_LEN;
>         chan->src_burst_len = ZYNQMP_DMA_MAX_SRC_BURST_LEN;
> @@ -1152,6 +1158,7 @@ static int zynqmp_dma_probe(struct platform_device *pdev)
>  err_disable_pm:
>         if (!pm_runtime_enabled(zdev->dev))
>                 zynqmp_dma_runtime_suspend(zdev->dev);
> +       pm_runtime_put_noidle(zdev->dev);
>         pm_runtime_disable(zdev->dev);
>         return ret;
>  }
> --
> 2.34.1
>


^ permalink raw reply

* Re: [PATCH v4 2/2] clk: amlogic: Add A9 AO clock controller driver
From: Julian Braha @ 2026-06-18 18:56 UTC (permalink / raw)
  To: jian.hu, Neil Armstrong, Jerome Brunet, Michael Turquette,
	Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Xianwei Zhao, Kevin Hilman, Martin Blumenstingl
  Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20260618-a9_aoclk-v4-2-569d0425e50c@amlogic.com>

Hi Jian,

On 6/18/26 10:49, Jian Hu via B4 Relay wrote:

> +config COMMON_CLK_A9_AO
> +	tristate "Amlogic A9 SoC AO clock controller support"
> +	depends on ARM64 || COMPILE_TEST
> +	default ARCH_MESON
> +	select COMMON_CLK_MESON_REGMAP
> +	select COMMON_CLK_MESON_CLKC_UTILS
> +	select COMMON_CLK_MESON_DUALDIV

Selecting COMMON_CLK_MESON_REGMAP is unnecessary since you're already
selecting COMMON_CLK_MESON_DUALDIV here.

- Julian Braha



^ permalink raw reply

* Re: [PATCH RFC v4 01/12] dt-bindings: clk: zte: Add zx297520v3 top clock and reset bindings
From: Stefan Dösinger @ 2026-06-18 18:59 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Brian Masney, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel
In-Reply-To: <20260617-deed-snap-4649ffae0e27@spud>

[-- Attachment #1: Type: text/plain, Size: 862 bytes --]

Am Donnerstag, 18. Juni 2026, 00:23:56 Ostafrikanische Zeit schrieben Sie:

> Do you actually need an aux bus here though? Since you have to add
> simple-mfd for your the syscon-reboot and simple-mfd is a real bus, can you
> set the reset controller up with an mfd_cell + devm_mfd_add_devices()
> instead?

I'll have to read up on devm_mfd_add_devices; The aux bus was the suggestion 
of Philipp Zabel. At first sight it sounds to me like they do fairly similar 
things. I don't see any precedence for [devm_]mfd_add_devices in drivers/clk/.

Whatever way I go I'd like to use the same for all 3 clock/reset controllers. 
So far I only made topclk a simple-mfd. I recently stumbled upon spinlock 
registers in matrixclk, so I guess I can justify a simple-mfd there too. For 
lspclk all I can see is clocks and resets and I ran out of unknown registers 
in there.

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 870 bytes --]

^ permalink raw reply

* Re: [PATCH kvmtool v2 7/7] arm64: Improve KVM_ARM_VCPU_PMU_V3_CTRL diagnostics
From: Oliver Upton @ 2026-06-18 19:06 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, jean-philippe.brucker,
	andre.przywara, suzuki.poulose, kvm, linux-arm-kernel, kvmarm
In-Reply-To: <20260618155001.226266-8-alexandru.elisei@arm.com>

On Thu, Jun 18, 2026 at 04:50:01PM +0100, Alexandru Elisei wrote:
> kvmtool issues several ioctls when configuring the PMU, and each of them
> can fail for different reasons. Be more specific about the ioctl that
> failed when that happens.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  arm64/pmu.c | 31 ++++++++++++++++++++++++-------
>  1 file changed, 24 insertions(+), 7 deletions(-)
> 
> diff --git a/arm64/pmu.c b/arm64/pmu.c
> index 92cacd62479e..78c15f153fad 100644
> --- a/arm64/pmu.c
> +++ b/arm64/pmu.c
> @@ -12,6 +12,24 @@
>  
>  #include "asm/pmu.h"
>  
> +static const char *pmu_attr_names[] = {
> +	[KVM_ARM_VCPU_PMU_V3_IRQ]	= "KVM_ARM_VCPU_PMU_V3_IRQ",
> +	[KVM_ARM_VCPU_PMU_V3_INIT]	= "KVM_ARM_VCPU_PMU_V3_INIT",
> +	[KVM_ARM_VCPU_PMU_V3_FILTER]	= "KVM_ARM_VCPU_PMU_V3_FILTER",
> +	[KVM_ARM_VCPU_PMU_V3_SET_PMU]	= "KVM_ARM_VCPU_PMU_V3_SET_PMU",
> +	[KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS] = "KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTER",
> +};
> +
> +static const char *pmu_get_attr_name(u64 attr)
> +{
> +	switch (attr) {
> +	case KVM_ARM_VCPU_PMU_V3_IRQ ... KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS:
> +		return pmu_attr_names[attr];
> +	default:
> +		return "UNKNOWN";
> +	}
> +}
> +
>  static bool pmu_has_attr(struct kvm_cpu *vcpu, u64 attr)
>  {
>  	struct kvm_device_attr pmu_attr = {
> @@ -32,13 +50,12 @@ static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr)
>  	};
>  	int ret;
>  
> -	if (pmu_has_attr(vcpu, attr)) {
> -		ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
> -		if (ret)
> -			die_perror("PMU KVM_SET_DEVICE_ATTR");
> -	} else {
> -		die_perror("PMU KVM_HAS_DEVICE_ATTR");
> -	}
> +	if (!pmu_has_attr(vcpu, attr))
> +		die_perror("KVM_HAS_DEVICE_ATTR(%s)", pmu_get_attr_name(attr));
> +
> +	ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
> +	if (ret)
> +		die_perror("KVM_SET_DEVICE_ATTR(%s)", pmu_get_attr_name(attr));
>  }

The whole if (ret) die_perror(...) thing is a bit repetetive IMO. A
treewide cleanup replacing this with macros would be nice, then you could
stringize the ioctl under the hood.

diff --git a/arm64/pmu.c b/arm64/pmu.c
index 5f31d6b..0d9f3df 100644
--- a/arm64/pmu.c
+++ b/arm64/pmu.c
@@ -23,23 +23,19 @@ static bool pmu_has_attr(struct kvm_cpu *vcpu, u64 attr)
 	return ret == 0;
 }
 
-static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr)
-{
-	struct kvm_device_attr pmu_attr = {
-		.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
-		.addr	= (u64)addr,
-		.attr	= attr,
-	};
-	int ret;
-
-	if (pmu_has_attr(vcpu, attr)) {
-		ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
-		if (ret)
-			die_perror("PMU KVM_SET_DEVICE_ATTR");
-	} else {
-		die_perror("PMU KVM_HAS_DEVICE_ATTR");
-	}
-}
+#define kvm_set_device_attr(fd, _group, _attr, _addr)					\
+do {											\
+	struct kvm_device_attr __attr = {						\
+		.group	= (_group),							\
+		.attr	= (_attr),							\
+		.addr	= (u64)(_addr),							\
+	};										\
+	int r;										\
+											\
+	r = ioctl((fd), KVM_SET_DEVICE_ATTR, &__attr);					\
+	if (r)										\
+		die_perror("KVM_SET_DEVICE_ATTR(group:"#_group", attr:"#_attr")");	\
+} while (0)
 
 #define SYS_EVENT_SOURCE	"/sys/bus/event_source/devices/"
 /*
@@ -218,14 +214,18 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
 
 	for (i = 0; i < kvm->nrcpus; i++) {
 		vcpu = kvm->cpus[i];
-		set_pmu_attr(vcpu, &irq, KVM_ARM_VCPU_PMU_V3_IRQ);
+		kvm_set_device_attr(vcpu->vcpu_fd, KVM_ARM_VCPU_PMU_V3_CTRL,
+				    KVM_ARM_VCPU_PMU_V3_IRQ, &irq);
 		/*
 		 * PMU IDs 0-5 are reserved; a positive value means a PMU was
 		 * found.
 		 */
 		if (pmu_id > 0)
-			set_pmu_attr(vcpu, &pmu_id, KVM_ARM_VCPU_PMU_V3_SET_PMU);
-		set_pmu_attr(vcpu, NULL, KVM_ARM_VCPU_PMU_V3_INIT);
+			kvm_set_device_attr(vcpu->vcpu_fd, KVM_ARM_VCPU_PMU_V3_CTRL,
+					    KVM_ARM_VCPU_PMU_V3_SET_PMU, &pmu_id);
+
+		kvm_set_device_attr(vcpu->vcpu_fd, KVM_ARM_VCPU_PMU_V3_CTRL,
+				    KVM_ARM_VCPU_PMU_V3_INIT, NULL);
 	}
 
 	_FDT(fdt_begin_node(fdt, "pmu"));


^ permalink raw reply related

* Re: [PATCH V2 3/3] dmaengine: zynqmp_dma: Guard IRQ handler against spurious interrupts
From: Frank Li @ 2026-06-18 19:15 UTC (permalink / raw)
  To: Golla Nagendra
  Cc: vkoul, Frank.Li, michal.simek, robh, krzk+dt, conor+dt,
	jay.buddhabhatti, harini.katakam, m.tretter, radhey.shyam.pandey,
	abin.joseph, kees, sakari.ailus, git, dmaengine, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20260618071056.2024286-4-nagendra.golla@amd.com>

On Thu, Jun 18, 2026 at 12:40:56PM +0530, Golla Nagendra wrote:
> [You don't often get email from nagendra.golla@amd.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> Add pm_runtime_get_if_active() check in zynqmp_dma_irq_handler() to
> safely handle spurious interrupts that may arrive while the device is
> runtime-suspended. Without this guard, a spurious interrupt could cause
> the handler to access hardware registers (ISR, IMR) with clocks gated,
> potentially leading to a synchronous external abort and kernel crash.
>
> When the device is not runtime-active, pm_runtime_get_if_active()
> returns false without incrementing the usage counter, and the handler
> returns IRQ_NONE immediately. When the device is active, it increments
> the usage counter to prevent a concurrent runtime suspend during
> register access, and pm_runtime_put() releases the reference afterward.
>
> Signed-off-by: Golla Nagendra <nagendra.golla@amd.com>
> ---
>  drivers/dma/xilinx/zynqmp_dma.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
> index a9dfec3c0ca3..ce9163138be7 100644
> --- a/drivers/dma/xilinx/zynqmp_dma.c
> +++ b/drivers/dma/xilinx/zynqmp_dma.c
> @@ -730,6 +730,9 @@ static irqreturn_t zynqmp_dma_irq_handler(int irq, void *data)
>         u32 isr, imr, status;
>         irqreturn_t ret = IRQ_NONE;
>
> +       if (pm_runtime_get_if_active(chan->dev) <= 0)
> +               return IRQ_NONE;
> +

Can you add AQUIRE macro in include/linux/pm_runtime.h
so here can use PM_RUNTIME_ACQUIRE_IF_ACITVE

Other person can get benefit for auto clean up especially if there are some
difference return path.

Frank

>         isr = readl(chan->regs + ZYNQMP_DMA_ISR);
>         imr = readl(chan->regs + ZYNQMP_DMA_IMR);
>         status = isr & ~imr;
> @@ -756,6 +759,8 @@ static irqreturn_t zynqmp_dma_irq_handler(int irq, void *data)
>                 ret = IRQ_HANDLED;
>         }
>
> +       pm_runtime_put(chan->dev);
> +
>         return ret;
>  }
>
> --
> 2.34.1
>


^ permalink raw reply

* Re: [PATCH RFC v4 10/12] reset: zte: Add a zx297520v3 reset driver
From: Stefan Dösinger @ 2026-06-18 19:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Brian Masney, Philipp Zabel
  Cc: linux-clk, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <90c4f50eb23dec06497d46f9c0f522a6b90a918b.camel@pengutronix.de>

[-- Attachment #1: Type: text/plain, Size: 3121 bytes --]

Am Donnerstag, 18. Juni 2026, 12:24:26 Ostafrikanische Zeit schrieb Philipp 
Zabel:
> On Di, 2026-06-16 at 23:26 +0300, Stefan Dösinger wrote:
> > This drives the auxiliary devices created by the clock driver.
> 
> Which auxiliary devices? Which clock driver?

The ones from patches 7-10. But I guess you're telling me to spell this out 
for readers who see my patch in the kernel commit log rather than the 
submission series.

> > +	[ZX297520V3_UART0_RESET]     = { .reg = 0x78,  .mask = BIT(6)  | 
BIT(7) 
> > },
> Is this a single reset line controlled by two bits (do you know what
> they are)? Or might these actually be two different reset controls that
> are just always set together?

Most devices on this SoC have two reset lines. In most cases asserting one is 
enough to reset the device, and consequently both need to be deasserted to 
bring the device out of reset. In some cases both need to be asserted to reset 
the device and it keeps operating fine with only one asserted. I believe I 
documented some of that in comments, but maybe I forgot to move it from the 
clock part of the driver.

Exceptions apply - some devices have only one reset bit and for some I haven't 
found any. USB as you noticed has 3.

I don't really know the difference between the two lines. I don't have a 
datasheet and ZTE's downstream kernel only operates on the USB resets. The old 
upstream zx2967xx code had no reset driver at all. So I found the resets by 
setting the registers and then single bits to 0 and seeing what disappears 
from mmio space. Everything on this board except USB comes with resets 
deasserted on boot.

I'm pretty sure that what I identified as resets are actually resets and not 
extra clocks because previous device configuration gets lost after asserting a 
reset, whereas it is retained when disabling pclk.

I absolutely expect to run into surprises and epiphanies in the future and 
problems on as of yet untested types of zx297520v3 devices.

> > +	[ZX297520V3_USB_RESET]      =  { .reg = 0x80,   .mask = BIT(3) | 
BIT(4)
> > | BIT(5), +		.wait_mask = BIT(1)},
> 
> Same as above, are these actually three separate reset lines?

It is likely a combination of the same 2 indistinguishable lines (4, 5) and a 
separate USB PHY line (3) - this is what ZTE's code suggests, but it is a mess 
of #ifdefs and redirection, so I don't know if I isolated the correct 
codepath. (No, a kernel built from that ugly code doesn't boot, so I can't add 
printks).

The PHY reset line does not do anything observable on my device if I recall 
correctly. It might be nonexistent, it might be a leftover from older 
revisions or some devices might have different PHYs, similarly to how Ethernet 
PHYs differ.

I'll double check those USB resets before I resend. It's been months since I 
looked at this particular part of the board, and maybe I missed something. On 
the booted ZTE kernel and in the bootloader, when booted via USB, all 3 are 
deasserted. When booted via the NAND boot chain they are asserted when the 
kernel takes over.



[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 870 bytes --]

^ permalink raw reply

* Re: [PATCH v1 1/1] i2c: nomadik: Use generic definitions for bus frequencies
From: Linus Walleij @ 2026-06-18 19:48 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: linux-arm-kernel, linux-i2c, linux-kernel, Andi Shyti
In-Reply-To: <20260618141730.3243303-1-andriy.shevchenko@linux.intel.com>

On Thu, Jun 18, 2026 at 4:17 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:

> Since we have generic definitions for bus frequencies, let's use them.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Oh, neat.
Reviewed-by: Linus Walleij <linusw@kernel.org>

Yours,
Linus Walleij


^ permalink raw reply

* Re: [PATCH RFC v4 01/12] dt-bindings: clk: zte: Add zx297520v3 top clock and reset bindings
From: Conor Dooley @ 2026-06-18 19:54 UTC (permalink / raw)
  To: Stefan Dösinger
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Brian Masney, linux-clk, devicetree,
	linux-kernel, linux-arm-kernel
In-Reply-To: <BXIzXc2sQ5SGynZ1chd-pw@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2850 bytes --]

On Thu, Jun 18, 2026 at 09:59:00PM +0300, Stefan Dösinger wrote:
> Am Donnerstag, 18. Juni 2026, 00:23:56 Ostafrikanische Zeit schrieben Sie:
> 
> > Do you actually need an aux bus here though? Since you have to add
> > simple-mfd for your the syscon-reboot and simple-mfd is a real bus, can you
> > set the reset controller up with an mfd_cell + devm_mfd_add_devices()
> > instead?
> 
> I'll have to read up on devm_mfd_add_devices; The aux bus was the suggestion 
> of Philipp Zabel. At first sight it sounds to me like they do fairly similar 
> things. I don't see any precedence for [devm_]mfd_add_devices in drivers/clk/.

I think you don't see it because the driver calling mfd_add_devices()
probably isn't in drivers/clk and probably also uses an mfd_cell for the
clock.
There's some in drivers/soc and some in drivers/mfd (I'll be honest and
admit to not knowing what actually drives the placement of the mfd
driver).

I think aux bus makes perfect sense when you have a clock/reset
controller, but once you start expanding past that and you have reboot
or hwmon or hwspinlock then mfd starts to make sense.

> 
> Whatever way I go I'd like to use the same for all 3 clock/reset controllers. 
> So far I only made topclk a simple-mfd. I recently stumbled upon spinlock 
> registers in matrixclk, so I guess I can justify a simple-mfd there too. For 

Just to note, simple-mfd is used when you have child nodes. You don't
need simple-mfd if a device fills multiple roles but doesn't have
children.
Your hwspinlock may not require a child node at all, you can just put
#hwlock-cells into the main node and use mfd_add_devices().

You'd then have topclock that is a syscon + simple-mfd, matrixclk that is
a syscon and lsp that's using the aux bus. The topclock and matrixclock
would have dedicated and trivial drivers somewhere that have the mfd_cells
and call mfd_add_devices(). The fact that topclock would be a simple-mfd
has basically no impact - I think the difference is that topclock will
call of_platform_populate() where matrixclk will not.

Probably the compatibles you've chosen start to make less sense at this
point though, but probably "topclk" and "matrixclk" are not what the
documentation for this device calls these register regions?

> lspclk all I can see is clocks and resets and I ran out of unknown registers 
> in there.

I think the priority is having something that reflects the hardware
accurately, I wouldn't compromise on that just to have the same design
for all three drivers.

I guess the problem you have is that the reset driver is shared? You can
always have more than one way to probe a driver. Because I messed up
stuff in the past, reset-mpfs.c has both aux bus and mfd probing in it,
which could serve as an example for how to have both in one file.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH] dt-bindings: spi: st,stm32-qspi: Add power-domains property
From: Mark Brown @ 2026-06-18 20:05 UTC (permalink / raw)
  To: Patrice Chotard
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
	Alexandre Torgue, Christophe Kerello, linux-spi, devicetree,
	linux-stm32, linux-arm-kernel, linux-kernel
In-Reply-To: <20260618-add_power_domain_for_qpsi-v1-1-4d7e57bcfb9a@foss.st.com>

[-- Attachment #1: Type: text/plain, Size: 490 bytes --]

On Thu, Jun 18, 2026 at 08:46:35AM +0200, Patrice Chotard wrote:
> STM32 QSPI may be in a power domain. Allow a single 'power-domains'
> entry for STM32 QSPI.

Please submit patches using subject lines reflecting the style for the
subsystem, this makes it easier for people to identify relevant patches.
Look at what existing commits in the area you're changing are doing and
make sure your subject lines visually resemble what they're doing.
There's no need to resubmit to fix this alone.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH v7 09/20] KVM: selftests: Add VFIO device support to eventfd IRQ test
From: David Matlack @ 2026-06-18 20:21 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: Paolo Bonzini, Marc Zyngier, Oliver Upton, Joey Gouly,
	Steffen Eiden, Suzuki K Poulose, Zenghui Yu, kvm,
	linux-arm-kernel, kvmarm, linux-kernel, Josh Hilke
In-Reply-To: <20260613002031.745413-10-seanjc@google.com>

On 2026-06-12 05:20 PM, Sean Christopherson wrote:
> From: David Matlack <dmatlack@google.com>
> 
> Extend the eventfd IRQ test with a '-d' argument that takes a BDF (in the
> format segment:bus:device.function) of an interrupt-capable PCI(e) device
> bound to VFIO, and use said device to trigger interrupts instead of always
> synthesizing interrupts via direct writes to the eventfd.
> 
> Using a VFIO device to trigger interrupts validates the end-to-end delivery
> of IRQs for "real" devices, and when supported by hardware (and KVM), also
> validates interrupt delivery via IRQ bypass, i.e. via device posted IRQs.
> 
> Now that IOMMUFD is a thing, auto-probe IOMMUFD vs. "legacy" VFIO by
> temporarily opening /dev/iommufd, and skip the test if neither IOMMUFD nor
> legacy VFIO is available.  Add a '-t' option to the user override the probe
> logic, e.g. in case IOMMUFD is available but the system is configured for
> legacy usage.
> 
> Note, the device must have a VFIO selftest driver in order to work with
> the test.  A helper script to list supported devices will hopefully be
> available in the near future at
> tools/testing/selftests/vfio/scripts/list_supported_devices.sh[1].

> +static int vfio_setup_msi(struct vfio_pci_device *device)
> +{
> +	const int flags = MAP_SHARED | MAP_ANONYMOUS;
> +	const int prot = PROT_READ | PROT_WRITE;
> +	struct dma_region *region;
> +
> +	/* A driver is required to generate an MSI. */
> +	TEST_REQUIRE(device->driver.ops);

This series is probably going to race with merging another VFIO
selftests patch to make send_msi() optional [1]. Can you add a check for
that here?

  TEST_REQUIRE(device->driver.ops);
  TEST_REQUIRE(device->driver.ops->send_msi);

[1] https://lore.kernel.org/kvm/20260609232855.3808971-4-rubind@nvidia.com/


^ permalink raw reply

* Re: [PATCH v2 0/2] firmware: arm_scmi: Ensure automatic module loading
From: Hans de Goede @ 2026-06-18 20:31 UTC (permalink / raw)
  To: Bjorn Andersson, Sudeep Holla, Cristian Marussi,
	Nathan Chancellor, Nicolas Schier, Michael Turquette
  Cc: arm-scmi, linux-arm-kernel, linux-kernel, linux-kbuild,
	Stephen Boyd, Brian Masney, Rafael J. Wysocki, Viresh Kumar,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Guenter Roeck, Jyoti Bhayana, Jonathan Cameron, David Lechner,
	Nuno Sá, Andy Shevchenko, Dmitry Torokhov, Ulf Hansson,
	Liam Girdwood, Mark Brown, Philipp Zabel, Alexandre Belloni,
	linux-clk, linux-pm, imx, linux-hwmon, linux-iio, linux-input,
	linux-rtc
In-Reply-To: <20260618-scmi-modalias-v2-0-8c7547c1be21@oss.qualcomm.com>

Hi,

On 18-Jun-26 17:56, Bjorn Andersson wrote:
> SCMI drivers such as the Arm SCMI CPUfreq driver are allowed to built as
> modules, but they are then not automatically loaded. Rework the SCMI
> device table alias support to make modpost consume the information from
> MODULE_DEVICE_TABLE(scmi, ...) and allow drivers to be loaded based on
> this information, if known. Also add a protocol-based alias to also
> trigger driver loading when only the SCMI protocol id is known.
> 
> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>

So I just gave this a test spin and unfortunately it does not work.

The problem with Fedora's kernel-config / setup is that the
request_module() from patch 2/2 runs from the initramfs, but
the scmi_cpufreq module is only available in the rootfs.

It does work if I explictly add the scmi_cpufreq module to
the initramfs, then it does get autoloaded.

We really need some place to put a uevent sysfs attr which then
gets replayed when udev is restarted from the rootfs and then
re-reads all the uevent files as part of its coldplug
enumeration.

I wonder if it is ok for a single uevent file to have
multiple MODALIAS= lines in there.

Regards,

Hans



> ---
> Changes in v2:
> - Use request_module_nowait()
> - Drop #include <linux/mod_devicetable.h> from scmi_protocol.h
> - Link to v1: https://patch.msgid.link/20260616-scmi-modalias-v1-0-662b8dd52ab2@oss.qualcomm.com
> 
> To: Sudeep Holla <sudeep.holla@kernel.org>
> To: Cristian Marussi <cristian.marussi@arm.com>
> To: Michael Turquette <mturquette@baylibre.com>
> To: Nicolas Schier <nsc@kernel.org>
> Cc: Stephen Boyd <sboyd@kernel.org>
> Cc: Brian Masney <bmasney@redhat.com>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: Viresh Kumar <viresh.kumar@linaro.org>
> Cc: Frank Li <Frank.Li@nxp.com>
> Cc: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Guenter Roeck <linux@roeck-us.net>
> Cc: Jyoti Bhayana <jbhayana@google.com>
> Cc: Jonathan Cameron <jic23@kernel.org>
> Cc: David Lechner <dlechner@baylibre.com>
> Cc: Nuno Sá <nuno.sa@analog.com>
> Cc: Andy Shevchenko <andy@kernel.org>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Cc: Ulf Hansson <ulfh@kernel.org>
> Cc: Liam Girdwood <lgirdwood@gmail.com>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Cc: Nathan Chancellor <nathan@kernel.org>
> Cc: arm-scmi@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-pm@vger.kernel.org
> Cc: imx@lists.linux.dev
> Cc: linux-hwmon@vger.kernel.org
> Cc: linux-iio@vger.kernel.org
> Cc: linux-input@vger.kernel.org
> Cc: linux-rtc@vger.kernel.org
> Cc: linux-kbuild@vger.kernel.org
> 
> ---
> Bjorn Andersson (2):
>       module: add SCMI device table alias support
>       firmware: arm_scmi: request modules for discovered protocols
> 
>  drivers/clk/clk-scmi.c                         |  1 +
>  drivers/cpufreq/scmi-cpufreq.c                 |  1 +
>  drivers/firmware/arm_scmi/bus.c                | 20 ++++++++++----------
>  drivers/firmware/arm_scmi/driver.c             |  3 +++
>  drivers/firmware/arm_scmi/scmi_power_control.c |  1 +
>  drivers/firmware/imx/sm-cpu.c                  |  1 +
>  drivers/firmware/imx/sm-lmm.c                  |  1 +
>  drivers/firmware/imx/sm-misc.c                 |  1 +
>  drivers/hwmon/scmi-hwmon.c                     |  1 +
>  drivers/iio/common/scmi_sensors/scmi_iio.c     |  1 +
>  drivers/input/keyboard/imx-sm-bbm-key.c        |  1 +
>  drivers/pmdomain/arm/scmi_perf_domain.c        |  1 +
>  drivers/pmdomain/arm/scmi_pm_domain.c          |  1 +
>  drivers/powercap/arm_scmi_powercap.c           |  1 +
>  drivers/regulator/scmi-regulator.c             |  1 +
>  drivers/reset/reset-scmi.c                     |  1 +
>  drivers/rtc/rtc-imx-sm-bbm.c                   |  1 +
>  include/linux/mod_devicetable.h                | 12 ++++++++++++
>  include/linux/scmi_protocol.h                  |  5 +----
>  scripts/mod/devicetable-offsets.c              |  4 ++++
>  scripts/mod/file2alias.c                       | 13 +++++++++++++
>  21 files changed, 58 insertions(+), 14 deletions(-)
> ---
> base-commit: 8d6dbbbe3ba62de0a63e962ee004afb848c8e3ac
> change-id: 20260616-scmi-modalias-0f32421bd452
> 
> Best regards,
> --  
> Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
> 
> 



^ permalink raw reply

* Re: [PATCH] iommu/arm-smmu-v3: Fix VCMDQ indexing in tegra241_vintf0_handle_error
From: Nicolin Chen @ 2026-06-18 20:53 UTC (permalink / raw)
  To: lirongqing
  Cc: Thierry Reding, Krishna Reddy, Will Deacon, Robin Murphy,
	Joerg Roedel, Jonathan Hunter, Nate Watterson, Jason Gunthorpe,
	linux-tegra, linux-arm-kernel, iommu, linux-kernel
In-Reply-To: <20260618075945.2217-1-lirongqing@baidu.com>

On Thu, Jun 18, 2026 at 03:59:45PM +0800, lirongqing wrote:
> From: Li RongQing <lirongqing@baidu.com>
> 
> In tegra241_vintf0_handle_error(), the driver loops through the
> LVCMDQ_ERR_MAP_64(i) registers to detect and handle error flags for
> each virtual command queue (VCMDQ).
> 
> However, the code erroneously uses the register-local bit offset
> returned by __ffs64(map) directly as the global logical queue index

Hmm, what do you mean by "global"? It should be just the logical
index to a VINTF:

  		u64 map = readq_relaxed(REG_VINTF(vintf, LVCMDQ_ERR_MAP_64(i)));

So, nothing "global" here.

> (lidx) into the vintf->lvcmdqs[] array. When 'i' is greater than 0
> (i.e., handling queues 64 and above), this logic incorrectly targets
> the queues in the first block (0-63) instead of the intended queues
> (i * 64 + bit).

This should not be reachable: kernel limits num_lvcmdqs_per_vintf
to 2, covered by the first 64-bit map (i=0); in other words, that
"'i' is greater than 0" shouldn't happen.

> This leads to handling errors on the wrong VCMDQ
> structures and clearing the wrong hardware error status.

Neither should this.

So, I don't think this "bug" requires a separate patch to fix.

With that being said, I have prepared a series of VCMDQ patches,
which I plan to send on rc1. And it does cover this part for a
defensive enhancement:

@@ -352,13 +352,20 @@ static void tegra241_vintf0_handle_error(struct tegra241_vintf *vintf)
 		u64 map = readq_relaxed(REG_VINTF(vintf, LVCMDQ_ERR_MAP_64(i)));
 
 		while (map) {
-			unsigned long lidx = __ffs64(map);
-			struct tegra241_vcmdq *vcmdq = vintf->lvcmdqs[lidx];
-			u32 gerror = readl_relaxed(REG_VCMDQ_PAGE0(vcmdq, GERROR));
+			unsigned long map_bit = __ffs64(map);
+			unsigned long lidx = 64 * i + map_bit;
+			struct tegra241_vcmdq *vcmdq;
+			u32 gerror;
 
+			map &= ~BIT_ULL(map_bit);
+
+			vcmdq = vintf->lvcmdqs[lidx];
+			if (!vcmdq)
+				continue;
+
+			gerror = readl_relaxed(REG_VCMDQ_PAGE0(vcmdq, GERROR));
 			__arm_smmu_cmdq_skip_err(&vintf->cmdqv->smmu, &vcmdq->cmdq);
 			writel(gerror, REG_VCMDQ_PAGE0(vcmdq, GERRORN));
-			map &= ~BIT_ULL(lidx);
 		}
 	}
 }

Nicolin


^ permalink raw reply

* [PATCH v6 1/2] iio: dac: add mcf54415 DAC
From: Angelo Dureghello @ 2026-06-18 21:04 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Geert Uytterhoeven, Maxime Coquelin, Alexandre Torgue
  Cc: linux-kernel, linux-iio, linux-m68k, linux-stm32,
	linux-arm-kernel, Angelo Dureghello
In-Reply-To: <20260618-wip-stmark2-dac-v6-0-48761dbb96d7@baylibre.com>

From: Angelo Dureghello <adureghello@baylibre.com>

Add basic version of mcf54415 DAC driver. DAC is embedded in the SoC and
DAC configuration registers are mapped in the internal IO address space.

The DAC accepts a 12-bit digital signal and creates a monotonic 12-bit
analog output varying from DAC_VREFL to DAC_VREFH. The DAC module
consists of a conversion unit, an output amplifier, and the associated
digital control blocks. Default register values for DAC_VREFL and DAC_VREFH
are respectively 0 and 0xfff, left untouched in this initial version.

This initial version of the driver is minimalistic, "output raw" only, to
be extended in the future. DMA and external sync are disabled, default mode
is high speed, default format is right-justified 12-bit on 16-bit word.

Signed-off-by: Angelo Dureghello <adureghello@baylibre.com>
---
Changes in v2:
- remove tests from commit message, moved to patch 0
- remove additional blank lines
- remove dead code and unused definitions
- use regmap
- add limit check on raw write
- non functional style fixes
- add COMPILE_TEST to Kconfig
Changes in v3:
- add comments where needed
- code style changes
- remove unneeded variables
- use regmap_set_bits where possible
- remove macro not needed to define a single channel
- set up regmap to big_endian accesses for next patches that will come,
  that will adjust ColdFire readx/writex as standard LE (links in 0/x).
- add return value check on regmap calls
- sashiko: remove unneeded .io_port from regmap init.
- sashiko: add select REGMAP_MMIO in Kconfig
Changes in v4:
- remove unused includes
- sashiko: return "ret" as regmap_read ret value in case of error
- sashiko: using u32 as regmap_read value
- use local variable in mcf54415_dac_init() for better readability
- sashiko: check mcf54415_dac_init return value also in resume()
Changes in v5:
- commit syntax fixes
- minor code style fixes
- use include <linux/type.h>
- removed unneeded cast
- disable clock in case of DAC init error
- use unsigned int for regmap_read and GENMASK for masking 12 bits
- add id table to match "mcfdac" platform device name
Changes in v6:
- removed pm ops, can't be tested for mcf54415 with mmu enabled
- Kconfig desc line rewrap
- minor coding style fixes
---
 drivers/iio/dac/Kconfig        |  11 +++
 drivers/iio/dac/Makefile       |   1 +
 drivers/iio/dac/mcf54415_dac.c | 183 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 195 insertions(+)

diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index cd4870b65415..b23078c8986a 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -516,6 +516,17 @@ config MAX5821
 	  Say yes here to build support for Maxim MAX5821
 	  10 bits DAC.
 
+config MCF54415_DAC
+	tristate "NXP MCF54415 DAC driver"
+	depends on M5441x || COMPILE_TEST
+	select REGMAP_MMIO
+	help
+	  Say yes here if you want to build support for NXP ColdFire
+	  MCF54415/6/7/8 12-bit DAC module.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called mcf54415_dac.
+
 config MCP4725
 	tristate "MCP4725/6 DAC driver"
 	depends on I2C
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
index 2a80bbf4e80a..1cb93e83d0eb 100644
--- a/drivers/iio/dac/Makefile
+++ b/drivers/iio/dac/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_MAX517) += max517.o
 obj-$(CONFIG_MAX22007) += max22007.o
 obj-$(CONFIG_MAX5522) += max5522.o
 obj-$(CONFIG_MAX5821) += max5821.o
+obj-$(CONFIG_MCF54415_DAC) += mcf54415_dac.o
 obj-$(CONFIG_MCP4725) += mcp4725.o
 obj-$(CONFIG_MCP4728) += mcp4728.o
 obj-$(CONFIG_MCP47FEB02) += mcp47feb02.o
diff --git a/drivers/iio/dac/mcf54415_dac.c b/drivers/iio/dac/mcf54415_dac.c
new file mode 100644
index 000000000000..986c4c6ac727
--- /dev/null
+++ b/drivers/iio/dac/mcf54415_dac.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * NXP mcf54415 DAC driver
+ *
+ * Copyright 2026 BayLibre - adureghello@baylibre.com
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+#include <linux/iio/iio.h>
+
+#define MCF54415_DAC_CR			0x00
+#define MCF54415_DAC_CR_PDN		BIT(0)
+#define MCF54415_DAC_CR_HSLS		BIT(6)
+#define MCF54415_DAC_CR_WMLVL		GENMASK(9, 8)
+#define MCF54415_DAC_CR_FILT		BIT(12)
+
+#define MCF54415_DAC_DATA		0x02
+
+struct mcf54415_dac {
+	struct regmap *map;
+	struct clk *clk;
+};
+
+static const struct regmap_config mcf54415_dac_regmap_config = {
+	.reg_bits = 16,
+	.reg_stride = 2,
+	.val_bits = 16,
+	.max_register = 0x0c, /* DACX_FILTCNT,  R.M. Table 30-2 */
+	.val_format_endian = REGMAP_ENDIAN_BIG,
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+};
+
+static int mcf54415_dac_init(struct mcf54415_dac *info)
+{
+	u16 val = MCF54415_DAC_CR_FILT | FIELD_PREP(MCF54415_DAC_CR_WMLVL, 1);
+	int ret;
+
+	/* Fixed defaults and enable DAC (bit 0 set to 0) */
+	ret = regmap_write(info->map, MCF54415_DAC_CR, val);
+	if (ret)
+		return ret;
+
+	/* DAC is ready after 12us, from RM table 40-3  */
+	fsleep(12);
+
+	return 0;
+}
+
+static void mcf54415_dac_exit(void *data)
+{
+	struct mcf54415_dac *info = data;
+
+	regmap_set_bits(info->map, MCF54415_DAC_CR, MCF54415_DAC_CR_PDN);
+}
+
+static const struct iio_chan_spec mcf54415_dac_iio_channel = {
+	.type = IIO_VOLTAGE,
+	.output = 1,
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+};
+
+static int mcf54415_read_raw(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     int *val, int *val2, long mask)
+{
+	struct mcf54415_dac *info = iio_priv(indio_dev);
+	unsigned int reg;
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		ret = regmap_read(info->map, MCF54415_DAC_DATA, &reg);
+		if (ret)
+			return ret;
+		*val = reg & GENMASK(11, 0);
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		/* Reference voltage as per ColdFire datasheet is 3.3V */
+		*val = 3300 /* mV */;
+		*val2 = 12;
+		return IIO_VAL_FRACTIONAL_LOG2;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mcf54415_write_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int val, int val2, long mask)
+{
+	struct mcf54415_dac *info = iio_priv(indio_dev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		/* Check based on RM 30.3.2 (DACn_DATA) reg. resolution */
+		if (val < 0 || val > 4095)
+			return -EINVAL;
+		return regmap_write(info->map, MCF54415_DAC_DATA, val);
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct iio_info mcf54415_dac_iio_info = {
+	.read_raw = &mcf54415_read_raw,
+	.write_raw = &mcf54415_write_raw,
+};
+
+static int mcf54415_dac_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct iio_dev *indio_dev;
+	struct mcf54415_dac *info;
+	void __iomem *regs;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*info));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	info = iio_priv(indio_dev);
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return dev_err_probe(dev, PTR_ERR(regs), "failed to get io regs\n");
+
+	info->map = devm_regmap_init_mmio(dev, regs, &mcf54415_dac_regmap_config);
+	if (IS_ERR(info->map))
+		return PTR_ERR(info->map);
+
+	info->clk = devm_clk_get_enabled(dev, "dac");
+	if (IS_ERR(info->clk))
+		return dev_err_probe(dev, PTR_ERR(info->clk), "failed getting clock\n");
+
+	platform_set_drvdata(pdev, indio_dev);
+
+	indio_dev->name = "mcf54415";
+	indio_dev->info = &mcf54415_dac_iio_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = &mcf54415_dac_iio_channel;
+	indio_dev->num_channels = 1;
+
+	ret = mcf54415_dac_init(info);
+	if (ret)
+		return ret;
+
+	ret = devm_add_action_or_reset(dev, mcf54415_dac_exit, info);
+	if (ret)
+		return ret;
+
+	return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct platform_device_id mcf54415_dac_ids[] = {
+	{ .name = "mcfdac" },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, mcf54415_dac_ids);
+
+static struct platform_driver mcf54415_dac_driver = {
+	.driver = {
+		.name = "mcf54415_dac",
+	},
+	.probe = mcf54415_dac_probe,
+	.id_table = mcf54415_dac_ids,
+};
+module_platform_driver(mcf54415_dac_driver);
+
+MODULE_AUTHOR("Angelo Dureghello <angelo@kernel-space.org>");
+MODULE_DESCRIPTION("NXP MCF54415 DAC driver");
+MODULE_LICENSE("GPL");

-- 
2.54.0



^ permalink raw reply related

* [PATCH v6 2/2] m68k: defconfig: update stmark2 defconfig
From: Angelo Dureghello @ 2026-06-18 21:04 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Geert Uytterhoeven, Maxime Coquelin, Alexandre Torgue
  Cc: linux-kernel, linux-iio, linux-m68k, linux-stm32,
	linux-arm-kernel, Angelo Dureghello
In-Reply-To: <20260618-wip-stmark2-dac-v6-0-48761dbb96d7@baylibre.com>

From: Angelo Dureghello <adureghello@baylibre.com>

Update stmark2 defconfig enabling MCF5441X DACs.

Signed-off-by: Angelo Dureghello <adureghello@baylibre.com>
---
Changes for v5:
- move this patch after new Kconfig symbols are added
---
 arch/m68k/configs/stmark2_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/m68k/configs/stmark2_defconfig b/arch/m68k/configs/stmark2_defconfig
index b3fb95f73a95..3941113bc60b 100644
--- a/arch/m68k/configs/stmark2_defconfig
+++ b/arch/m68k/configs/stmark2_defconfig
@@ -76,6 +76,8 @@ CONFIG_DMADEVICES=y
 CONFIG_MCF_EDMA=y
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_VHOST_MENU is not set
+CONFIG_IIO=y
+CONFIG_MCF54415_DAC=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y

-- 
2.54.0



^ permalink raw reply related

* [PATCH v6 0/2] add mcf54415 DAC driver
From: Angelo Dureghello @ 2026-06-18 21:04 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Geert Uytterhoeven, Maxime Coquelin, Alexandre Torgue
  Cc: linux-kernel, linux-iio, linux-m68k, linux-stm32,
	linux-arm-kernel, Angelo Dureghello

This patchset adds a minimalistic DAC driver for the NXP mcf54415/6/7/8
builtin DACs.

Currently the driver enables the raw write only. Feature as dma, sync, or
format are not supoprted for this version.

Additional options suppoerted by the DAC module will be added to the driver
later on, as needed.

The same patchset prepares the m68k/coldfire architecture to support
the driver.

Below some basic tests done on stmark2 mcf54415-based board, voltage check
on DAC0 and DAC1:

~ # cd /sys/bus/iio/devices/iio:device0/
/sys/bus/iio/devices/iio:device0 # ls
name               out_voltage_scale  uevent
out_voltage_raw    subsystem
/sys/bus/iio/devices/iio:device0 # cat name
mcf54415
/sys/bus/iio/devices/iio:device0 # echo 4095 > out_voltage_raw 
/sys/bus/iio/devices/iio:device0 # echo 2048 > out_voltage_raw 
/sys/bus/iio/devices/iio:device0 # echo 4096 > out_voltage_raw 
sh: write error: Invalid argument
/sys/bus/iio/devices/iio:device0 # cat out_voltage_raw 
2048
/sys/bus/iio/devices/iio:device0 # 

Same behavior for /sys/bus/iio/devices/iio:device1.

Generated a sine wave by shell script, sine shape is good.

is actually in progress:

Note: this patchset depends on mew mcf_read/mcf_write implementation that
Link: https://lore.kernel.org/linux-m68k/209d0653-6386-4b64-9e15-e358f84453ab@app.fastmail.com/T/#t
Link: https://lore.kernel.org/linux-m68k/20260506142644.3234270-2-gerg@kernel.org/
---
Changes in v6:
- Removed patches 1 to 8, already pushed in m68knommu for-next by
  Greg Ungerer <gerg@linux-m68k.org>
- keeping changelog in each single patch, where any
- Link to v5: https://patch.msgid.link/20260610-wip-stmark2-dac-v5-0-b76b83366d5c@baylibre.com

Changes in v5:
- keeping changelog in each single patch, where any
- Link to v4: https://patch.msgid.link/20260531-wip-stmark2-dac-v4-0-7e65ab4215dd@baylibre.com

Changes in v4:
- keeping changelog in each single patch, where any
- Link to v3: https://patch.msgid.link/20260522-wip-stmark2-dac-v3-0-16be0ad35a67@baylibre.com

Changes in v3:
- keeping changelog in each single patch, where any
- Link to v2: https://patch.msgid.link/20260513-wip-stmark2-dac-v2-0-fcdae50cf51a@baylibre.com

Changes in v2:
- keeping changelog in each single patch, where any
- Link to v1: https://patch.msgid.link/20260504-wip-stmark2-dac-v1-0-874c36a4910d@baylibre.com

To: Jonathan Cameron <jic23@kernel.org>
To: David Lechner <dlechner@baylibre.com>
To: Nuno Sá <nuno.sa@analog.com>
To: Andy Shevchenko <andy@kernel.org>
To: Geert Uytterhoeven <geert@linux-m68k.org>
To: Maxime Coquelin <mcoquelin.stm32@gmail.com>
To: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-iio@vger.kernel.org
Cc: linux-m68k@lists.linux-m68k.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-arm-kernel@lists.infradead.org

---
Angelo Dureghello (2):
      iio: dac: add mcf54415 DAC
      m68k: defconfig: update stmark2 defconfig

 arch/m68k/configs/stmark2_defconfig |   2 +
 drivers/iio/dac/Kconfig             |  11 +++
 drivers/iio/dac/Makefile            |   1 +
 drivers/iio/dac/mcf54415_dac.c      | 183 ++++++++++++++++++++++++++++++++++++
 4 files changed, 197 insertions(+)
---
base-commit: d43c76b1fd85cf6f9a53145ed397d10e76f99213
change-id: 20260430-wip-stmark2-dac-7060f49dd94f

Best regards,
--  
Angelo Dureghello <adureghello@baylibre.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