* [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling
@ 2026-03-13 11:13 Jacopo Mondi
2026-03-13 11:13 ` [PATCH 1/7] media: rzv2h-ivc: Revise default VBLANK formula Jacopo Mondi
` (7 more replies)
0 siblings, 8 replies; 19+ messages in thread
From: Jacopo Mondi @ 2026-03-13 11:13 UTC (permalink / raw)
To: Daniel Scally, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Daniel Scally, stable, Barnabás Pőcze
We have been exercizing the RZ/V2H(P) IVC block quite intensly these
last two months.
Here it is a collection of fixes and improvements to the driver.
The first 4 patches in the series address a few registers writes that
do not respect the documentation.
The 5th and 6th patches fixes concurrent access to the list of queued
buffers and fix a WARN() visible under heavy system load conditions
caused by concurrent buffer transfers.
The last patch is actually up for discussion. It is my opinion that the
trouble of setting up a workqueue item is not justified by the
relatively small amount of work that has to be carried out in interrupt
context. In any case, there shouldn't be any functional change
introduced by this patch.
Patch #7 makes patch #6 reduntant: if we use direct function
calls, then the issue of concurrently running workqueue items cannot
happen. However, I actually think patch #6 has value regardless as it
makes the code more robust.
Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
---
Barnabás Pőcze (4):
media: rzv2h-ivc: Fix AXIRX_VBLANK register write
media: rzv2h-ivc: Write AXIRX_PIXFMT once
media: rzv2h-ivc: Fix FM_STOP register write
media: rzv2h-ivc: Fix concurrent buffer list access
Daniel Scally (1):
media: rzv2h-ivc: Revise default VBLANK formula
Jacopo Mondi (2):
media: rzv2h-ivc: Avoid double job scheduling
media: rzv2h-ivc: Replace workqueue with direct function call
.../platform/renesas/rzv2h-ivc/rzv2h-ivc-dev.c | 2 +-
.../platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 63 +++++++++++-----------
.../media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 13 ++---
3 files changed, 39 insertions(+), 39 deletions(-)
---
base-commit: f6390408a846aacc2171c17d88b062e202d84e86
change-id: 20260311-mali-ivc-fixes-v7-0-43fc33b87793
Best regards,
--
Jacopo Mondi <jacopo.mondi@ideasonboard.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/7] media: rzv2h-ivc: Revise default VBLANK formula
2026-03-13 11:13 [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Jacopo Mondi
@ 2026-03-13 11:13 ` Jacopo Mondi
2026-03-13 11:13 ` [PATCH 2/7] media: rzv2h-ivc: Fix AXIRX_VBLANK register write Jacopo Mondi
` (6 subsequent siblings)
7 siblings, 0 replies; 19+ messages in thread
From: Jacopo Mondi @ 2026-03-13 11:13 UTC (permalink / raw)
To: Daniel Scally, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Daniel Scally, stable
From: Daniel Scally <dan.scally+renesas@ideasonboard.com>
The vertical blanking settings for the IVC block are dependent on
settings in the ISP. This was originally set to calculate as the
worst-case possible value, but it seems that this can cause the IVC
block to hang. Instead calculate the vblank to match the default
settings (which are currently all the driver sets anyway).
Cc: stable@vger.kernel.org
Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
Signed-off-by: Daniel Scally <dan.scally+renesas@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
---
drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
index 799453250b85..1e016b17dcee 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
@@ -24,7 +24,7 @@
#include <media/videobuf2-dma-contig.h>
#define RZV2H_IVC_FIXED_HBLANK 0x20
-#define RZV2H_IVC_MIN_VBLANK(hts) max(0x1b, 15 + (120501 / (hts)))
+#define RZV2H_IVC_MIN_VBLANK(hts) max(0x1b, 70100 / (hts))
struct rzv2h_ivc_buf {
struct vb2_v4l2_buffer vb;
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 2/7] media: rzv2h-ivc: Fix AXIRX_VBLANK register write
2026-03-13 11:13 [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Jacopo Mondi
2026-03-13 11:13 ` [PATCH 1/7] media: rzv2h-ivc: Revise default VBLANK formula Jacopo Mondi
@ 2026-03-13 11:13 ` Jacopo Mondi
2026-03-13 16:15 ` Dan Scally
2026-03-18 8:24 ` Barnabás Pőcze
2026-03-13 11:13 ` [PATCH 3/7] media: rzv2h-ivc: Write AXIRX_PIXFMT once Jacopo Mondi
` (5 subsequent siblings)
7 siblings, 2 replies; 19+ messages in thread
From: Jacopo Mondi @ 2026-03-13 11:13 UTC (permalink / raw)
To: Daniel Scally, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Barnabás Pőcze, stable
From: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
According to the documentation there are writable reserved bits in the
register and those should not be set to 0. So use `rzv2h_ivc_update_bits()`
with a proper bitmask.
Cc: stable@vger.kernel.org
Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
---
drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 7 +++++--
drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 2 +-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
index 1e016b17dcee..bfe5b0c7045e 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
@@ -7,6 +7,7 @@
#include "rzv2h-ivc.h"
+#include <linux/bitfield.h>
#include <linux/cleanup.h>
#include <linux/iopoll.h>
#include <linux/lockdep.h>
@@ -235,8 +236,10 @@ static void rzv2h_ivc_format_configure(struct rzv2h_ivc *ivc)
hts = pix->width + RZV2H_IVC_FIXED_HBLANK;
vblank = RZV2H_IVC_MIN_VBLANK(hts);
- rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_BLANK,
- RZV2H_IVC_VBLANK(vblank));
+ rzv2h_ivc_update_bits(ivc, RZV2H_IVC_REG_AXIRX_BLANK,
+ RZV2H_IVC_AXIRX_BLANK_FIELD_VBLANK,
+ FIELD_PREP(RZV2H_IVC_AXIRX_BLANK_FIELD_VBLANK,
+ vblank));
}
static void rzv2h_ivc_return_buffers(struct rzv2h_ivc *ivc,
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
index 3bcaab990b0f..4ef44c8b4656 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
@@ -34,7 +34,7 @@
#define RZV2H_IVC_REG_AXIRX_HSIZE 0x0020
#define RZV2H_IVC_REG_AXIRX_VSIZE 0x0024
#define RZV2H_IVC_REG_AXIRX_BLANK 0x0028
-#define RZV2H_IVC_VBLANK(x) ((x) << 16)
+#define RZV2H_IVC_AXIRX_BLANK_FIELD_VBLANK GENMASK(25, 16)
#define RZV2H_IVC_REG_AXIRX_STRD 0x0030
#define RZV2H_IVC_REG_AXIRX_ISSU 0x0040
#define RZV2H_IVC_REG_AXIRX_ERACT 0x0048
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 3/7] media: rzv2h-ivc: Write AXIRX_PIXFMT once
2026-03-13 11:13 [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Jacopo Mondi
2026-03-13 11:13 ` [PATCH 1/7] media: rzv2h-ivc: Revise default VBLANK formula Jacopo Mondi
2026-03-13 11:13 ` [PATCH 2/7] media: rzv2h-ivc: Fix AXIRX_VBLANK register write Jacopo Mondi
@ 2026-03-13 11:13 ` Jacopo Mondi
2026-03-13 16:07 ` Dan Scally
2026-03-13 11:14 ` [PATCH 4/7] media: rzv2h-ivc: Fix FM_STOP register write Jacopo Mondi
` (4 subsequent siblings)
7 siblings, 1 reply; 19+ messages in thread
From: Jacopo Mondi @ 2026-03-13 11:13 UTC (permalink / raw)
To: Daniel Scally, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Barnabás Pőcze, stable
From: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
The documentation prescribes that invalid formats should not be set,
so do a single write to ensure that both the CLFMT and DTYPE fields
are set to valid values.
Cc: stable@vger.kernel.org
Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
---
drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 8 ++++----
drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 7 ++++---
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
index bfe5b0c7045e..d894a880c33f 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
@@ -215,10 +215,10 @@ static void rzv2h_ivc_format_configure(struct rzv2h_ivc *ivc)
/* Currently only CRU packed pixel formats are supported */
rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_PXFMT,
- RZV2H_IVC_INPUT_FMT_CRU_PACKED);
-
- rzv2h_ivc_update_bits(ivc, RZV2H_IVC_REG_AXIRX_PXFMT,
- RZV2H_IVC_PXFMT_DTYPE, fmt->dtype);
+ FIELD_PREP(RZV2H_IVC_AXIRX_PXFMT_FIELD_DTYPE,
+ fmt->dtype) |
+ FIELD_PREP(RZV2H_IVC_AXIRX_PXFMT_FIELD_CLFMT,
+ RZV2H_IVC_CLFMT_CRU_PACKED));
rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_HSIZE, pix->width);
rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_VSIZE, pix->height);
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
index 4ef44c8b4656..54c70de31c1e 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
@@ -24,9 +24,10 @@
#define RZV2H_IVC_ONE_EXPOSURE 0x00
#define RZV2H_IVC_TWO_EXPOSURE 0x01
#define RZV2H_IVC_REG_AXIRX_PXFMT 0x0004
-#define RZV2H_IVC_INPUT_FMT_MIPI (0 << 16)
-#define RZV2H_IVC_INPUT_FMT_CRU_PACKED BIT(16)
-#define RZV2H_IVC_PXFMT_DTYPE GENMASK(7, 0)
+#define RZV2H_IVC_AXIRX_PXFMT_FIELD_CLFMT GENMASK(17, 16)
+#define RZV2H_IVC_CLFMT_MIPI 0
+#define RZV2H_IVC_CLFMT_CRU_PACKED 1
+#define RZV2H_IVC_AXIRX_PXFMT_FIELD_DTYPE GENMASK(7, 0)
#define RZV2H_IVC_REG_AXIRX_SADDL_P0 0x0010
#define RZV2H_IVC_REG_AXIRX_SADDH_P0 0x0014
#define RZV2H_IVC_REG_AXIRX_SADDL_P1 0x0018
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 4/7] media: rzv2h-ivc: Fix FM_STOP register write
2026-03-13 11:13 [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Jacopo Mondi
` (2 preceding siblings ...)
2026-03-13 11:13 ` [PATCH 3/7] media: rzv2h-ivc: Write AXIRX_PIXFMT once Jacopo Mondi
@ 2026-03-13 11:14 ` Jacopo Mondi
2026-03-13 20:39 ` Dan Scally
2026-03-13 11:14 ` [PATCH 5/7] media: rzv2h-ivc: Fix concurrent buffer list access Jacopo Mondi
` (3 subsequent siblings)
7 siblings, 1 reply; 19+ messages in thread
From: Jacopo Mondi @ 2026-03-13 11:14 UTC (permalink / raw)
To: Daniel Scally, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Barnabás Pőcze, stable
From: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
Bit 20 should be written in this register to stop frame processing.
So fix that, as well as the poll condition.
Cc: stable@vger.kernel.org
Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
---
drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 5 +++--
drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 1 +
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
index d894a880c33f..9b75e4b10e99 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
@@ -297,9 +297,10 @@ static void rzv2h_ivc_stop_streaming(struct vb2_queue *q)
struct rzv2h_ivc *ivc = vb2_get_drv_priv(q);
u32 val = 0;
- rzv2h_ivc_write(ivc, RZV2H_IVC_REG_FM_STOP, 0x1);
+ rzv2h_ivc_write(ivc, RZV2H_IVC_REG_FM_STOP, RZV2H_IVC_REG_FM_STOP_FSTOP);
readl_poll_timeout(ivc->base + RZV2H_IVC_REG_FM_STOP,
- val, !val, 10 * USEC_PER_MSEC, 250 * USEC_PER_MSEC);
+ val, !(val & RZV2H_IVC_REG_FM_STOP_FSTOP),
+ 10 * USEC_PER_MSEC, 250 * USEC_PER_MSEC);
rzv2h_ivc_return_buffers(ivc, VB2_BUF_STATE_ERROR);
video_device_pipeline_stop(&ivc->vdev.dev);
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
index 54c70de31c1e..049f223200e3 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
@@ -46,6 +46,7 @@
#define RZV2H_IVC_REG_FM_MCON 0x0104
#define RZV2H_IVC_REG_FM_FRCON 0x0108
#define RZV2H_IVC_REG_FM_STOP 0x010c
+#define RZV2H_IVC_REG_FM_STOP_FSTOP BIT(20)
#define RZV2H_IVC_REG_FM_INT_EN 0x0120
#define RZV2H_IVC_VVAL_IFPE BIT(0)
#define RZV2H_IVC_REG_FM_INT_STA 0x0124
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5/7] media: rzv2h-ivc: Fix concurrent buffer list access
2026-03-13 11:13 [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Jacopo Mondi
` (3 preceding siblings ...)
2026-03-13 11:14 ` [PATCH 4/7] media: rzv2h-ivc: Fix FM_STOP register write Jacopo Mondi
@ 2026-03-13 11:14 ` Jacopo Mondi
2026-03-13 22:11 ` Dan Scally
2026-03-13 11:14 ` [PATCH 6/7] media: rzv2h-ivc: Avoid double job scheduling Jacopo Mondi
` (2 subsequent siblings)
7 siblings, 1 reply; 19+ messages in thread
From: Jacopo Mondi @ 2026-03-13 11:14 UTC (permalink / raw)
To: Daniel Scally, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Barnabás Pőcze, stable
From: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
The list of buffers (`rzv2h_ivc::buffers.queue`) is protected by a
spinlock (`rzv2h_ivc::buffers.lock`). However, in
`rzv2h_ivc_transfer_buffer()`, which runs in a separate workqueue, the
`list_del()` call is executed without holding the spinlock, which makes
it possible for the list to be concurrently modified
Fix that by removing a buffer from the list in the lock protected section.
Cc: stable@vger.kernel.org
Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
[assign ivc->buffers.curr in critical section as reported by Barnabas]
Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
---
drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
index 9b75e4b10e99..a22aee0fe1cf 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
@@ -153,14 +153,13 @@ static void rzv2h_ivc_transfer_buffer(struct work_struct *work)
scoped_guard(spinlock_irqsave, &ivc->buffers.lock) {
buf = list_first_entry_or_null(&ivc->buffers.queue,
struct rzv2h_ivc_buf, queue);
- }
-
- if (!buf)
- return;
+ if (!buf)
+ return;
- list_del(&buf->queue);
+ list_del(&buf->queue);
+ ivc->buffers.curr = buf;
+ }
- ivc->buffers.curr = buf;
buf->addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_SADDL_P0, buf->addr);
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 6/7] media: rzv2h-ivc: Avoid double job scheduling
2026-03-13 11:13 [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Jacopo Mondi
` (4 preceding siblings ...)
2026-03-13 11:14 ` [PATCH 5/7] media: rzv2h-ivc: Fix concurrent buffer list access Jacopo Mondi
@ 2026-03-13 11:14 ` Jacopo Mondi
2026-03-18 8:00 ` Dan Scally
2026-03-18 8:18 ` Barnabás Pőcze
2026-03-13 11:14 ` [PATCH 7/7] media: rzv2h-ivc: Replace workqueue with direct function call Jacopo Mondi
2026-03-20 17:16 ` [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Lad, Prabhakar
7 siblings, 2 replies; 19+ messages in thread
From: Jacopo Mondi @ 2026-03-13 11:14 UTC (permalink / raw)
To: Daniel Scally, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
stable
From: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
The scheduling of a new buffer transfer in the IVC driver is triggered
by two occurrences of the "frame completed" interrupt.
The first interrupt occurrence identifies when all image data have been
transferred to the ISP, the second occurrence identifies when the
post-transfer VBLANK has completed and a new buffer can be transferred.
Under heavy system load conditions the actual execution of the workqueue
item might be delayed and two items might happen to run concurrently,
leading to a new frame transfer being triggered while the previous one
has not yet finished.
This error condition is only visible because the driver maintains a
status variable that counts the number of interrupts since the last
transfer, and warns in case an IRQ happens before the counter has been
reset.
To ensure sequential execution of the worqueue items and avoid a double
buffer transfer to run concurrently, protect the whole function body
with the spinlock that so far was solely used to reset the counter and
inspect the interrupt counter variable at the beginning of the buffer
transfer function.
and return
As soon as the ongoing transfer completes, the workqueue item will be
re-scheduled and will consume the pending buffer.
Cc: stable@vger.kernel.org
Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
---
drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
index a22aee0fe1cf..3580a57738a6 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
@@ -149,6 +149,11 @@ static void rzv2h_ivc_transfer_buffer(struct work_struct *work)
buffers.work);
struct rzv2h_ivc_buf *buf;
+ guard(spinlock_irqsave)(&ivc->spinlock);
+
+ if (ivc->vvalid_ifp)
+ return;
+
/* Setup buffers */
scoped_guard(spinlock_irqsave, &ivc->buffers.lock) {
buf = list_first_entry_or_null(&ivc->buffers.queue,
@@ -163,9 +168,7 @@ static void rzv2h_ivc_transfer_buffer(struct work_struct *work)
buf->addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_SADDL_P0, buf->addr);
- scoped_guard(spinlock_irqsave, &ivc->spinlock) {
- ivc->vvalid_ifp = 2;
- }
+ ivc->vvalid_ifp = 2;
rzv2h_ivc_write(ivc, RZV2H_IVC_REG_FM_FRCON, 0x1);
}
@@ -200,7 +203,7 @@ static void rzv2h_ivc_buf_queue(struct vb2_buffer *vb)
}
scoped_guard(spinlock_irq, &ivc->spinlock) {
- if (vb2_is_streaming(vb->vb2_queue) && !ivc->vvalid_ifp)
+ if (vb2_is_streaming(vb->vb2_queue))
queue_work(ivc->buffers.async_wq, &ivc->buffers.work);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 7/7] media: rzv2h-ivc: Replace workqueue with direct function call
2026-03-13 11:13 [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Jacopo Mondi
` (5 preceding siblings ...)
2026-03-13 11:14 ` [PATCH 6/7] media: rzv2h-ivc: Avoid double job scheduling Jacopo Mondi
@ 2026-03-13 11:14 ` Jacopo Mondi
2026-03-13 22:42 ` Dan Scally
2026-03-20 17:16 ` [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Lad, Prabhakar
7 siblings, 1 reply; 19+ messages in thread
From: Jacopo Mondi @ 2026-03-13 11:14 UTC (permalink / raw)
To: Daniel Scally, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi
From: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
Scheduling of work items with an async workqueue opens the door to
potential races between multiple instances of a work item.
While the frame transfer function is now protected agains races, using a
workqueue doesn't provide much benefit considering the limited cost of
creating a job transfer.
Replace usage of the work queue with direct function calls.
Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
---
.../platform/renesas/rzv2h-ivc/rzv2h-ivc-dev.c | 2 +-
.../platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 21 +++++++--------------
.../media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 3 +--
3 files changed, 9 insertions(+), 17 deletions(-)
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-dev.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-dev.c
index e9857eb5b51a..355842abb24b 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-dev.c
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-dev.c
@@ -119,7 +119,7 @@ static irqreturn_t rzv2h_ivc_isr(int irq, void *context)
* The second interrupt indicates that the post-frame transfer VBLANK
* has completed, we can now schedule a new frame transfer, if any.
*/
- queue_work(ivc->buffers.async_wq, &ivc->buffers.work);
+ rzv2h_ivc_transfer_buffer(ivc);
return IRQ_HANDLED;
}
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
index 3580a57738a6..b167f1bab7ef 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
@@ -143,13 +143,11 @@ void rzv2h_ivc_buffer_done(struct rzv2h_ivc *ivc)
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
-static void rzv2h_ivc_transfer_buffer(struct work_struct *work)
+void rzv2h_ivc_transfer_buffer(struct rzv2h_ivc *ivc)
{
- struct rzv2h_ivc *ivc = container_of(work, struct rzv2h_ivc,
- buffers.work);
struct rzv2h_ivc_buf *buf;
- guard(spinlock_irqsave)(&ivc->spinlock);
+ lockdep_assert_held(&ivc->spinlock);
if (ivc->vvalid_ifp)
return;
@@ -204,7 +202,7 @@ static void rzv2h_ivc_buf_queue(struct vb2_buffer *vb)
scoped_guard(spinlock_irq, &ivc->spinlock) {
if (vb2_is_streaming(vb->vb2_queue))
- queue_work(ivc->buffers.async_wq, &ivc->buffers.work);
+ rzv2h_ivc_transfer_buffer(ivc);
}
}
@@ -282,7 +280,9 @@ static int rzv2h_ivc_start_streaming(struct vb2_queue *q, unsigned int count)
rzv2h_ivc_format_configure(ivc);
- queue_work(ivc->buffers.async_wq, &ivc->buffers.work);
+ scoped_guard(spinlock_irq, &ivc->spinlock) {
+ rzv2h_ivc_transfer_buffer(ivc);
+ }
return 0;
@@ -449,11 +449,6 @@ int rzv2h_ivc_init_vdev(struct rzv2h_ivc *ivc, struct v4l2_device *v4l2_dev)
spin_lock_init(&ivc->buffers.lock);
INIT_LIST_HEAD(&ivc->buffers.queue);
- INIT_WORK(&ivc->buffers.work, rzv2h_ivc_transfer_buffer);
-
- ivc->buffers.async_wq = alloc_workqueue("rzv2h-ivc", 0, 0);
- if (!ivc->buffers.async_wq)
- return -EINVAL;
/* Initialise vb2 queue */
vb2q = &ivc->vdev.vb2q;
@@ -471,7 +466,7 @@ int rzv2h_ivc_init_vdev(struct rzv2h_ivc *ivc, struct v4l2_device *v4l2_dev)
ret = vb2_queue_init(vb2q);
if (ret) {
dev_err(ivc->dev, "vb2 queue init failed\n");
- goto err_destroy_workqueue;
+ return ret;
}
/* Initialise Video Device */
@@ -520,8 +515,6 @@ int rzv2h_ivc_init_vdev(struct rzv2h_ivc *ivc, struct v4l2_device *v4l2_dev)
media_entity_cleanup(&vdev->entity);
err_release_vb2q:
vb2_queue_release(vb2q);
-err_destroy_workqueue:
- destroy_workqueue(ivc->buffers.async_wq);
return ret;
}
diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
index 049f223200e3..6f644ba796a9 100644
--- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
+++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
@@ -104,8 +104,6 @@ struct rzv2h_ivc {
struct {
/* Spinlock to guard buffer queue */
spinlock_t lock;
- struct workqueue_struct *async_wq;
- struct work_struct work;
struct list_head queue;
struct rzv2h_ivc_buf *curr;
unsigned int sequence;
@@ -130,3 +128,4 @@ void rzv2h_ivc_deinit_subdevice(struct rzv2h_ivc *ivc);
void rzv2h_ivc_write(struct rzv2h_ivc *ivc, u32 addr, u32 val);
void rzv2h_ivc_update_bits(struct rzv2h_ivc *ivc, unsigned int addr,
u32 mask, u32 val);
+void rzv2h_ivc_transfer_buffer(struct rzv2h_ivc *ivc);
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 3/7] media: rzv2h-ivc: Write AXIRX_PIXFMT once
2026-03-13 11:13 ` [PATCH 3/7] media: rzv2h-ivc: Write AXIRX_PIXFMT once Jacopo Mondi
@ 2026-03-13 16:07 ` Dan Scally
2026-03-13 16:12 ` Jacopo Mondi
0 siblings, 1 reply; 19+ messages in thread
From: Dan Scally @ 2026-03-13 16:07 UTC (permalink / raw)
To: Jacopo Mondi, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Barnabás Pőcze, stable
Hi Jacopo (and Barnabás)
On 13/03/2026 11:13, Jacopo Mondi wrote:
> From: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
>
> The documentation prescribes that invalid formats should not be set,
> so do a single write to ensure that both the CLFMT and DTYPE fields
> are set to valid values.
>
> Cc: stable@vger.kernel.org
> Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
> Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 8 ++++----
> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 7 ++++---
> 2 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> index bfe5b0c7045e..d894a880c33f 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> @@ -215,10 +215,10 @@ static void rzv2h_ivc_format_configure(struct rzv2h_ivc *ivc)
>
> /* Currently only CRU packed pixel formats are supported */
> rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_PXFMT,
> - RZV2H_IVC_INPUT_FMT_CRU_PACKED);
> -
> - rzv2h_ivc_update_bits(ivc, RZV2H_IVC_REG_AXIRX_PXFMT,
> - RZV2H_IVC_PXFMT_DTYPE, fmt->dtype);
> + FIELD_PREP(RZV2H_IVC_AXIRX_PXFMT_FIELD_DTYPE,
> + fmt->dtype) |
> + FIELD_PREP(RZV2H_IVC_AXIRX_PXFMT_FIELD_CLFMT,
> + RZV2H_IVC_CLFMT_CRU_PACKED));
TIL of FIELD_PREP(), I like that! Maybe #include <linux/bitfield.h> though?
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
>
> rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_HSIZE, pix->width);
> rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_VSIZE, pix->height);
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> index 4ef44c8b4656..54c70de31c1e 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> @@ -24,9 +24,10 @@
> #define RZV2H_IVC_ONE_EXPOSURE 0x00
> #define RZV2H_IVC_TWO_EXPOSURE 0x01
> #define RZV2H_IVC_REG_AXIRX_PXFMT 0x0004
> -#define RZV2H_IVC_INPUT_FMT_MIPI (0 << 16)
> -#define RZV2H_IVC_INPUT_FMT_CRU_PACKED BIT(16)
> -#define RZV2H_IVC_PXFMT_DTYPE GENMASK(7, 0)
> +#define RZV2H_IVC_AXIRX_PXFMT_FIELD_CLFMT GENMASK(17, 16)
> +#define RZV2H_IVC_CLFMT_MIPI 0
> +#define RZV2H_IVC_CLFMT_CRU_PACKED 1
> +#define RZV2H_IVC_AXIRX_PXFMT_FIELD_DTYPE GENMASK(7, 0)
> #define RZV2H_IVC_REG_AXIRX_SADDL_P0 0x0010
> #define RZV2H_IVC_REG_AXIRX_SADDH_P0 0x0014
> #define RZV2H_IVC_REG_AXIRX_SADDL_P1 0x0018
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/7] media: rzv2h-ivc: Write AXIRX_PIXFMT once
2026-03-13 16:07 ` Dan Scally
@ 2026-03-13 16:12 ` Jacopo Mondi
2026-03-13 16:14 ` Dan Scally
0 siblings, 1 reply; 19+ messages in thread
From: Jacopo Mondi @ 2026-03-13 16:12 UTC (permalink / raw)
To: Dan Scally
Cc: Jacopo Mondi, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil, linux-media, linux-renesas-soc, linux-kernel,
Jacopo Mondi, Barnabás Pőcze, stable
Hi Dan
On Fri, Mar 13, 2026 at 04:07:47PM +0000, Dan Scally wrote:
> Hi Jacopo (and Barnabás)
>
> On 13/03/2026 11:13, Jacopo Mondi wrote:
> > From: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
> >
> > The documentation prescribes that invalid formats should not be set,
> > so do a single write to ensure that both the CLFMT and DTYPE fields
> > are set to valid values.
> >
> > Cc: stable@vger.kernel.org
> > Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
> > Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
> > Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> > ---
> > drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 8 ++++----
> > drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 7 ++++---
> > 2 files changed, 8 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> > index bfe5b0c7045e..d894a880c33f 100644
> > --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> > +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> > @@ -215,10 +215,10 @@ static void rzv2h_ivc_format_configure(struct rzv2h_ivc *ivc)
> > /* Currently only CRU packed pixel formats are supported */
> > rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_PXFMT,
> > - RZV2H_IVC_INPUT_FMT_CRU_PACKED);
> > -
> > - rzv2h_ivc_update_bits(ivc, RZV2H_IVC_REG_AXIRX_PXFMT,
> > - RZV2H_IVC_PXFMT_DTYPE, fmt->dtype);
> > + FIELD_PREP(RZV2H_IVC_AXIRX_PXFMT_FIELD_DTYPE,
> > + fmt->dtype) |
> > + FIELD_PREP(RZV2H_IVC_AXIRX_PXFMT_FIELD_CLFMT,
> > + RZV2H_IVC_CLFMT_CRU_PACKED));
>
> TIL of FIELD_PREP(), I like that! Maybe #include <linux/bitfield.h> though?
It has been included in the previous patch if I'm not mistaken ?
>
> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
>
> > rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_HSIZE, pix->width);
> > rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_VSIZE, pix->height);
> > diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> > index 4ef44c8b4656..54c70de31c1e 100644
> > --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> > +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> > @@ -24,9 +24,10 @@
> > #define RZV2H_IVC_ONE_EXPOSURE 0x00
> > #define RZV2H_IVC_TWO_EXPOSURE 0x01
> > #define RZV2H_IVC_REG_AXIRX_PXFMT 0x0004
> > -#define RZV2H_IVC_INPUT_FMT_MIPI (0 << 16)
> > -#define RZV2H_IVC_INPUT_FMT_CRU_PACKED BIT(16)
> > -#define RZV2H_IVC_PXFMT_DTYPE GENMASK(7, 0)
> > +#define RZV2H_IVC_AXIRX_PXFMT_FIELD_CLFMT GENMASK(17, 16)
> > +#define RZV2H_IVC_CLFMT_MIPI 0
> > +#define RZV2H_IVC_CLFMT_CRU_PACKED 1
> > +#define RZV2H_IVC_AXIRX_PXFMT_FIELD_DTYPE GENMASK(7, 0)
> > #define RZV2H_IVC_REG_AXIRX_SADDL_P0 0x0010
> > #define RZV2H_IVC_REG_AXIRX_SADDH_P0 0x0014
> > #define RZV2H_IVC_REG_AXIRX_SADDL_P1 0x0018
> >
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/7] media: rzv2h-ivc: Write AXIRX_PIXFMT once
2026-03-13 16:12 ` Jacopo Mondi
@ 2026-03-13 16:14 ` Dan Scally
0 siblings, 0 replies; 19+ messages in thread
From: Dan Scally @ 2026-03-13 16:14 UTC (permalink / raw)
To: Jacopo Mondi
Cc: Barnabás Pőcze, Mauro Carvalho Chehab, Hans Verkuil,
linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Barnabás Pőcze, stable
Hi Jacopo
On 13/03/2026 16:12, Jacopo Mondi wrote:
> Hi Dan
>
> On Fri, Mar 13, 2026 at 04:07:47PM +0000, Dan Scally wrote:
>> Hi Jacopo (and Barnabás)
>>
>> On 13/03/2026 11:13, Jacopo Mondi wrote:
>>> From: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
>>>
>>> The documentation prescribes that invalid formats should not be set,
>>> so do a single write to ensure that both the CLFMT and DTYPE fields
>>> are set to valid values.
>>>
>>> Cc: stable@vger.kernel.org
>>> Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
>>> Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
>>> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
>>> ---
>>> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 8 ++++----
>>> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 7 ++++---
>>> 2 files changed, 8 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
>>> index bfe5b0c7045e..d894a880c33f 100644
>>> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
>>> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
>>> @@ -215,10 +215,10 @@ static void rzv2h_ivc_format_configure(struct rzv2h_ivc *ivc)
>>> /* Currently only CRU packed pixel formats are supported */
>>> rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_PXFMT,
>>> - RZV2H_IVC_INPUT_FMT_CRU_PACKED);
>>> -
>>> - rzv2h_ivc_update_bits(ivc, RZV2H_IVC_REG_AXIRX_PXFMT,
>>> - RZV2H_IVC_PXFMT_DTYPE, fmt->dtype);
>>> + FIELD_PREP(RZV2H_IVC_AXIRX_PXFMT_FIELD_DTYPE,
>>> + fmt->dtype) |
>>> + FIELD_PREP(RZV2H_IVC_AXIRX_PXFMT_FIELD_CLFMT,
>>> + RZV2H_IVC_CLFMT_CRU_PACKED));
>>
>> TIL of FIELD_PREP(), I like that! Maybe #include <linux/bitfield.h> though?
>
> It has been included in the previous patch if I'm not mistaken ?
Somehow I read this one before that one; sorry for the noise!
Thanks
Dan
>
>>
>> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
>>
>>> rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_HSIZE, pix->width);
>>> rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_VSIZE, pix->height);
>>> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
>>> index 4ef44c8b4656..54c70de31c1e 100644
>>> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
>>> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
>>> @@ -24,9 +24,10 @@
>>> #define RZV2H_IVC_ONE_EXPOSURE 0x00
>>> #define RZV2H_IVC_TWO_EXPOSURE 0x01
>>> #define RZV2H_IVC_REG_AXIRX_PXFMT 0x0004
>>> -#define RZV2H_IVC_INPUT_FMT_MIPI (0 << 16)
>>> -#define RZV2H_IVC_INPUT_FMT_CRU_PACKED BIT(16)
>>> -#define RZV2H_IVC_PXFMT_DTYPE GENMASK(7, 0)
>>> +#define RZV2H_IVC_AXIRX_PXFMT_FIELD_CLFMT GENMASK(17, 16)
>>> +#define RZV2H_IVC_CLFMT_MIPI 0
>>> +#define RZV2H_IVC_CLFMT_CRU_PACKED 1
>>> +#define RZV2H_IVC_AXIRX_PXFMT_FIELD_DTYPE GENMASK(7, 0)
>>> #define RZV2H_IVC_REG_AXIRX_SADDL_P0 0x0010
>>> #define RZV2H_IVC_REG_AXIRX_SADDH_P0 0x0014
>>> #define RZV2H_IVC_REG_AXIRX_SADDL_P1 0x0018
>>>
>>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/7] media: rzv2h-ivc: Fix AXIRX_VBLANK register write
2026-03-13 11:13 ` [PATCH 2/7] media: rzv2h-ivc: Fix AXIRX_VBLANK register write Jacopo Mondi
@ 2026-03-13 16:15 ` Dan Scally
2026-03-18 8:24 ` Barnabás Pőcze
1 sibling, 0 replies; 19+ messages in thread
From: Dan Scally @ 2026-03-13 16:15 UTC (permalink / raw)
To: Jacopo Mondi, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Barnabás Pőcze, stable
Hi Jacopo and Barnabás
On 13/03/2026 11:13, Jacopo Mondi wrote:
> From: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
>
> According to the documentation there are writable reserved bits in the
> register and those should not be set to 0. So use `rzv2h_ivc_update_bits()`
> with a proper bitmask.
>
> Cc: stable@vger.kernel.org
> Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
> Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 7 +++++--
> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 2 +-
> 2 files changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> index 1e016b17dcee..bfe5b0c7045e 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> @@ -7,6 +7,7 @@
>
> #include "rzv2h-ivc.h"
>
> +#include <linux/bitfield.h>
> #include <linux/cleanup.h>
> #include <linux/iopoll.h>
> #include <linux/lockdep.h>
> @@ -235,8 +236,10 @@ static void rzv2h_ivc_format_configure(struct rzv2h_ivc *ivc)
> hts = pix->width + RZV2H_IVC_FIXED_HBLANK;
> vblank = RZV2H_IVC_MIN_VBLANK(hts);
>
> - rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_BLANK,
> - RZV2H_IVC_VBLANK(vblank));
> + rzv2h_ivc_update_bits(ivc, RZV2H_IVC_REG_AXIRX_BLANK,
> + RZV2H_IVC_AXIRX_BLANK_FIELD_VBLANK,
> + FIELD_PREP(RZV2H_IVC_AXIRX_BLANK_FIELD_VBLANK,
> + vblank));
> }
>
> static void rzv2h_ivc_return_buffers(struct rzv2h_ivc *ivc,
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> index 3bcaab990b0f..4ef44c8b4656 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> @@ -34,7 +34,7 @@
> #define RZV2H_IVC_REG_AXIRX_HSIZE 0x0020
> #define RZV2H_IVC_REG_AXIRX_VSIZE 0x0024
> #define RZV2H_IVC_REG_AXIRX_BLANK 0x0028
> -#define RZV2H_IVC_VBLANK(x) ((x) << 16)
> +#define RZV2H_IVC_AXIRX_BLANK_FIELD_VBLANK GENMASK(25, 16)
> #define RZV2H_IVC_REG_AXIRX_STRD 0x0030
> #define RZV2H_IVC_REG_AXIRX_ISSU 0x0040
> #define RZV2H_IVC_REG_AXIRX_ERACT 0x0048
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 4/7] media: rzv2h-ivc: Fix FM_STOP register write
2026-03-13 11:14 ` [PATCH 4/7] media: rzv2h-ivc: Fix FM_STOP register write Jacopo Mondi
@ 2026-03-13 20:39 ` Dan Scally
0 siblings, 0 replies; 19+ messages in thread
From: Dan Scally @ 2026-03-13 20:39 UTC (permalink / raw)
To: Jacopo Mondi, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Barnabás Pőcze, stable
Hi Jacopo and Barnabás
On 13/03/2026 11:14, Jacopo Mondi wrote:
> From: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
>
> Bit 20 should be written in this register to stop frame processing.
> So fix that, as well as the poll condition.
>
> Cc: stable@vger.kernel.org
> Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
> Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 5 +++--
> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 1 +
> 2 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> index d894a880c33f..9b75e4b10e99 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> @@ -297,9 +297,10 @@ static void rzv2h_ivc_stop_streaming(struct vb2_queue *q)
> struct rzv2h_ivc *ivc = vb2_get_drv_priv(q);
> u32 val = 0;
>
> - rzv2h_ivc_write(ivc, RZV2H_IVC_REG_FM_STOP, 0x1);
> + rzv2h_ivc_write(ivc, RZV2H_IVC_REG_FM_STOP, RZV2H_IVC_REG_FM_STOP_FSTOP);
> readl_poll_timeout(ivc->base + RZV2H_IVC_REG_FM_STOP,
> - val, !val, 10 * USEC_PER_MSEC, 250 * USEC_PER_MSEC);
> + val, !(val & RZV2H_IVC_REG_FM_STOP_FSTOP),
> + 10 * USEC_PER_MSEC, 250 * USEC_PER_MSEC);
>
> rzv2h_ivc_return_buffers(ivc, VB2_BUF_STATE_ERROR);
> video_device_pipeline_stop(&ivc->vdev.dev);
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> index 54c70de31c1e..049f223200e3 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> @@ -46,6 +46,7 @@
> #define RZV2H_IVC_REG_FM_MCON 0x0104
> #define RZV2H_IVC_REG_FM_FRCON 0x0108
> #define RZV2H_IVC_REG_FM_STOP 0x010c
> +#define RZV2H_IVC_REG_FM_STOP_FSTOP BIT(20)
> #define RZV2H_IVC_REG_FM_INT_EN 0x0120
> #define RZV2H_IVC_VVAL_IFPE BIT(0)
> #define RZV2H_IVC_REG_FM_INT_STA 0x0124
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 5/7] media: rzv2h-ivc: Fix concurrent buffer list access
2026-03-13 11:14 ` [PATCH 5/7] media: rzv2h-ivc: Fix concurrent buffer list access Jacopo Mondi
@ 2026-03-13 22:11 ` Dan Scally
0 siblings, 0 replies; 19+ messages in thread
From: Dan Scally @ 2026-03-13 22:11 UTC (permalink / raw)
To: Jacopo Mondi, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Barnabás Pőcze, stable
Hi Jacopo and Barnabás
On 13/03/2026 11:14, Jacopo Mondi wrote:
> From: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
>
> The list of buffers (`rzv2h_ivc::buffers.queue`) is protected by a
> spinlock (`rzv2h_ivc::buffers.lock`). However, in
> `rzv2h_ivc_transfer_buffer()`, which runs in a separate workqueue, the
> `list_del()` call is executed without holding the spinlock, which makes
> it possible for the list to be concurrently modified
>
> Fix that by removing a buffer from the list in the lock protected section.
>
> Cc: stable@vger.kernel.org
> Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
> Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
> [assign ivc->buffers.curr in critical section as reported by Barnabas]
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
Looks good, thanks
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 11 +++++------
> 1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> index 9b75e4b10e99..a22aee0fe1cf 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> @@ -153,14 +153,13 @@ static void rzv2h_ivc_transfer_buffer(struct work_struct *work)
> scoped_guard(spinlock_irqsave, &ivc->buffers.lock) {
> buf = list_first_entry_or_null(&ivc->buffers.queue,
> struct rzv2h_ivc_buf, queue);
> - }
> -
> - if (!buf)
> - return;
> + if (!buf)
> + return;
>
> - list_del(&buf->queue);
> + list_del(&buf->queue);
> + ivc->buffers.curr = buf;
> + }
>
> - ivc->buffers.curr = buf;
> buf->addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
> rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_SADDL_P0, buf->addr);
>
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 7/7] media: rzv2h-ivc: Replace workqueue with direct function call
2026-03-13 11:14 ` [PATCH 7/7] media: rzv2h-ivc: Replace workqueue with direct function call Jacopo Mondi
@ 2026-03-13 22:42 ` Dan Scally
0 siblings, 0 replies; 19+ messages in thread
From: Dan Scally @ 2026-03-13 22:42 UTC (permalink / raw)
To: Jacopo Mondi, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi
Hi Jacopo
On 13/03/2026 11:14, Jacopo Mondi wrote:
> From: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
>
> Scheduling of work items with an async workqueue opens the door to
> potential races between multiple instances of a work item.
>
> While the frame transfer function is now protected agains races, using a
> workqueue doesn't provide much benefit considering the limited cost of
> creating a job transfer.
>
> Replace usage of the work queue with direct function calls.
>
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
> .../platform/renesas/rzv2h-ivc/rzv2h-ivc-dev.c | 2 +-
> .../platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 21 +++++++--------------
> .../media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 3 +--
> 3 files changed, 9 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-dev.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-dev.c
> index e9857eb5b51a..355842abb24b 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-dev.c
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-dev.c
> @@ -119,7 +119,7 @@ static irqreturn_t rzv2h_ivc_isr(int irq, void *context)
> * The second interrupt indicates that the post-frame transfer VBLANK
> * has completed, we can now schedule a new frame transfer, if any.
> */
> - queue_work(ivc->buffers.async_wq, &ivc->buffers.work);
> + rzv2h_ivc_transfer_buffer(ivc);
>
> return IRQ_HANDLED;
> }
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> index 3580a57738a6..b167f1bab7ef 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> @@ -143,13 +143,11 @@ void rzv2h_ivc_buffer_done(struct rzv2h_ivc *ivc)
> vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
> }
>
> -static void rzv2h_ivc_transfer_buffer(struct work_struct *work)
> +void rzv2h_ivc_transfer_buffer(struct rzv2h_ivc *ivc)
> {
> - struct rzv2h_ivc *ivc = container_of(work, struct rzv2h_ivc,
> - buffers.work);
> struct rzv2h_ivc_buf *buf;
>
> - guard(spinlock_irqsave)(&ivc->spinlock);
> + lockdep_assert_held(&ivc->spinlock);
>
> if (ivc->vvalid_ifp)
> return;
> @@ -204,7 +202,7 @@ static void rzv2h_ivc_buf_queue(struct vb2_buffer *vb)
>
> scoped_guard(spinlock_irq, &ivc->spinlock) {
> if (vb2_is_streaming(vb->vb2_queue))
> - queue_work(ivc->buffers.async_wq, &ivc->buffers.work);
> + rzv2h_ivc_transfer_buffer(ivc);
> }
> }
>
> @@ -282,7 +280,9 @@ static int rzv2h_ivc_start_streaming(struct vb2_queue *q, unsigned int count)
>
> rzv2h_ivc_format_configure(ivc);
>
> - queue_work(ivc->buffers.async_wq, &ivc->buffers.work);
> + scoped_guard(spinlock_irq, &ivc->spinlock) {
> + rzv2h_ivc_transfer_buffer(ivc);
> + }
>
> return 0;
>
> @@ -449,11 +449,6 @@ int rzv2h_ivc_init_vdev(struct rzv2h_ivc *ivc, struct v4l2_device *v4l2_dev)
>
> spin_lock_init(&ivc->buffers.lock);
> INIT_LIST_HEAD(&ivc->buffers.queue);
> - INIT_WORK(&ivc->buffers.work, rzv2h_ivc_transfer_buffer);
> -
> - ivc->buffers.async_wq = alloc_workqueue("rzv2h-ivc", 0, 0);
> - if (!ivc->buffers.async_wq)
> - return -EINVAL;
>
> /* Initialise vb2 queue */
> vb2q = &ivc->vdev.vb2q;
> @@ -471,7 +466,7 @@ int rzv2h_ivc_init_vdev(struct rzv2h_ivc *ivc, struct v4l2_device *v4l2_dev)
> ret = vb2_queue_init(vb2q);
> if (ret) {
> dev_err(ivc->dev, "vb2 queue init failed\n");
> - goto err_destroy_workqueue;
> + return ret;
> }
>
> /* Initialise Video Device */
> @@ -520,8 +515,6 @@ int rzv2h_ivc_init_vdev(struct rzv2h_ivc *ivc, struct v4l2_device *v4l2_dev)
> media_entity_cleanup(&vdev->entity);
> err_release_vb2q:
> vb2_queue_release(vb2q);
> -err_destroy_workqueue:
> - destroy_workqueue(ivc->buffers.async_wq);
>
> return ret;
> }
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> index 049f223200e3..6f644ba796a9 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> @@ -104,8 +104,6 @@ struct rzv2h_ivc {
> struct {
> /* Spinlock to guard buffer queue */
> spinlock_t lock;
> - struct workqueue_struct *async_wq;
> - struct work_struct work;
> struct list_head queue;
> struct rzv2h_ivc_buf *curr;
> unsigned int sequence;
> @@ -130,3 +128,4 @@ void rzv2h_ivc_deinit_subdevice(struct rzv2h_ivc *ivc);
> void rzv2h_ivc_write(struct rzv2h_ivc *ivc, u32 addr, u32 val);
> void rzv2h_ivc_update_bits(struct rzv2h_ivc *ivc, unsigned int addr,
> u32 mask, u32 val);
> +void rzv2h_ivc_transfer_buffer(struct rzv2h_ivc *ivc);
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 6/7] media: rzv2h-ivc: Avoid double job scheduling
2026-03-13 11:14 ` [PATCH 6/7] media: rzv2h-ivc: Avoid double job scheduling Jacopo Mondi
@ 2026-03-18 8:00 ` Dan Scally
2026-03-18 8:18 ` Barnabás Pőcze
1 sibling, 0 replies; 19+ messages in thread
From: Dan Scally @ 2026-03-18 8:00 UTC (permalink / raw)
To: Jacopo Mondi, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
stable
Morning Jacopo - sorry for missing this one
On 13/03/2026 11:14, Jacopo Mondi wrote:
> From: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
>
> The scheduling of a new buffer transfer in the IVC driver is triggered
> by two occurrences of the "frame completed" interrupt.
>
> The first interrupt occurrence identifies when all image data have been
> transferred to the ISP, the second occurrence identifies when the
> post-transfer VBLANK has completed and a new buffer can be transferred.
>
> Under heavy system load conditions the actual execution of the workqueue
> item might be delayed and two items might happen to run concurrently,
> leading to a new frame transfer being triggered while the previous one
> has not yet finished.
>
> This error condition is only visible because the driver maintains a
> status variable that counts the number of interrupts since the last
> transfer, and warns in case an IRQ happens before the counter has been
> reset.
>
> To ensure sequential execution of the worqueue items and avoid a double
> buffer transfer to run concurrently, protect the whole function body
> with the spinlock that so far was solely used to reset the counter and
> inspect the interrupt counter variable at the beginning of the buffer
> transfer function.
> and return
>
> As soon as the ongoing transfer completes, the workqueue item will be
> re-scheduled and will consume the pending buffer.
>
> Cc: stable@vger.kernel.org
> Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> index a22aee0fe1cf..3580a57738a6 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> @@ -149,6 +149,11 @@ static void rzv2h_ivc_transfer_buffer(struct work_struct *work)
> buffers.work);
> struct rzv2h_ivc_buf *buf;
>
> + guard(spinlock_irqsave)(&ivc->spinlock);
> +
> + if (ivc->vvalid_ifp)
> + return;
> +
> /* Setup buffers */
> scoped_guard(spinlock_irqsave, &ivc->buffers.lock) {
> buf = list_first_entry_or_null(&ivc->buffers.queue,
> @@ -163,9 +168,7 @@ static void rzv2h_ivc_transfer_buffer(struct work_struct *work)
> buf->addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
> rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_SADDL_P0, buf->addr);
>
> - scoped_guard(spinlock_irqsave, &ivc->spinlock) {
> - ivc->vvalid_ifp = 2;
> - }
> + ivc->vvalid_ifp = 2;
> rzv2h_ivc_write(ivc, RZV2H_IVC_REG_FM_FRCON, 0x1);
> }
>
> @@ -200,7 +203,7 @@ static void rzv2h_ivc_buf_queue(struct vb2_buffer *vb)
> }
>
> scoped_guard(spinlock_irq, &ivc->spinlock) {
> - if (vb2_is_streaming(vb->vb2_queue) && !ivc->vvalid_ifp)
> + if (vb2_is_streaming(vb->vb2_queue))
> queue_work(ivc->buffers.async_wq, &ivc->buffers.work);
> }
> }
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 6/7] media: rzv2h-ivc: Avoid double job scheduling
2026-03-13 11:14 ` [PATCH 6/7] media: rzv2h-ivc: Avoid double job scheduling Jacopo Mondi
2026-03-18 8:00 ` Dan Scally
@ 2026-03-18 8:18 ` Barnabás Pőcze
1 sibling, 0 replies; 19+ messages in thread
From: Barnabás Pőcze @ 2026-03-18 8:18 UTC (permalink / raw)
To: Jacopo Mondi, Daniel Scally, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
stable
2026. 03. 13. 12:14 keltezéssel, Jacopo Mondi írta:
> From: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
>
> The scheduling of a new buffer transfer in the IVC driver is triggered
> by two occurrences of the "frame completed" interrupt.
>
> The first interrupt occurrence identifies when all image data have been
> transferred to the ISP, the second occurrence identifies when the
> post-transfer VBLANK has completed and a new buffer can be transferred.
>
> Under heavy system load conditions the actual execution of the workqueue
> item might be delayed and two items might happen to run concurrently,
> leading to a new frame transfer being triggered while the previous one
> has not yet finished.
>
> This error condition is only visible because the driver maintains a
> status variable that counts the number of interrupts since the last
> transfer, and warns in case an IRQ happens before the counter has been
> reset.
>
> To ensure sequential execution of the worqueue items and avoid a double
> buffer transfer to run concurrently, protect the whole function body
> with the spinlock that so far was solely used to reset the counter and
> inspect the interrupt counter variable at the beginning of the buffer
> transfer function.
> and return
>
> As soon as the ongoing transfer completes, the workqueue item will be
> re-scheduled and will consume the pending buffer.
>
> Cc: stable@vger.kernel.org
> Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
Looks ok to me.
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> index a22aee0fe1cf..3580a57738a6 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> @@ -149,6 +149,11 @@ static void rzv2h_ivc_transfer_buffer(struct work_struct *work)
> buffers.work);
> struct rzv2h_ivc_buf *buf;
>
> + guard(spinlock_irqsave)(&ivc->spinlock);
> +
> + if (ivc->vvalid_ifp)
> + return;
> +
> /* Setup buffers */
> scoped_guard(spinlock_irqsave, &ivc->buffers.lock) {
> buf = list_first_entry_or_null(&ivc->buffers.queue,
> @@ -163,9 +168,7 @@ static void rzv2h_ivc_transfer_buffer(struct work_struct *work)
> buf->addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
> rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_SADDL_P0, buf->addr);
>
> - scoped_guard(spinlock_irqsave, &ivc->spinlock) {
> - ivc->vvalid_ifp = 2;
> - }
> + ivc->vvalid_ifp = 2;
> rzv2h_ivc_write(ivc, RZV2H_IVC_REG_FM_FRCON, 0x1);
> }
>
> @@ -200,7 +203,7 @@ static void rzv2h_ivc_buf_queue(struct vb2_buffer *vb)
> }
>
> scoped_guard(spinlock_irq, &ivc->spinlock) {
> - if (vb2_is_streaming(vb->vb2_queue) && !ivc->vvalid_ifp)
> + if (vb2_is_streaming(vb->vb2_queue))
> queue_work(ivc->buffers.async_wq, &ivc->buffers.work);
> }
> }
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/7] media: rzv2h-ivc: Fix AXIRX_VBLANK register write
2026-03-13 11:13 ` [PATCH 2/7] media: rzv2h-ivc: Fix AXIRX_VBLANK register write Jacopo Mondi
2026-03-13 16:15 ` Dan Scally
@ 2026-03-18 8:24 ` Barnabás Pőcze
1 sibling, 0 replies; 19+ messages in thread
From: Barnabás Pőcze @ 2026-03-18 8:24 UTC (permalink / raw)
To: Jacopo Mondi, Daniel Scally, Mauro Carvalho Chehab, Hans Verkuil
Cc: linux-media, linux-renesas-soc, linux-kernel, Jacopo Mondi,
Barnabás Pőcze, stable
2026. 03. 13. 12:13 keltezéssel, Jacopo Mondi írta:
> From: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
>
> According to the documentation there are writable reserved bits in the
> register and those should not be set to 0. So use `rzv2h_ivc_update_bits()`
> with a proper bitmask.
>
> Cc: stable@vger.kernel.org
> Fixes: f0b3984d821b ("media: platform: Add Renesas Input Video Control block driver")
> Signed-off-by: Barnabás Pőcze <barnabas.pocze+renesas@ideasonboard.com>
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c | 7 +++++--
> drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h | 2 +-
> 2 files changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> index 1e016b17dcee..bfe5b0c7045e 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc-video.c
> @@ -7,6 +7,7 @@
>
> #include "rzv2h-ivc.h"
>
> +#include <linux/bitfield.h>
> #include <linux/cleanup.h>
> #include <linux/iopoll.h>
> #include <linux/lockdep.h>
> @@ -235,8 +236,10 @@ static void rzv2h_ivc_format_configure(struct rzv2h_ivc *ivc)
> hts = pix->width + RZV2H_IVC_FIXED_HBLANK;
> vblank = RZV2H_IVC_MIN_VBLANK(hts);
>
> - rzv2h_ivc_write(ivc, RZV2H_IVC_REG_AXIRX_BLANK,
> - RZV2H_IVC_VBLANK(vblank));
> + rzv2h_ivc_update_bits(ivc, RZV2H_IVC_REG_AXIRX_BLANK,
> + RZV2H_IVC_AXIRX_BLANK_FIELD_VBLANK,
> + FIELD_PREP(RZV2H_IVC_AXIRX_BLANK_FIELD_VBLANK,
> + vblank));
> }
>
> static void rzv2h_ivc_return_buffers(struct rzv2h_ivc *ivc,
> diff --git a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> index 3bcaab990b0f..4ef44c8b4656 100644
> --- a/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> +++ b/drivers/media/platform/renesas/rzv2h-ivc/rzv2h-ivc.h
> @@ -34,7 +34,7 @@
> #define RZV2H_IVC_REG_AXIRX_HSIZE 0x0020
> #define RZV2H_IVC_REG_AXIRX_VSIZE 0x0024
> #define RZV2H_IVC_REG_AXIRX_BLANK 0x0028
> -#define RZV2H_IVC_VBLANK(x) ((x) << 16)
> +#define RZV2H_IVC_AXIRX_BLANK_FIELD_VBLANK GENMASK(25, 16)
On second look, I have a small comment: I now greatly dislike how I have named this.
Especially that it is inconsistent with `RZV2H_IVC_REG_FM_STOP_FSTOP` in patch 4/7.
Possibly `RZV2H_IVC_REG_AXIRX_BLANK_VBLANK` or `RZV2H_IVC_REG_AXIRX_BLANK_FIELD_VBLANK`
would be better (although in the latter case I would rename the macro in patch 4/7 to
`RZV2H_IVC_REG_FM_STOP_FIELD_FSTOP`). The same applies to patch 3/7 as well, I'd now do
`RZV2H_IVC_REG_AXIRX_PXFMT_(FIELD_){CLFMT,DTYPE}` or similar. Sorry about that.
Regards,
Barnabás Pőcze
> #define RZV2H_IVC_REG_AXIRX_STRD 0x0030
> #define RZV2H_IVC_REG_AXIRX_ISSU 0x0040
> #define RZV2H_IVC_REG_AXIRX_ERACT 0x0048
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling
2026-03-13 11:13 [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Jacopo Mondi
` (6 preceding siblings ...)
2026-03-13 11:14 ` [PATCH 7/7] media: rzv2h-ivc: Replace workqueue with direct function call Jacopo Mondi
@ 2026-03-20 17:16 ` Lad, Prabhakar
7 siblings, 0 replies; 19+ messages in thread
From: Lad, Prabhakar @ 2026-03-20 17:16 UTC (permalink / raw)
To: Jacopo Mondi
Cc: Daniel Scally, Barnabás Pőcze, Mauro Carvalho Chehab,
Hans Verkuil, linux-media, linux-renesas-soc, linux-kernel,
Jacopo Mondi, Daniel Scally, stable, Barnabás Pőcze
Hi Jacopo,
Thank you for the patches.
On Fri, Mar 13, 2026 at 11:14 AM Jacopo Mondi
<jacopo.mondi@ideasonboard.com> wrote:
>
> We have been exercizing the RZ/V2H(P) IVC block quite intensly these
> last two months.
>
> Here it is a collection of fixes and improvements to the driver.
>
> The first 4 patches in the series address a few registers writes that
> do not respect the documentation.
>
> The 5th and 6th patches fixes concurrent access to the list of queued
> buffers and fix a WARN() visible under heavy system load conditions
> caused by concurrent buffer transfers.
>
> The last patch is actually up for discussion. It is my opinion that the
> trouble of setting up a workqueue item is not justified by the
> relatively small amount of work that has to be carried out in interrupt
> context. In any case, there shouldn't be any functional change
> introduced by this patch.
>
> Patch #7 makes patch #6 reduntant: if we use direct function
> calls, then the issue of concurrently running workqueue items cannot
> happen. However, I actually think patch #6 has value regardless as it
> makes the code more robust.
>
> Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
> ---
> Barnabás Pőcze (4):
> media: rzv2h-ivc: Fix AXIRX_VBLANK register write
> media: rzv2h-ivc: Write AXIRX_PIXFMT once
> media: rzv2h-ivc: Fix FM_STOP register write
> media: rzv2h-ivc: Fix concurrent buffer list access
>
> Daniel Scally (1):
> media: rzv2h-ivc: Revise default VBLANK formula
>
> Jacopo Mondi (2):
> media: rzv2h-ivc: Avoid double job scheduling
> media: rzv2h-ivc: Replace workqueue with direct function call
>
Tested the patches on RZ/V2H EVK with IMX708 sensor on next-20260319.
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> #
On RZ/V2H EVK
Cheers,
Prabhakar
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-03-20 17:17 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-13 11:13 [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Jacopo Mondi
2026-03-13 11:13 ` [PATCH 1/7] media: rzv2h-ivc: Revise default VBLANK formula Jacopo Mondi
2026-03-13 11:13 ` [PATCH 2/7] media: rzv2h-ivc: Fix AXIRX_VBLANK register write Jacopo Mondi
2026-03-13 16:15 ` Dan Scally
2026-03-18 8:24 ` Barnabás Pőcze
2026-03-13 11:13 ` [PATCH 3/7] media: rzv2h-ivc: Write AXIRX_PIXFMT once Jacopo Mondi
2026-03-13 16:07 ` Dan Scally
2026-03-13 16:12 ` Jacopo Mondi
2026-03-13 16:14 ` Dan Scally
2026-03-13 11:14 ` [PATCH 4/7] media: rzv2h-ivc: Fix FM_STOP register write Jacopo Mondi
2026-03-13 20:39 ` Dan Scally
2026-03-13 11:14 ` [PATCH 5/7] media: rzv2h-ivc: Fix concurrent buffer list access Jacopo Mondi
2026-03-13 22:11 ` Dan Scally
2026-03-13 11:14 ` [PATCH 6/7] media: rzv2h-ivc: Avoid double job scheduling Jacopo Mondi
2026-03-18 8:00 ` Dan Scally
2026-03-18 8:18 ` Barnabás Pőcze
2026-03-13 11:14 ` [PATCH 7/7] media: rzv2h-ivc: Replace workqueue with direct function call Jacopo Mondi
2026-03-13 22:42 ` Dan Scally
2026-03-20 17:16 ` [PATCH 0/7] media: renesas: rzv2h-ivc: Fix concurrent job scheduling Lad, Prabhakar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox