From 6a7992e12267fda77c41ef1c5536fa4d1391cb92 Mon Sep 17 00:00:00 2001 From: Vicent Chi Date: Wed, 10 Mar 2021 21:06:05 +0800 Subject: [PATCH] media: platform: cif: not allow reset work after all streams off Change-Id: Ifceccb3788dae7a95dae09a0c524a52b33808a26 Signed-off-by: Vicent Chi Signed-off-by: Zefa Chen --- drivers/media/platform/rockchip/cif/capture.c | 25 +++++++++++++------ drivers/media/platform/rockchip/cif/dev.h | 1 + 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index db966f92d72c..667ba9e44a21 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -1904,6 +1904,8 @@ static void rkcif_destroy_dummy_buf(struct rkcif_stream *stream) if (dummy_buf->vaddr) dma_free_coherent(hw_dev->dev, dummy_buf->size, dummy_buf->vaddr, dummy_buf->dma_addr); + dummy_buf->dma_addr = 0; + dummy_buf->vaddr = NULL; } static void rkcif_do_cru_reset(struct rkcif_device *dev) @@ -2056,9 +2058,10 @@ static void rkcif_stop_streaming(struct vb2_queue *queue) dev->can_be_reset = true; } - if (dev->can_be_reset) { + if (dev->can_be_reset && !atomic_read(&(dev->pipe.stream_cnt))) { rkcif_do_cru_reset(dev); dev->can_be_reset = false; + dev->reset_work_cancel = true; } pm_runtime_put(dev->dev); @@ -2713,6 +2716,8 @@ static int rkcif_start_streaming(struct vb2_queue *queue, unsigned int count) } } + dev->reset_work_cancel = false; + goto out; stop_stream: @@ -4510,6 +4515,11 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev, int i, j, ret = 0; u32 on; + mutex_lock(&cif_dev->stream_lock); + + if (cif_dev->reset_work_cancel) + goto unlock_stream; + v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev, "do rkcif reset\n"); for (i = 0, j = 0; i < RKCIF_MAX_STREAM_MIPI; i++) { @@ -4517,8 +4527,6 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev, if (stream->state == RKCIF_STATE_STREAMING) { - mutex_lock(&cif_dev->stream_lock); - v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev, "stream[%d] stopping\n", stream->id); @@ -4539,8 +4547,6 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev, resume_stream[j] = stream; j += 1; - mutex_unlock(&cif_dev->stream_lock); - v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev, "%s stop stream[%d] in streaming, frm_id:%d, csi_sof:%d\n", __func__, stream->id, stream->frame_idx, rkcif_csi2_get_sof()); @@ -4586,7 +4592,7 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev, ret = rkcif_enable_sys_clk(cif_dev->hw_dev); if (ret < 0) { v4l2_err(&cif_dev->v4l2_dev, "%s:resume cif clk failed\n", __func__); - return ret; + goto unlock_stream; } for (i = 0; i < j; i++) { @@ -4594,7 +4600,7 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev, if (ret) { v4l2_err(&cif_dev->v4l2_dev, "%s:resume stream[%d] failed\n", __func__, stream->id); - return ret; + goto unlock_stream; } v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev, @@ -4641,7 +4647,12 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev, v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev, "do rkcif reset successfully!\n"); + mutex_unlock(&cif_dev->stream_lock); return 0; + +unlock_stream: + mutex_unlock(&cif_dev->stream_lock); + return ret; } static void rkcif_reset_work(struct work_struct *work) diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index 11b93c235632..d194755077da 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -510,6 +510,7 @@ struct rkcif_device { struct notifier_block reset_notifier; /* reset for mipi csi crc err */ struct rkcif_work_struct reset_work; + bool reset_work_cancel; struct rkcif_timer reset_watchdog_timer; struct work_struct async_register_work; unsigned int buf_wake_up_cnt;