From 4e30068212a544d79568ab84b0e2a31e42f83192 Mon Sep 17 00:00:00 2001 From: Abhilash Kumar Date: Wed, 18 Dec 2019 16:27:40 +0530 Subject: [PATCH] msm: camera: cdm: Clear IRQ before reading userdata CDM driver read the user_data reg to inform CDM's clients about the request status being served. If before clearing the IRQ, the value of userdata register gets updated, then CDM will not receive another INLINE_IRQ for the updated userdata. This change will make sure that another interrupt is fired by clearing the IRQ first and reading the userdata later. CRs-Fixed: 2581559 Change-Id: I74edf1b8439ae2f88f30b6c2fdbf9ac9f3742503 Signed-off-by: Abhilash Kumar Signed-off-by: Venkat Chinta --- drivers/cam_cdm/cam_cdm_hw_core.c | 50 +++++++++------------ drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 15 ++++++- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/drivers/cam_cdm/cam_cdm_hw_core.c b/drivers/cam_cdm/cam_cdm_hw_core.c index 1142f2776f4f..8145b3293216 100644 --- a/drivers/cam_cdm/cam_cdm_hw_core.c +++ b/drivers/cam_cdm/cam_cdm_hw_core.c @@ -1108,19 +1108,25 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data) for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo_irq; i++) { if (cam_cdm_read_hw_reg(cdm_hw, - cdm_core->offsets->irq_reg[i]->irq_status, - &irq_status[i])) { + cdm_core->offsets->irq_reg[i]->irq_status, + &irq_status[i])) { CAM_ERR(CAM_CDM, "Failed to read CDM HW IRQ status"); } + if (cam_cdm_write_hw_reg(cdm_hw, + cdm_core->offsets->irq_reg[i]->irq_clear, + irq_status[i])) { + CAM_ERR(CAM_CDM, + "Failed to Write CDM HW IRQ Clear"); + } } + if (cam_cdm_write_hw_reg(cdm_hw, + cdm_core->offsets->irq_reg[0]->irq_clear_cmd, 0x01)) + CAM_ERR(CAM_CDM, "Failed to Write CDM HW IRQ cmd 0"); + for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo_irq; i++) { - if (!irq_status[i]) { - cam_cdm_write_hw_reg(cdm_hw, - cdm_core->offsets->irq_reg[i]->irq_clear, - irq_status[i]); + if (!irq_status[i]) continue; - } payload[i] = kzalloc(sizeof(struct cam_cdm_work_payload), GFP_ATOMIC); @@ -1128,11 +1134,10 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data) if (!payload[i]) continue; - if (irq_status[i] & - CAM_CDM_IRQ_STATUS_INLINE_IRQ_MASK) { + if (irq_status[i] & CAM_CDM_IRQ_STATUS_INLINE_IRQ_MASK) { if (cam_cdm_read_hw_reg(cdm_hw, - cdm_core->offsets->cmn_reg->usr_data, - &user_data)) { + cdm_core->offsets->cmn_reg->usr_data, + &user_data)) { CAM_ERR(CAM_CDM, "Failed to read CDM HW IRQ data"); kfree(payload[i]); @@ -1142,9 +1147,8 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data) payload[i]->irq_data = user_data >> (i * 0x8); if (payload[i]->irq_data == - CAM_CDM_DBG_GEN_IRQ_USR_DATA) - CAM_INFO(CAM_CDM, - "Debug gen_irq received"); + CAM_CDM_DBG_GEN_IRQ_USR_DATA) + CAM_INFO(CAM_CDM, "Debug gen_irq received"); } payload[i]->fifo_idx = i; @@ -1154,18 +1158,9 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data) INIT_WORK((struct work_struct *)&payload[i]->work, cam_hw_cdm_work); - if (cam_cdm_write_hw_reg(cdm_hw, - cdm_core->offsets->irq_reg[i]->irq_clear, - payload[i]->irq_status)) { - CAM_ERR(CAM_CDM, - "Failed to Write CDM HW IRQ Clear"); - kfree(payload[i]); - return IRQ_HANDLED; - } - work_status = queue_work( - cdm_core->bl_fifo[i].work_queue, - &payload[i]->work); + cdm_core->bl_fifo[i].work_queue, + &payload[i]->work); if (work_status == false) { CAM_ERR(CAM_CDM, @@ -1175,11 +1170,6 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data) } } - if (cam_cdm_write_hw_reg(cdm_hw, - cdm_core->offsets->irq_reg[0]->irq_clear_cmd, - 0x01)) - CAM_ERR(CAM_CDM, "Failed to Write CDM HW IRQ cmd 0"); - return IRQ_HANDLED; } diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 4baf5f37ac38..379a33c71d34 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -3711,7 +3711,20 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) cam_ife_mgr_pause_hw(ctx); - wait_for_completion(&ctx->config_done_complete); + rc = wait_for_completion_timeout( + &ctx->config_done_complete, + msecs_to_jiffies(300)); + if (rc <= 0) { + CAM_WARN(CAM_ISP, + "config done completion timeout for last applied req_id=%llu rc=%d ctx_index %d", + ctx->applied_req_id, rc, ctx->ctx_index); + rc = -ETIMEDOUT; + } else { + CAM_DBG(CAM_ISP, + "config done Success for req_id=%llu ctx_index %d", + ctx->applied_req_id, ctx->ctx_index); + rc = 0; + } if (stop_isp->stop_only) goto end;