Răsfoiți Sursa

msm: camera: isp: Avoid possible NOC crash in case of overflow

In case of path errors, CSID debug registers are printed after sending
the error event to hw manager. In some scenarios, work queue calling the
stop hw can be called before printing the registers. This can cause
NOC errors while accessing the registers.
This commit moves the printing of registers to single location just
before sending the event to hw manager.

CRs-Fixed: 2962255
Change-Id: I929741cbe8211d4b3cb012588ea923ddd2e5a97c
Signed-off-by: Gaurav Jindal <[email protected]>
Gaurav Jindal 4 ani în urmă
părinte
comite
042e596c30

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.c

@@ -587,7 +587,7 @@ int cam_ife_csid_convert_res_to_irq_reg(uint32_t res_id)
 	case CAM_IFE_PIX_PATH_RES_UDI_2:
 		return CAM_IFE_CSID_IRQ_REG_UDI_2;
 	default:
-		return -EINVAL;
+		return CAM_IFE_CSID_IRQ_REG_MAX;
 	}
 }
 

+ 12 - 10
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -51,6 +51,10 @@
 /* Max CSI Rx irq error count threshold value */
 #define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT               100
 
+static void cam_ife_csid_ver2_print_debug_reg_status(
+	struct cam_ife_csid_ver2_hw *csid_hw,
+	struct cam_isp_resource_node    *res);
+
 static int cam_ife_csid_ver2_set_debug(
 	struct cam_ife_csid_ver2_hw *csid_hw,
 	uint32_t debug_val)
@@ -885,6 +889,7 @@ static int cam_ife_csid_ver2_handle_event_err(
 	evt.err_type = err_type;
 
 	if (res) {
+		cam_ife_csid_ver2_print_debug_reg_status(csid_hw, res);
 		path_cfg = (struct cam_ife_csid_ver2_path_cfg *)res->res_priv;
 		evt.res_id   = res->res_id;
 		CAM_ERR_RATE_LIMIT(CAM_ISP,
@@ -1341,9 +1346,6 @@ static int cam_ife_csid_ver2_ipp_bottom_half(
 			err_type,
 			res);
 
-	if (irq_status_ipp & err_mask)
-		cam_ife_csid_ver2_print_debug_reg_status(csid_hw, res);
-
 	cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload,
 			&csid_hw->path_free_payload_list,
 			&csid_hw->path_payload_lock);
@@ -1430,9 +1432,6 @@ static int cam_ife_csid_ver2_ppp_bottom_half(
 			err_type,
 			res);
 
-	if (irq_status_ppp & err_mask)
-		cam_ife_csid_ver2_print_debug_reg_status(csid_hw, res);
-
 	cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload,
 			&csid_hw->path_free_payload_list,
 			&csid_hw->path_payload_lock);
@@ -1527,10 +1526,6 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
 
 		cam_ife_csid_ver2_handle_event_err(csid_hw,
 			irq_status_rdi, err_type, res);
-
-		if (irq_status_rdi & err_mask)
-			cam_ife_csid_ver2_print_debug_reg_status(
-				csid_hw, res);
 		goto end;
 	}
 
@@ -2753,6 +2748,13 @@ static int cam_ife_csid_ver2_program_rdi_path(
 	path_cfg->irq_reg_idx =
 		cam_ife_csid_convert_res_to_irq_reg(res->res_id);
 
+	if (path_cfg->irq_reg_idx >= CAM_IFE_CSID_IRQ_REG_MAX) {
+		CAM_ERR(CAM_ISP, "CSID[%d] Invalid irq reg id %d",
+			csid_hw->hw_intf->hw_idx, path_cfg->irq_reg_idx);
+		rc = -EINVAL;
+		goto end;
+	}
+
 	irq_mask[CAM_IFE_CSID_IRQ_REG_TOP] = path_reg->top_irq_mask;
 
 	irq_mask[path_cfg->irq_reg_idx] = val;