diff --git a/drivers/cam_icp/cam_icp_context.c b/drivers/cam_icp/cam_icp_context.c index 7d2ef39e0aeb..180ea7152a76 100644 --- a/drivers/cam_icp/cam_icp_context.c +++ b/drivers/cam_icp/cam_icp_context.c @@ -37,8 +37,6 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova, return -EINVAL; } - mutex_lock(&ctx->ctx_mutex); - if (ctx->state < CAM_CTX_ACQUIRED || ctx->state > CAM_CTX_ACTIVATED) { CAM_ERR(CAM_ICP, "Invalid state icp ctx %d state %d", ctx->ctx_id, ctx->state); @@ -64,7 +62,6 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova, } end: - mutex_unlock(&ctx->ctx_mutex); return rc; } diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 67cb42aa1661..65e0f7f66c09 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -3031,6 +3031,36 @@ static int cam_icp_mgr_hfi_resume(struct cam_icp_hw_mgr *hw_mgr) hw_mgr->a5_jtag_debug); } +static int cam_icp_retry_wait_for_abort( + struct cam_icp_hw_ctx_data *ctx_data) +{ + int retry_cnt = 1; + unsigned long rem_jiffies; + int timeout = 1000; + + CAM_WARN(CAM_ICP, "FW timeout in abort ctx: %u retry_left: %d", + ctx_data->ctx_id, retry_cnt); + while (retry_cnt > 0) { + rem_jiffies = wait_for_completion_timeout( + &ctx_data->wait_complete, + msecs_to_jiffies((timeout))); + if (!rem_jiffies) { + retry_cnt--; + if (retry_cnt > 0) { + CAM_WARN(CAM_ICP, + "FW timeout in abort ctx: %u retry_left: %u", + ctx_data->ctx_id, retry_cnt); + continue; + } + } + + if (retry_cnt > 0) + return 0; + } + + return -ETIMEDOUT; +} + static int cam_icp_mgr_abort_handle( struct cam_icp_hw_ctx_data *ctx_data) { @@ -3074,10 +3104,14 @@ static int cam_icp_mgr_abort_handle( rem_jiffies = wait_for_completion_timeout(&ctx_data->wait_complete, msecs_to_jiffies((timeout))); if (!rem_jiffies) { - rc = -ETIMEDOUT; - CAM_ERR(CAM_ICP, "FW timeout/err in abort handle command"); - cam_icp_mgr_process_dbg_buf(icp_hw_mgr.a5_dbg_lvl); - cam_hfi_queue_dump(); + rc = cam_icp_retry_wait_for_abort(ctx_data); + if (rc) { + CAM_ERR(CAM_ICP, + "FW timeout/err in abort handle command ctx: %u", + ctx_data->ctx_id); + cam_icp_mgr_process_dbg_buf(icp_hw_mgr.a5_dbg_lvl); + cam_hfi_queue_dump(); + } } kfree(abort_cmd); @@ -4805,6 +4839,24 @@ static int cam_icp_mgr_flush_req(struct cam_icp_hw_ctx_data *ctx_data, return 0; } +static void cam_icp_mgr_flush_info_dump( + struct cam_hw_flush_args *flush_args, uint32_t ctx_id) +{ + int i; + + for (i = 0; i < flush_args->num_req_active; i++) { + CAM_DBG(CAM_ICP, "Flushing active request %lld in ctx %u", + *(int64_t *)flush_args->flush_req_active[i], + ctx_id); + } + + for (i = 0; i < flush_args->num_req_pending; i++) { + CAM_DBG(CAM_ICP, "Flushing pending request %lld in ctx %u", + *(int64_t *)flush_args->flush_req_pending[i], + ctx_id); + } +} + static int cam_icp_mgr_hw_flush(void *hw_priv, void *hw_flush_args) { struct cam_hw_flush_args *flush_args = hw_flush_args; @@ -4838,6 +4890,8 @@ static int cam_icp_mgr_hw_flush(void *hw_priv, void *hw_flush_args) if (!atomic_read(&hw_mgr->recovery) && flush_args->num_req_active) { mutex_unlock(&hw_mgr->hw_mgr_mutex); + cam_icp_mgr_flush_info_dump(flush_args, + ctx_data->ctx_id); cam_icp_mgr_abort_handle(ctx_data); } else { mutex_unlock(&hw_mgr->hw_mgr_mutex);