From: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
The CRU driver uses a single spinlock to protect the buffers queue and
the hardware operations.
This single spinlock is held for the whole duration of the interrupt
handler, causing all other driver's operations to freeze.
Under heavy system stress conditions with userspace not providing
buffers fast enough, this causes loss of frames.
Prepare to re-work the driver locking by introducing (but not using yet)
a new spinlock to protect the hardware registers programming.
Signed-off-by: Jacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
Reviewed-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
---
drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h | 10 +++++++---
drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c | 1 +
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
index be4a9a4953d1..12d574182eb8 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
@@ -111,7 +111,6 @@ struct rzg2l_cru_info {
* @v4l2_dev: V4L2 device
* @num_buf: Holds the current number of buffers enabled
* @svc_channel: SVC0/1/2/3 to use for RZ/G3E
- * @buf_addr: Memory addresses where current video data is written.
* @notifier: V4L2 asynchronous subdevs notifier
*
* @ip: Image processing subdev info
@@ -120,6 +119,10 @@ struct rzg2l_cru_info {
* @mdev_lock: protects the count, notifier and csi members
* @pad: media pad for the video device entity
*
+ * @hw_lock: protects the slot counter, hardware programming of
+ * slot addresses and the @buf_addr[] list
+ * @buf_addr: Memory addresses where current video data is written
+ *
* @lock: protects @queue
* @queue: vb2 buffers queue
* @scratch: cpu address for scratch buffer
@@ -149,8 +152,6 @@ struct rzg2l_cru_dev {
u8 num_buf;
u8 svc_channel;
- dma_addr_t buf_addr[RZG2L_CRU_HW_BUFFER_DEFAULT];
-
struct v4l2_async_notifier notifier;
struct rzg2l_cru_ip ip;
@@ -159,6 +160,9 @@ struct rzg2l_cru_dev {
struct mutex mdev_lock;
struct media_pad pad;
+ spinlock_t hw_lock;
+ dma_addr_t buf_addr[RZG2L_CRU_HW_BUFFER_DEFAULT];
+
struct mutex lock;
struct vb2_queue queue;
void *scratch;
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
index c49131587679..b6616d54f8a3 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
@@ -843,6 +843,7 @@ int rzg2l_cru_dma_register(struct rzg2l_cru_dev *cru)
mutex_init(&cru->lock);
INIT_LIST_HEAD(&cru->buf_list);
+ spin_lock_init(&cru->hw_lock);
spin_lock_init(&cru->qlock);
cru->state = RZG2L_CRU_DMA_STOPPED;
--
2.53.0