Browse Source

msm: camera: reqmgr: On bubble reset appropriate slots

In case of bubble, reset all slots starting from bubbled
request slot to the last applied slot. On occasions of
workq delays, this might lead to having a slot in the
wrong state.

CRs-Fixed: 3079337
Change-Id: I08dc4cf4f00f487b34eddd1771c67b3c1a8319ce
Signed-off-by: Karthik Anantha Ram <[email protected]>
Karthik Anantha Ram 3 năm trước cách đây
mục cha
commit
261b99ed56
1 tập tin đã thay đổi với 28 bổ sung9 xóa
  1. 28 9
      drivers/cam_req_mgr/cam_req_mgr_core.c

+ 28 - 9
drivers/cam_req_mgr/cam_req_mgr_core.c

@@ -817,8 +817,8 @@ static int __cam_req_mgr_check_next_req_slot(
 	 */
 	if (slot->status == CRM_SLOT_STATUS_REQ_APPLIED) {
 		CAM_WARN(CAM_CRM,
-			"slot[%d] wasn't reset, reset it now",
-			idx);
+			"slot [idx: %d req: %lld last_applied_idx: %d] was not reset, reset it now",
+			idx, in_q->slot[idx].req_id, in_q->last_applied_idx);
 		if (in_q->last_applied_idx == idx) {
 			CAM_WARN(CAM_CRM,
 				"last_applied_idx: %d",
@@ -2986,6 +2986,7 @@ void __cam_req_mgr_apply_on_bubble(
 int cam_req_mgr_process_error(void *priv, void *data)
 {
 	int                                  rc = 0, idx = -1;
+	int                                  i, slot_diff;
 	struct cam_req_mgr_error_notify     *err_info = NULL;
 	struct cam_req_mgr_core_link        *link = NULL;
 	struct cam_req_mgr_req_queue        *in_q = NULL;
@@ -3017,8 +3018,8 @@ int cam_req_mgr_process_error(void *priv, void *data)
 				"req_id %lld not found in input queue",
 				err_info->req_id);
 		} else {
-			CAM_DBG(CAM_CRM, "req_id %lld found at idx %d",
-				err_info->req_id, idx);
+			CAM_DBG(CAM_CRM, "req_id %lld found at idx %d last_applied %d",
+				err_info->req_id, idx, in_q->last_applied_idx);
 			slot = &in_q->slot[idx];
 			if (!slot->recover) {
 				CAM_WARN(CAM_CRM,
@@ -3045,13 +3046,31 @@ int cam_req_mgr_process_error(void *priv, void *data)
 				in_q->slot[idx].sync_mode = 0;
 			}
 
-			/* The next req may also be applied */
+			/*
+			 * Reset till last applied, even if there are scheduling delays
+			 * we start fresh from the request on which bubble has
+			 * been reported
+			 */
 			idx = in_q->rd_idx;
-			__cam_req_mgr_inc_idx(&idx, 1,
-				link->req.l_tbl->num_slots);
+			if (in_q->last_applied_idx >= 0) {
+				slot_diff = in_q->last_applied_idx - idx;
+				if (slot_diff < 0)
+					slot_diff += link->req.l_tbl->num_slots;
+			} else {
+				/* Next req at the minimum may be applied */
+				slot_diff = 1;
+			}
 
-			if (in_q->slot[idx].status == CRM_SLOT_STATUS_REQ_APPLIED)
-				in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED;
+			for (i = 0; i < slot_diff; i++) {
+				__cam_req_mgr_inc_idx(&idx, 1,
+					link->req.l_tbl->num_slots);
+
+				CAM_DBG(CAM_CRM,
+					"Recovery on idx: %d reset slot [idx: %d status: %d]",
+					in_q->rd_idx, idx, in_q->slot[idx].status);
+				if (in_q->slot[idx].status == CRM_SLOT_STATUS_REQ_APPLIED)
+					in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED;
+			}
 
 			spin_lock_bh(&link->link_state_spin_lock);
 			link->state = CAM_CRM_LINK_STATE_ERR;