Devicetree
 help / color / mirror / Atom feed
* [PATCH v22 5/7] remoteproc: Add TEE support
From: Arnaud Pouliquen @ 2026-04-14 15:29 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Jens Wiklander, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sumit Garg
  Cc: linux-stm32, linux-arm-kernel, linux-remoteproc, linux-kernel,
	op-tee, devicetree, Arnaud Pouliquen
In-Reply-To: <20260414152904.1679724-1-arnaud.pouliquen@foss.st.com>

Add a remoteproc TEE (Trusted Execution Environment) driver that will be
probed by the TEE bus. If the associated Trusted application is supported
on the secure part, this driver offers a client interface to load firmware
by the secure part.
This firmware could be authenticated by the secure trusted application.

A specificity of the implementation is that the firmware has to be
authenticated and optionally decrypted to access the resource table.

Consequently, the boot sequence is:

1) rproc_parse_fw --> rproc_tee_parse_fw
   remoteproc TEE:
   - Requests the TEE application to authenticate and load the firmware
     in the remote processor memories.
   - Requests the TEE application for the address of the resource table.
   - Creates a copy of the resource table stored in rproc->cached_table.

2) rproc_load_segments --> rproc_tee_load_fw
   remoteproc TEE:
   - Requests the TEE application to load the firmware. Nothing is done
     at the TEE application as the firmware is already loaded.
   - In case of recovery, the TEE application has to reload the firmware.

3) rproc_tee_get_loaded_rsc_table
   remoteproc TEE requests the TEE application for the address of the
   resource table.

4) rproc_start --> rproc_tee_start
   - Requests the TEE application to start the remote processor.

The shutdown sequence is:

5) rproc_stop --> rproc_tee_stop
   - Requests the TEE application to stop the remote processor.

6) rproc_tee_release_fw
   This function is used to request the TEE application to perform actions
   to return to the initial state on stop or on error during the boot
   sequence.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
---
Version 22 updates:
- Revert to version 19, as the st,stm32-rproc-tee compatible has been
  rejected. As a consequence, we cannot have a rproc_stm32-tee.c driver
  and must reuse the rproc_stm32.c driver.
- Protect rproc_to_trproc() with lockdep_assert_held().

Version 21 updates:
- introduce uuid_to_str() to compute the compatible from the TEE UUID
- update rproc_tee_register() to provide phandle referenced in the
  remoteproc driver client.
- use device_link_add() to link the remoteproc driver client.

Version 20 updates:
- rework probe. the remoteproc-tee now probe the remoteproc devices
  defined in device tree as child.
  - creation of rproc-service-80a4c275-0a47-4905-8285-1486a9771a08 compatible
  - use of of_find_compatible_node() to find node in DT
  - use of of_platform_populate() to probe remoteproc devices
- remove device_link_add() as now managed by of_platform_populate)
- add "auto_boot" parameter in rproc_tee_register()
- rename TA_RPROC_FW_CMD_* TEE CMD in  TA_RPROC_CMD_* command
- use of DEFINE_MUTEX

Version 19 updates:
- rework/fix function headers
- use memremap instead of ioremap for the resource table.
- realign comments to 80 chars limit, with few exceptions for readability
- replace spinlock by mutex and and protect APIs from concurrent access
- add support of 64-bit address in rproc_tee_get_loaded_rsc_table()
- update copyright year

Version 18 updates
Fix warning:
warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing
---
 drivers/remoteproc/Kconfig          |  10 +
 drivers/remoteproc/Makefile         |   1 +
 drivers/remoteproc/remoteproc_tee.c | 789 ++++++++++++++++++++++++++++
 include/linux/remoteproc_tee.h      |  98 ++++
 4 files changed, 898 insertions(+)
 create mode 100644 drivers/remoteproc/remoteproc_tee.c
 create mode 100644 include/linux/remoteproc_tee.h

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index ee54436fea5a..87d69f200590 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -23,6 +23,16 @@ config REMOTEPROC_CDEV
 
 	  It's safe to say N if you don't want to use this interface.
 
+config REMOTEPROC_TEE
+	bool "Remoteproc support by a TEE application"
+	depends on OPTEE
+	help
+	  Support a remote processor that is managed by an application running in a Trusted
+	  Execution Environment (TEE). This application is responsible for loading the remote
+	  processor firmware image and managing its lifecycle.
+
+	  It's safe to say N if the remote processor is not managed by a TEE.
+
 config IMX_REMOTEPROC
 	tristate "i.MX remoteproc support"
 	depends on ARCH_MXC
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 1c7598b8475d..a1a5201982d4 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -11,6 +11,7 @@ remoteproc-y				+= remoteproc_sysfs.o
 remoteproc-y				+= remoteproc_virtio.o
 remoteproc-y				+= remoteproc_elf_loader.o
 obj-$(CONFIG_REMOTEPROC_CDEV)		+= remoteproc_cdev.o
+obj-$(CONFIG_REMOTEPROC_TEE)		+= remoteproc_tee.o
 obj-$(CONFIG_IMX_REMOTEPROC)		+= imx_rproc.o
 obj-$(CONFIG_IMX_DSP_REMOTEPROC)	+= imx_dsp_rproc.o
 obj-$(CONFIG_INGENIC_VPU_RPROC)		+= ingenic_rproc.o
diff --git a/drivers/remoteproc/remoteproc_tee.c b/drivers/remoteproc/remoteproc_tee.c
new file mode 100644
index 000000000000..b4e01ad84010
--- /dev/null
+++ b/drivers/remoteproc/remoteproc_tee.c
@@ -0,0 +1,789 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) STMicroelectronics 2025
+ * Author: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
+ */
+
+#include <linux/firmware.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/mutex.h>
+#include <linux/remoteproc.h>
+#include <linux/remoteproc_tee.h>
+#include <linux/slab.h>
+#include <linux/tee_drv.h>
+
+#include "remoteproc_internal.h"
+
+#define MAX_TEE_PARAM_ARRAY_MEMBER	4
+
+/*
+ * Authentication and load of the firmware image in the remote processor
+ * memories by the TEE. After this step the firmware is installed in destination
+ * memories, which can then be locked to prevent access by Linux.
+ *
+ * [in]  params[0].value.a: remote processor identifier
+ * [in]  params[1].memref:  buffer containing a temporary copy of the signed
+ *			    image to load.
+ */
+#define TA_RPROC_CMD_LOAD_FW		1
+
+/*
+ * Start the remote processor by the TEE
+ *
+ * [in]  params[0].value.a: remote processor identifier
+ */
+#define TA_RPROC_CMD_START		2
+
+/*
+ * Stop the remote processor by the TEE
+ *
+ * [in]  params[0].value.a: remote processor identifier
+ */
+#define TA_RPROC_CMD_STOP		3
+
+/*
+ * Return the address of the resource table, or 0 if not found.
+ *
+ * [in]  params[0].value.a: remote processor identifier
+ * [out] params[1].value.a: 32bit LSB resource table memory address
+ * [out] params[1].value.b: 32bit MSB resource table memory address
+ * [out] params[2].value.a: 32bit LSB resource table memory size
+ * [out] params[2].value.b: 32bit MSB resource table memory size
+ */
+#define TA_RPROC_CMD_GET_RSC_TABLE	4
+
+/*
+ * Release remote processor firmware images and associated resources.
+ * This command should be used in case an error occurs between the loading of
+ * the firmware images (TA_RPROC_CMD_LOAD_FW) and the starting of the remote
+ * processor (TA_RPROC_CMD_START) or after stopping the remote processor
+ * to release associated resources (TA_RPROC_CMD_STOP).
+ *
+ * [in]  params[0].value.a: remote processor identifier
+ */
+#define TA_RPROC_CMD_RELEASE_FW		6
+
+/**
+ * struct rproc_tee_context - Global TEE backend context
+ * @rproc_list: List of registered TEE-backed remoteprocs
+ * @tee_ctx:    TEE context handle
+ * @dev:        TEE client device
+ */
+struct rproc_tee_context {
+	struct list_head	rproc_list;
+	struct tee_context	*tee_ctx;
+	struct device		*dev;
+};
+
+/**
+ * struct rproc_tee - TEE remoteproc structure
+ * @node:       Reference in global list
+ * @rproc:      Remoteproc reference
+ * @rproc_id:   remote processor identifier
+ * @session_id: TEE session identifier
+ */
+struct rproc_tee {
+	struct list_head node;
+	struct rproc *rproc;
+	u32 rproc_id;
+	u32 session_id;
+};
+
+static struct rproc_tee_context rproc_tee_ctx;
+static DEFINE_MUTEX(ctx_lock); /* Protects concurrent manipulations of the rproc_tee_ctx*/
+
+static struct rproc_tee *rproc_to_trproc(struct rproc *rproc)
+{
+	struct rproc_tee *trproc;
+
+	lockdep_assert_held(&ctx_lock);
+
+	list_for_each_entry(trproc, &rproc_tee_ctx.rproc_list, node) {
+		if (trproc->rproc == rproc)
+			return trproc;
+	}
+
+	return NULL;
+}
+
+static void rproc_tee_prepare_args(struct rproc_tee *trproc, int cmd,
+				   struct tee_ioctl_invoke_arg *arg,
+				   struct tee_param *param,
+				   unsigned int num_params)
+{
+	memset(arg, 0, sizeof(*arg));
+	memset(param, 0, MAX_TEE_PARAM_ARRAY_MEMBER * sizeof(*param));
+
+	arg->func = cmd;
+	arg->session = trproc->session_id;
+	arg->num_params = num_params + 1;
+
+	param[0] = (struct tee_param) {
+		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
+		.u.value.a = trproc->rproc_id,
+	};
+}
+
+static int rproc_tee_sanity_check(struct device_node *tee_np)
+{
+	/* Backend not probed yet */
+	if (!rproc_tee_ctx.dev || !rproc_tee_ctx.dev->of_node)
+		return -EPROBE_DEFER;
+
+	/* DT error: phandle points to different node than the backend we use */
+	if (tee_np != rproc_tee_ctx.dev->of_node)
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * rproc_tee_release_fw() - Release the firmware for a TEE-based remote processor
+ * @rproc: Pointer to the struct rproc representing the remote processor
+ *
+ * This function invokes the TA_RPROC_CMD_RELEASE_FW TEE client function to
+ * release the firmware. It should only be called when the remoteproc state is
+ * RPROC_OFFLINE or RPROC_DETACHED. The function requests the TEE remoteproc
+ * application to release the firmware loaded by rproc_tee_load_fw().
+ * The request is ignored if the rproc state is RPROC_DETACHED as the remote
+ * processor is still running.
+ */
+void rproc_tee_release_fw(struct rproc *rproc)
+{
+	struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER];
+	struct rproc_tee *trproc;
+	struct tee_ioctl_invoke_arg arg;
+	int ret;
+
+	ret = mutex_lock_interruptible(&ctx_lock);
+	if (ret)
+		return;
+
+	if (!rproc_tee_ctx.dev)
+		goto out;
+
+	trproc = rproc_to_trproc(rproc);
+	if (!trproc)
+		goto out;
+
+	/*
+	 * If the remote processor state is RPROC_DETACHED, just ignore the
+	 * request, as the remote processor is still running.
+	 */
+	if (rproc->state == RPROC_DETACHED)
+		goto out;
+
+	if (rproc->state != RPROC_OFFLINE) {
+		dev_err(rproc_tee_ctx.dev, "unexpected rproc state: %d\n", rproc->state);
+		goto out;
+	}
+
+	rproc_tee_prepare_args(trproc, TA_RPROC_CMD_RELEASE_FW, &arg, param, 0);
+
+	ret = tee_client_invoke_func(rproc_tee_ctx.tee_ctx, &arg, param);
+	if (ret < 0 || arg.ret != 0) {
+		dev_err(rproc_tee_ctx.dev,
+			"TA_RPROC_CMD_RELEASE_FW invoke failed TEE err: %#x, ret:%d\n",
+			arg.ret, ret);
+	}
+
+out:
+	mutex_unlock(&ctx_lock);
+}
+EXPORT_SYMBOL_GPL(rproc_tee_release_fw);
+
+/**
+ * rproc_tee_load_fw() - Load firmware from TEE application
+ * @rproc: Pointer to the struct rproc representing the remote processor
+ * @fw: Pointer to the firmware structure containing the firmware data and size
+ *
+ * This function invokes the TA_RPROC_CMD_LOAD_FW TEE client function to load
+ * the firmware. It registers the fw->data as a shared memory region with the
+ * TEE, and request the TEE to load the firmware. This function can be called
+ * twice during the remote processor boot, a first by rproc_tee_parse_fw() to
+ * parse the resource table , and a second time by rproc_tee_load_fw().
+ * The TEE application should ignores the command if the firmware
+ * is already loaded by rproc_tee_parse_fw().
+ *
+ * Return: 0 on success, or an error code on failure
+ */
+int rproc_tee_load_fw(struct rproc *rproc, const struct firmware *fw)
+{
+	struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER];
+	struct rproc_tee *trproc;
+	struct tee_ioctl_invoke_arg arg;
+	struct tee_shm *fw_shm;
+	int ret;
+
+	ret = mutex_lock_interruptible(&ctx_lock);
+	if (ret)
+		return ret;
+
+	if (!rproc_tee_ctx.dev) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	trproc = rproc_to_trproc(rproc);
+	if (!trproc) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	fw_shm = tee_shm_register_kernel_buf(rproc_tee_ctx.tee_ctx, (void *)fw->data, fw->size);
+	if (IS_ERR(fw_shm)) {
+		ret = PTR_ERR(fw_shm);
+		goto out;
+	}
+
+	rproc_tee_prepare_args(trproc, TA_RPROC_CMD_LOAD_FW, &arg, param, 1);
+
+	/* Provide the address of the firmware image */
+	param[1] = (struct tee_param) {
+		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
+		.u.memref = {
+			.shm = fw_shm,
+			.size = fw->size,
+			.shm_offs = 0,
+		},
+	};
+
+	ret = tee_client_invoke_func(rproc_tee_ctx.tee_ctx, &arg, param);
+	if (ret < 0 || arg.ret != 0) {
+		dev_err(rproc_tee_ctx.dev,
+			"TA_RPROC_CMD_LOAD_FW invoke failed TEE err: %#x, ret:%d\n",
+			arg.ret, ret);
+		if (!ret)
+			ret = -EIO;
+	}
+
+	tee_shm_free(fw_shm);
+
+out:
+	mutex_unlock(&ctx_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rproc_tee_load_fw);
+
+static int rproc_tee_get_loaded_rsc_table(struct rproc *rproc, phys_addr_t *rsc_pa,
+					  size_t *table_sz)
+{
+	struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER];
+	struct rproc_tee *trproc;
+	struct tee_ioctl_invoke_arg arg;
+	int ret;
+
+	ret = mutex_lock_interruptible(&ctx_lock);
+	if (ret)
+		return ret;
+
+	if (!rproc_tee_ctx.dev) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	trproc = rproc_to_trproc(rproc);
+	if (!trproc) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	rproc_tee_prepare_args(trproc, TA_RPROC_CMD_GET_RSC_TABLE, &arg, param, 2);
+
+	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
+	param[2].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
+
+	ret = tee_client_invoke_func(rproc_tee_ctx.tee_ctx, &arg, param);
+	if (ret < 0 || arg.ret != 0) {
+		dev_err(rproc_tee_ctx.dev,
+			"TA_RPROC_CMD_GET_RSC_TABLE invoke failed TEE err: %#x, ret:%d\n",
+			arg.ret, ret);
+		ret = -EIO;
+		goto out;
+	}
+
+	*table_sz = param[2].u.value.a;
+	if (sizeof(phys_addr_t) == sizeof(u64))
+		*table_sz |= param[2].u.value.b << 32;
+
+	if (*table_sz) {
+		*rsc_pa = param[1].u.value.a;
+		if (sizeof(phys_addr_t) == sizeof(u64))
+			*rsc_pa |= param[1].u.value.b << 32;
+	} else {
+		*rsc_pa = 0;
+	}
+
+out:
+	mutex_unlock(&ctx_lock);
+	return ret;
+}
+
+/**
+ * rproc_tee_parse_fw() - Get the resource table from TEE application
+ * @rproc: Pointer to the struct rproc representing the remote processor
+ * @fw: Pointer to the firmware structure containing the firmware data and size
+ *
+ * This function retrieves the loaded resource table and creates a cached_table
+ * copy. Since the firmware image is signed and potentially encrypted, the
+ * firmware must be loaded first to access the loaded resource table.
+ *
+ * Return: 0 on success, or an error code on failure
+ */
+int rproc_tee_parse_fw(struct rproc *rproc, const struct firmware *fw)
+{
+	phys_addr_t rsc_table;
+	void *rsc_va;
+	size_t table_sz;
+	int ret;
+
+	if (!rproc)
+		return -EINVAL;
+
+	/* We need first to Load the firmware, to be able to get the resource table. */
+	ret = rproc_tee_load_fw(rproc, fw);
+	if (ret)
+		return ret;
+
+	ret = rproc_tee_get_loaded_rsc_table(rproc, &rsc_table, &table_sz);
+	if (ret)
+		goto release_fw;
+
+	/* A missing resource table is valid for some firmware images. */
+	if (!table_sz) {
+		rproc->table_ptr = NULL;
+		rproc->table_sz = 0;
+		return 0;
+	}
+
+	/*
+	 * We assume here that the memory mapping is the same between the TEE
+	 * and Linux kernel contexts. Else a new TEE remoteproc service could be
+	 * needed to get a copy of the resource table.
+	 */
+	rsc_va = memremap(rsc_table, table_sz, MEMREMAP_WC);
+	if (!rsc_va) {
+		dev_err(rproc_tee_ctx.dev, "Unable to map memory region: %pa+%zx\n",
+			&rsc_table, table_sz);
+		ret = -ENOMEM;
+		goto release_fw;
+	}
+
+	/*
+	 * Create a copy of the resource table to have the same behavior as the
+	 * ELF loader. This cached table will be used by the remoteproc core
+	 * after the remoteproc stops to free resources and for crash recovery
+	 * to reapply the settings.
+	 * The cached table will be freed by the remoteproc core.
+	 */
+	rproc->cached_table = kmemdup(rsc_va, table_sz, GFP_KERNEL);
+	memunmap(rsc_va);
+
+	if (!rproc->cached_table) {
+		ret = -ENOMEM;
+		goto release_fw;
+	}
+
+	rproc->table_ptr = rproc->cached_table;
+	rproc->table_sz = table_sz;
+
+	return 0;
+
+release_fw:
+	rproc_tee_release_fw(rproc);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rproc_tee_parse_fw);
+
+/**
+ * rproc_tee_find_loaded_rsc_table() - Find the loaded resource table loaded by
+ *				       the TEE application
+ * @rproc: Pointer to the struct rproc representing the remote processor
+ * @fw: Pointer to the firmware structure containing the firmware data and size
+ *
+ * This function retrieves the physical address and size of the resource table
+ * loaded by the TEE application.
+ *
+ * Return: pointer to the resource table if found, or NULL if not found or size
+ * is 0
+ */
+struct resource_table *rproc_tee_find_loaded_rsc_table(struct rproc *rproc,
+						       const struct firmware *fw)
+{
+	phys_addr_t rsc_table;
+	size_t table_sz;
+	int ret;
+
+	ret = rproc_tee_get_loaded_rsc_table(rproc, &rsc_table, &table_sz);
+	if (ret)
+		return NULL;
+
+	rproc->table_sz = table_sz;
+	if (!table_sz)
+		return NULL;
+
+	/*
+	 * At this step the memory area that contains the resource table should
+	 * have been registered by the remote proc platform driver and allocated
+	 * by rproc_alloc_registered_carveouts().
+	 */
+	return rproc_pa_to_va(rproc, rsc_table, table_sz, NULL);
+}
+EXPORT_SYMBOL_GPL(rproc_tee_find_loaded_rsc_table);
+
+/**
+ * rproc_tee_start() - Request the TEE application to start the remote processor
+ * @rproc: Pointer to the struct rproc representing the remote processor
+ *
+ * This function invokes the TA_RPROC_CMD_START command to start the remote
+ * processor.
+ *
+ * Return: Returns 0 on success, -EINVAL or -EIO on failure
+ */
+int rproc_tee_start(struct rproc *rproc)
+{
+	struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER];
+	struct rproc_tee *trproc;
+	struct tee_ioctl_invoke_arg arg;
+	int ret;
+
+	ret = mutex_lock_interruptible(&ctx_lock);
+	if (ret)
+		return ret;
+
+	if (!rproc_tee_ctx.dev) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	trproc = rproc_to_trproc(rproc);
+	if (!trproc) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	rproc_tee_prepare_args(trproc, TA_RPROC_CMD_START, &arg, param, 0);
+
+	ret = tee_client_invoke_func(rproc_tee_ctx.tee_ctx, &arg, param);
+	if (ret < 0 || arg.ret != 0) {
+		dev_err(rproc_tee_ctx.dev,
+			"TA_RPROC_CMD_START invoke failed TEE err: %#x, ret:%d\n", arg.ret, ret);
+		if (!ret)
+			ret = -EIO;
+	}
+
+out:
+	mutex_unlock(&ctx_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rproc_tee_start);
+
+/**
+ * rproc_tee_stop() - Request the TEE application to start the remote processor
+ * @rproc: Pointer to the struct rproc representing the remote processor
+ *
+ * This function invokes the TA_RPROC_CMD_STOP command to stop the remote
+ * processor.
+ *
+ * Return: Returns 0 on success, -EINVAL or -EIO on failure
+ */
+int rproc_tee_stop(struct rproc *rproc)
+{
+	struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER];
+	struct rproc_tee *trproc;
+	struct tee_ioctl_invoke_arg arg;
+	int ret;
+
+	ret = mutex_lock_interruptible(&ctx_lock);
+	if (ret)
+		return ret;
+
+	if (!rproc_tee_ctx.dev) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	trproc = rproc_to_trproc(rproc);
+	if (!trproc) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	rproc_tee_prepare_args(trproc, TA_RPROC_CMD_STOP, &arg, param, 0);
+
+	ret = tee_client_invoke_func(rproc_tee_ctx.tee_ctx, &arg, param);
+	if (ret < 0 || arg.ret != 0) {
+		dev_err(rproc_tee_ctx.dev,
+			"TA_RPROC_CMD_STOP invoke failed TEE err: %#x, ret:%d\n", arg.ret, ret);
+		if (!ret)
+			ret = -EIO;
+	}
+
+out:
+	mutex_unlock(&ctx_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rproc_tee_stop);
+
+/**
+ * rproc_tee_register() - Register a remote processor controlled by the TEE application
+ * @dev:        client rproc device
+ * @rproc:      out pointer to the struct rproc representing the remote processor
+ * @tee_phandle: backend phandle args (np + 1 cell: rproc_id)
+ *
+ * The phandle must point to the same DT node that rproc_tee_probe() attached
+ * to the TEE client device.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int rproc_tee_register(struct device *dev, struct rproc *rproc,
+		       const struct of_phandle_args *tee_phandle)
+{
+	struct tee_param param[MAX_TEE_PARAM_ARRAY_MEMBER];
+	unsigned int rproc_id;
+	struct device_node *tee_np;
+	struct tee_ioctl_open_session_arg sess_arg;
+	struct tee_client_device *tee_device;
+	struct device_link *link;
+	struct rproc_tee *trproc;
+	int ret;
+
+	if (!tee_phandle || !tee_phandle->np || tee_phandle->args_count < 1)
+		return -EINVAL;
+
+	rproc_id = tee_phandle->args[0];
+	tee_np = tee_phandle->np;
+
+	ret = mutex_lock_interruptible(&ctx_lock);
+	if (ret)
+		return ret;
+
+	ret = rproc_tee_sanity_check(tee_np);
+	if (ret)
+		goto out;
+
+	trproc = kzalloc_obj(*trproc);
+	if (!trproc) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	tee_device = to_tee_client_device(rproc_tee_ctx.dev);
+	memset(&sess_arg, 0, sizeof(sess_arg));
+	memcpy(sess_arg.uuid, tee_device->id.uuid.b, TEE_IOCTL_UUID_LEN);
+
+	sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
+	sess_arg.num_params = 1;
+
+	param[0] = (struct tee_param) {
+		.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
+		.u.value.a = rproc_id,
+	};
+
+	ret = tee_client_open_session(rproc_tee_ctx.tee_ctx, &sess_arg, param);
+	if (ret < 0 || sess_arg.ret != 0) {
+		dev_err(dev, "tee_client_open_session failed, err: %#x\n",
+			sess_arg.ret);
+		ret = -EINVAL;
+		goto free_trproc;
+	}
+
+	trproc->rproc_id = rproc_id;
+	trproc->session_id = sess_arg.session;
+
+	ret = rproc_add(rproc);
+	if (ret)
+		goto close_tee;
+
+	trproc->rproc = rproc;
+	/* Create device link between the rproc device and the TEE device */
+	link = device_link_add(dev, rproc_tee_ctx.dev,
+			       DL_FLAG_AUTOREMOVE_CONSUMER);
+	if (!link) {
+		ret = -ENOMEM;
+		goto del_rproc;
+	}
+
+	list_add_rcu(&trproc->node, &rproc_tee_ctx.rproc_list);
+
+	mutex_unlock(&ctx_lock);
+
+	return 0;
+
+del_rproc:
+	rproc_del(rproc);
+close_tee:
+	if (tee_client_close_session(rproc_tee_ctx.tee_ctx, trproc->session_id))
+		dev_err(rproc_tee_ctx.dev,
+			"tee_client_close_session failed\n");
+free_trproc:
+	kfree(trproc);
+out:
+	mutex_unlock(&ctx_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rproc_tee_register);
+
+/**
+ * rproc_tee_unregister - Unregister a remote processor controlled by the TEE
+ *                        application.
+ * @dev: Pointer to client rproc device
+ * @rproc: Pointer to the struct rproc representing the remote processor
+ *
+ * This function unregisters a remote processor previously registered by the
+ * rproc_tee_register() function.
+ *
+ * Return: Returns 0 on success, or an error code on failure
+ */
+int rproc_tee_unregister(struct device *dev, struct rproc *rproc)
+{
+	struct rproc_tee *trproc;
+	int ret;
+
+	ret = mutex_lock_interruptible(&ctx_lock);
+	if (ret)
+		return ret;
+
+	if (!rproc_tee_ctx.dev) {
+		ret = -ENODEV;
+		goto out_unlock;
+	}
+
+	trproc = rproc_to_trproc(rproc);
+	if (!trproc) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	/*
+	 * Unlock ctx_lock before calling rproc_del(),
+	 * they may call into rproc core and take other locks to stop the
+	 * remote processor, if it is running.
+	 */
+	mutex_unlock(&ctx_lock);
+
+	rproc_del(rproc);
+
+	ret = mutex_lock_interruptible(&ctx_lock);
+	if (ret)
+		return ret;
+
+	ret = tee_client_close_session(rproc_tee_ctx.tee_ctx,
+				       trproc->session_id);
+	if (ret < 0)
+		dev_err(rproc_tee_ctx.dev,
+			"tee_client_close_session failed, err: %#x\n", ret);
+
+	list_del(&trproc->node);
+	kfree(trproc);
+
+out_unlock:
+	mutex_unlock(&ctx_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rproc_tee_unregister);
+
+static int rproc_tee_ctx_match(struct tee_ioctl_version_data *ver,
+			       const void *data)
+{
+	/* Today we support only OP-TEE; could be extended to other TEEs */
+	return ver->impl_id == TEE_IMPL_ID_OPTEE;
+}
+
+static const struct tee_client_device_id rproc_tee_id_table[] = {
+	{UUID_INIT(0x80a4c275, 0x0a47, 0x4905, 0x82, 0x85, 0x14, 0x86, 0xa9, 0x77, 0x1a, 0x08)},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(tee, rproc_tee_id_table);
+
+static void uuid_to_str(const struct tee_client_device_id *id, char *uuid_str)
+{
+	snprintf(uuid_str, UUID_STRING_LEN + 1,
+		 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		 id->uuid.b[0], id->uuid.b[1], id->uuid.b[2], id->uuid.b[3],
+		 id->uuid.b[4], id->uuid.b[5], id->uuid.b[6], id->uuid.b[7],
+		 id->uuid.b[8], id->uuid.b[9], id->uuid.b[10], id->uuid.b[11],
+		 id->uuid.b[12], id->uuid.b[13], id->uuid.b[14], id->uuid.b[15]);
+}
+
+static int rproc_tee_probe(struct tee_client_device *tee_dev)
+{
+	struct device *dev = &tee_dev->dev;
+	struct tee_context *tee_ctx;
+	struct device_node *np;
+	char uuid_str[UUID_STRING_LEN + 1];
+	int ret;
+
+	uuid_to_str(&rproc_tee_id_table[0], uuid_str);
+	np = of_find_compatible_node(NULL, NULL, uuid_str);
+	if (!np) {
+		dev_err(dev, "Device node not found for UUID: %s\n", uuid_str);
+		return -ENODEV;
+	}
+
+	/* Open context with TEE driver */
+	tee_ctx = tee_client_open_context(NULL, rproc_tee_ctx_match, NULL, NULL);
+	if (IS_ERR(tee_ctx)) {
+		ret = PTR_ERR(tee_ctx);
+		goto put_node;
+	}
+
+	ret = mutex_lock_interruptible(&ctx_lock);
+	if (ret)
+		goto close_ctx;
+
+	INIT_LIST_HEAD(&rproc_tee_ctx.rproc_list);
+
+	ret = device_add_of_node(dev, np);
+
+	if (ret) {
+		mutex_unlock(&ctx_lock);
+		goto close_ctx;
+	}
+	rproc_tee_ctx.dev = dev;
+	rproc_tee_ctx.tee_ctx = tee_ctx;
+
+	mutex_unlock(&ctx_lock);
+	of_node_put(np);
+
+	return 0;
+
+close_ctx:
+	tee_client_close_context(tee_ctx);
+put_node:
+	of_node_put(np);
+	return ret;
+}
+
+static void rproc_tee_remove(struct tee_client_device *tee_dev)
+{
+	struct device *dev = &tee_dev->dev;
+	int ret;
+
+	ret = mutex_lock_interruptible(&ctx_lock);
+	if (ret)
+		return;
+
+	rproc_tee_ctx.dev = NULL;
+	mutex_unlock(&ctx_lock);
+	device_remove_of_node(dev);
+
+	tee_client_close_context(rproc_tee_ctx.tee_ctx);
+	rproc_tee_ctx.tee_ctx = NULL;
+}
+
+static struct tee_client_driver rproc_tee_fw_driver = {
+	.id_table	= rproc_tee_id_table,
+	.probe		= rproc_tee_probe,
+	.remove		= rproc_tee_remove,
+	.driver		= {
+		.name		= KBUILD_MODNAME,
+	},
+};
+
+module_tee_client_driver(rproc_tee_fw_driver);
+
+MODULE_DESCRIPTION("remote processor TEE module");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/remoteproc_tee.h b/include/linux/remoteproc_tee.h
new file mode 100644
index 000000000000..8cf805f3b65e
--- /dev/null
+++ b/include/linux/remoteproc_tee.h
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright(c) 2025 STMicroelectronics
+ */
+
+#ifndef REMOTEPROC_TEE_H
+#define REMOTEPROC_TEE_H
+
+#include <linux/tee_drv.h>
+#include <linux/firmware.h>
+#include <linux/remoteproc.h>
+
+#if IS_ENABLED(CONFIG_REMOTEPROC_TEE)
+
+int rproc_tee_register(struct device *dev, struct rproc *rproc,
+		       const struct of_phandle_args *tee_phandle);
+int rproc_tee_unregister(struct device *dev, struct rproc *rproc);
+int rproc_tee_parse_fw(struct rproc *rproc, const struct firmware *fw);
+int rproc_tee_load_fw(struct rproc *rproc, const struct firmware *fw);
+void rproc_tee_release_fw(struct rproc *rproc);
+struct resource_table *rproc_tee_find_loaded_rsc_table(struct rproc *rproc,
+						       const struct firmware *fw);
+int rproc_tee_start(struct rproc *rproc);
+int rproc_tee_stop(struct rproc *rproc);
+int rproc_tee_pa_to_da(struct rproc *rproc, phys_addr_t pa, size_t size, u64 *da);
+#else
+
+static inline int rproc_tee_register(struct device *dev, struct rproc *rproc,
+				     const struct of_phandle_args *tee_phandle)
+{
+	return -ENODEV;
+}
+
+static inline int rproc_tee_parse_fw(struct rproc *rproc, const struct firmware *fw)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return 0;
+}
+
+static inline int rproc_tee_unregister(struct device *dev, struct rproc *rproc)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return 0;
+}
+
+static inline int rproc_tee_load_fw(struct rproc *rproc, const struct firmware *fw)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return 0;
+}
+
+static inline int rproc_tee_start(struct rproc *rproc)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return 0;
+}
+
+static inline int rproc_tee_stop(struct rproc *rproc)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return 0;
+}
+
+static inline int rproc_tee_pa_to_da(struct rproc *rproc, phys_addr_t pa,
+				     size_t size, u64 *da)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return -EINVAL;
+}
+
+static inline void rproc_tee_release_fw(struct rproc *rproc)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+}
+
+static inline struct resource_table *
+rproc_tee_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
+{
+	/* This shouldn't be possible */
+	WARN_ON(1);
+
+	return NULL;
+}
+#endif /* CONFIG_REMOTEPROC_TEE */
+#endif /* REMOTEPROC_TEE_H */
-- 
2.43.0


^ permalink raw reply related

* [PATCH v22 3/7] remoteproc: core: Introduce rproc_pa_to_va helper
From: Arnaud Pouliquen @ 2026-04-14 15:28 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Jens Wiklander, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sumit Garg
  Cc: linux-stm32, linux-arm-kernel, linux-remoteproc, linux-kernel,
	op-tee, devicetree, Arnaud Pouliquen
In-Reply-To: <20260414152904.1679724-1-arnaud.pouliquen@foss.st.com>

When a resource table is loaded by an external entity such as U-boot or
OP-TEE, we do not necessarily get the device address(da) but the physical
address(pa).
This helper performs similar translation than the rproc_da_to_va()
but based on a physical address.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
---
V22 updates:
-  use size_t for offset and remove its comparaison with 0
---
 drivers/remoteproc/remoteproc_core.c | 50 ++++++++++++++++++++++++++++
 include/linux/remoteproc.h           |  1 +
 2 files changed, 51 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index b087ed21858a..ec1860e1cfa9 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -225,6 +225,56 @@ void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
 }
 EXPORT_SYMBOL(rproc_da_to_va);
 
+/**
+ * rproc_pa_to_va() - lookup the kernel virtual address for a physical address of a remoteproc
+ * memory
+ *
+ * @rproc: handle of a remote processor
+ * @pa: remoteproc physical address
+ * @len: length of the memory region @pa is pointing to
+ * @is_iomem: optional pointer filled in to indicate if @pa is iomapped memory
+ *
+ * This function is a helper function similar to rproc_da_to_va() but it deals with physical
+ * addresses instead of device addresses.
+ *
+ * Return: a valid kernel address on success or NULL on failure
+ */
+void *rproc_pa_to_va(struct rproc *rproc, phys_addr_t pa, size_t len, bool *is_iomem)
+{
+	struct rproc_mem_entry *carveout;
+	void *ptr = NULL;
+	size_t offset;
+
+	list_for_each_entry(carveout, &rproc->carveouts, node) {
+		/* Verify that carveout is allocated */
+		if (!carveout->va)
+			continue;
+
+		/* try next carveout if pa is too small */
+		if (pa < carveout->dma)
+			continue;
+
+		offset = pa - carveout->dma;
+
+		/* try next carveout if pa is too large */
+		if (offset > carveout->len)
+			continue;
+
+		if (len > carveout->len - offset)
+			continue;
+
+		ptr = carveout->va + offset;
+
+		if (is_iomem)
+			*is_iomem = carveout->is_iomem;
+
+		break;
+	}
+
+	return ptr;
+}
+EXPORT_SYMBOL(rproc_pa_to_va);
+
 /**
  * rproc_find_carveout_by_name() - lookup the carveout region by a name
  * @rproc: handle of a remote processor
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index b4795698d8c2..8fd0d7f63c8e 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -690,6 +690,7 @@ int rproc_detach(struct rproc *rproc);
 int rproc_set_firmware(struct rproc *rproc, const char *fw_name);
 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
 void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem);
+void *rproc_pa_to_va(struct rproc *rproc, phys_addr_t pa, size_t len, bool *is_iomem);
 
 /* from remoteproc_coredump.c */
 void rproc_coredump_cleanup(struct rproc *rproc);
-- 
2.43.0


^ permalink raw reply related

* [PATCH v22 6/7] remoteproc: stm32: Create sub-functions to request shutdown and release
From: Arnaud Pouliquen @ 2026-04-14 15:29 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Jens Wiklander, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sumit Garg
  Cc: linux-stm32, linux-arm-kernel, linux-remoteproc, linux-kernel,
	op-tee, devicetree, Arnaud Pouliquen
In-Reply-To: <20260414152904.1679724-1-arnaud.pouliquen@foss.st.com>

To prepare for the support of TEE remoteproc, create sub-functions
that can be used in both cases, with and without remoteproc TEE support.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
---
 drivers/remoteproc/stm32_rproc.c | 82 +++++++++++++++++++-------------
 1 file changed, 49 insertions(+), 33 deletions(-)

diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 632614013dc6..4bcd6a784935 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -209,6 +209,52 @@ static int stm32_rproc_mbox_idx(struct rproc *rproc, const unsigned char *name)
 	return -EINVAL;
 }
 
+static void stm32_rproc_request_shutdown(struct rproc *rproc)
+{
+	struct stm32_rproc *ddata = rproc->priv;
+	int err, idx;
+
+	/* Request shutdown of the remote processor */
+	if (rproc->state != RPROC_OFFLINE && rproc->state != RPROC_CRASHED) {
+		idx = stm32_rproc_mbox_idx(rproc, STM32_MBX_SHUTDOWN);
+		if (idx >= 0 && ddata->mb[idx].chan) {
+			err = mbox_send_message(ddata->mb[idx].chan, "detach");
+			if (err < 0)
+				dev_warn(&rproc->dev, "warning: remote FW shutdown without ack\n");
+		}
+	}
+}
+
+static int stm32_rproc_release(struct rproc *rproc)
+{
+	struct stm32_rproc *ddata = rproc->priv;
+	int err = 0;
+
+	/* To allow platform Standby power mode, set remote proc Deep Sleep */
+	if (ddata->pdds.map) {
+		err = regmap_update_bits(ddata->pdds.map, ddata->pdds.reg,
+					 ddata->pdds.mask, 1);
+		if (err) {
+			dev_err(&rproc->dev, "failed to set pdds\n");
+			return err;
+		}
+	}
+
+	/* Update coprocessor state to OFF if available */
+	if (ddata->m4_state.map) {
+		err = regmap_update_bits(ddata->m4_state.map,
+					 ddata->m4_state.reg,
+					 ddata->m4_state.mask,
+					 M4_STATE_OFF);
+		if (err) {
+			dev_err(&rproc->dev, "failed to set copro state\n");
+			return err;
+		}
+	}
+
+	return 0;
+}
+
 static int stm32_rproc_prepare(struct rproc *rproc)
 {
 	struct device *dev = rproc->dev.parent;
@@ -511,17 +557,9 @@ static int stm32_rproc_detach(struct rproc *rproc)
 static int stm32_rproc_stop(struct rproc *rproc)
 {
 	struct stm32_rproc *ddata = rproc->priv;
-	int err, idx;
+	int err;
 
-	/* request shutdown of the remote processor */
-	if (rproc->state != RPROC_OFFLINE && rproc->state != RPROC_CRASHED) {
-		idx = stm32_rproc_mbox_idx(rproc, STM32_MBX_SHUTDOWN);
-		if (idx >= 0 && ddata->mb[idx].chan) {
-			err = mbox_send_message(ddata->mb[idx].chan, "detach");
-			if (err < 0)
-				dev_warn(&rproc->dev, "warning: remote FW shutdown without ack\n");
-		}
-	}
+	stm32_rproc_request_shutdown(rproc);
 
 	err = stm32_rproc_set_hold_boot(rproc, true);
 	if (err)
@@ -533,29 +571,7 @@ static int stm32_rproc_stop(struct rproc *rproc)
 		return err;
 	}
 
-	/* to allow platform Standby power mode, set remote proc Deep Sleep */
-	if (ddata->pdds.map) {
-		err = regmap_update_bits(ddata->pdds.map, ddata->pdds.reg,
-					 ddata->pdds.mask, 1);
-		if (err) {
-			dev_err(&rproc->dev, "failed to set pdds\n");
-			return err;
-		}
-	}
-
-	/* update coprocessor state to OFF if available */
-	if (ddata->m4_state.map) {
-		err = regmap_update_bits(ddata->m4_state.map,
-					 ddata->m4_state.reg,
-					 ddata->m4_state.mask,
-					 M4_STATE_OFF);
-		if (err) {
-			dev_err(&rproc->dev, "failed to set copro state\n");
-			return err;
-		}
-	}
-
-	return 0;
+	return stm32_rproc_release(rproc);
 }
 
 static void stm32_rproc_kick(struct rproc *rproc, int vqid)
-- 
2.43.0


^ permalink raw reply related

* [PATCH v22 4/7] remoteproc: Introduce optional release_fw operation
From: Arnaud Pouliquen @ 2026-04-14 15:28 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Jens Wiklander, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sumit Garg
  Cc: linux-stm32, linux-arm-kernel, linux-remoteproc, linux-kernel,
	op-tee, devicetree, Arnaud Pouliquen
In-Reply-To: <20260414152904.1679724-1-arnaud.pouliquen@foss.st.com>

The release_fw operation allows releasing remote processor resources
configured during rproc_parse_fw() and rproc_load_segments().
For example, it can release carveouts mapped during these operations.

This operation is invoked in the following cases:
 - When an error occurs during remote processor boot.
 - When an error occurs during remote processor recovery start.
 - After stopping the remote processor.

This operation is required for the remoteproc_tee implementation following
a stop or upon encountering an error. Since the remoteproc image is loaded
during resource table parsing, multiple failure scenarios may occur prior
to remote processor startup, including issues with resource handling and
carveout allocation.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>

---

Updates from version 18:
- Rewrite rproc_ops::release_fw documentation
- Improve commit message

Updates from version 16:
- Removed the rproc:load_fw() ops introduced in previous version.
- Removed duplicate calls to rproc_release_fw in rproc_fw_boot and rproc_boot.
---
 drivers/remoteproc/remoteproc_core.c     | 6 ++++++
 drivers/remoteproc/remoteproc_internal.h | 6 ++++++
 include/linux/remoteproc.h               | 5 +++++
 3 files changed, 17 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index ec1860e1cfa9..93ab505ff014 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1856,6 +1856,8 @@ static int rproc_boot_recovery(struct rproc *rproc)
 
 	/* boot the remote processor up again */
 	ret = rproc_start(rproc, firmware_p);
+	if (ret)
+		rproc_release_fw(rproc);
 
 	release_firmware(firmware_p);
 
@@ -1997,6 +1999,8 @@ int rproc_boot(struct rproc *rproc)
 		}
 
 		ret = rproc_fw_boot(rproc, firmware_p);
+		if (ret)
+			rproc_release_fw(rproc);
 
 		release_firmware(firmware_p);
 	}
@@ -2066,6 +2070,8 @@ int rproc_shutdown(struct rproc *rproc)
 
 	rproc_disable_iommu(rproc);
 
+	rproc_release_fw(rproc);
+
 	/* Free the copy of the resource table */
 	kfree(rproc->cached_table);
 	rproc->cached_table = NULL;
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index 0cd09e67ac14..c7fb908f8652 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -221,4 +221,10 @@ bool rproc_u64_fit_in_size_t(u64 val)
 	return (val <= (size_t) -1);
 }
 
+static inline void rproc_release_fw(struct rproc *rproc)
+{
+	if (rproc->ops->release_fw)
+		rproc->ops->release_fw(rproc);
+}
+
 #endif /* REMOTEPROC_INTERNAL_H */
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 8fd0d7f63c8e..a2bb51a113b1 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -381,6 +381,10 @@ enum rsc_handling_status {
  * @panic:	optional callback to react to system panic, core will delay
  *		panic at least the returned number of milliseconds
  * @coredump:	  collect firmware dump after the subsystem is shutdown
+ * @release_fw:	Optional function to release resources allocated during
+ *		parse_fw() or load() operations. This function is called after
+ *		stopping the remote processor or in case of an error during the
+ *		boot or recovery sequence.
  */
 struct rproc_ops {
 	int (*prepare)(struct rproc *rproc);
@@ -403,6 +407,7 @@ struct rproc_ops {
 	u64 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
 	unsigned long (*panic)(struct rproc *rproc);
 	void (*coredump)(struct rproc *rproc);
+	void (*release_fw)(struct rproc *rproc);
 };
 
 /**
-- 
2.43.0


^ permalink raw reply related

* [PATCH v22 2/7] dt-bindings: remoteproc: st,stm32-rproc: add st,rproc-tee
From: Arnaud Pouliquen @ 2026-04-14 15:28 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Jens Wiklander, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sumit Garg
  Cc: linux-stm32, linux-arm-kernel, linux-remoteproc, linux-kernel,
	op-tee, devicetree, Arnaud Pouliquen
In-Reply-To: <20260414152904.1679724-1-arnaud.pouliquen@foss.st.com>

Add st,rproc-tee to describe the remoteprocessor control through the TEE
remoteproc backend.

The property is a phandle to the TEE remoteproc node with one argument
cell carrying the remote processor identifier.

When st,rproc-tee is present, Linux must not manage MCU reset/holdboot
directly. Update schema conditionals accordingly:
- do not require resets unconditionally
- forbid resets, reset-names and st,syscfg-holdboot when st,rproc-tee
  is present
- keep legacy holdboot checks for non-TEE configurations

Also add a DT example showing the TEE-based configuration.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
---
 .../bindings/remoteproc/st,stm32-rproc.yaml   | 55 ++++++++++++++++---
 1 file changed, 46 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
index 843679c557e7..7fe54d529e04 100644
--- a/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/st,stm32-rproc.yaml
@@ -143,24 +143,45 @@ properties:
     maxItems: 1
     description: Default name of the remote processor firmware.
 
+  st,rproc-tee:
+    description:
+      Reference the remote processor node on TEE bus. The value is a phandle
+      reference to the remote processor node, followed by a cell specifying
+      the remote processor device identifier used by the TEE.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: Phandle of the remote processor node on the TEE bus
+          - description: Remote processor device identifier used by the TEE
+
 required:
   - compatible
   - reg
-  - resets
 
 allOf:
   - if:
-      properties:
-        reset-names:
-          not:
-            contains:
-              const: hold_boot
-    then:
       required:
-        - st,syscfg-holdboot
-    else:
+        - st,rproc-tee
+    then:
       properties:
+        resets: false
+        reset-names: false
         st,syscfg-holdboot: false
+    else:
+      required:
+        - resets
+      if:
+        properties:
+          reset-names:
+            not:
+              contains:
+                const: hold_boot
+      then:
+        required:
+          - st,syscfg-holdboot
+      else:
+        properties:
+          st,syscfg-holdboot: false
 
 additionalProperties: false
 
@@ -192,5 +213,21 @@ examples:
       st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>;
       st,syscfg-m4-state = <&tamp 0x148 0xFFFFFFFF>;
     };
+  - |
+    firmware {
+      tee_rproc: optee-rproc {
+        compatible = "80a4c275-0a47-4905-8285-1486a9771a08";
+      };
+    };
+
+    m4@10000000 {
+      compatible = "st,stm32mp1-m4";
+      reg = <0x10000000 0x40000>,
+            <0x30000000 0x40000>,
+            <0x38000000 0x10000>;
+      st,rproc-tee = <&tee_rproc 0>;
+      st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>;
+      st,syscfg-m4-state = <&tamp 0x148 0xFFFFFFFF>;
+    };
 
 ...
-- 
2.43.0


^ permalink raw reply related

* [PATCH v22 1/7] dt-bindings: firmware: Add TEE remoteproc service binding
From: Arnaud Pouliquen @ 2026-04-14 15:28 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Jens Wiklander, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sumit Garg
  Cc: linux-stm32, linux-arm-kernel, linux-remoteproc, linux-kernel,
	op-tee, devicetree, Arnaud Pouliquen
In-Reply-To: <20260414152904.1679724-1-arnaud.pouliquen@foss.st.com>

Add a device tree binding for the TEE-based remote processor control
service implemented as an OP-TEE Trusted Application identified by
UUID 80a4c275-0a47-4905-8285-1486a9771a08.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
---
v21 updates:
- rename compatible to exactly match with the TEE UUID
- the remoteproc device driver is no more declared as a child,
  but use phandle as done for the SCMI.
- remove linaro,optee-tz bindings update are now useless.
---
 .../bindings/remoteproc/remoteproc-tee.yaml   | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/remoteproc-tee.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/remoteproc-tee.yaml b/Documentation/devicetree/bindings/remoteproc/remoteproc-tee.yaml
new file mode 100644
index 000000000000..498a7e590905
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/remoteproc-tee.yaml
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/remoteproc-tee.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TEE Remote Processor Control Service (UUID 80a4c275-0a47-4905-8285-1486a9771a08)
+
+maintainers:
+  - Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
+
+description:
+  Node describing a TEE-based remote processor control service implemented as
+  a Trusted Application identified by UUID 80a4c275-0a47-4905-8285-1486a9771a08.
+
+  This binding is intended to define the interface for remoteproc services
+  implemented as TAs running in a TEE, and is used by the a remoteproc driver
+  to bind to such a service and control a remote processor through it.
+
+properties:
+  compatible:
+    const: 80a4c275-0a47-4905-8285-1486a9771a08
+
+required:
+  - compatible
+
+additionalProperties: false
+
+examples:
+  - |
+    firmware {
+        tee_rproc: optee-rproc {
+            compatible = "80a4c275-0a47-4905-8285-1486a9771a08";
+        };
+    };
+...
-- 
2.43.0


^ permalink raw reply related

* [PATCH v22 0/7] Introduction of a remoteproc tee to load signed firmware
From: Arnaud Pouliquen @ 2026-04-14 15:28 UTC (permalink / raw)
  To: Bjorn Andersson, Mathieu Poirier, Jens Wiklander, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sumit Garg
  Cc: linux-stm32, linux-arm-kernel, linux-remoteproc, linux-kernel,
	op-tee, devicetree, Arnaud Pouliquen

Main updates from version V21[1]:
--------------------------------
This version removes the st,stm32mp1-m4-tee compatibility string,
which no longer seems to be accepted by the Devicetree maintainers.
As a consequence, the stm32-rproc-tee driver, introduced to simplify
the code, is removed. The STM32 integration reuses the existing
stm32_rproc driver implemented in V19.

The devicetree is now structured as follows:

    firmware {
        tee_rproc: optee-rproc {
            compatible = "80a4c275-0a47-4905-8285-1486a9771a08";
        };
    };

    m4: m4@10000000 {
      compatible = "st,stm32mp1-m4";
      reg = <0x10000000 0x40000>,
            <0x30000000 0x40000>,
            <0x38000000 0x10000>;

      mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>;
      mbox-names = "vq0", "vq1", "shutdown", "detach";

      memory-region = <&vdev0vring0>, <&m_ipc_shm>, <&mcuram2>,
                      <&vdev0vring1>, <&vdev0buffer>, <&retram>;

      interrupt-parent = <&exti>;
      interrupts = <68 1>;

      st,rproc-tee = <&tee_rproc 0>;

      status = "okay";
    };

As a consequence, this version:
- reintroduce v19 commits for stm32_rproc.c driver , adding the support
  of the st,rproc-tee binding.
- drops the dedicated remoteproc-tee.yaml and st,stm32-rproc-tee.yaml
  bindings from the series.
- extends st,stm32-rproc.yaml with st,rproc-tee to describe the link to
  the TEE remoteproc backend.
- removes the dedicated stm32_rproc_tee.c driver and reuses stm32_rproc.c
  for both native and TEE-controlled cases.
- keeps remoteproc_tee.c aligned with the phandle-based lookup introduced
  in v21 and uses a device_link between the STM32 remoteproc instance and
  the TEE backend device.

More details are available in each patch commit message.

Main updates from version V20[3]:
--------------------------------
To address Rob’s concern on v20concerning resource declaration under the
tee node, the device tree is now structured as follows,replacing the
child-parent hierarchy with a phandle:

    firmware {
        tee_rproc: optee-rproc {
            compatible = "80a4c275-0a47-4905-8285-1486a9771a08";
        };
    };

    m4: m4@0 {
      compatible = "st,stm32mp1-m4-tee";
      reg = <0 0>;

      mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
      mbox-names = "vq0", "vq1", "shutdown";

      memory-region = <&vdev0vring0>, <&m_ipc_shm>, <&mcuram2>,
                      <&vdev0vring1>, <&vdev0buffer>, <&retram>;

      interrupt-parent = <&exti>;
      interrupts = <68 1>;

      rproc-tee-phandle = <&tee_rproc 0>;
      st,auto-boot;
      wakeup-source;

      status = "okay";
    };

As a consequence, this version:
- Updates the device tree and bindings to:
  - Change the compatible property from
    "rproc-service-80a4c275-0a47-4905-8285-1486a9771a08" to
    "80a4c275-0a47-4905-8285-1486a9771a08".
  - Use the rproc-tee-phandle to avoid the parent-child hierarchy.
- Updates stm32_rproc_tee.c and remoteproc_tee.c to adapt to the new bindings.
- Updates remoteproc_tee.c to compute the device tree compatible string from
  the TEE UUID.

Main updates from version V19[4]:
--------------------------------
The devicetree is now structured as follows:

	firmware {
		optee {
			compatible = "linaro,optee-tz";
			method = "smc";
			#address-cells = <1>;
			#size-cells = <0>;
			rproc-service@0 {
				compatible = "rproc-service-80a4c275-0a47-4905-8285-1486a9771a08";
				reg = <0>;
				#address-cells = <1>;
				#size-cells = <0>;
				status = "okay";
				m4: m4@0 {
					compatible = "st,stm32mp15-m4-tee";
					reg = <0>;
					mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
					mbox-names = "vq0", "vq1", "shutdown";
					memory-region = <&vdev0vring0>,	<&m_ipc_shm>, <&mcuram2>,
							<&vdev0vring1>, <&vdev0buffer>, <&retram>;
					interrupt-parent = <&exti>;
					interrupts = <68 1>;
					status = "okay";
				};
			};
		};
	};

As a consequence, this version:

- Introduces a new stm32_rproc_tee.c remoteproc driver.

  Instead of further complicating the existing stm32_rproc.c driver, a
  dedicated TEE-based driver is added. Both drivers are intended to also
  support the STM32MP2x Cortex-M33 remote processor in a next step.

- Reworks the bindings:
  - Drop the st,stm32-rproc.yaml updates that were introduced in previous
    revisions.
  - Add remoteproc-tee.yaml for the
    "rproc-service-80a4c275-0a47-4905-8285-1486a9771a08" compatible.
  - Add st,stm32-rproc-tee.yaml for the "st,stm32mp15-m4-tee" compatible.

- Reworks the probing sequence:

  The m4@0 device is now probed by the remoteproc-tee driver, which itself
  is instantiated by the TEE (OP-TEE) bus.

More details are available in each patch commit message.

[1] https://lore.kernel.org/linux-remoteproc/20260317180329.1207625-1-arnaud.pouliquen@foss.st.com/
[2] https://lore.kernel.org/linux-remoteproc/20251217153917.3998544-1-arnaud.pouliquen@foss.st.com/
[3] https://lore.kernel.org/linux-devicetree/20250625094028.758016-1-arnaud.pouliquen@foss.st.com/


Tested-on:
---------
commit 591cd656a1bf ("Linux 7.0-rc7")

Description of the feature:
--------------------------
This series proposes the implementation of a remoteproc tee driver to
communicate with a TEE trusted application responsible for authenticating
and loading the remoteproc firmware image in an Arm secure context.

1) Principle:

The remoteproc tee driver provides services to communicate with the OP-TEE
trusted application running on the Trusted Execution Context (TEE).
The trusted application in TEE manages the remote processor lifecycle:

- authenticating and loading firmware images,
- isolating and securing the remote processor memories,
- supporting multi-firmware (e.g., TF-M + Zephyr on a Cortex-M33),
- managing the start and stop of the firmware by the TEE.

2) Format of the signed image:

Refer to:
https://github.com/OP-TEE/optee_os/blob/master/ta/remoteproc/src/remoteproc_core.c#L18-L57

3) OP-TEE trusted application API:

Refer to:
https://github.com/OP-TEE/optee_os/blob/master/ta/remoteproc/include/ta_remoteproc.h

4) OP-TEE signature script

Refer to:
https://github.com/OP-TEE/optee_os/blob/master/scripts/sign_rproc_fw.py

Example of usage:
sign_rproc_fw.py --in <fw1.elf> --in <fw2.elf> --out <signed_fw.sign> --key ${OP-TEE_PATH}/keys/default.pem


5) Impact on User space Application

No sysfs impact. The user only needs to provide the signed firmware image
instead of the ELF image.


For more information about the implementation, a presentation is available here
(note that the format of the signed image has evolved between the presentation
and the integration in OP-TEE).

https://resources.linaro.org/en/resource/6c5bGvZwUAjX56fvxthxds

Arnaud Pouliquen (7):
  dt-bindings: firmware: Add TEE remoteproc service binding
  dt-bindings: remoteproc: st,stm32-rproc: add st,rproc-tee
  remoteproc: core: Introduce rproc_pa_to_va helper
  remoteproc: Introduce optional release_fw operation
  remoteproc: Add TEE support
  remoteproc: stm32: Create sub-functions to request shutdown and
    release
  remoteproc: stm32: Add support of an OP-TEE TA to load the firmware

 .../bindings/remoteproc/remoteproc-tee.yaml   |  36 +
 .../bindings/remoteproc/st,stm32-rproc.yaml   |  55 +-
 drivers/remoteproc/Kconfig                    |  10 +
 drivers/remoteproc/Makefile                   |   1 +
 drivers/remoteproc/remoteproc_core.c          |  56 ++
 drivers/remoteproc/remoteproc_internal.h      |   6 +
 drivers/remoteproc/remoteproc_tee.c           | 789 ++++++++++++++++++
 drivers/remoteproc/stm32_rproc.c              | 249 ++++--
 include/linux/remoteproc.h                    |   6 +
 include/linux/remoteproc_tee.h                |  98 +++
 10 files changed, 1220 insertions(+), 86 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/remoteproc-tee.yaml
 create mode 100644 drivers/remoteproc/remoteproc_tee.c
 create mode 100644 include/linux/remoteproc_tee.h


base-commit: 591cd656a1bf5ea94a222af5ef2ee76df029c1d2
-- 
2.43.0


^ permalink raw reply

* Re: [PATCH 2/2] iio: dac: mcp47feb02: add MCP48FEB02 SPI driver to MCP47FEB02 I2C driver
From: Ariana.Lazar @ 2026-04-14 15:28 UTC (permalink / raw)
  To: robh, krzk+dt, jic23, nuno.sa, dlechner, conor+dt, andy
  Cc: Jonathan.Cameron, Conor.Dooley, devicetree, linux-iio,
	linux-kernel
In-Reply-To: <1e05b8f9-e95e-458d-9179-ac8268023ae5@baylibre.com>

Hi David,

> > --- a/drivers/iio/dac/Makefile
> > +++ b/drivers/iio/dac/Makefile
> > @@ -54,6 +54,9 @@ obj-$(CONFIG_MAX5821) += max5821.o
> >  obj-$(CONFIG_MCP4725) += mcp4725.o
> >  obj-$(CONFIG_MCP4728) += mcp4728.o
> >  obj-$(CONFIG_MCP47FEB02) += mcp47feb02.o
> 
> Shouldn't we be removing this old file?
> 
> The patch series would be eaiser to understand if it was split into
> one commit to split the existing driver into two files and then
> another commit to add support for the new parts.
> 
> 
> > +mcp47feb02-objs := mcp47feb02-core.o
> > +obj-$(CONFIG_MCP47FEB02_I2C) += mcp47feb02-i2c.o
> > +obj-$(CONFIG_MCP47FEB02_SPI) += mcp47feb02-spi.o
> >  obj-$(CONFIG_MCP4821) += mcp4821.o
> >  obj-$(CONFIG_MCP4922) += mcp4922.o
> >  obj-$(CONFIG_STM32_DAC_CORE) += stm32-dac-core.o
> 

Thank you for the review.

I kept that line so the core module would compile as 'mcp47feb02.ko'.
If you prefer, I can rename the core file to mcp47feb02.c and add just
the lines for the SPI and I2C modules in the Makefile.

Another option would be to keep the core module named mcp47feb02-core.c
and compile it as 'mcp47feb02-core.ko'.

Best regards,
Ariana

^ permalink raw reply

* Re: Phandles
From: Rob Herring @ 2026-04-14 15:24 UTC (permalink / raw)
  To: Kyle Bonnici
  Cc: Krzysztof Kozlowski, Herve Codina,
	devicetree-compiler@vger.kernel.org, Krzysztof Kozlowski,
	Conor Dooley, devicetree@vger.kernel.org
In-Reply-To: <DB5F7CA0-08E8-4CF5-9815-598002AF471F@hotmail.com>

On Mon, Apr 13, 2026 at 4:50 AM Kyle Bonnici <kylebonnici@hotmail.com> wrote:
>
>
> > You cannot have random values. I quoted the DT spec.
>
> Where in the DTS 0.4 spec are property names such as  pwms, clocks
>  etc… mandated to be of format <phandle cell …>?

I would not read too much into what is defined in the spec vs. what is
defined in dtschema. It's a conscious decision that all these
properties are not in the spec. The goal is the whole spec or at least
any parts defining properties is just schemas and the spec is
generated from the schemas. That's the only way new properties will
get added to the spec (with a few exceptions). However, no one is
working on generating the spec from schemas.

> > Well, we don't use discord but IRC... but that github issue also uses
> > "pwms = <1 &pwm0 1 20 PWM_POLARITY_NORMAL>;"
> >
> > So again - what is "1"?
> >
> > I am asking because if you use incorrect value as phandle value, then
> > DTC warning is obviously expected and nothing to fix here.
>
> The warning is only valid if ‘1’  is expected to be a phandle which is what I am
> Arguing the spec does not mandate this.
>
> > You asked why phandle has to be the first entry in phandle-value type? I
> > responded that DT spec makes it.
>
> Which section in DTS 0.4 spec?

Doesn't matter. How would you ever parse the properties if that's not
the case. You have to have the phandle first to get the number of arg
cells to find the next phandle. I suppose you could define some other
convention, but it would have to be pretty much global like this
convention is. And this convention dates back to the GPIO binding
which dates back to at least 2005 if not the 1990s. And most of these
properties you list date back to well before Zephyr existed.

The spec, dtc and the dts format will let you do something like this:

foo = <0x12345678>, "bar", /bits/ 16 <0xabcd>;

You would have to be out of your mind to do something like that when
the format has zero type information.

Every warning in dtc can be disabled. So if they are a problem, turn them off.

Rob

^ permalink raw reply

* Re: [PATCH 08/11] media: iris: Add power sequence for Glymur
From: Dmitry Baryshkov @ 2026-04-14 15:23 UTC (permalink / raw)
  To: Vishnu Reddy
  Cc: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
	Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
	Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
	Hans Verkuil, linux-media, linux-arm-msm, devicetree,
	linux-kernel, iommu
In-Reply-To: <20260414-glymur-v1-8-7d3d1cf57b16@oss.qualcomm.com>

On Tue, Apr 14, 2026 at 10:30:04AM +0530, Vishnu Reddy wrote:
> Add power sequence hooks for controller, vcodec and vcodec1. reuse the
> existing code where ever is possible. add vcodec1 power on and off code
> separately which has different power domains and clocks.

You need to describe, what vcodec1 is and what are the requirements. Is
it supposed to be brought up together with the vcodec0 or is it a
separate entity?

> 
> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> ---
>  .../platform/qcom/iris/iris_platform_common.h      |   9 ++
>  drivers/media/platform/qcom/iris/iris_vpu3x.c      | 123 +++++++++++++++++++++
>  drivers/media/platform/qcom/iris/iris_vpu_common.h |   1 +
>  .../platform/qcom/iris/iris_vpu_register_defines.h |   7 ++
>  4 files changed, 140 insertions(+)
> 

-- 
With best wishes
Dmitry

^ permalink raw reply

* Re: [PATCH 06/11] media: iris: Fix VM count passed to firmware
From: Dmitry Baryshkov @ 2026-04-14 15:20 UTC (permalink / raw)
  To: Vishnu Reddy
  Cc: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
	Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
	Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
	Hans Verkuil, linux-media, linux-arm-msm, devicetree,
	linux-kernel, iommu, stable
In-Reply-To: <20260414-glymur-v1-6-7d3d1cf57b16@oss.qualcomm.com>

On Tue, Apr 14, 2026 at 10:30:02AM +0530, Vishnu Reddy wrote:
> On Glymur, firmware interprets the value written to CPU_CS_SCIACMDARG3 as
> the number of virtual machines (VMs) and internally adds 1 to it. Writing

Does this apply to Glymur only or to other platforms too?

> 1 causes firmware to treat it as 2 VMs. Since only one VM is required,
> remove this write to leave the register at its reset value of 0. This does
> not affect other platforms as only Glymur firmware uses this register,
> earlier platform firmwares ignore it.
> 
> Fixes: abf5bac63f68a ("media: iris: implement the boot sequence of the firmware")
> Cc: stable@vger.kernel.org
> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> ---
>  drivers/media/platform/qcom/iris/iris_vpu_common.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
> index 548e5f1727fd..bfd1e762c38e 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
> @@ -78,7 +78,6 @@ int iris_vpu_boot_firmware(struct iris_core *core)
>  	iris_vpu_setup_ucregion_memory_map(core);
>  
>  	writel(ctrl_init, core->reg_base + CTRL_INIT);
> -	writel(0x1, core->reg_base + CPU_CS_SCIACMDARG3);
>  
>  	while (!ctrl_status && count < max_tries) {
>  		ctrl_status = readl(core->reg_base + CTRL_STATUS);
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry

^ permalink raw reply

* Re: [PATCH 04/11] media: iris: Add helper to create a context bank device on iris vpu bus
From: Dmitry Baryshkov @ 2026-04-14 15:18 UTC (permalink / raw)
  To: Vishnu Reddy
  Cc: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
	Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
	Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
	Hans Verkuil, linux-media, linux-arm-msm, devicetree,
	linux-kernel, iommu
In-Reply-To: <20260414-glymur-v1-4-7d3d1cf57b16@oss.qualcomm.com>

On Tue, Apr 14, 2026 at 10:30:00AM +0530, Vishnu Reddy wrote:
> From: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> 
> Add a helper function to allocate and register context bank (CB) device
> on the iris vpu bus. The function ID associated with the CB is specified
> from the platform data, allowing the bus dma_configure callback to apply
> correct stream ID mapping when device is registered.
> 
> Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> ---
>  drivers/media/platform/qcom/iris/iris_resources.c | 33 +++++++++++++++++++++++
>  drivers/media/platform/qcom/iris/iris_resources.h |  1 +
>  2 files changed, 34 insertions(+)
> 
> diff --git a/drivers/media/platform/qcom/iris/iris_resources.c b/drivers/media/platform/qcom/iris/iris_resources.c
> index 773f6548370a..a25e0f2e9d26 100644
> --- a/drivers/media/platform/qcom/iris/iris_resources.c
> +++ b/drivers/media/platform/qcom/iris/iris_resources.c
> @@ -6,6 +6,7 @@
>  #include <linux/clk.h>
>  #include <linux/devfreq.h>
>  #include <linux/interconnect.h>
> +#include <linux/iris_vpu_bus.h>
>  #include <linux/pm_domain.h>
>  #include <linux/pm_opp.h>
>  #include <linux/pm_runtime.h>
> @@ -141,3 +142,35 @@ int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type
>  
>  	return 0;
>  }
> +
> +static void iris_release_cb_dev(struct device *dev)
> +{
> +	kfree(dev);
> +}
> +
> +struct device *iris_create_cb_dev(struct iris_core *core, const char *name, const u32 *f_id)

Please move into the bus code and make it generic enough.

> +{
> +	struct device *dev;
> +	int ret;
> +
> +	dev = kzalloc_obj(*dev);
> +	if (!dev)
> +		return ERR_PTR(-ENOMEM);
> +
> +	dev->release = iris_release_cb_dev;
> +	dev->bus = &iris_vpu_bus_type;
> +	dev->parent = core->dev;
> +	dev->coherent_dma_mask = core->iris_platform_data->dma_mask;
> +	dev->dma_mask = &dev->coherent_dma_mask;

Would you also need to set the of_node? See
device_set_of_node_from_dev()

> +
> +	dev_set_name(dev, "%s", name);
> +	dev_set_drvdata(dev, (void *)f_id);
> +
> +	ret = device_register(dev);
> +	if (ret) {
> +		put_device(dev);
> +		return ERR_PTR(ret);
> +	}
> +
> +	return dev;
> +}
> diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/media/platform/qcom/iris/iris_resources.h
> index 6bfbd2dc6db0..4a494627ff23 100644
> --- a/drivers/media/platform/qcom/iris/iris_resources.h
> +++ b/drivers/media/platform/qcom/iris/iris_resources.h
> @@ -15,5 +15,6 @@ int iris_unset_icc_bw(struct iris_core *core);
>  int iris_set_icc_bw(struct iris_core *core, unsigned long icc_bw);
>  int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type clk_type);
>  int iris_prepare_enable_clock(struct iris_core *core, enum platform_clk_type clk_type);
> +struct device *iris_create_cb_dev(struct iris_core *core, const char *name, const u32 *f_id);
>  
>  #endif
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry

^ permalink raw reply

* Re: [PATCH 03/11] media: iris: Add context bank hooks for platform specific initialization
From: Dmitry Baryshkov @ 2026-04-14 15:16 UTC (permalink / raw)
  To: Vishnu Reddy
  Cc: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
	Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
	Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
	Hans Verkuil, linux-media, linux-arm-msm, devicetree,
	linux-kernel, iommu
In-Reply-To: <20260414-glymur-v1-3-7d3d1cf57b16@oss.qualcomm.com>

On Tue, Apr 14, 2026 at 10:29:59AM +0530, Vishnu Reddy wrote:
> Add init and deinit hooks in the platform data for context bank setup.
> These hooks allow platform specific code to initialize and tear down
> context banks.
> 
> The Glymur platform requires a dedicated firmware context bank device
> which is mapped to the firmware stream ID to load the firmware.

Change the order of paragraphs. You should start with the definition of
the problem rather than putting the cart before the horse and starting
from the solution.

> 
> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> ---
>  .../platform/qcom/iris/iris_platform_common.h      |  2 ++
>  drivers/media/platform/qcom/iris/iris_probe.c      | 23 +++++++++++++++++++++-
>  2 files changed, 24 insertions(+), 1 deletion(-)
> 

-- 
With best wishes
Dmitry

^ permalink raw reply

* Re: [PATCH 02/11] media: iris: Add iris vpu bus support and register it with iommu_buses
From: Dmitry Baryshkov @ 2026-04-14 15:14 UTC (permalink / raw)
  To: Vishnu Reddy
  Cc: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
	Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
	Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
	Hans Verkuil, linux-media, linux-arm-msm, devicetree,
	linux-kernel, iommu
In-Reply-To: <20260414-glymur-v1-2-7d3d1cf57b16@oss.qualcomm.com>

On Tue, Apr 14, 2026 at 10:29:58AM +0530, Vishnu Reddy wrote:
> From: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> 
> Add a dedicated iris VPU bus type and register it into the iommu_buses
> list. Iris devices require their own bus so that each device can run its
> own dma_configure() logic.

This really tells nothing, unless one has full context about the Iris
needs. Start by describing the issue (that the device needs to have
multiple devices talking to describe IOMMUs / VAs for several hardware
functions), then continue by describing what is needed from the IOMMU
subsys.

> 
> Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> ---
>  drivers/iommu/iommu.c                           |  4 ++++
>  drivers/media/platform/qcom/iris/Makefile       |  4 ++++
>  drivers/media/platform/qcom/iris/iris_vpu_bus.c | 32 +++++++++++++++++++++++++
>  include/linux/iris_vpu_bus.h                    | 13 ++++++++++

How are you supposed to merge this? Through IOMMU tree? Through venus
tree? Can we add one single bus to the IOMMU code and use it for Iris,
Venus, FastRPC, host1x and all other device drivers which require
per-device DMA configuration?

Your colleagues from the FastRPC team posted a very similar code few
weeks ago and got exactly the same feedback. Is there a reason why your
teams don't sync on the IOMMU parts at all?

>  4 files changed, 53 insertions(+)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 61c12ba78206..d8ed6ef70ecd 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -13,6 +13,7 @@
>  #include <linux/bug.h>
>  #include <linux/types.h>
>  #include <linux/init.h>
> +#include <linux/iris_vpu_bus.h>
>  #include <linux/export.h>
>  #include <linux/slab.h>
>  #include <linux/errno.h>
> @@ -179,6 +180,9 @@ static const struct bus_type * const iommu_buses[] = {
>  #ifdef CONFIG_CDX_BUS
>  	&cdx_bus_type,
>  #endif
> +#if IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)
> +	&iris_vpu_bus_type,
> +#endif
>  };
>  
>  /*
> diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
> index 2abbd3aeb4af..6f4052b98491 100644
> --- a/drivers/media/platform/qcom/iris/Makefile
> +++ b/drivers/media/platform/qcom/iris/Makefile
> @@ -31,3 +31,7 @@ qcom-iris-objs += iris_platform_gen1.o
>  endif
>  
>  obj-$(CONFIG_VIDEO_QCOM_IRIS) += qcom-iris.o
> +
> +ifdef CONFIG_VIDEO_QCOM_IRIS
> +obj-y += iris_vpu_bus.o
> +endif
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_bus.c b/drivers/media/platform/qcom/iris/iris_vpu_bus.c
> new file mode 100644
> index 000000000000..b51bb4b82b0e
> --- /dev/null
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_bus.c
> @@ -0,0 +1,32 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/of_device.h>
> +
> +#include "iris_platform_common.h"
> +
> +static int iris_vpu_bus_dma_configure(struct device *dev)
> +{
> +	const u32 *f_id = dev_get_drvdata(dev);
> +
> +	if (!f_id)
> +		return -ENODEV;
> +
> +	return of_dma_configure_id(dev, dev->parent->of_node, true, f_id);

I think it was discussed that this is not enough. Some of devices need
multiple function IDs.

> +}
> +
> +const struct bus_type iris_vpu_bus_type = {
> +	.name = "iris-vpu-bus",
> +	.dma_configure = iris_vpu_bus_dma_configure,
> +};
> +EXPORT_SYMBOL_GPL(iris_vpu_bus_type);
> +
> +static int __init iris_vpu_bus_init(void)
> +{
> +	return bus_register(&iris_vpu_bus_type);
> +}
> +
> +postcore_initcall(iris_vpu_bus_init);
> diff --git a/include/linux/iris_vpu_bus.h b/include/linux/iris_vpu_bus.h
> new file mode 100644
> index 000000000000..5704b226f7d6
> --- /dev/null
> +++ b/include/linux/iris_vpu_bus.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#ifndef __IRIS_VPU_BUS_H__
> +#define __IRIS_VPU_BUS_H__
> +
> +#if IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)
> +extern const struct bus_type iris_vpu_bus_type;
> +#endif
> +
> +#endif /* __IRIS_VPU_BUS_H__ */
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry

^ permalink raw reply

* Re: [PATCH] arm64: dts: qcom: x1e80100-dell-xps13-9345: enable onboard accelerometers
From: Konrad Dybcio @ 2026-04-14 15:09 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Aleksandrs Vinarskis, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, laurentiu.tudor1,
	linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <l3cfeezstqrabhgba2xnzciztfwp6ijunzemlb5uanpxhgmscu@kh3jdcc2dhbj>

On 3/23/26 6:05 PM, Dmitry Baryshkov wrote:
> On Mon, Mar 23, 2026 at 04:06:53PM +0100, Konrad Dybcio wrote:
>> On 3/2/26 2:25 PM, Aleksandrs Vinarskis wrote:
>>>
>>> On Monday, March 2nd, 2026 at 13:14, Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> wrote:
>>>
>>>> On 2/28/26 6:46 PM, Aleksandrs Vinarskis wrote:
>>>>> Particular laptop comes with two sets of sensors:
>>>>> 1. Motherboard: accelerometer
>>>>> 2. Display/Camera module: accelerometer, ambient ligth (and more)
>>>>>    sensor
>>>>>
>>>>> Define both i2c busses (bitbanged), sensors and respective rotation
>>>>> matrices.
>>>>
>>>> These GPIOs correspond to ADSP/SSC-bound QUPs. It may be that you're
>>>> poking at the same bus as the DSP is, concurrently.
>>>
>>> Indeed, Val already pointed out that there is hexagonrpcd to access
>>> sensors behind Sensor Core from DSP. I found corresponding .json sensor
>>> files in Windows for all x3 sensors, but could not make it work yet.
>>>
>>> Without these additional things in userspace it does not cause any
>>> conflicts: I've been using this for a week now, no i2c communication
>>> issues and device orientation information is present.
>>>
>>> The question is then if we want to keep this series which ignores DSP
>>> capabilities with the advantage that it will work for everyone with
>>> the new kernel vs doing it 'correct' way over DSP which requires
>>> additional json (and binary blobs?) and userpsace configuration,
>>> meaning that most users will never have these sensors?
>>
>> I don't know what's the endgame for sensors. Maybe +Dmitry knows whether
>> there's any action on that point.
>>
>> Going through the DSP allows you to keep aggregating the data at close
>> to no power cost (""low power island""), notably without waking up the
>> CPUs if there's no other work. That, plus I'm somewhat skeptical about
>> going behind its back, since it may be that a firmware update or some
>> other trigger makes it start trying to communicate with them.
> 
> The sensors story would require DSP libraries matching the firmware,
> sensors descriptions and several still-closed-source libraries to work.
> There is an open-source libssc project, but I don't know if anybody has
> tested it on this platform (and it will still require DSP libs to
> function).
> 
>>
>> But I'm not 100% against this either
> 
> I guess it is a necessary evil until we get libssc to work on it.

Aleksandrs, if you're interested in trying that one out:

https://codeberg.org/DylanVanAssche/libssc.git

Konrad

^ permalink raw reply

* Re: [PATCH v1] arm64: dts: qcom: Enable CAN RX via GPIO expander
From: Konrad Dybcio @ 2026-04-14 15:07 UTC (permalink / raw)
  To: Anup Kulkarni, andersson, konradybcio, robh, krzk+dt, conor+dt,
	linux-arm-msm, devicetree, linux-kernel
  Cc: mukesh.savaliya, viken.dadhaniya
In-Reply-To: <20260402105253.3009382-1-anup.kulkarni@oss.qualcomm.com>

On 4/2/26 12:52 PM, Anup Kulkarni wrote:
> Few CAN controllers, part of RTSS sub-system on LeMans, route
> their RX signal through a I2C GPIO expander at address 0x3b.
> RTSS subsystem is an MCU like sub-system on LeMans with independent
> booting capability through OSPI interface and supports peripherals like
> RGMII, CAN-FD, UART, I2C, SPI etc.
> 
> Describe this hardware wiring by configuring the expander GPIO 4 pin as
> hog with output-high, asserting the selected line during boot.
> 
> Signed-off-by: Anup Kulkarni <anup.kulkarni@oss.qualcomm.com>
> ---

Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

^ permalink raw reply

* Re: [PATCH v7 5/6] iio: adc: ad4691: add oversampling support
From: David Lechner @ 2026-04-14 15:02 UTC (permalink / raw)
  To: Sabau, Radu bogdan, Jonathan Cameron
  Cc: Lars-Peter Clausen, Hennerich, Michael, Sa, Nuno, Andy Shevchenko,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Uwe Kleine-König, Liam Girdwood, Mark Brown, Linus Walleij,
	Bartosz Golaszewski, Philipp Zabel, Jonathan Corbet, Shuah Khan,
	linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org
In-Reply-To: <LV9PR03MB8414E0A68C5676302909E220F7252@LV9PR03MB8414.namprd03.prod.outlook.com>

On 4/14/26 9:25 AM, Sabau, Radu bogdan wrote:
> 
> 
>> -----Original Message-----
>> From: Jonathan Cameron <jic23@kernel.org>
>> Sent: Sunday, April 12, 2026 8:58 PM
>> To: David Lechner <dlechner@baylibre.com>
>> Cc: Sabau, Radu bogdan <Radu.Sabau@analog.com>; Lars-Peter Clausen
>> <lars@metafoo.de>; Hennerich, Michael <Michael.Hennerich@analog.com>;
>> Sa, Nuno <Nuno.Sa@analog.com>; Andy Shevchenko <andy@kernel.org>;
>> Rob Herring <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>;
>> Conor Dooley <conor+dt@kernel.org>; Uwe Kleine-König
>> <ukleinek@kernel.org>; Liam Girdwood <lgirdwood@gmail.com>; Mark Brown
>> <broonie@kernel.org>; Linus Walleij <linusw@kernel.org>; Bartosz
>> Golaszewski <brgl@kernel.org>; Philipp Zabel <p.zabel@pengutronix.de>;
>> Jonathan Corbet <corbet@lwn.net>; Shuah Khan
>> <skhan@linuxfoundation.org>; linux-iio@vger.kernel.org;
>> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
>> pwm@vger.kernel.org; linux-gpio@vger.kernel.org; linux-doc@vger.kernel.org
>> Subject: Re: [PATCH v7 5/6] iio: adc: ad4691: add oversampling support
>>
>> [External]
>>
>> On Fri, 10 Apr 2026 16:15:20 -0500
>> David Lechner <dlechner@baylibre.com> wrote:
>>
>>> On 4/9/26 10:28 AM, Radu Sabau via B4 Relay wrote:
>>>> From: Radu Sabau <radu.sabau@analog.com>
>>>>
>>>> Add per-channel oversampling ratio (OSR) support for CNV burst mode.
>>>> The accumulator depth register (ACC_DEPTH_IN) is programmed with the
>>>> selected OSR at buffer enable time and before each single-shot read.
>>>>
>>>> Supported OSR values: 1, 2, 4, 8, 16, 32.
>>>>
>>>> Introduce AD4691_MANUAL_CHANNEL() for manual mode channels,
>> which do
>>>> not expose the oversampling ratio attribute since OSR is not applicable
>>>> in that mode. A separate manual_channels array is added to
>>>> struct ad4691_channel_info and selected at probe time; offload paths
>>>> reuse the same arrays with num_channels capping access before the soft
>>>> timestamp entry.
>>>>
>>>> The reported sampling frequency accounts for the active OSR:
>>>> effective_freq = oscillator_freq / osr
>>>
>>> Technically, the way this is implemented is fine according to IIO ABI
>>> rules. Writing any attribute can cause others to change. It does
>>> introduce a potential pitfall though. Currently, changing the OSR will
>>> change the sampling frequency, so you have to always write
>> oversampling_ratio
>>> first, then write sampling_frequency to get what you asked for. If you want
>>> to change the OSR and keep the same sample rate, you still have to write
>> both
>>> attributes again.
>>>
>>> In other drivers, I've implemented it so that the requested sampling
>> frequency
>>> is stored any you always get the closest sampling frequency available based
>> on
>>> the oversampling ratio. This way, it doesn't matter which order you write
>>> the attributes. In that case, the actual periodic trigger source isn't set up
>>> until we actually start sampling.
>>>
>> Agreed. This is more intuitive. Now generally the userspace should
>> be sanity checking the value anyway as limitations may mean the new
>> sampling frequency is not particularly close to the original one but
>> at least it increases the chances of getting the expected value somewhat!
>>
>> So to me this is a nice useability improvement given the code to implement
>> it tends not to be too complex.
>>
> 
> Hi David, Jonathan,
> 
> What I understand from this is that the osr should be taken into account when writing
> the sampling frequency as well, right? Here's what I understand:
> 
> If the user wants a 125kHz freq with 4 OSR, then when internal osc will be written
> to 500kHz before single-shot read, buffer preenable/postenable.
> However, if the user wants a 500kHz frequency with 4 OSR, that would mean a 2MHz
> Internal osc freq, which is impossible.

It is up to the user to request something that is legal. They should know this
from reading the datasheet.

> 
> More than this, if the OSR is 32 the maximum effective rate would be 31250, so 25kHz
> would make it the closes available one. If the user would select 1MHz from the available
> list it would be weird I would say. So perhaps a solution for this is to display the avail list
> depending on the set OSR value.

Yes, the available list should reflect the current state of any other attributes
that affect it.

> 
> Linking the two together is perhaps wrong to begin with from my end, since in this
> driver's case, the per-channel sampling frequency is controlled by the internal oscillator
> which has static available values. So perhaps sampling frequency should be separate, and
> OSR separate as well, which would make everything cleaner.
> 
> Indeed, the effective rate is changed by OSR, but perhaps that is something the user
> should be aware of, since the sampling frequency is the rate at which the channel samples
> (1 sample per period) and OSR is how many times the channel samples upon a final sample
> is to be read. The user already has to take this into account when setting the buffer
> sampling frequency, so it would make sense to take this into account here too.

We can't change the definition of the IIO ABI just to make one driver simpler
to implement. The OSR and sample rate can't be completely independent.

If you want to leave it the way it is currently implemented though, that is fine.

> 
> Please let me know you thoughts on this,
> Radu


^ permalink raw reply

* Re: [PATCH v1 0/4] Enable audio over HDMI and
From: Dmitry Baryshkov @ 2026-04-14 14:58 UTC (permalink / raw)
  To: Kumar Anurag
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Srinivas Kandagatla, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, devicetree,
	linux-kernel, linux-sound
In-Reply-To: <20260413091937.134469-1-kumar.singh@oss.qualcomm.com>

On Mon, Apr 13, 2026 at 02:19:33AM -0700, Kumar Anurag wrote:
> This series adds the dt and driver changes for enabling 
> audio over HDMI and Displayport. 

Do we need topology changes or UCM changes for these to work?

> 
> Kumar Anurag (4):
>   arm64: dts: qcom: Enable secondary mi2s
>   arm64: dts: qcom: qcs6490: Enable DP audio
>   ASoC: qcom: q6dsp: Update bit format support for secondary i2s
>   ASoC: qcom: sc8280xp: don't force S16_LE in hw_params fixup
> 
>  arch/arm64/boot/dts/qcom/kodiak.dtsi         |  5 ++
>  arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 59 ++++++++++++++++++++
>  sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c     |  7 ++-
>  sound/soc/qcom/sc8280xp.c                    |  2 -
>  4 files changed, 69 insertions(+), 4 deletions(-)
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry

^ permalink raw reply

* Re: [PATCH v1 2/4] arm64: dts: qcom: qcs6490: Enable DP audio
From: Dmitry Baryshkov @ 2026-04-14 14:58 UTC (permalink / raw)
  To: Kumar Anurag
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Srinivas Kandagatla, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, devicetree,
	linux-kernel, linux-sound
In-Reply-To: <20260413091937.134469-3-kumar.singh@oss.qualcomm.com>

On Mon, Apr 13, 2026 at 02:19:35AM -0700, Kumar Anurag wrote:
> Add new dai link to enable DP audio.

DAI

Also, will this enable audio for the USB-C DP only? Please add support
for audio over the mini-DP port (or mention that it's not available in
HW).

> 
> Signed-off-by: Kumar Anurag <kumar.singh@oss.qualcomm.com>
> ---
>  arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> index 2e4062052828..90fd8822dabd 100644
> --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> @@ -1169,6 +1169,22 @@ platform {
>  			sound-dai = <&q6apm>;
>  		};
>  	};
> +
> +	dp-dai-link {

Still keep it sorted.

> +		link-name = "DisplayPort0 Playback";
> +
> +		codec {
> +			sound-dai = <&mdss_dp>;
> +		};
> +
> +		cpu {
> +			sound-dai = <&q6apmbedai DISPLAY_PORT_RX_0>;
> +		};
> +
> +		platform {
> +			sound-dai = <&q6apm>;
> +		};
> +	};
>  };
>  
>  &swr2 {
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry

^ permalink raw reply

* Re: [PATCH v1 1/4] arm64: dts: qcom: Enable secondary mi2s
From: Dmitry Baryshkov @ 2026-04-14 14:56 UTC (permalink / raw)
  To: Kumar Anurag
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Srinivas Kandagatla, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, devicetree,
	linux-kernel, linux-sound
In-Reply-To: <20260413091937.134469-2-kumar.singh@oss.qualcomm.com>

On Mon, Apr 13, 2026 at 02:19:34AM -0700, Kumar Anurag wrote:
> Enable secondary mi2s to support HDMI audio.

Please also correct subject line to mention kodiak.

> 
> Signed-off-by: Kumar Anurag <kumar.singh@oss.qualcomm.com>
> ---
>  arch/arm64/boot/dts/qcom/kodiak.dtsi         |  5 +++
>  arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 43 ++++++++++++++++++++
>  2 files changed, 48 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
> index 6079e67ea829..d1009debc12b 100644
> --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
> +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
> @@ -5827,6 +5827,11 @@ mi2s1_ws: mi2s1-ws-state {
>  				function = "mi2s1_ws";
>  			};
>  
> +			mi2s1_mclk: mi2s1-mclk-state {
> +				pins = "gpio105";
> +				function = "sec_mi2s";
> +			};
> +
>  			pcie0_clkreq_n: pcie0-clkreq-n-state {
>  				pins = "gpio88";
>  				function = "pcie0_clkreqn";
> diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> index e3d2f01881ae..2e4062052828 100644
> --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> @@ -672,6 +672,7 @@ &i2c0 {
>  	lt9611_codec: hdmi-bridge@2b {
>  		compatible = "lontium,lt9611uxc";
>  		reg = <0x2b>;
> +		#sound-dai-cells = <1>;

Separate patch.

>  
>  		interrupts-extended = <&tlmm 24 IRQ_TYPE_EDGE_FALLING>;
>  		reset-gpios = <&pm7250b_gpios 2 GPIO_ACTIVE_HIGH>;
> @@ -1110,6 +1111,9 @@ &sound {
>  	compatible = "qcom,qcs6490-rb3gen2-sndcard";
>  	model = "QCS6490-RB3Gen2";
>  
> +	pinctrl-0 = <&mi2s1_data0>, <&mi2s1_mclk>, <&mi2s1_sclk>, <&mi2s1_ws>;
> +	pinctrl-names = "default";
> +
>  	audio-routing = "SpkrLeft IN", "WSA_SPK1 OUT",
>  			"SpkrRight IN", "WSA_SPK2 OUT",
>  			"VA DMIC0", "vdd-micb",
> @@ -1149,6 +1153,22 @@ platform {
>  			sound-dai = <&q6apm>;
>  		};
>  	};
> +
> +	mi2s1-playback-dai-link {

Keep the entries sorted. mi2s1 < va

> +		link-name = "Secondary MI2S Playback";
> +
> +		codec {
> +			sound-dai = <&lt9611_codec 0>;
> +		};
> +
> +		cpu {
> +			sound-dai = <&q6apmbedai SECONDARY_MI2S_RX>;
> +		};
> +
> +		platform {
> +			sound-dai = <&q6apm>;
> +		};
> +	};
>  };
>  
>  &swr2 {
> @@ -1437,3 +1457,26 @@ &lpass_audiocc {
>  	compatible = "qcom,qcm6490-lpassaudiocc";
>  	/delete-property/ power-domains;
>  };
> +
> +&mi2s1_data0 {
> +	drive-strength = <8>;
> +	bias-disable;
> +};
> +
> +&mi2s1_mclk {
> +	drive-strength = <8>;
> +	bias-disable;
> +	output-high;
> +};
> +
> +&mi2s1_sclk {
> +	drive-strength = <8>;
> +	bias-disable;
> +	output-high;
> +};
> +
> +&mi2s1_ws {
> +	drive-strength = <8>;
> +	bias-disable;
> +	output-high;
> +};
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry

^ permalink raw reply

* Re: [PATCH v2 2/7] dt-bindings: soc: samsung: exynos-pmu: add samsung,pmu-intr-gen phandle
From: Alexey Klimov @ 2026-04-14 14:54 UTC (permalink / raw)
  To: Rob Herring
  Cc: Sam Protsenko, linux-samsung-soc, Krzysztof Kozlowski,
	Peter Griffin, André Draszik, Conor Dooley, Alim Akhtar,
	Tudor Ambarus, Krzysztof Kozlowski, linux-arm-kernel, devicetree,
	linux-kernel
In-Reply-To: <20260413221638.GA3624532-robh@kernel.org>

On Mon Apr 13, 2026 at 11:16 PM BST, Rob Herring wrote:
> On Wed, Apr 01, 2026 at 05:51:55AM +0100, Alexey Klimov wrote:
>> Some Exynos-based SoCs, for instance Exynos850, require access
>> to the pmu interrupt generation register region which is exposed
>> as a syscon. Update the exynos-pmu bindings documentation to
>> reflect this.
>> 
>> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
>> ---
>>  .../devicetree/bindings/soc/samsung/exynos-pmu.yaml    | 18 ++++++++++++++++++
>>  1 file changed, 18 insertions(+)
>> 
>> diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
>> index 76ce7e98c10f..92acdfd5d44e 100644
>> --- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
>> +++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml
>> @@ -110,6 +110,11 @@ properties:
>>      description:
>>        Node for reboot method
>>  
>> +  samsung,pmu-intr-gen-syscon:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description:
>> +      Phandle to PMU interrupt generation interface.
>> +
>>    google,pmu-intr-gen-syscon:
>
> Does this mean the driver is just going to have to look at both 
> properties for the same thing? If so, just use the existing property. We 
> don't need 2. Yeah, 'google' in Samsung SoCs is a bit weird, but that's 
> Samsung's fault for not upstreaming support for their h/w first.

First question - yes, look for both properties. Using the existing
property is even better, I don't mind at all. Thanks for pointing that
out.

Initially, I added more generic samsung,... property because I thought
that device tree style prefers <vendor>,<property-name> semantics where
<vendor> is actual (real) HW vendor of corresponding hw block and it
should also refer to the first/earlier hw vendor in terms of the
timeline.

Using google,<..> is simplier and I don't need need commit that
obsoletes that, so I'll rework the series in that way.

BR,
Alexey


^ permalink raw reply

* Re: [PATCH v1 0/4] Enable audio over HDMI and
From: Dmitry Baryshkov @ 2026-04-14 14:54 UTC (permalink / raw)
  To: Kumar Anurag
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Srinivas Kandagatla, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, linux-arm-msm, devicetree,
	linux-kernel, linux-sound
In-Reply-To: <20260413091937.134469-1-kumar.singh@oss.qualcomm.com>

On Mon, Apr 13, 2026 at 02:19:33AM -0700, Kumar Anurag wrote:
> This series adds the dt and driver changes for enabling 
> audio over HDMI and Displayport. 

Starting from the cover letter subject. On which platform?

> 
> Kumar Anurag (4):
>   arm64: dts: qcom: Enable secondary mi2s
>   arm64: dts: qcom: qcs6490: Enable DP audio
>   ASoC: qcom: q6dsp: Update bit format support for secondary i2s
>   ASoC: qcom: sc8280xp: don't force S16_LE in hw_params fixup
> 
>  arch/arm64/boot/dts/qcom/kodiak.dtsi         |  5 ++
>  arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 59 ++++++++++++++++++++
>  sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c     |  7 ++-
>  sound/soc/qcom/sc8280xp.c                    |  2 -
>  4 files changed, 69 insertions(+), 4 deletions(-)
> 
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry

^ permalink raw reply

* RE: [PATCH v7 5/6] iio: adc: ad4691: add oversampling support
From: Sabau, Radu bogdan @ 2026-04-14 14:25 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner
  Cc: Lars-Peter Clausen, Hennerich, Michael, Sa, Nuno, Andy Shevchenko,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Uwe Kleine-König, Liam Girdwood, Mark Brown, Linus Walleij,
	Bartosz Golaszewski, Philipp Zabel, Jonathan Corbet, Shuah Khan,
	linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org,
	linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org
In-Reply-To: <20260412185821.739e477f@jic23-huawei>



> -----Original Message-----
> From: Jonathan Cameron <jic23@kernel.org>
> Sent: Sunday, April 12, 2026 8:58 PM
> To: David Lechner <dlechner@baylibre.com>
> Cc: Sabau, Radu bogdan <Radu.Sabau@analog.com>; Lars-Peter Clausen
> <lars@metafoo.de>; Hennerich, Michael <Michael.Hennerich@analog.com>;
> Sa, Nuno <Nuno.Sa@analog.com>; Andy Shevchenko <andy@kernel.org>;
> Rob Herring <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>;
> Conor Dooley <conor+dt@kernel.org>; Uwe Kleine-König
> <ukleinek@kernel.org>; Liam Girdwood <lgirdwood@gmail.com>; Mark Brown
> <broonie@kernel.org>; Linus Walleij <linusw@kernel.org>; Bartosz
> Golaszewski <brgl@kernel.org>; Philipp Zabel <p.zabel@pengutronix.de>;
> Jonathan Corbet <corbet@lwn.net>; Shuah Khan
> <skhan@linuxfoundation.org>; linux-iio@vger.kernel.org;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
> pwm@vger.kernel.org; linux-gpio@vger.kernel.org; linux-doc@vger.kernel.org
> Subject: Re: [PATCH v7 5/6] iio: adc: ad4691: add oversampling support
> 
> [External]
> 
> On Fri, 10 Apr 2026 16:15:20 -0500
> David Lechner <dlechner@baylibre.com> wrote:
> 
> > On 4/9/26 10:28 AM, Radu Sabau via B4 Relay wrote:
> > > From: Radu Sabau <radu.sabau@analog.com>
> > >
> > > Add per-channel oversampling ratio (OSR) support for CNV burst mode.
> > > The accumulator depth register (ACC_DEPTH_IN) is programmed with the
> > > selected OSR at buffer enable time and before each single-shot read.
> > >
> > > Supported OSR values: 1, 2, 4, 8, 16, 32.
> > >
> > > Introduce AD4691_MANUAL_CHANNEL() for manual mode channels,
> which do
> > > not expose the oversampling ratio attribute since OSR is not applicable
> > > in that mode. A separate manual_channels array is added to
> > > struct ad4691_channel_info and selected at probe time; offload paths
> > > reuse the same arrays with num_channels capping access before the soft
> > > timestamp entry.
> > >
> > > The reported sampling frequency accounts for the active OSR:
> > > effective_freq = oscillator_freq / osr
> >
> > Technically, the way this is implemented is fine according to IIO ABI
> > rules. Writing any attribute can cause others to change. It does
> > introduce a potential pitfall though. Currently, changing the OSR will
> > change the sampling frequency, so you have to always write
> oversampling_ratio
> > first, then write sampling_frequency to get what you asked for. If you want
> > to change the OSR and keep the same sample rate, you still have to write
> both
> > attributes again.
> >
> > In other drivers, I've implemented it so that the requested sampling
> frequency
> > is stored any you always get the closest sampling frequency available based
> on
> > the oversampling ratio. This way, it doesn't matter which order you write
> > the attributes. In that case, the actual periodic trigger source isn't set up
> > until we actually start sampling.
> >
> Agreed. This is more intuitive. Now generally the userspace should
> be sanity checking the value anyway as limitations may mean the new
> sampling frequency is not particularly close to the original one but
> at least it increases the chances of getting the expected value somewhat!
> 
> So to me this is a nice useability improvement given the code to implement
> it tends not to be too complex.
> 

Hi David, Jonathan,

What I understand from this is that the osr should be taken into account when writing
the sampling frequency as well, right? Here's what I understand:

If the user wants a 125kHz freq with 4 OSR, then when internal osc will be written
to 500kHz before single-shot read, buffer preenable/postenable.
However, if the user wants a 500kHz frequency with 4 OSR, that would mean a 2MHz
Internal osc freq, which is impossible.

More than this, if the OSR is 32 the maximum effective rate would be 31250, so 25kHz
would make it the closes available one. If the user would select 1MHz from the available
list it would be weird I would say. So perhaps a solution for this is to display the avail list
depending on the set OSR value.

Linking the two together is perhaps wrong to begin with from my end, since in this
driver's case, the per-channel sampling frequency is controlled by the internal oscillator
which has static available values. So perhaps sampling frequency should be separate, and
OSR separate as well, which would make everything cleaner.

Indeed, the effective rate is changed by OSR, but perhaps that is something the user
should be aware of, since the sampling frequency is the rate at which the channel samples
(1 sample per period) and OSR is how many times the channel samples upon a final sample
is to be read. The user already has to take this into account when setting the buffer
sampling frequency, so it would make sense to take this into account here too.

Please let me know you thoughts on this,
Radu

^ permalink raw reply

* Re: [PATCH v2 4/6] ASoC: renesas: fsi: refactor clock initialization
From: Bui Duc Phuc @ 2026-04-14 14:25 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: broonie, lgirdwood, robh, krzk+dt, conor+dt, geert+renesas,
	magnus.damm, perex, tiwai, linux-sound, linux-renesas-soc,
	devicetree, linux-kernel
In-Reply-To: <87qzoipdo4.wl-kuninori.morimoto.gx@renesas.com>

Hi Morimoto-san,

Thank you for the review.

> I have mentioned in previous mail to just move fsi_clk_init(), but why do
> you need to move it ? It works without any issue without moving function,
> I guess ?

I moved fsi_clk_init() below the two functions fsi_clk_set_rate_cpg
and fsi_clk_set_rate_external because, inside fsi_clk_init(),
I assign these functions to clock->set_rate. Moving the function was
necessary to avoid compilation errors.

+       if (is_cpg) {
+               xck = 0; ick = 1; div = 1;
+               clock->set_rate = fsi_clk_set_rate_cpg;
+       } else {
+               xck = 1; ick = 1; div = 0;
+               clock->set_rate = fsi_clk_set_rate_external;
+       }

Would you prefer that I use forward declarations instead of changing
the function order?

> Note is that the comment /* clock function */ is not only for fsi_clk_init()
> but for all fsi_clk_xxx() functions. Here is that position.

Understood, I will fix the comment placement accordingly.

> > -     if (fsi_is_clk_master(fsi)) {
> > -             if (fsi->clk_cpg)
> > -                     fsi_clk_init(dai->dev, fsi, 0, 1, 1,
> > -                                  fsi_clk_set_rate_cpg);
> > -             else
> > -                     fsi_clk_init(dai->dev, fsi, 1, 1, 0,
> > -                                  fsi_clk_set_rate_external);
> > -     }
>
> You removes fsi_is_clk_master() check in new fsi_clk_init() ?

At the probe stage, the Master/Slave status has not yet been determined
because it depends on a subsequent set_fmt() call. Therefore, I am not using
the fsi_is_clk_master() function inside the new fsi_clk_init() during
the probe process.

Instead, the new fsi_clk_init() function acquires all resources
(including the mandatory SPU clock) upfront using
devm_clk_get_optional().
The actual fsi_is_clk_master() check remains strictly enforced in
fsi_hw_startup() before enabling any functional clocks.

/* start master clock */
if (fsi_is_clk_master(fsi))
return fsi_clk_enable(dev, fsi);

> Why don't use fsi->clk_cpg ?

You're right, using fsi->clk_cpg is cleaner since it's already
initialized in fsi_port_info_init().
 I will use it in the next version.

> And why you need to call fsi_clk_init() twice ?
The FSI controller has two independent ports (Port A and Port B).
Each port requires its own clock resource initialization and configuration.

Best regards,
Phuc

^ permalink raw reply

* Re: [PATCH v1 3/4] ASoC: qcom: q6dsp: Update bit format support for secondary i2s
From: Srinivas Kandagatla @ 2026-04-14 14:21 UTC (permalink / raw)
  To: Kumar Anurag, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Srinivas Kandagatla,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai
  Cc: linux-arm-msm, devicetree, linux-kernel, linux-sound
In-Reply-To: <20260413091937.134469-4-kumar.singh@oss.qualcomm.com>



On 4/13/26 9:19 AM, Kumar Anurag wrote:
> Add 32bit for playback and capture over secondary mi2s.
> 
> Signed-off-by: Kumar Anurag <kumar.singh@oss.qualcomm.com>
> ---

Pretty much simillar changes a are already submitted by "	[PATCH v1 0/2]
ASoC: qcom: q6dsp-lpass-ports: Add support for extended sampling rates
and PCM formats"  https://lkml.org/lkml/2025/11/18/673


--srini


>  sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
> index 4eed54b071a5..0664f18d7a44 100644
> --- a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
> +++ b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
> @@ -380,7 +380,9 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = {
>  			.stream_name = "Secondary MI2S Playback",
>  			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
>  				 SNDRV_PCM_RATE_16000,
> -			.formats = SNDRV_PCM_FMTBIT_S16_LE,
> +			.formats = SNDRV_PCM_FMTBIT_S16_LE |
> +				   SNDRV_PCM_FMTBIT_S24_LE |
> +				   SNDRV_PCM_FMTBIT_S32_LE,
>  			.channels_min = 1,
>  			.channels_max = 8,
>  			.rate_min =     8000,
> @@ -394,7 +396,8 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = {
>  			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
>  				 SNDRV_PCM_RATE_16000,
>  			.formats = SNDRV_PCM_FMTBIT_S16_LE |
> -				   SNDRV_PCM_FMTBIT_S24_LE,
> +				   SNDRV_PCM_FMTBIT_S24_LE |
> +				   SNDRV_PCM_FMTBIT_S32_LE,
>  			.channels_min = 1,
>  			.channels_max = 8,
>  			.rate_min =     8000,


^ 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