media: platform: cif: not allow reset work after all streams off

Change-Id: Ifceccb3788dae7a95dae09a0c524a52b33808a26
Signed-off-by: Vicent Chi <vicent.chi@rock-chips.com>
Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com>
This commit is contained in:
Vicent Chi
2021-03-10 21:06:05 +08:00
committed by Zefa Chen
parent 82cb10f7bc
commit 6a7992e122
2 changed files with 19 additions and 7 deletions

View File

@@ -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)

View File

@@ -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;