* [PATCH 1/9] media: rzg2l-cru: Add device_link from CRU to CSI-2
2026-06-16 17:05 [PATCH 0/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
@ 2026-06-16 17:05 ` Tommaso Merciai
2026-06-16 17:05 ` [PATCH 2/9] media: rzg2l-cru: csi2: Add device_link from CSI-2 to sensor Tommaso Merciai
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tommaso Merciai @ 2026-06-16 17:05 UTC (permalink / raw)
To: tomm.merciai
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Sakari Ailus,
Mauro Carvalho Chehab, Lad Prabhakar, Jacopo Mondi, Philipp Zabel,
linux-media, linux-kernel
The CRU device depends on CSI-2 to operate. Without an explicit
device_link the PM core has no knowledge of this dependency and may
suspend CSI-2 while CRU is still active, or resume CRU before CSI-2
is ready.
Add a DL_FLAG_STATELESS device_link from the CRU to CSI-2 when the
CSI-2 subdev binds. This instructs the PM core to suspend CRU before
CSI-2 and to resume CSI-2 before CRU. The link is deleted on unbind.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c
index 3c5fbd857371..1b12d91eaec9 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c
@@ -101,6 +101,7 @@ static void rzg2l_cru_group_notify_unbind(struct v4l2_async_notifier *notifier,
mutex_lock(&cru->mdev_lock);
if (cru->csi.asd == asd) {
+ device_link_remove(cru->dev, subdev->dev);
cru->csi.subdev = NULL;
dev_dbg(cru->dev, "Unbind CSI-2 %s\n", subdev->name);
}
@@ -118,6 +119,12 @@ static int rzg2l_cru_group_notify_bound(struct v4l2_async_notifier *notifier,
if (cru->csi.asd == asd) {
cru->csi.subdev = subdev;
+ if (!device_link_add(cru->dev, subdev->dev, DL_FLAG_STATELESS)) {
+ dev_err(cru->dev, "Failed to create device link to CSI-2 %s\n",
+ subdev->name);
+ mutex_unlock(&cru->mdev_lock);
+ return -EINVAL;
+ }
dev_dbg(cru->dev, "Bound CSI-2 %s\n", subdev->name);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 2/9] media: rzg2l-cru: csi2: Add device_link from CSI-2 to sensor
2026-06-16 17:05 [PATCH 0/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
2026-06-16 17:05 ` [PATCH 1/9] media: rzg2l-cru: Add device_link from CRU to CSI-2 Tommaso Merciai
@ 2026-06-16 17:05 ` Tommaso Merciai
2026-06-16 17:05 ` [PATCH 3/9] media: rzg2l-cru: Use bulk reset API in rzg2l_cru_start_streaming_vq() Tommaso Merciai
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tommaso Merciai @ 2026-06-16 17:05 UTC (permalink / raw)
To: tomm.merciai
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Sakari Ailus,
Mauro Carvalho Chehab, Lad Prabhakar, Jacopo Mondi, Philipp Zabel,
linux-media, linux-kernel
The CSI-2 receiver depends on its remote sensor being powered and
configured before it can receive data. Without an explicit device_link
the PM core has no knowledge of this dependency and may suspend the
sensor while CSI-2 is still active, or resume CSI-2 before the sensor
is ready.
Add a DL_FLAG_STATELESS device_link from the CSI-2 device to the sensor
device when the sensor subdev binds. This instructs the PM core to
suspend CSI-2 before the sensor and to resume the sensor before CSI-2.
The link is deleted on unbind.
Move csi2->remote_source assignment to the end of the function.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
.../platform/renesas/rzg2l-cru/rzg2l-csi2.c | 24 +++++++++++++++----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
index 6dc4b53607b4..3a4bc4ef72fc 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
@@ -773,15 +773,28 @@ static int rzg2l_csi2_notify_bound(struct v4l2_async_notifier *notifier,
struct v4l2_async_connection *asd)
{
struct rzg2l_csi2 *csi2 = notifier_to_csi2(notifier);
+ int ret;
- csi2->remote_source = subdev;
+ if (!device_link_add(csi2->dev, subdev->dev, DL_FLAG_STATELESS)) {
+ dev_err(csi2->dev, "Failed to create device link to sensor %s\n",
+ subdev->name);
+ return -EINVAL;
+ }
dev_dbg(csi2->dev, "Bound subdev: %s pad\n", subdev->name);
- return media_create_pad_link(&subdev->entity, RZG2L_CSI2_SINK,
- &csi2->subdev.entity, 0,
- MEDIA_LNK_FL_ENABLED |
- MEDIA_LNK_FL_IMMUTABLE);
+ ret = media_create_pad_link(&subdev->entity, RZG2L_CSI2_SINK,
+ &csi2->subdev.entity, 0,
+ MEDIA_LNK_FL_ENABLED |
+ MEDIA_LNK_FL_IMMUTABLE);
+ if (ret) {
+ device_link_remove(csi2->dev, subdev->dev);
+ return ret;
+ }
+
+ csi2->remote_source = subdev;
+
+ return 0;
}
static void rzg2l_csi2_notify_unbind(struct v4l2_async_notifier *notifier,
@@ -790,6 +803,7 @@ static void rzg2l_csi2_notify_unbind(struct v4l2_async_notifier *notifier,
{
struct rzg2l_csi2 *csi2 = notifier_to_csi2(notifier);
+ device_link_remove(csi2->dev, subdev->dev);
csi2->remote_source = NULL;
dev_dbg(csi2->dev, "Unbind subdev %s\n", subdev->name);
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 3/9] media: rzg2l-cru: Use bulk reset API in rzg2l_cru_start_streaming_vq()
2026-06-16 17:05 [PATCH 0/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
2026-06-16 17:05 ` [PATCH 1/9] media: rzg2l-cru: Add device_link from CRU to CSI-2 Tommaso Merciai
2026-06-16 17:05 ` [PATCH 2/9] media: rzg2l-cru: csi2: Add device_link from CSI-2 to sensor Tommaso Merciai
@ 2026-06-16 17:05 ` Tommaso Merciai
2026-06-16 17:05 ` [PATCH 4/9] media: rzg2l-cru: Drop stop streaming function Tommaso Merciai
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tommaso Merciai @ 2026-06-16 17:05 UTC (permalink / raw)
To: tomm.merciai
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Sakari Ailus,
Mauro Carvalho Chehab, Lad Prabhakar, Jacopo Mondi, Philipp Zabel,
linux-media, linux-kernel
Replace individual reset_control_deassert() calls for aresetn and presetn
with reset_control_bulk_deassert(), and consolidate the error path labels
into a single err_assert_resets using reset_control_bulk_assert().
No functional changes intended.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
.../platform/renesas/rzg2l-cru/rzg2l-video.c | 23 ++++++++-----------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
index 5185a547461d..bf61a74f8f74 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
@@ -672,6 +672,10 @@ irqreturn_t rzg3e_cru_irq(int irq, void *data)
static int rzg2l_cru_start_streaming_vq(struct vb2_queue *vq, unsigned int count)
{
struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vq);
+ struct reset_control_bulk_data resets[] = {
+ { .rstc = cru->aresetn },
+ { .rstc = cru->presetn },
+ };
int ret;
ret = pm_runtime_resume_and_get(cru->dev);
@@ -683,19 +687,12 @@ static int rzg2l_cru_start_streaming_vq(struct vb2_queue *vq, unsigned int count
goto err_pm_put;
/* Release reset state */
- ret = reset_control_deassert(cru->aresetn);
+ ret = reset_control_bulk_deassert(ARRAY_SIZE(resets), resets);
if (ret) {
- dev_err(cru->dev, "failed to deassert aresetn\n");
+ dev_err(cru->dev, "failed to deassert resets\n");
goto err_vclk_disable;
}
- ret = reset_control_deassert(cru->presetn);
- if (ret) {
- reset_control_assert(cru->aresetn);
- dev_err(cru->dev, "failed to deassert presetn\n");
- goto assert_aresetn;
- }
-
/* Allocate scratch buffer */
cru->scratch = dma_alloc_coherent(cru->dev, cru->format.sizeimage,
&cru->scratch_phys, GFP_KERNEL);
@@ -703,7 +700,7 @@ static int rzg2l_cru_start_streaming_vq(struct vb2_queue *vq, unsigned int count
rzg2l_cru_return_buffers(cru, VB2_BUF_STATE_QUEUED);
dev_err(cru->dev, "Failed to allocate scratch buffer\n");
ret = -ENOMEM;
- goto assert_presetn;
+ goto err_assert_resets;
}
cru->active_slot = 0;
@@ -722,11 +719,9 @@ static int rzg2l_cru_start_streaming_vq(struct vb2_queue *vq, unsigned int count
if (ret)
dma_free_coherent(cru->dev, cru->format.sizeimage, cru->scratch,
cru->scratch_phys);
-assert_presetn:
- reset_control_assert(cru->presetn);
-assert_aresetn:
- reset_control_assert(cru->aresetn);
+err_assert_resets:
+ reset_control_bulk_assert(ARRAY_SIZE(resets), resets);
err_vclk_disable:
clk_disable_unprepare(cru->vclk);
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 4/9] media: rzg2l-cru: Drop stop streaming function
2026-06-16 17:05 [PATCH 0/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
` (2 preceding siblings ...)
2026-06-16 17:05 ` [PATCH 3/9] media: rzg2l-cru: Use bulk reset API in rzg2l_cru_start_streaming_vq() Tommaso Merciai
@ 2026-06-16 17:05 ` Tommaso Merciai
2026-06-16 17:05 ` [PATCH 5/9] media: rzg2l-cru: Move active_slot reset into rzg2l_cru_set_stream() Tommaso Merciai
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tommaso Merciai @ 2026-06-16 17:05 UTC (permalink / raw)
To: tomm.merciai
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Sakari Ailus,
Mauro Carvalho Chehab, Lad Prabhakar, Jacopo Mondi, Philipp Zabel,
linux-media, linux-kernel
Drop rzg2l_cru_stop_streaming() function and replace that with the
direct call to rzg2l_cru_set_stream(cru, 0).
This is a refactoring with no functional changes.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
index bf61a74f8f74..e283d9b69342 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
@@ -583,11 +583,6 @@ static int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on)
return ret;
}
-static void rzg2l_cru_stop_streaming(struct rzg2l_cru_dev *cru)
-{
- rzg2l_cru_set_stream(cru, 0);
-}
-
irqreturn_t rzg2l_cru_irq(int irq, void *data)
{
struct rzg2l_cru_dev *cru = data;
@@ -736,7 +731,7 @@ static void rzg2l_cru_stop_streaming_vq(struct vb2_queue *vq)
{
struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vq);
- rzg2l_cru_stop_streaming(cru);
+ rzg2l_cru_set_stream(cru, 0);
/* Free scratch buffer */
dma_free_coherent(cru->dev, cru->format.sizeimage,
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 5/9] media: rzg2l-cru: Move active_slot reset into rzg2l_cru_set_stream()
2026-06-16 17:05 [PATCH 0/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
` (3 preceding siblings ...)
2026-06-16 17:05 ` [PATCH 4/9] media: rzg2l-cru: Drop stop streaming function Tommaso Merciai
@ 2026-06-16 17:05 ` Tommaso Merciai
2026-06-16 17:05 ` [PATCH 6/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tommaso Merciai @ 2026-06-16 17:05 UTC (permalink / raw)
To: tomm.merciai
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Sakari Ailus,
Mauro Carvalho Chehab, Lad Prabhakar, Jacopo Mondi, Philipp Zabel,
linux-media, linux-kernel
active_slot tracks the current DMA slot index and must always be reset
to zero before starting a new stream. Previously callers were responsible
for this reset before each rzg2l_cru_set_stream(cru, 1) invocation.
Move the reset inside rzg2l_cru_set_stream() so the invariant is
enforced in a single place and future callers cannot accidentally omit
it.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
index e283d9b69342..71d9c671f739 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
@@ -559,6 +559,7 @@ static int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on)
return stream_off_ret;
}
+ cru->active_slot = 0;
pipe = media_entity_pipeline(&sd->entity) ? : &cru->vdev.pipe;
ret = video_device_pipeline_start(&cru->vdev, pipe);
if (ret)
@@ -698,7 +699,6 @@ static int rzg2l_cru_start_streaming_vq(struct vb2_queue *vq, unsigned int count
goto err_assert_resets;
}
- cru->active_slot = 0;
cru->sequence = 0;
ret = rzg2l_cru_set_stream(cru, 1);
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 6/9] media: rzg2l-cru: Add suspend/resume support
2026-06-16 17:05 [PATCH 0/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
` (4 preceding siblings ...)
2026-06-16 17:05 ` [PATCH 5/9] media: rzg2l-cru: Move active_slot reset into rzg2l_cru_set_stream() Tommaso Merciai
@ 2026-06-16 17:05 ` Tommaso Merciai
2026-06-16 17:05 ` [PATCH 7/9] media: rzg2l-cru: csi2: Add system sleep PM support Tommaso Merciai
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tommaso Merciai @ 2026-06-16 17:05 UTC (permalink / raw)
To: tomm.merciai
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Sakari Ailus,
Mauro Carvalho Chehab, Lad Prabhakar, Jacopo Mondi, Philipp Zabel,
linux-media, linux-kernel
The CRU has no system sleep hooks, leaving the device in an undefined
state across suspend/resume.
On suspend, stop the pipeline, requeue any buffers held by the hardware
back to the software queue, and assert the resets. On resume, deassert
the resets and restart streaming.
Add a bool running field to track pipeline state. stop_streaming uses it
to skip rzg2l_cru_set_stream() when the pipeline was already stopped by
a failed resume, avoiding a double-stop. Export rzg2l_cru_set_stream()
and add rzg2l_cru_requeue_active_buffers() for use by the PM callbacks.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
.../platform/renesas/rzg2l-cru/rzg2l-core.c | 67 +++++++++++++++++++
.../platform/renesas/rzg2l-cru/rzg2l-cru.h | 5 ++
.../platform/renesas/rzg2l-cru/rzg2l-video.c | 25 ++++++-
3 files changed, 95 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c
index 1b12d91eaec9..2840f40e4c01 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c
@@ -246,6 +246,72 @@ static int rzg2l_cru_media_init(struct rzg2l_cru_dev *cru)
return 0;
}
+static int rzg2l_cru_pm_suspend(struct device *dev)
+{
+ struct rzg2l_cru_dev *cru = dev_get_drvdata(dev);
+ struct reset_control_bulk_data resets[] = {
+ { .rstc = cru->aresetn },
+ { .rstc = cru->presetn },
+ };
+ int ret;
+
+ if (!cru->running)
+ return 0;
+
+ ret = rzg2l_cru_set_stream(cru, 0);
+ if (ret)
+ return ret;
+
+ rzg2l_cru_requeue_active_buffers(cru);
+
+ ret = reset_control_bulk_assert(ARRAY_SIZE(resets), resets);
+ if (ret) {
+ if (rzg2l_cru_set_stream(cru, 1))
+ vb2_queue_error(&cru->queue);
+
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rzg2l_cru_pm_resume(struct device *dev)
+{
+ struct rzg2l_cru_dev *cru = dev_get_drvdata(dev);
+ struct reset_control_bulk_data resets[] = {
+ { .rstc = cru->aresetn },
+ { .rstc = cru->presetn },
+ };
+ int ret;
+
+ if (!cru->running)
+ return 0;
+
+ ret = reset_control_bulk_deassert(ARRAY_SIZE(resets), resets);
+ if (ret)
+ goto err_running;
+
+ ret = rzg2l_cru_set_stream(cru, 1);
+ if (ret) {
+ dev_err(cru->dev, "Failed to restart streaming: %d\n", ret);
+ goto err_reset_assert;
+ }
+
+ return 0;
+
+err_reset_assert:
+ reset_control_bulk_assert(ARRAY_SIZE(resets), resets);
+err_running:
+ cru->running = false;
+ vb2_queue_error(&cru->queue);
+
+ return ret;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(rzg2l_cru_pm_ops,
+ rzg2l_cru_pm_suspend,
+ rzg2l_cru_pm_resume);
+
static int rzg2l_cru_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -437,6 +503,7 @@ static struct platform_driver rzg2l_cru_driver = {
.driver = {
.name = "rzg2l-cru",
.of_match_table = rzg2l_cru_of_id_table,
+ .pm = pm_sleep_ptr(&rzg2l_cru_pm_ops),
},
.probe = rzg2l_cru_probe,
.remove = rzg2l_cru_remove,
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
index 5bf334e173d2..c079cad41266 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
@@ -161,12 +161,17 @@ struct rzg2l_cru_dev {
struct list_head buf_list;
unsigned int sequence;
+ bool running;
+
struct v4l2_pix_format format;
};
int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru);
void rzg2l_cru_stop_image_processing(struct rzg2l_cru_dev *cru);
+int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on);
+void rzg2l_cru_requeue_active_buffers(struct rzg2l_cru_dev *cru);
+
int rzg2l_cru_dma_register(struct rzg2l_cru_dev *cru);
void rzg2l_cru_dma_unregister(struct rzg2l_cru_dev *cru);
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
index 71d9c671f739..46a0823e1300 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
@@ -155,6 +155,23 @@ static void rzg2l_cru_return_buffers(struct rzg2l_cru_dev *cru,
}
}
+void rzg2l_cru_requeue_active_buffers(struct rzg2l_cru_dev *cru)
+{
+ unsigned int i;
+
+ scoped_guard(spinlock_irqsave, &cru->hw_lock) {
+ for (i = 0; i < cru->num_buf; i++) {
+ if (!cru->queue_buf[i])
+ continue;
+ scoped_guard(spinlock_irqsave, &cru->qlock) {
+ list_add_tail(to_buf_list(cru->queue_buf[i]),
+ &cru->buf_list);
+ }
+ cru->queue_buf[i] = NULL;
+ }
+ }
+}
+
static int rzg2l_cru_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
unsigned int *nplanes, unsigned int sizes[],
struct device *alloc_devs[])
@@ -528,7 +545,7 @@ int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru)
return 0;
}
-static int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on)
+int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on)
{
struct media_pipeline *pipe;
struct v4l2_subdev *sd;
@@ -707,6 +724,7 @@ static int rzg2l_cru_start_streaming_vq(struct vb2_queue *vq, unsigned int count
goto out;
}
+ cru->running = true;
dev_dbg(cru->dev, "Starting to capture\n");
return 0;
@@ -731,7 +749,10 @@ static void rzg2l_cru_stop_streaming_vq(struct vb2_queue *vq)
{
struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vq);
- rzg2l_cru_set_stream(cru, 0);
+ if (cru->running) {
+ rzg2l_cru_set_stream(cru, 0);
+ cru->running = false;
+ }
/* Free scratch buffer */
dma_free_coherent(cru->dev, cru->format.sizeimage,
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 7/9] media: rzg2l-cru: csi2: Add system sleep PM support
2026-06-16 17:05 [PATCH 0/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
` (5 preceding siblings ...)
2026-06-16 17:05 ` [PATCH 6/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
@ 2026-06-16 17:05 ` Tommaso Merciai
2026-06-16 17:05 ` [PATCH 8/9] media: i2c: ov5645: Switch to RUNTIME_PM_OPS() and pm_ptr() Tommaso Merciai
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tommaso Merciai @ 2026-06-16 17:05 UTC (permalink / raw)
To: tomm.merciai
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Sakari Ailus,
Mauro Carvalho Chehab, Lad Prabhakar, Jacopo Mondi, Philipp Zabel,
linux-media, linux-kernel
The rzg2l-csi2 driver has runtime PM callbacks but no system sleep
hooks,leaving the device in an undefined state across system
suspend/resume.
Wire up SYSTEM_SLEEP_PM_OPS with pm_runtime_force_suspend/resume to
reuse the existing runtime PM callbacks for system sleep.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
index 3a4bc4ef72fc..ae1a1816b90a 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
@@ -1042,6 +1042,7 @@ static int rzg2l_csi2_pm_runtime_resume(struct device *dev)
static const struct dev_pm_ops rzg2l_csi2_pm_ops = {
RUNTIME_PM_OPS(rzg2l_csi2_pm_runtime_suspend,
rzg2l_csi2_pm_runtime_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
};
static const struct of_device_id rzg2l_csi2_of_table[] = {
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 8/9] media: i2c: ov5645: Switch to RUNTIME_PM_OPS() and pm_ptr()
2026-06-16 17:05 [PATCH 0/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
` (6 preceding siblings ...)
2026-06-16 17:05 ` [PATCH 7/9] media: rzg2l-cru: csi2: Add system sleep PM support Tommaso Merciai
@ 2026-06-16 17:05 ` Tommaso Merciai
2026-06-16 17:05 ` [PATCH 9/9] media: i2c: ov5645: Add suspend/resume support Tommaso Merciai
2026-07-15 8:47 ` [PATCH 0/9] media: rzg2l-cru: " Tommaso Merciai
9 siblings, 0 replies; 11+ messages in thread
From: Tommaso Merciai @ 2026-06-16 17:05 UTC (permalink / raw)
To: tomm.merciai
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Sakari Ailus,
Mauro Carvalho Chehab, Lad Prabhakar, Jacopo Mondi, Philipp Zabel,
linux-media, linux-kernel
Replace SET_RUNTIME_PM_OPS() with RUNTIME_PM_OPS() and use pm_ptr()
for the power management operations. This brings the driver in line
with current kernel power management APIs and prepares for future
deprecations.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/media/i2c/ov5645.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
index c772ef6e51d2..14692d128571 100644
--- a/drivers/media/i2c/ov5645.c
+++ b/drivers/media/i2c/ov5645.c
@@ -1231,14 +1231,14 @@ static const struct of_device_id ov5645_of_match[] = {
MODULE_DEVICE_TABLE(of, ov5645_of_match);
static const struct dev_pm_ops ov5645_pm_ops = {
- SET_RUNTIME_PM_OPS(ov5645_set_power_off, ov5645_set_power_on, NULL)
+ RUNTIME_PM_OPS(ov5645_set_power_off, ov5645_set_power_on, NULL)
};
static struct i2c_driver ov5645_i2c_driver = {
.driver = {
.of_match_table = ov5645_of_match,
.name = "ov5645",
- .pm = &ov5645_pm_ops,
+ .pm = pm_ptr(&ov5645_pm_ops),
},
.probe = ov5645_probe,
.remove = ov5645_remove,
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 9/9] media: i2c: ov5645: Add suspend/resume support
2026-06-16 17:05 [PATCH 0/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
` (7 preceding siblings ...)
2026-06-16 17:05 ` [PATCH 8/9] media: i2c: ov5645: Switch to RUNTIME_PM_OPS() and pm_ptr() Tommaso Merciai
@ 2026-06-16 17:05 ` Tommaso Merciai
2026-07-15 8:47 ` [PATCH 0/9] media: rzg2l-cru: " Tommaso Merciai
9 siblings, 0 replies; 11+ messages in thread
From: Tommaso Merciai @ 2026-06-16 17:05 UTC (permalink / raw)
To: tomm.merciai
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Sakari Ailus,
Mauro Carvalho Chehab, Lad Prabhakar, Jacopo Mondi, Philipp Zabel,
linux-media, linux-kernel
Add suspend/resume support to the ov5645 driver.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/media/i2c/ov5645.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
index 14692d128571..ac64936bef09 100644
--- a/drivers/media/i2c/ov5645.c
+++ b/drivers/media/i2c/ov5645.c
@@ -1232,6 +1232,7 @@ MODULE_DEVICE_TABLE(of, ov5645_of_match);
static const struct dev_pm_ops ov5645_pm_ops = {
RUNTIME_PM_OPS(ov5645_set_power_off, ov5645_set_power_on, NULL)
+ SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
};
static struct i2c_driver ov5645_i2c_driver = {
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 0/9] media: rzg2l-cru: Add suspend/resume support
2026-06-16 17:05 [PATCH 0/9] media: rzg2l-cru: Add suspend/resume support Tommaso Merciai
` (8 preceding siblings ...)
2026-06-16 17:05 ` [PATCH 9/9] media: i2c: ov5645: Add suspend/resume support Tommaso Merciai
@ 2026-07-15 8:47 ` Tommaso Merciai
9 siblings, 0 replies; 11+ messages in thread
From: Tommaso Merciai @ 2026-07-15 8:47 UTC (permalink / raw)
To: tomm.merciai
Cc: linux-renesas-soc, biju.das.jz, Sakari Ailus,
Mauro Carvalho Chehab, Lad Prabhakar, Jacopo Mondi, Philipp Zabel,
linux-media, linux-kernel
Dear All,
On Tue, Jun 16, 2026 at 07:05:30PM +0200, Tommaso Merciai wrote:
> Dear All,
>
> This patch series adds suspend/resume support to the CRU/CSI-2 driver.
> The series has been tested using ov5645 camera sensor connected to
> the RZ/G3E via CSI-2 connector of the RZ SMARC Carrier II board.
>
> Thanks & Regards,
> Tommaso
>
> Tommaso Merciai (9):
> media: rzg2l-cru: Add device_link from CRU to CSI-2
> media: rzg2l-cru: csi2: Add device_link from CSI-2 to sensor
> media: rzg2l-cru: Use bulk reset API in rzg2l_cru_start_streaming_vq()
> media: rzg2l-cru: Drop stop streaming function
> media: rzg2l-cru: Move active_slot reset into rzg2l_cru_set_stream()
> media: rzg2l-cru: Add suspend/resume support
> media: rzg2l-cru: csi2: Add system sleep PM support
> media: i2c: ov5645: Switch to RUNTIME_PM_OPS() and pm_ptr()
> media: i2c: ov5645: Add suspend/resume support
A gentle ping on this series.
Kind Regards,
Tommaso
>
> drivers/media/i2c/ov5645.c | 5 +-
> .../platform/renesas/rzg2l-cru/rzg2l-core.c | 74 +++++++++++++++++++
> .../platform/renesas/rzg2l-cru/rzg2l-cru.h | 5 ++
> .../platform/renesas/rzg2l-cru/rzg2l-csi2.c | 25 +++++--
> .../platform/renesas/rzg2l-cru/rzg2l-video.c | 55 ++++++++------
> 5 files changed, 135 insertions(+), 29 deletions(-)
>
> --
> 2.54.0
>
^ permalink raw reply [flat|nested] 11+ messages in thread