diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index 49daf9454c6e..64a4e74a17b0 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -689,6 +689,9 @@ static int rkisp_get_reserved_mem(struct rkisp_device *isp_dev) DMA_BIDIRECTIONAL); ret = dma_mapping_error(dev, isp_dev->resmem_addr); + isp_dev->is_thunderboot = true; + atomic_inc(&isp_dev->hw_dev->tb_ref); + dev_info(dev, "Allocated reserved memory, paddr: 0x%x\n", (u32)isp_dev->resmem_pa); return ret; @@ -729,9 +732,11 @@ static int rkisp_plat_probe(struct platform_device *pdev) sprintf(isp_dev->media_dev.model, "%s%d", DRIVER_NAME, isp_dev->dev_id); - ret = rkisp_get_reserved_mem(isp_dev); - if (ret) - return ret; + if (isp_dev->hw_dev->is_thunderboot) { + ret = rkisp_get_reserved_mem(isp_dev); + if (ret) + return ret; + } mutex_init(&isp_dev->apilock); mutex_init(&isp_dev->iqlock); @@ -790,6 +795,8 @@ static int rkisp_plat_probe(struct platform_device *pdev) mutex_unlock(&rkisp_dev_mutex); pm_runtime_enable(dev); + if (isp_dev->hw_dev->is_thunderboot && isp_dev->is_thunderboot) + pm_runtime_get_noresume(isp_dev->hw_dev->dev); return 0; err_unreg_media_dev: diff --git a/drivers/media/platform/rockchip/isp/dev.h b/drivers/media/platform/rockchip/isp/dev.h index e3f9951c22cf..1b61bd7ac167 100644 --- a/drivers/media/platform/rockchip/isp/dev.h +++ b/drivers/media/platform/rockchip/isp/dev.h @@ -228,6 +228,7 @@ struct rkisp_device { bool send_fbcgain; struct rkisp_ispp_buf *cur_fbcgain; struct rkisp_buffer *cur_spbuf; + bool is_thunderboot; struct kfifo rdbk_kfifo; spinlock_t rdbk_lock; diff --git a/drivers/media/platform/rockchip/isp/hw.c b/drivers/media/platform/rockchip/isp/hw.c index 5707b29ea975..60aa89587db8 100644 --- a/drivers/media/platform/rockchip/isp/hw.c +++ b/drivers/media/platform/rockchip/isp/hw.c @@ -729,6 +729,7 @@ static int rkisp_hw_probe(struct platform_device *pdev) mutex_init(&hw_dev->dev_lock); spin_lock_init(&hw_dev->rdbk_lock); atomic_set(&hw_dev->refcnt, 0); + atomic_set(&hw_dev->tb_ref, 0); spin_lock_init(&hw_dev->buf_lock); INIT_LIST_HEAD(&hw_dev->list); INIT_LIST_HEAD(&hw_dev->rpt_list); diff --git a/drivers/media/platform/rockchip/isp/hw.h b/drivers/media/platform/rockchip/isp/hw.h index 8b34e203bd6a..f7d1e80b42b5 100644 --- a/drivers/media/platform/rockchip/isp/hw.h +++ b/drivers/media/platform/rockchip/isp/hw.h @@ -79,6 +79,7 @@ struct rkisp_hw_dev { bool is_thunderboot; bool is_buf_init; bool is_shutdown; + atomic_t tb_ref; }; int rkisp_register_irq(struct rkisp_hw_dev *dev); diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index f7101ed60ea9..14c2670f7bac 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -2271,6 +2271,9 @@ static int rkisp_isp_sd_s_power(struct v4l2_subdev *sd, int on) struct rkisp_device *isp_dev = sd_to_isp_dev(sd); int ret; + if (isp_dev->hw_dev->is_thunderboot) + return 0; + v4l2_dbg(1, rkisp_debug, &isp_dev->v4l2_dev, "%s on:%d\n", __func__, on); @@ -2764,23 +2767,22 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev) enum rkisp_tb_state tb_state; void *resmem_va; - if (!isp_dev->resmem_pa || !isp_dev->resmem_size) { - v4l2_info(&isp_dev->v4l2_dev, - "no reserved memory for thunderboot\n"); - if (isp_dev->hw_dev->is_thunderboot) { - rkisp_tb_set_state(RKISP_TB_NG); - rkisp_tb_unprotect_clk(); - rkisp_register_irq(isp_dev->hw_dev); - isp_dev->hw_dev->is_thunderboot = false; - } + if (!isp_dev->hw_dev->is_thunderboot) + return; + + if (!atomic_read(&isp_dev->hw_dev->tb_ref)) { + rkisp_tb_set_state(RKISP_TB_NG); + rkisp_tb_unprotect_clk(); + rkisp_register_irq(isp_dev->hw_dev); + isp_dev->hw_dev->is_thunderboot = false; return; } resmem_va = phys_to_virt(isp_dev->resmem_pa); head = (struct rkisp_thunderboot_resmem_head *)resmem_va; - if (isp_dev->hw_dev->is_thunderboot) { + if (isp_dev->is_thunderboot) { shm_head_poll_timeout(isp_dev, !!head->enable, 2000, 200 * USEC_PER_MSEC); - shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 500 * USEC_PER_MSEC); + shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 600 * USEC_PER_MSEC); if (head->complete != RKISP_TB_OK) v4l2_info(&isp_dev->v4l2_dev, "wait thunderboot over timeout\n"); @@ -2800,11 +2802,13 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev) head->frm_total = 0; tb_state = RKISP_TB_NG; } - rkisp_tb_set_state(tb_state); rkisp_tb_unprotect_clk(); rkisp_register_irq(isp_dev->hw_dev); + pm_runtime_put(isp_dev->hw_dev->dev); isp_dev->hw_dev->is_thunderboot = false; + isp_dev->is_thunderboot = false; + atomic_dec(&isp_dev->hw_dev->tb_ref); } } #endif