Loading drivers/cam_isp/cam_isp_context.c +32 −4 Original line number Diff line number Diff line Loading @@ -658,6 +658,7 @@ static int __cam_isp_ctx_handle_buf_done_for_request( CAM_DBG(CAM_REQ, "Move active request %lld to free list(cnt = %d) [all fences done], ctx %u", buf_done_req_id, ctx_isp->active_req_cnt, ctx->ctx_id); ctx_isp->req_info.last_bufdone_req_id = req->request_id; } __cam_isp_ctx_update_state_monitor_array(ctx_isp, Loading Loading @@ -857,6 +858,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -1027,7 +1029,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, * If no wait req in epoch, this is an error case. * The recovery is to go back to sof state */ CAM_ERR(CAM_ISP, "No wait request"); CAM_ERR(CAM_ISP, "Ctx:%d No wait request", ctx->ctx_id); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; /* Send SOF event as empty frame*/ Loading @@ -1043,7 +1045,8 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, req_isp->bubble_detected = true; req_isp->reapply = true; CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); CAM_INFO(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld", ctx->ctx_id, req_isp->bubble_report, req->request_id); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; Loading Loading @@ -1192,7 +1195,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( * If no pending req in epoch, this is an error case. * Just go back to the bubble state. */ CAM_ERR(CAM_ISP, "No pending request."); CAM_ERR(CAM_ISP, "ctx:%d No pending request.", ctx->ctx_id); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); Loading @@ -1204,6 +1207,8 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld", ctx->ctx_id, req_isp->bubble_report, req->request_id); req_isp->reapply = true; if (req_isp->bubble_report && ctx->ctx_crm_intf && Loading Loading @@ -1542,6 +1547,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -1719,6 +1725,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -2406,6 +2413,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_top_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -2502,9 +2510,10 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld", ctx->ctx_id, req_isp->bubble_report, req->request_id); req_isp->reapply = true; CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; Loading Loading @@ -2603,6 +2612,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -2675,6 +2685,7 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -2872,6 +2883,7 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx, ctx_isp->reported_req_id = 0; ctx_isp->hw_acquired = false; ctx_isp->init_received = false; ctx_isp->req_info.last_bufdone_req_id = 0; atomic64_set(&ctx_isp->state_monitor_head, -1); Loading Loading @@ -2932,6 +2944,7 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx, ctx_isp->hw_acquired = false; ctx_isp->init_received = false; ctx_isp->rdi_only_context = false; ctx_isp->req_info.last_bufdone_req_id = 0; atomic64_set(&ctx_isp->state_monitor_head, -1); Loading Loading @@ -3862,6 +3875,18 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( __cam_isp_ctx_substate_val_to_type( ctx_isp->substate_activated)); if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_stop) { struct cam_req_mgr_notify_stop notify; notify.link_hdl = ctx->link_hdl; CAM_DBG(CAM_ISP, "Notify CRM about device stop ctx %u link 0x%x", ctx->ctx_id, ctx->link_hdl); ctx->ctx_crm_intf->notify_stop(¬ify); } else CAM_ERR(CAM_ISP, "cb not present"); while (!list_empty(&ctx->pending_req_list)) { req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request, list); Loading Loading @@ -3909,11 +3934,13 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( } list_add_tail(&req->list, &ctx->free_req_list); } ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; ctx_isp->reported_req_id = 0; ctx_isp->bubble_frame_cnt = 0; ctx_isp->last_applied_req_id = 0; ctx_isp->req_info.last_bufdone_req_id = 0; atomic_set(&ctx_isp->process_bubble, 0); atomic64_set(&ctx_isp->state_monitor_head, -1); Loading Loading @@ -4372,6 +4399,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx, ctx->frame_id = 0; ctx->active_req_cnt = 0; ctx->reported_req_id = 0; ctx->req_info.last_bufdone_req_id = 0; ctx->bubble_frame_cnt = 0; ctx->hw_ctx = NULL; ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; Loading drivers/cam_isp/cam_isp_context.h +14 −0 Original line number Diff line number Diff line Loading @@ -149,6 +149,18 @@ struct cam_isp_context_state_monitor { }; /** * struct cam_isp_context_req_id_info - ISP context request id * information for bufdone. * *@last_bufdone_req_id: Last bufdone request id * */ struct cam_isp_context_req_id_info { int64_t last_bufdone_req_id; }; /** * * struct cam_isp_context - ISP context object * * @base: Common context object pointer Loading @@ -170,6 +182,7 @@ struct cam_isp_context_state_monitor { * will invoke CRM cb at those event. * @last_applied_req_id: Last applied request id * @state_monitor_head: Write index to the state monitoring array * @req_info Request id information about last buf done * @cam_isp_ctx_state_monitor: State monitoring array * @rdi_only_context: Get context type information. * true, if context is rdi only context Loading Loading @@ -202,6 +215,7 @@ struct cam_isp_context { atomic64_t state_monitor_head; struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES]; struct cam_isp_context_req_id_info req_info; bool rdi_only_context; bool hw_acquired; bool init_received; Loading drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +89 −65 Original line number Diff line number Diff line Loading @@ -1036,7 +1036,7 @@ static int cam_ife_hw_mgr_acquire_res_bus_rd( /*TBD */ vfe_acquire.vfe_out.is_master = 1; vfe_acquire.vfe_out.dual_slave_core = (hw_intf->hw_idx == 0) ? 1 : 0; ife_ctx->slave_hw_idx; } else { vfe_acquire.vfe_out.is_master = 0; vfe_acquire.vfe_out.dual_slave_core = Loading @@ -1047,7 +1047,7 @@ static int cam_ife_hw_mgr_acquire_res_bus_rd( CAM_ISP_HW_SPLIT_RIGHT; vfe_acquire.vfe_out.is_master = 0; vfe_acquire.vfe_out.dual_slave_core = (hw_intf->hw_idx == 0) ? 1 : 0; ife_ctx->master_hw_idx; } rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire, Loading Loading @@ -1229,7 +1229,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel( /*TBD */ vfe_acquire.vfe_out.is_master = 1; vfe_acquire.vfe_out.dual_slave_core = (hw_intf->hw_idx == 0) ? 1 : 0; ife_ctx->slave_hw_idx; } else { vfe_acquire.vfe_out.is_master = 0; vfe_acquire.vfe_out.dual_slave_core = Loading @@ -1240,9 +1240,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel( CAM_ISP_HW_SPLIT_RIGHT; vfe_acquire.vfe_out.is_master = 0; vfe_acquire.vfe_out.dual_slave_core = (hw_intf->hw_idx == 0) ? 1 : 0; ife_ctx->master_hw_idx; } rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire, sizeof(struct cam_vfe_acquire_args)); Loading Loading @@ -1659,6 +1658,54 @@ static int cam_ife_hw_mgr_acquire_res_ife_src( return rc; } static int cam_ife_hw_mgr_acquire_csid_hw( struct cam_ife_hw_mgr *ife_hw_mgr, struct cam_csid_hw_reserve_resource_args *csid_acquire, bool is_start_lower_idx) { int i; int rc = -1; struct cam_hw_intf *hw_intf; if (!ife_hw_mgr || !csid_acquire) { CAM_ERR(CAM_ISP, "Invalid args ife hw mgr %pK csid_acquire %pK", ife_hw_mgr, csid_acquire); return -EINVAL; } if (is_start_lower_idx) { for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) { if (!ife_hw_mgr->csid_devices[i]) continue; hw_intf = ife_hw_mgr->csid_devices[i]; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, csid_acquire, sizeof(struct cam_csid_hw_reserve_resource_args)); if (!rc) return rc; } return rc; } for (i = CAM_IFE_CSID_HW_NUM_MAX - 1; i >= 0; i--) { if (!ife_hw_mgr->csid_devices[i]) continue; hw_intf = ife_hw_mgr->csid_devices[i]; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, csid_acquire, sizeof(struct cam_csid_hw_reserve_resource_args)); if (!rc) return rc; } return rc; } static int cam_ife_mgr_acquire_cid_res( struct cam_ife_hw_mgr_ctx *ife_ctx, struct cam_isp_in_port_generic_info *in_port, Loading Loading @@ -1751,52 +1798,21 @@ static int cam_ife_mgr_acquire_cid_res( } /* Acquire Left if not already acquired */ if (ife_ctx->is_fe_enable) { for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) { if (!ife_hw_mgr->csid_devices[i]) continue; hw_intf = ife_hw_mgr->csid_devices[i]; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &csid_acquire, sizeof(csid_acquire)); if (rc) continue; else { cid_res_temp->hw_res[acquired_cnt++] = csid_acquire.node_res; break; } } if (i == CAM_IFE_CSID_HW_NUM_MAX || !csid_acquire.node_res) { CAM_ERR(CAM_ISP, "Can not acquire ife cid resource for path %d", path_res_id); goto put_res; } } else { for (i = CAM_IFE_CSID_HW_NUM_MAX - 1; i >= 0; i--) { if (!ife_hw_mgr->csid_devices[i]) continue; /* For dual IFE cases, start acquiring the lower idx first */ if (ife_ctx->is_fe_enable || in_port->usage_type) rc = cam_ife_hw_mgr_acquire_csid_hw(ife_hw_mgr, &csid_acquire, true); else rc = cam_ife_hw_mgr_acquire_csid_hw(ife_hw_mgr, &csid_acquire, false); hw_intf = ife_hw_mgr->csid_devices[i]; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &csid_acquire, sizeof(csid_acquire)); if (rc) continue; else { cid_res_temp->hw_res[acquired_cnt++] = csid_acquire.node_res; break; } } if (i == -1 || !csid_acquire.node_res) { if (rc || !csid_acquire.node_res) { CAM_ERR(CAM_ISP, "Can not acquire ife cid resource for path %d", path_res_id); goto put_res; } } cid_res_temp->hw_res[acquired_cnt++] = csid_acquire.node_res; acquire_successful: CAM_DBG(CAM_ISP, "CID left acquired success is_dual %d", Loading @@ -1807,7 +1823,9 @@ static int cam_ife_mgr_acquire_cid_res( cid_res_temp->res_id = csid_acquire.node_res->res_id; cid_res_temp->is_dual_vfe = in_port->usage_type; ife_ctx->is_dual = (bool)in_port->usage_type; if (ife_ctx->is_dual) ife_ctx->master_hw_idx = cid_res_temp->hw_res[0]->hw_intf->hw_idx; if (in_port->num_out_res) cid_res_temp->is_secure = out_port->secure_mode; Loading Loading @@ -1844,6 +1862,8 @@ static int cam_ife_mgr_acquire_cid_res( goto end; } cid_res_temp->hw_res[1] = csid_acquire.node_res; ife_ctx->slave_hw_idx = cid_res_temp->hw_res[1]->hw_intf->hw_idx; CAM_DBG(CAM_ISP, "CID right acquired success is_dual %d", in_port->usage_type); } Loading Loading @@ -6249,8 +6269,9 @@ static int cam_ife_hw_mgr_handle_hw_rup( switch (event_info->res_id) { case CAM_ISP_HW_VFE_IN_CAMIF: if (ife_hw_mgr_ctx->is_dual) if (event_info->hw_idx != 1) if ((ife_hw_mgr_ctx->is_dual) && (event_info->hw_idx != ife_hw_mgr_ctx->master_hw_idx)) break; if (atomic_read(&ife_hw_mgr_ctx->overflow_pending)) Loading Loading @@ -6292,8 +6313,8 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe( { int32_t rc = -1; uint32_t *event_cnt = NULL; uint32_t core_idx0 = 0; uint32_t core_idx1 = 1; uint32_t master_hw_idx; uint32_t slave_hw_idx; if (!ife_hw_mgr_ctx->is_dual) return 0; Loading @@ -6312,24 +6333,27 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe( return 0; } if (event_cnt[core_idx0] == event_cnt[core_idx1]) { master_hw_idx = ife_hw_mgr_ctx->master_hw_idx; slave_hw_idx = ife_hw_mgr_ctx->slave_hw_idx; if (event_cnt[master_hw_idx] == event_cnt[slave_hw_idx]) { event_cnt[core_idx0] = 0; event_cnt[core_idx1] = 0; event_cnt[master_hw_idx] = 0; event_cnt[slave_hw_idx] = 0; rc = 0; return rc; } if ((event_cnt[core_idx0] && (event_cnt[core_idx0] - event_cnt[core_idx1] > 1)) || (event_cnt[core_idx1] && (event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) { if ((event_cnt[master_hw_idx] && (event_cnt[master_hw_idx] - event_cnt[slave_hw_idx] > 1)) || (event_cnt[slave_hw_idx] && (event_cnt[slave_hw_idx] - event_cnt[master_hw_idx] > 1))) { CAM_ERR_RATE_LIMIT(CAM_ISP, "One of the VFE could not generate hw event %d core_0_cnt %d core_1_cnt %d", hw_event_type, event_cnt[core_idx0], event_cnt[core_idx1]); "One of the VFE could not generate hw event %d master[%d] core_cnt %d slave[%d] core_cnt %d", hw_event_type, master_hw_idx, event_cnt[master_hw_idx], slave_hw_idx, event_cnt[slave_hw_idx]); rc = -1; return rc; } Loading drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +4 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,8 @@ struct cam_ife_hw_mgr_debug { * @list: used by the ctx list. * @common: common acquired context data * @ctx_index: acquired context id. * @master_hw_idx: hw index for master core * @slave_hw_idx: hw index for slave core * @hw_mgr: IFE hw mgr which owns this context * @ctx_in_use: flag to tell whether context is active * @res_list_ife_in: Starting resource(TPG,PHY0, PHY1...) Can only be Loading Loading @@ -144,6 +146,8 @@ struct cam_ife_hw_mgr_ctx { struct cam_isp_hw_mgr_ctx common; uint32_t ctx_index; uint32_t master_hw_idx; uint32_t slave_hw_idx; struct cam_ife_hw_mgr *hw_mgr; uint32_t ctx_in_use; Loading drivers/cam_req_mgr/cam_req_mgr_core.c +114 −1 Original line number Diff line number Diff line Loading @@ -480,7 +480,9 @@ static void __cam_req_mgr_reset_req_slot(struct cam_req_mgr_core_link *link, CAM_DBG(CAM_CRM, "RESET: idx: %d: slot->status %d", idx, slot->status); /* Check if CSL has already pushed new request*/ if (slot->status == CRM_SLOT_STATUS_REQ_ADDED) if (slot->status == CRM_SLOT_STATUS_REQ_ADDED || in_q->last_applied_idx == idx || idx < 0) return; /* Reset input queue slot */ Loading Loading @@ -1500,6 +1502,10 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, reset_step = link->sync_link->max_delay; } if (slot->req_id > 0) in_q->last_applied_idx = idx; __cam_req_mgr_dec_idx( &idx, reset_step + 1, in_q->num_slots); Loading Loading @@ -2403,6 +2409,12 @@ int cam_req_mgr_process_error(void *priv, void *data) __cam_req_mgr_tbl_set_all_skip_cnt(&link->req.l_tbl); in_q->rd_idx = idx; in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED; if (link->sync_link) { in_q->slot[idx].sync_mode = 0; __cam_req_mgr_inc_idx(&idx, 1, link->req.l_tbl->num_slots); in_q->slot[idx].sync_mode = 0; } spin_lock_bh(&link->link_state_spin_lock); link->state = CAM_CRM_LINK_STATE_ERR; spin_unlock_bh(&link->link_state_spin_lock); Loading @@ -2415,6 +2427,31 @@ int cam_req_mgr_process_error(void *priv, void *data) return rc; } /** * cam_req_mgr_process_stop() * * @brief: This runs in workque thread context. stop notification. * @priv : link information. * @data : contains information about frame_id, link etc. * * @return: 0 on success. */ int cam_req_mgr_process_stop(void *priv, void *data) { int rc = 0; struct cam_req_mgr_core_link *link = NULL; if (!data || !priv) { CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv); rc = -EINVAL; goto end; } link = (struct cam_req_mgr_core_link *)priv; __cam_req_mgr_flush_req_slot(link); end: return rc; } /** * cam_req_mgr_process_trigger() * Loading @@ -2428,6 +2465,7 @@ int cam_req_mgr_process_error(void *priv, void *data) static int cam_req_mgr_process_trigger(void *priv, void *data) { int rc = 0; int32_t idx = -1; struct cam_req_mgr_trigger_notify *trigger_data = NULL; struct cam_req_mgr_core_link *link = NULL; struct cam_req_mgr_req_queue *in_q = NULL; Loading @@ -2450,6 +2488,17 @@ static int cam_req_mgr_process_trigger(void *priv, void *data) in_q = link->req.in_q; mutex_lock(&link->req.lock); if (trigger_data->trigger == CAM_TRIGGER_POINT_SOF) { idx = __cam_req_mgr_find_slot_for_req(in_q, trigger_data->req_id); if (idx >= 0) { if (idx == in_q->last_applied_idx) in_q->last_applied_idx = -1; __cam_req_mgr_reset_req_slot(link, idx); } } /* * Check if current read index is in applied state, if yes make it free * and increment read index to next slot. Loading Loading @@ -2714,6 +2763,68 @@ static int cam_req_mgr_cb_notify_timer( return rc; } /* * cam_req_mgr_cb_notify_stop() * * @brief : Stop received from device, resets the morked slots * @err_info : contains information about error occurred like bubble/overflow * * @return : 0 on success, negative in case of failure * */ static int cam_req_mgr_cb_notify_stop( struct cam_req_mgr_notify_stop *stop_info) { int rc = 0; struct crm_workq_task *task = NULL; struct cam_req_mgr_core_link *link = NULL; struct cam_req_mgr_notify_stop *notify_stop; struct crm_task_payload *task_data; if (!stop_info) { CAM_ERR(CAM_CRM, "stop_info is NULL"); rc = -EINVAL; goto end; } link = (struct cam_req_mgr_core_link *) cam_get_device_priv(stop_info->link_hdl); if (!link) { CAM_DBG(CAM_CRM, "link ptr NULL %x", stop_info->link_hdl); rc = -EINVAL; goto end; } spin_lock_bh(&link->link_state_spin_lock); if (link->state != CAM_CRM_LINK_STATE_READY) { CAM_WARN(CAM_CRM, "invalid link state:%d", link->state); spin_unlock_bh(&link->link_state_spin_lock); rc = -EPERM; goto end; } crm_timer_reset(link->watchdog); spin_unlock_bh(&link->link_state_spin_lock); task = cam_req_mgr_workq_get_task(link->workq); if (!task) { CAM_ERR(CAM_CRM, "no empty task"); rc = -EBUSY; goto end; } task_data = (struct crm_task_payload *)task->payload; task_data->type = CRM_WORKQ_TASK_NOTIFY_ERR; notify_stop = (struct cam_req_mgr_notify_stop *)&task_data->u; notify_stop->link_hdl = stop_info->link_hdl; task->process_cb = &cam_req_mgr_process_stop; rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0); end: return rc; } /** * cam_req_mgr_cb_notify_trigger() * Loading Loading @@ -2774,6 +2885,7 @@ static int cam_req_mgr_cb_notify_trigger( notify_trigger->link_hdl = trigger_data->link_hdl; notify_trigger->dev_hdl = trigger_data->dev_hdl; notify_trigger->trigger = trigger_data->trigger; notify_trigger->req_id = trigger_data->req_id; notify_trigger->sof_timestamp_val = trigger_data->sof_timestamp_val; task->process_cb = &cam_req_mgr_process_trigger; rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0); Loading @@ -2787,6 +2899,7 @@ static struct cam_req_mgr_crm_cb cam_req_mgr_ops = { .notify_err = cam_req_mgr_cb_notify_err, .add_req = cam_req_mgr_cb_add_req, .notify_timer = cam_req_mgr_cb_notify_timer, .notify_stop = cam_req_mgr_cb_notify_stop, }; /** Loading Loading
drivers/cam_isp/cam_isp_context.c +32 −4 Original line number Diff line number Diff line Loading @@ -658,6 +658,7 @@ static int __cam_isp_ctx_handle_buf_done_for_request( CAM_DBG(CAM_REQ, "Move active request %lld to free list(cnt = %d) [all fences done], ctx %u", buf_done_req_id, ctx_isp->active_req_cnt, ctx->ctx_id); ctx_isp->req_info.last_bufdone_req_id = req->request_id; } __cam_isp_ctx_update_state_monitor_array(ctx_isp, Loading Loading @@ -857,6 +858,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -1027,7 +1029,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, * If no wait req in epoch, this is an error case. * The recovery is to go back to sof state */ CAM_ERR(CAM_ISP, "No wait request"); CAM_ERR(CAM_ISP, "Ctx:%d No wait request", ctx->ctx_id); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; /* Send SOF event as empty frame*/ Loading @@ -1043,7 +1045,8 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, req_isp->bubble_detected = true; req_isp->reapply = true; CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); CAM_INFO(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld", ctx->ctx_id, req_isp->bubble_report, req->request_id); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; Loading Loading @@ -1192,7 +1195,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( * If no pending req in epoch, this is an error case. * Just go back to the bubble state. */ CAM_ERR(CAM_ISP, "No pending request."); CAM_ERR(CAM_ISP, "ctx:%d No pending request.", ctx->ctx_id); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); Loading @@ -1204,6 +1207,8 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld", ctx->ctx_id, req_isp->bubble_report, req->request_id); req_isp->reapply = true; if (req_isp->bubble_report && ctx->ctx_crm_intf && Loading Loading @@ -1542,6 +1547,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -1719,6 +1725,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -2406,6 +2413,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_top_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -2502,9 +2510,10 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld", ctx->ctx_id, req_isp->bubble_report, req->request_id); req_isp->reapply = true; CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; Loading Loading @@ -2603,6 +2612,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -2675,6 +2685,7 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; ctx->ctx_crm_intf->notify_trigger(¬ify); Loading Loading @@ -2872,6 +2883,7 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx, ctx_isp->reported_req_id = 0; ctx_isp->hw_acquired = false; ctx_isp->init_received = false; ctx_isp->req_info.last_bufdone_req_id = 0; atomic64_set(&ctx_isp->state_monitor_head, -1); Loading Loading @@ -2932,6 +2944,7 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx, ctx_isp->hw_acquired = false; ctx_isp->init_received = false; ctx_isp->rdi_only_context = false; ctx_isp->req_info.last_bufdone_req_id = 0; atomic64_set(&ctx_isp->state_monitor_head, -1); Loading Loading @@ -3862,6 +3875,18 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( __cam_isp_ctx_substate_val_to_type( ctx_isp->substate_activated)); if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_stop) { struct cam_req_mgr_notify_stop notify; notify.link_hdl = ctx->link_hdl; CAM_DBG(CAM_ISP, "Notify CRM about device stop ctx %u link 0x%x", ctx->ctx_id, ctx->link_hdl); ctx->ctx_crm_intf->notify_stop(¬ify); } else CAM_ERR(CAM_ISP, "cb not present"); while (!list_empty(&ctx->pending_req_list)) { req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request, list); Loading Loading @@ -3909,11 +3934,13 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( } list_add_tail(&req->list, &ctx->free_req_list); } ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; ctx_isp->reported_req_id = 0; ctx_isp->bubble_frame_cnt = 0; ctx_isp->last_applied_req_id = 0; ctx_isp->req_info.last_bufdone_req_id = 0; atomic_set(&ctx_isp->process_bubble, 0); atomic64_set(&ctx_isp->state_monitor_head, -1); Loading Loading @@ -4372,6 +4399,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx, ctx->frame_id = 0; ctx->active_req_cnt = 0; ctx->reported_req_id = 0; ctx->req_info.last_bufdone_req_id = 0; ctx->bubble_frame_cnt = 0; ctx->hw_ctx = NULL; ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; Loading
drivers/cam_isp/cam_isp_context.h +14 −0 Original line number Diff line number Diff line Loading @@ -149,6 +149,18 @@ struct cam_isp_context_state_monitor { }; /** * struct cam_isp_context_req_id_info - ISP context request id * information for bufdone. * *@last_bufdone_req_id: Last bufdone request id * */ struct cam_isp_context_req_id_info { int64_t last_bufdone_req_id; }; /** * * struct cam_isp_context - ISP context object * * @base: Common context object pointer Loading @@ -170,6 +182,7 @@ struct cam_isp_context_state_monitor { * will invoke CRM cb at those event. * @last_applied_req_id: Last applied request id * @state_monitor_head: Write index to the state monitoring array * @req_info Request id information about last buf done * @cam_isp_ctx_state_monitor: State monitoring array * @rdi_only_context: Get context type information. * true, if context is rdi only context Loading Loading @@ -202,6 +215,7 @@ struct cam_isp_context { atomic64_t state_monitor_head; struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES]; struct cam_isp_context_req_id_info req_info; bool rdi_only_context; bool hw_acquired; bool init_received; Loading
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +89 −65 Original line number Diff line number Diff line Loading @@ -1036,7 +1036,7 @@ static int cam_ife_hw_mgr_acquire_res_bus_rd( /*TBD */ vfe_acquire.vfe_out.is_master = 1; vfe_acquire.vfe_out.dual_slave_core = (hw_intf->hw_idx == 0) ? 1 : 0; ife_ctx->slave_hw_idx; } else { vfe_acquire.vfe_out.is_master = 0; vfe_acquire.vfe_out.dual_slave_core = Loading @@ -1047,7 +1047,7 @@ static int cam_ife_hw_mgr_acquire_res_bus_rd( CAM_ISP_HW_SPLIT_RIGHT; vfe_acquire.vfe_out.is_master = 0; vfe_acquire.vfe_out.dual_slave_core = (hw_intf->hw_idx == 0) ? 1 : 0; ife_ctx->master_hw_idx; } rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire, Loading Loading @@ -1229,7 +1229,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel( /*TBD */ vfe_acquire.vfe_out.is_master = 1; vfe_acquire.vfe_out.dual_slave_core = (hw_intf->hw_idx == 0) ? 1 : 0; ife_ctx->slave_hw_idx; } else { vfe_acquire.vfe_out.is_master = 0; vfe_acquire.vfe_out.dual_slave_core = Loading @@ -1240,9 +1240,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel( CAM_ISP_HW_SPLIT_RIGHT; vfe_acquire.vfe_out.is_master = 0; vfe_acquire.vfe_out.dual_slave_core = (hw_intf->hw_idx == 0) ? 1 : 0; ife_ctx->master_hw_idx; } rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire, sizeof(struct cam_vfe_acquire_args)); Loading Loading @@ -1659,6 +1658,54 @@ static int cam_ife_hw_mgr_acquire_res_ife_src( return rc; } static int cam_ife_hw_mgr_acquire_csid_hw( struct cam_ife_hw_mgr *ife_hw_mgr, struct cam_csid_hw_reserve_resource_args *csid_acquire, bool is_start_lower_idx) { int i; int rc = -1; struct cam_hw_intf *hw_intf; if (!ife_hw_mgr || !csid_acquire) { CAM_ERR(CAM_ISP, "Invalid args ife hw mgr %pK csid_acquire %pK", ife_hw_mgr, csid_acquire); return -EINVAL; } if (is_start_lower_idx) { for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) { if (!ife_hw_mgr->csid_devices[i]) continue; hw_intf = ife_hw_mgr->csid_devices[i]; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, csid_acquire, sizeof(struct cam_csid_hw_reserve_resource_args)); if (!rc) return rc; } return rc; } for (i = CAM_IFE_CSID_HW_NUM_MAX - 1; i >= 0; i--) { if (!ife_hw_mgr->csid_devices[i]) continue; hw_intf = ife_hw_mgr->csid_devices[i]; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, csid_acquire, sizeof(struct cam_csid_hw_reserve_resource_args)); if (!rc) return rc; } return rc; } static int cam_ife_mgr_acquire_cid_res( struct cam_ife_hw_mgr_ctx *ife_ctx, struct cam_isp_in_port_generic_info *in_port, Loading Loading @@ -1751,52 +1798,21 @@ static int cam_ife_mgr_acquire_cid_res( } /* Acquire Left if not already acquired */ if (ife_ctx->is_fe_enable) { for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) { if (!ife_hw_mgr->csid_devices[i]) continue; hw_intf = ife_hw_mgr->csid_devices[i]; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &csid_acquire, sizeof(csid_acquire)); if (rc) continue; else { cid_res_temp->hw_res[acquired_cnt++] = csid_acquire.node_res; break; } } if (i == CAM_IFE_CSID_HW_NUM_MAX || !csid_acquire.node_res) { CAM_ERR(CAM_ISP, "Can not acquire ife cid resource for path %d", path_res_id); goto put_res; } } else { for (i = CAM_IFE_CSID_HW_NUM_MAX - 1; i >= 0; i--) { if (!ife_hw_mgr->csid_devices[i]) continue; /* For dual IFE cases, start acquiring the lower idx first */ if (ife_ctx->is_fe_enable || in_port->usage_type) rc = cam_ife_hw_mgr_acquire_csid_hw(ife_hw_mgr, &csid_acquire, true); else rc = cam_ife_hw_mgr_acquire_csid_hw(ife_hw_mgr, &csid_acquire, false); hw_intf = ife_hw_mgr->csid_devices[i]; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &csid_acquire, sizeof(csid_acquire)); if (rc) continue; else { cid_res_temp->hw_res[acquired_cnt++] = csid_acquire.node_res; break; } } if (i == -1 || !csid_acquire.node_res) { if (rc || !csid_acquire.node_res) { CAM_ERR(CAM_ISP, "Can not acquire ife cid resource for path %d", path_res_id); goto put_res; } } cid_res_temp->hw_res[acquired_cnt++] = csid_acquire.node_res; acquire_successful: CAM_DBG(CAM_ISP, "CID left acquired success is_dual %d", Loading @@ -1807,7 +1823,9 @@ static int cam_ife_mgr_acquire_cid_res( cid_res_temp->res_id = csid_acquire.node_res->res_id; cid_res_temp->is_dual_vfe = in_port->usage_type; ife_ctx->is_dual = (bool)in_port->usage_type; if (ife_ctx->is_dual) ife_ctx->master_hw_idx = cid_res_temp->hw_res[0]->hw_intf->hw_idx; if (in_port->num_out_res) cid_res_temp->is_secure = out_port->secure_mode; Loading Loading @@ -1844,6 +1862,8 @@ static int cam_ife_mgr_acquire_cid_res( goto end; } cid_res_temp->hw_res[1] = csid_acquire.node_res; ife_ctx->slave_hw_idx = cid_res_temp->hw_res[1]->hw_intf->hw_idx; CAM_DBG(CAM_ISP, "CID right acquired success is_dual %d", in_port->usage_type); } Loading Loading @@ -6249,8 +6269,9 @@ static int cam_ife_hw_mgr_handle_hw_rup( switch (event_info->res_id) { case CAM_ISP_HW_VFE_IN_CAMIF: if (ife_hw_mgr_ctx->is_dual) if (event_info->hw_idx != 1) if ((ife_hw_mgr_ctx->is_dual) && (event_info->hw_idx != ife_hw_mgr_ctx->master_hw_idx)) break; if (atomic_read(&ife_hw_mgr_ctx->overflow_pending)) Loading Loading @@ -6292,8 +6313,8 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe( { int32_t rc = -1; uint32_t *event_cnt = NULL; uint32_t core_idx0 = 0; uint32_t core_idx1 = 1; uint32_t master_hw_idx; uint32_t slave_hw_idx; if (!ife_hw_mgr_ctx->is_dual) return 0; Loading @@ -6312,24 +6333,27 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe( return 0; } if (event_cnt[core_idx0] == event_cnt[core_idx1]) { master_hw_idx = ife_hw_mgr_ctx->master_hw_idx; slave_hw_idx = ife_hw_mgr_ctx->slave_hw_idx; if (event_cnt[master_hw_idx] == event_cnt[slave_hw_idx]) { event_cnt[core_idx0] = 0; event_cnt[core_idx1] = 0; event_cnt[master_hw_idx] = 0; event_cnt[slave_hw_idx] = 0; rc = 0; return rc; } if ((event_cnt[core_idx0] && (event_cnt[core_idx0] - event_cnt[core_idx1] > 1)) || (event_cnt[core_idx1] && (event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) { if ((event_cnt[master_hw_idx] && (event_cnt[master_hw_idx] - event_cnt[slave_hw_idx] > 1)) || (event_cnt[slave_hw_idx] && (event_cnt[slave_hw_idx] - event_cnt[master_hw_idx] > 1))) { CAM_ERR_RATE_LIMIT(CAM_ISP, "One of the VFE could not generate hw event %d core_0_cnt %d core_1_cnt %d", hw_event_type, event_cnt[core_idx0], event_cnt[core_idx1]); "One of the VFE could not generate hw event %d master[%d] core_cnt %d slave[%d] core_cnt %d", hw_event_type, master_hw_idx, event_cnt[master_hw_idx], slave_hw_idx, event_cnt[slave_hw_idx]); rc = -1; return rc; } Loading
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +4 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,8 @@ struct cam_ife_hw_mgr_debug { * @list: used by the ctx list. * @common: common acquired context data * @ctx_index: acquired context id. * @master_hw_idx: hw index for master core * @slave_hw_idx: hw index for slave core * @hw_mgr: IFE hw mgr which owns this context * @ctx_in_use: flag to tell whether context is active * @res_list_ife_in: Starting resource(TPG,PHY0, PHY1...) Can only be Loading Loading @@ -144,6 +146,8 @@ struct cam_ife_hw_mgr_ctx { struct cam_isp_hw_mgr_ctx common; uint32_t ctx_index; uint32_t master_hw_idx; uint32_t slave_hw_idx; struct cam_ife_hw_mgr *hw_mgr; uint32_t ctx_in_use; Loading
drivers/cam_req_mgr/cam_req_mgr_core.c +114 −1 Original line number Diff line number Diff line Loading @@ -480,7 +480,9 @@ static void __cam_req_mgr_reset_req_slot(struct cam_req_mgr_core_link *link, CAM_DBG(CAM_CRM, "RESET: idx: %d: slot->status %d", idx, slot->status); /* Check if CSL has already pushed new request*/ if (slot->status == CRM_SLOT_STATUS_REQ_ADDED) if (slot->status == CRM_SLOT_STATUS_REQ_ADDED || in_q->last_applied_idx == idx || idx < 0) return; /* Reset input queue slot */ Loading Loading @@ -1500,6 +1502,10 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, reset_step = link->sync_link->max_delay; } if (slot->req_id > 0) in_q->last_applied_idx = idx; __cam_req_mgr_dec_idx( &idx, reset_step + 1, in_q->num_slots); Loading Loading @@ -2403,6 +2409,12 @@ int cam_req_mgr_process_error(void *priv, void *data) __cam_req_mgr_tbl_set_all_skip_cnt(&link->req.l_tbl); in_q->rd_idx = idx; in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED; if (link->sync_link) { in_q->slot[idx].sync_mode = 0; __cam_req_mgr_inc_idx(&idx, 1, link->req.l_tbl->num_slots); in_q->slot[idx].sync_mode = 0; } spin_lock_bh(&link->link_state_spin_lock); link->state = CAM_CRM_LINK_STATE_ERR; spin_unlock_bh(&link->link_state_spin_lock); Loading @@ -2415,6 +2427,31 @@ int cam_req_mgr_process_error(void *priv, void *data) return rc; } /** * cam_req_mgr_process_stop() * * @brief: This runs in workque thread context. stop notification. * @priv : link information. * @data : contains information about frame_id, link etc. * * @return: 0 on success. */ int cam_req_mgr_process_stop(void *priv, void *data) { int rc = 0; struct cam_req_mgr_core_link *link = NULL; if (!data || !priv) { CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv); rc = -EINVAL; goto end; } link = (struct cam_req_mgr_core_link *)priv; __cam_req_mgr_flush_req_slot(link); end: return rc; } /** * cam_req_mgr_process_trigger() * Loading @@ -2428,6 +2465,7 @@ int cam_req_mgr_process_error(void *priv, void *data) static int cam_req_mgr_process_trigger(void *priv, void *data) { int rc = 0; int32_t idx = -1; struct cam_req_mgr_trigger_notify *trigger_data = NULL; struct cam_req_mgr_core_link *link = NULL; struct cam_req_mgr_req_queue *in_q = NULL; Loading @@ -2450,6 +2488,17 @@ static int cam_req_mgr_process_trigger(void *priv, void *data) in_q = link->req.in_q; mutex_lock(&link->req.lock); if (trigger_data->trigger == CAM_TRIGGER_POINT_SOF) { idx = __cam_req_mgr_find_slot_for_req(in_q, trigger_data->req_id); if (idx >= 0) { if (idx == in_q->last_applied_idx) in_q->last_applied_idx = -1; __cam_req_mgr_reset_req_slot(link, idx); } } /* * Check if current read index is in applied state, if yes make it free * and increment read index to next slot. Loading Loading @@ -2714,6 +2763,68 @@ static int cam_req_mgr_cb_notify_timer( return rc; } /* * cam_req_mgr_cb_notify_stop() * * @brief : Stop received from device, resets the morked slots * @err_info : contains information about error occurred like bubble/overflow * * @return : 0 on success, negative in case of failure * */ static int cam_req_mgr_cb_notify_stop( struct cam_req_mgr_notify_stop *stop_info) { int rc = 0; struct crm_workq_task *task = NULL; struct cam_req_mgr_core_link *link = NULL; struct cam_req_mgr_notify_stop *notify_stop; struct crm_task_payload *task_data; if (!stop_info) { CAM_ERR(CAM_CRM, "stop_info is NULL"); rc = -EINVAL; goto end; } link = (struct cam_req_mgr_core_link *) cam_get_device_priv(stop_info->link_hdl); if (!link) { CAM_DBG(CAM_CRM, "link ptr NULL %x", stop_info->link_hdl); rc = -EINVAL; goto end; } spin_lock_bh(&link->link_state_spin_lock); if (link->state != CAM_CRM_LINK_STATE_READY) { CAM_WARN(CAM_CRM, "invalid link state:%d", link->state); spin_unlock_bh(&link->link_state_spin_lock); rc = -EPERM; goto end; } crm_timer_reset(link->watchdog); spin_unlock_bh(&link->link_state_spin_lock); task = cam_req_mgr_workq_get_task(link->workq); if (!task) { CAM_ERR(CAM_CRM, "no empty task"); rc = -EBUSY; goto end; } task_data = (struct crm_task_payload *)task->payload; task_data->type = CRM_WORKQ_TASK_NOTIFY_ERR; notify_stop = (struct cam_req_mgr_notify_stop *)&task_data->u; notify_stop->link_hdl = stop_info->link_hdl; task->process_cb = &cam_req_mgr_process_stop; rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0); end: return rc; } /** * cam_req_mgr_cb_notify_trigger() * Loading Loading @@ -2774,6 +2885,7 @@ static int cam_req_mgr_cb_notify_trigger( notify_trigger->link_hdl = trigger_data->link_hdl; notify_trigger->dev_hdl = trigger_data->dev_hdl; notify_trigger->trigger = trigger_data->trigger; notify_trigger->req_id = trigger_data->req_id; notify_trigger->sof_timestamp_val = trigger_data->sof_timestamp_val; task->process_cb = &cam_req_mgr_process_trigger; rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0); Loading @@ -2787,6 +2899,7 @@ static struct cam_req_mgr_crm_cb cam_req_mgr_ops = { .notify_err = cam_req_mgr_cb_notify_err, .add_req = cam_req_mgr_cb_add_req, .notify_timer = cam_req_mgr_cb_notify_timer, .notify_stop = cam_req_mgr_cb_notify_stop, }; /** Loading