Browse Source

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 <[email protected]>
Signed-off-by: Venkat Chinta <[email protected]>
Abhilash Kumar 5 years ago
parent
commit
4e30068212
2 changed files with 34 additions and 31 deletions
  1. 20 30
      drivers/cam_cdm/cam_cdm_hw_core.c
  2. 14 1
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

+ 20 - 30
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;
 }
 

+ 14 - 1
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;