Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9d5e89e authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge 911c7152 on remote branch

Change-Id: Ic6e973a4469c6198f46b1f72b9ad2ad225869868
parents cdf624e2 911c7152
Loading
Loading
Loading
Loading
+32 −4
Original line number Diff line number Diff line
@@ -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,
@@ -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(&notify);
@@ -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*/
@@ -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;
@@ -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);

@@ -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 &&
@@ -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(&notify);
@@ -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(&notify);
@@ -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(&notify);
@@ -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;
@@ -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(&notify);
@@ -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(&notify);
@@ -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);

@@ -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);

@@ -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(&notify);
	} 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);
@@ -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);

@@ -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;
+14 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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;
+89 −65
Original line number Diff line number Diff line
@@ -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 =
@@ -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,
@@ -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 =
@@ -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));
@@ -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,
@@ -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",
@@ -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;

@@ -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);
	}
@@ -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))
@@ -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;
@@ -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;
	}
+4 −0
Original line number Diff line number Diff line
@@ -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
@@ -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;

+114 −1
Original line number Diff line number Diff line
@@ -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 */
@@ -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);
@@ -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);
@@ -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()
 *
@@ -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;
@@ -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.
@@ -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()
 *
@@ -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);
@@ -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