[PATCH 5/7] media: v4l2-isp: Add v4l2_isp_params_for_each_block()

Daniel Scally dan.scally at ideasonboard.com
Wed Nov 4 04:28:20 PST 2026


ISP drivers using the V4L2 extensible parameters need to iterate
through parameter blocks in a buffer. Currently they all open code
this operation. Add a macro that can be used instead.

Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
---
 drivers/media/platform/amlogic/c3/isp/c3-isp-params.c  |  9 +++------
 drivers/media/platform/arm/mali-c55/mali-c55-params.c  | 11 +++--------
 drivers/media/platform/dreamchip/rppx1/rpp_params.c    | 10 ++++------
 drivers/media/platform/rockchip/rkisp1/rkisp1-params.c |  8 +++-----
 include/media/v4l2-isp.h                               | 15 +++++++++++++++
 5 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c b/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c
index f0b330520f97ad3bb701de3aed35670158508829..8ef8df7c033219eb11e7e9d8838c37a817153eb6 100644
--- a/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c
+++ b/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c
@@ -594,23 +594,20 @@ static_assert(ARRAY_SIZE(c3_isp_params_handlers) ==
 static void c3_isp_params_cfg_blocks(struct c3_isp_params *params)
 {
 	struct c3_isp_params_cfg *config = params->buff->cfg;
-	size_t block_offset = 0;
+	struct v4l2_isp_params_block_header *header;
 
 	if (WARN_ON(!config))
 		return;
 
 	/* Walk the list of parameter blocks and process them */
-	while (block_offset < config->data_size) {
+	v4l2_isp_params_for_each_block(config, header) {
 		const union c3_isp_params_block *block;
 		c3_isp_block_handler block_handler;
 
-		block = (const union c3_isp_params_block *)
-			 &config->data[block_offset];
+		block = (const union c3_isp_params_block *)header;
 
 		block_handler = c3_isp_params_handlers[block->header.type];
 		block_handler(params->isp, block);
-
-		block_offset += block->header.size;
 	}
 }
 
diff --git a/drivers/media/platform/arm/mali-c55/mali-c55-params.c b/drivers/media/platform/arm/mali-c55/mali-c55-params.c
index 7b9d2650ce8730ccc05eee0c9dc33a88d022acf1..809a3587a5eee4d9817e720ae24e37f5f54397c0 100644
--- a/drivers/media/platform/arm/mali-c55/mali-c55-params.c
+++ b/drivers/media/platform/arm/mali-c55/mali-c55-params.c
@@ -817,10 +817,9 @@ static const struct vb2_ops mali_c55_params_vb2_ops = {
 void mali_c55_params_write_config(struct mali_c55 *mali_c55)
 {
 	struct mali_c55_params *params = &mali_c55->params;
+	struct v4l2_isp_params_block_header *header;
 	struct v4l2_isp_params_buffer *config;
 	struct mali_c55_params_buf *buf;
-	size_t block_offset = 0;
-	size_t max_offset;
 
 	spin_lock(&params->buffers.lock);
 
@@ -836,24 +835,20 @@ void mali_c55_params_write_config(struct mali_c55 *mali_c55)
 	buf->vb.sequence = mali_c55->isp.frame_sequence;
 	config = buf->config;
 
-	max_offset = config->data_size;
-
 	/*
 	 * Walk the list of parameter blocks and process them. No validation is
 	 * done here, as the contents of the config buffer are already checked
 	 * when the buffer is queued.
 	 */
-	while (max_offset && block_offset < max_offset) {
+	v4l2_isp_params_for_each_block(config, header) {
 		union mali_c55_params_block block;
 		mali_c55_params_handler handler;
 
-		block.data = &config->data[block_offset];
+		block.header = header;
 
 		/* We checked the array index already in .buf_queue() */
 		handler = mali_c55_params_handlers[block.header->type];
 		handler(mali_c55, block);
-
-		block_offset += block.header->size;
 	}
 
 	vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/dreamchip/rppx1/rpp_params.c b/drivers/media/platform/dreamchip/rppx1/rpp_params.c
index aff3f3a997b4134b753fd1e1faf2058216f4b939..b8468d5c0fe1c783216567fab3366024fd9fcc63 100644
--- a/drivers/media/platform/dreamchip/rppx1/rpp_params.c
+++ b/drivers/media/platform/dreamchip/rppx1/rpp_params.c
@@ -53,8 +53,8 @@ int rppx1_params(struct rppx1 *rpp, struct vb2_buffer *vb,
 		 rppx1_reg_write write, void *priv)
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct v4l2_isp_params_block_header *header;
 	struct v4l2_isp_buffer *cfg;
-	size_t block_offset;
 	int ret;
 
 	ret = v4l2_isp_params_validate_buffer_size(&rpp->isp, vb);
@@ -68,14 +68,12 @@ int rppx1_params(struct rppx1 *rpp, struct vb2_buffer *vb,
 		return ret;
 
 	/* Walk the list of parameter blocks and process them. */
-	block_offset = 0;
-	while (block_offset < cfg->data_size) {
-		const union rppx1_params_block *block =
-			(const union rppx1_params_block *)&cfg->data[block_offset];
+	v4l2_isp_params_for_each_block(cfg, header) {
+		const union rppx1_params_block *block;
 		struct rpp_module *module;
 		int ret;
 
-		block_offset += block->header.size;
+		block = (const union rppx1_params_block *)header;
 
 		switch (block->header.type) {
 		case RPPX1_PARAMS_BLOCK_TYPE_BLS_PRE1:
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
index 8974c520d1879f3f0f642819a41984f6ac3ee01d..178da1f648869b7b963f634f29f5653cfb16dd77 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
@@ -2291,19 +2291,17 @@ static void rkisp1_ext_params_config(struct rkisp1_params *params,
 				     struct rkisp1_ext_params_cfg *cfg,
 				     u32 block_group_mask)
 {
-	size_t block_offset = 0;
+	struct v4l2_isp_params_block_header *header;
 
 	if (WARN_ON(!cfg))
 		return;
 
 	/* Walk the list of parameter blocks and process them. */
-	while (block_offset < cfg->data_size) {
+	v4l2_isp_params_for_each_block(cfg, header) {
 		const struct rkisp1_ext_params_handler *block_handler;
 		const union rkisp1_ext_params_config *block;
 
-		block = (const union rkisp1_ext_params_config *)
-			&cfg->data[block_offset];
-		block_offset += block->header.size;
+		block = (const union rkisp1_ext_params_config *)header;
 
 		/*
 		 * Make sure the block is supported by the platform and in the
diff --git a/include/media/v4l2-isp.h b/include/media/v4l2-isp.h
index b758d9b0e7f5c29cd8c4197f4a4a86cf3e5334fc..5f13651b53d3c06fc676b32826daa68ad77b5cf6 100644
--- a/include/media/v4l2-isp.h
+++ b/include/media/v4l2-isp.h
@@ -31,6 +31,21 @@ struct vb2_buffer;
 #define v4l2_isp_buffer_size(max_size)			\
 	(offsetof(struct v4l2_isp_buffer, data) + (max_size))
 
+/**
+ * v4l2_isp_params_for_each_block - Iterate through parameter blocks in a buffer
+ * @buffer: Pointer to the &struct v4l2_isp_buffer to iterate over
+ * @header: Pointer to the &struct v4l2_isp_block_header to store each block in
+ *
+ * Users of the V4L2 extensible parameters will need to iterate over the blocks
+ * within a buffer. Rather than allow each driver to do that in a bespoke manner
+ * this helper should be used to ensure commonality.
+ */
+#define v4l2_isp_params_for_each_block(buffer, header)			\
+	for (size_t offset = 0;						\
+	     offset < (buffer)->data_size &&				\
+	     (header = (void *)&(buffer)->data[offset], true);		\
+	     offset += header->size)					\
+
 /**
  * struct v4l2_isp_params_block_type_info - V4L2 ISP params per-block-type info
  * @size: the block type expected size

-- 
2.43.0




More information about the Linux-rockchip mailing list