From 4033489c828210e88eb65f714346356f1483ccf1 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Tue, 30 Mar 2021 11:15:30 +0800 Subject: [PATCH] media: rockchip: isp: fix multi dev refcnt Change-Id: Id6c742f1ce90bdf327b382864a26739bdf80661e Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/bridge.c | 28 +++++++----- drivers/media/platform/rockchip/isp/hw.c | 1 + drivers/media/platform/rockchip/isp/hw.h | 1 + drivers/media/platform/rockchip/isp/rkisp.c | 45 ++++++++------------ 4 files changed, 37 insertions(+), 38 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/bridge.c b/drivers/media/platform/rockchip/isp/bridge.c index f562dc64dc03..2cf375e36aa2 100644 --- a/drivers/media/platform/rockchip/isp/bridge.c +++ b/drivers/media/platform/rockchip/isp/bridge.c @@ -760,13 +760,15 @@ static void free_bridge_buf(struct rkisp_bridge_device *dev) unsigned long lock_flags = 0; int i, j; - if (atomic_dec_return(&hw->refcnt)) + spin_lock_irqsave(&hw->buf_lock, lock_flags); + if (--hw->buf_init_cnt > 0) { + spin_unlock_irqrestore(&hw->buf_lock, lock_flags); return; + } v4l2_dbg(1, rkisp_debug, &dev->ispdev->v4l2_dev, "%s\n", __func__); - spin_lock_irqsave(&hw->buf_lock, lock_flags); if (hw->cur_buf) { list_add_tail(&hw->cur_buf->list, &hw->list); if (hw->cur_buf == hw->nxt_buf) @@ -817,8 +819,12 @@ static int init_buf(struct rkisp_bridge_device *dev, u32 pic_size, u32 gain_size int i, j, val, ret = 0; unsigned long lock_flags = 0; - if (atomic_inc_return(&hw->refcnt) > 1) + spin_lock_irqsave(&hw->buf_lock, lock_flags); + if (++hw->buf_init_cnt > 1) { + spin_unlock_irqrestore(&hw->buf_lock, lock_flags); return 0; + } + spin_unlock_irqrestore(&hw->buf_lock, lock_flags); v4l2_dbg(1, rkisp_debug, &dev->ispdev->v4l2_dev, "%s pic size:%d gain size:%d\n", @@ -1201,11 +1207,12 @@ static int bridge_s_rx_buffer(struct v4l2_subdev *sd, struct rkisp_ispp_buf *dbufs = buf; unsigned long lock_flags = 0; - /* size isn't using now */ - if (!dbufs || !atomic_read(&hw->refcnt)) - return -EINVAL; - spin_lock_irqsave(&hw->buf_lock, lock_flags); + /* size isn't using now */ + if (!dbufs || !hw->buf_init_cnt) { + spin_unlock_irqrestore(&hw->buf_lock, lock_flags); + return -EINVAL; + } list_add_tail(&dbufs->list, &hw->list); spin_unlock_irqrestore(&hw->buf_lock, lock_flags); return 0; @@ -1302,13 +1309,12 @@ int rkisp_bridge_get_fbcbuf_fd(struct rkisp_device *dev, struct isp2x_buf_idxfd struct rkisp_bridge_buf *buf; struct rkisp_dummy_buffer *dummy; unsigned long lock_flags = 0; - int i, j, buf_idx, ret = 0; + int i, j, buf_idx; spin_lock_irqsave(&hw->buf_lock, lock_flags); if (!hw->is_buf_init) { spin_unlock_irqrestore(&hw->buf_lock, lock_flags); - ret = -EAGAIN; - return ret; + return -EAGAIN; } spin_unlock_irqrestore(&hw->buf_lock, lock_flags); @@ -1327,7 +1333,7 @@ int rkisp_bridge_get_fbcbuf_fd(struct rkisp_device *dev, struct isp2x_buf_idxfd idxfd->buf_num = buf_idx; - return ret; + return 0; } void rkisp_bridge_sendtopp_buffer(struct rkisp_device *dev, u32 dev_id, u32 buf_idx) diff --git a/drivers/media/platform/rockchip/isp/hw.c b/drivers/media/platform/rockchip/isp/hw.c index 06102e44940f..728bffd925c0 100644 --- a/drivers/media/platform/rockchip/isp/hw.c +++ b/drivers/media/platform/rockchip/isp/hw.c @@ -717,6 +717,7 @@ static int rkisp_hw_probe(struct platform_device *pdev) spin_lock_init(&hw_dev->buf_lock); INIT_LIST_HEAD(&hw_dev->list); INIT_LIST_HEAD(&hw_dev->rpt_list); + hw_dev->buf_init_cnt = 0; hw_dev->is_idle = true; hw_dev->is_single = true; hw_dev->is_mi_update = false; diff --git a/drivers/media/platform/rockchip/isp/hw.h b/drivers/media/platform/rockchip/isp/hw.h index a9490865dd66..d6cd8867d809 100644 --- a/drivers/media/platform/rockchip/isp/hw.h +++ b/drivers/media/platform/rockchip/isp/hw.h @@ -56,6 +56,7 @@ struct rkisp_hw_dev { struct rkisp_dummy_buffer dummy_buf; const struct vb2_mem_ops *mem_ops; u64 iq_feature; + int buf_init_cnt; bool is_feature_on; bool is_dma_contig; bool is_mmu; diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 6407c334926e..877af353218a 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -812,16 +812,13 @@ static int rkisp_config_path(struct rkisp_device *dev) static int rkisp_config_cif(struct rkisp_device *dev) { int ret = 0; - u32 cif_id; v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, - "SP streaming = %d, MP streaming = %d\n", + "%s CIF_ID:0x%x SP:%d, MP:%d\n", __func__, + readl(dev->base_addr + CIF_VI_ID), dev->cap_dev.stream[RKISP_STREAM_SP].streaming, dev->cap_dev.stream[RKISP_STREAM_MP].streaming); - cif_id = readl(dev->base_addr + CIF_VI_ID); - v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, "CIF_ID 0x%08x\n", cif_id); - ret = rkisp_config_isp(dev); if (ret < 0) return ret; @@ -900,9 +897,8 @@ static int rkisp_isp_stop(struct rkisp_device *dev) u32 i; v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, - "SP streaming = %d, MP streaming = %d\n", - dev->cap_dev.stream[RKISP_STREAM_SP].streaming, - dev->cap_dev.stream[RKISP_STREAM_MP].streaming); + "%s refcnt:%d\n", __func__, + atomic_read(&dev->hw_dev->refcnt)); if (atomic_read(&dev->hw_dev->refcnt) > 1) goto end; @@ -964,12 +960,8 @@ static int rkisp_isp_stop(struct rkisp_device *dev) readx_poll_timeout_atomic(readl, base + CIF_ISP_RIS, val, val & CIF_ISP_OFF, 20, 100); v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, - "streaming(MP:%d, SP:%d), MI_CTRL:%x, ISP_CTRL:%x, MIPI_CTRL:%x\n", - dev->cap_dev.stream[RKISP_STREAM_SP].streaming, - dev->cap_dev.stream[RKISP_STREAM_MP].streaming, - readl(base + CIF_MI_CTRL), - readl(base + CIF_ISP_CTRL), - readl(base + CIF_MIPI_CTRL)); + "MI_CTRL:%x, ISP_CTRL:%x\n", + readl(base + CIF_MI_CTRL), readl(base + CIF_ISP_CTRL)); val = rkisp_read(dev, CTRL_VI_ISP_CLK_CTRL, true); if (!in_interrupt()) { @@ -1027,9 +1019,8 @@ static int rkisp_isp_start(struct rkisp_device *dev) bool is_direct = true; v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, - "SP streaming = %d, MP streaming = %d\n", - dev->cap_dev.stream[RKISP_STREAM_SP].streaming, - dev->cap_dev.stream[RKISP_STREAM_MP].streaming); + "%s refcnt:%d\n", __func__, + atomic_read(&dev->hw_dev->refcnt)); /* Activate MIPI */ if (sensor && sensor->mbus.type == V4L2_MBUS_CSI2) { @@ -1070,13 +1061,8 @@ static int rkisp_isp_start(struct rkisp_device *dev) usleep_range(1000, 1200); v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, - "SP streaming = %d, MP streaming = %d MI_CTRL 0x%08x\n" - " ISP_CTRL 0x%08x MIPI_CTRL 0x%08x\n", - dev->cap_dev.stream[RKISP_STREAM_SP].streaming, - dev->cap_dev.stream[RKISP_STREAM_MP].streaming, - readl(base + CIF_MI_CTRL), - readl(base + CIF_ISP_CTRL), - readl(base + CIF_MIPI_CTRL)); + "%s MI_CTRL 0x%08x ISP_CTRL 0x%08x\n", __func__, + readl(base + CIF_MI_CTRL), readl(base + CIF_ISP_CTRL)); rkisp_csi_trigger_event(dev, T_CMD_QUEUE, NULL); return 0; @@ -1645,6 +1631,7 @@ static int rkisp_isp_sd_s_stream(struct v4l2_subdev *sd, int on) if (!on) { rkisp_stop_3a_run(isp_dev); + atomic_dec(&isp_dev->hw_dev->refcnt); wait_event_timeout(isp_dev->sync_onoff, isp_dev->irq_ends_mask == (ISP_FRAME_END | ISP_FRAME_IN) && (!IS_HDR_RDBK(isp_dev->csi_dev.rd_mode) || @@ -1653,13 +1640,17 @@ static int rkisp_isp_sd_s_stream(struct v4l2_subdev *sd, int on) } rkisp_start_3a_run(isp_dev); - + atomic_inc(&isp_dev->hw_dev->refcnt); atomic_set(&isp_dev->isp_sdev.frm_sync_seq, 0); ret = rkisp_config_cif(isp_dev); if (ret < 0) - return ret; + goto out; - return rkisp_isp_start(isp_dev); + ret = rkisp_isp_start(isp_dev); +out: + if (ret < 0) + atomic_dec(&isp_dev->hw_dev->refcnt); + return ret; } static int rkisp_isp_sd_s_power(struct v4l2_subdev *sd, int on)