Эх сурвалжийг харах

msm: camera: isp: Split event handler based on HW type

Based on whether the event posted to HW mgr is from CSID/IFE/SFE,
handle them accordingly. This change avoids breaking off new
functions in existing calls for different events, instead
have an independent handler for each HW type.

CRs-Fixed: 3045706
Change-Id: I139514d9028c6d613f1bc7403014474dc336df34
Signed-off-by: Karthik Anantha Ram <[email protected]>
Karthik Anantha Ram 3 жил өмнө
parent
commit
69919eb973

+ 235 - 134
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -159,6 +159,27 @@ static inline int __cam_ife_mgr_get_hw_soc_info(
 	return rc;
 }
 
+static const char *__cam_ife_hw_mgr_evt_type_to_string(
+	enum cam_isp_hw_event_type evt_type)
+{
+	switch (evt_type) {
+	case CAM_ISP_HW_EVENT_ERROR:
+		return "ERROR";
+	case CAM_ISP_HW_EVENT_SOF:
+		return "SOF";
+	case CAM_ISP_HW_EVENT_REG_UPDATE:
+		return "REG_UPDATE";
+	case CAM_ISP_HW_EVENT_EPOCH:
+		return "EPOCH";
+	case CAM_ISP_HW_EVENT_EOF:
+		return "EOF";
+	case CAM_ISP_HW_EVENT_DONE:
+		return "BUF_DONE";
+	default:
+		return "INVALID_EVT";
+	}
+}
+
 static int cam_ife_mgr_regspace_data_cb(uint32_t reg_base_type,
 	void *hw_mgr_ctx, struct cam_hw_soc_info **soc_info_ptr,
 	uint32_t *reg_base_idx)
@@ -11400,17 +11421,28 @@ end:
 }
 
 static int cam_ife_hw_mgr_handle_csid_error(
-	struct   cam_isp_hw_event_info *event_info,
-	void                           *ctx)
+	struct cam_ife_hw_mgr_ctx      *ctx,
+	struct cam_isp_hw_event_info   *event_info)
 {
 	int                                      rc = -EINVAL;
+	uint32_t                                 err_type;
+	struct cam_isp_hw_error_event_info      *err_evt_info;
 	struct cam_isp_hw_error_event_data       error_event_data = {0};
 	struct cam_ife_hw_event_recovery_data    recovery_data = {0};
 
-	CAM_DBG(CAM_ISP, "Entry CSID[%u] error %d", event_info->hw_idx,
-		event_info->err_type);
+	if (!event_info->event_data) {
+		CAM_ERR(CAM_ISP,
+			"No additional error event data failed to process for CSID[%u] ctx: %u",
+			event_info->hw_idx, ctx->ctx_index);
+		return -EINVAL;
+	}
 
-	if ((event_info->err_type & CAM_ISP_HW_ERROR_CSID_FATAL) &&
+	err_evt_info = (struct cam_isp_hw_error_event_info *)event_info->event_data;
+	err_type = err_evt_info->err_type;
+	CAM_DBG(CAM_ISP, "Entry CSID[%u] error %d", event_info->hw_idx, err_type);
+
+	spin_lock(&g_ife_hw_mgr.ctx_lock);
+	if ((err_type & CAM_ISP_HW_ERROR_CSID_FATAL) &&
 		g_ife_hw_mgr.debug_cfg.enable_csid_recovery) {
 
 		error_event_data.error_type = CAM_ISP_HW_ERROR_CSID_FATAL;
@@ -11420,19 +11452,19 @@ static int cam_ife_hw_mgr_handle_csid_error(
 		goto end;
 	}
 
-	if (event_info->err_type & (CAM_ISP_HW_ERROR_CSID_FIFO_OVERFLOW |
+	if (err_type & (CAM_ISP_HW_ERROR_CSID_FIFO_OVERFLOW |
 		CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW |
 		CAM_ISP_HW_ERROR_CSID_FRAME_SIZE)) {
 
 		cam_ife_hw_mgr_notify_overflow(event_info, ctx);
 		error_event_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW;
-		if (event_info->err_type & CAM_ISP_HW_ERROR_CSID_FIFO_OVERFLOW)
+		if (err_type & CAM_ISP_HW_ERROR_CSID_FIFO_OVERFLOW)
 			error_event_data.error_code |=
 				CAM_REQ_MGR_CSID_FIFO_OVERFLOW_ERROR;
-		if (event_info->err_type & CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW)
+		if (err_type & CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW)
 			error_event_data.error_code |=
 				CAM_REQ_MGR_CSID_RECOVERY_OVERFLOW_ERROR;
-		if (event_info->err_type & CAM_ISP_HW_ERROR_CSID_FRAME_SIZE)
+		if (err_type & CAM_ISP_HW_ERROR_CSID_FRAME_SIZE)
 			error_event_data.error_code |=
 				CAM_REQ_MGR_CSID_PIXEL_COUNT_MISMATCH;
 		rc = cam_ife_hw_mgr_find_affected_ctx(&error_event_data,
@@ -11442,22 +11474,22 @@ static int cam_ife_hw_mgr_handle_csid_error(
 end:
 
 	if (rc || !recovery_data.no_of_context)
-		return 0;
+		goto skip_recovery;
 
 	recovery_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW;
 	cam_ife_hw_mgr_do_error_recovery(&recovery_data);
 	CAM_DBG(CAM_ISP, "Exit CSID[%u] error %d", event_info->hw_idx,
-		event_info->err_type);
+		err_type);
 
+skip_recovery:
+	spin_unlock(&g_ife_hw_mgr.ctx_lock);
 	return 0;
 }
 
 static int cam_ife_hw_mgr_handle_csid_rup(
-	void                              *ctx,
-	void                              *evt_info)
+	struct cam_ife_hw_mgr_ctx        *ife_hw_mgr_ctx,
+	struct cam_isp_hw_event_info     *event_info)
 {
-	struct cam_isp_hw_event_info            *event_info = evt_info;
-	struct cam_ife_hw_mgr_ctx               *ife_hw_mgr_ctx = ctx;
 	cam_hw_event_cb_func                     ife_hwr_irq_rup_cb;
 	struct cam_isp_hw_reg_update_event_data  rup_event_data;
 
@@ -11488,29 +11520,6 @@ static int cam_ife_hw_mgr_handle_csid_rup(
 	return 0;
 }
 
-static int cam_ife_hw_mgr_handle_csid_event(
-	void                            *ctx,
-	struct    cam_isp_hw_event_info *event_info,
-	uint32_t                         evt_id)
-{
-	int                        rc = 0;
-
-	CAM_DBG(CAM_ISP, "CSID event %u", evt_id);
-
-	switch (evt_id) {
-	case CAM_ISP_HW_EVENT_ERROR:
-		rc = cam_ife_hw_mgr_handle_csid_error(event_info, ctx);
-		break;
-	default:
-		CAM_ERR(CAM_ISP, "Invalid event ID %d",
-			event_info->err_type);
-		rc = -EINVAL;
-		break;
-	}
-
-	return rc;
-}
-
 static int cam_ife_hw_mgr_handle_hw_dump_info(
 	void                                 *ctx,
 	void                                 *evt_info)
@@ -11590,75 +11599,70 @@ static int cam_ife_hw_mgr_handle_hw_dump_info(
 	return rc;
 }
 
-static int cam_ife_hw_mgr_handle_sfe_event(
-	uint32_t                         evt_id,
+static int cam_ife_hw_mgr_handle_sfe_hw_error(
 	struct cam_ife_hw_mgr_ctx       *ctx,
 	struct cam_isp_hw_event_info    *event_info)
 {
+	struct cam_isp_hw_error_event_info     *err_evt_info;
 	struct cam_isp_hw_error_event_data      error_event_data = {0};
 	struct cam_ife_hw_event_recovery_data   recovery_data = {0};
 
-	/* Currently only error events supported from SFE */
-	if (evt_id != CAM_ISP_HW_EVENT_ERROR) {
-		CAM_DBG(CAM_ISP, "SFE %u event not supported", evt_id);
-		return 0;
+	if (!event_info->event_data) {
+		CAM_ERR(CAM_ISP,
+			"No additional error event data failed to process for SFE[%u] ctx: %u",
+			event_info->hw_idx, ctx->ctx_index);
+		return -EINVAL;
 	}
 
+	err_evt_info = (struct cam_isp_hw_error_event_info *)event_info->event_data;
+
 	CAM_DBG(CAM_ISP, "SFE[%u] error [%u] on res_type %u",
-		event_info->hw_idx, event_info->err_type,
+		event_info->hw_idx, err_evt_info->err_type,
 		event_info->res_type);
 
+	spin_lock(&g_ife_hw_mgr.ctx_lock);
 	/* Only report error to userspace */
-	if (event_info->err_type & CAM_SFE_IRQ_STATUS_VIOLATION) {
+	if (err_evt_info->err_type & CAM_SFE_IRQ_STATUS_VIOLATION) {
 		error_event_data.error_type = CAM_ISP_HW_ERROR_VIOLATION;
 		error_event_data.error_code = CAM_REQ_MGR_ISP_UNREPORTED_ERROR;
 		CAM_DBG(CAM_ISP, "Notify context for SFE error");
 		cam_ife_hw_mgr_find_affected_ctx(&error_event_data,
 			event_info->hw_idx, &recovery_data);
 	}
+	spin_unlock(&g_ife_hw_mgr.ctx_lock);
 
 	return 0;
 }
 
 static int cam_ife_hw_mgr_handle_hw_err(
-	uint32_t                             evt_id,
-	void                                *ctx,
-	void                                *evt_info)
+	struct cam_ife_hw_mgr_ctx         *ife_hw_mgr_ctx,
+	struct cam_isp_hw_event_info      *event_info)
 {
-	struct cam_ife_hw_mgr_ctx               *ife_hw_mgr_ctx;
-	struct cam_isp_hw_event_info            *event_info = evt_info;
-	uint32_t                                 core_idx;
+	uint32_t                                 core_idx, err_type;
+	struct cam_isp_hw_error_event_info      *err_evt_info;
 	struct cam_isp_hw_error_event_data       error_event_data = {0};
 	struct cam_ife_hw_event_recovery_data    recovery_data = {0};
 	int                                      rc = -EINVAL;
 
-	spin_lock(&g_ife_hw_mgr.ctx_lock);
-
-	if (event_info->hw_type == CAM_ISP_HW_TYPE_CSID) {
-		rc = cam_ife_hw_mgr_handle_csid_event(ctx, event_info,
-			evt_id);
-		goto end;
-	}
-
-	if (event_info->hw_type == CAM_ISP_HW_TYPE_SFE) {
-		rc = cam_ife_hw_mgr_handle_sfe_event(evt_id, ctx,
-			event_info);
-		goto end;
+	if (!event_info->event_data) {
+		CAM_ERR(CAM_ISP,
+			"No additional error event data failed to process for IFE[%u] ctx: %u",
+			event_info->hw_idx, ife_hw_mgr_ctx->ctx_index);
+		return -EINVAL;
 	}
 
-	if (ctx) {
-		ife_hw_mgr_ctx =
-			(struct cam_ife_hw_mgr_ctx *)ctx;
-		if (event_info->res_type ==
-			CAM_ISP_RESOURCE_VFE_IN &&
-			!ife_hw_mgr_ctx->flags.is_rdi_only_context &&
-			event_info->res_id !=
-			CAM_ISP_HW_VFE_IN_CAMIF)
-			cam_ife_hw_mgr_handle_hw_dump_info(
-			ife_hw_mgr_ctx, event_info);
-	}
+	err_evt_info = (struct cam_isp_hw_error_event_info *)event_info->event_data;
+	err_type =  err_evt_info->err_type;
 
-	if (event_info->err_type == CAM_VFE_IRQ_STATUS_VIOLATION)
+	spin_lock(&g_ife_hw_mgr.ctx_lock);
+	if (event_info->res_type ==
+		CAM_ISP_RESOURCE_VFE_IN &&
+		!ife_hw_mgr_ctx->flags.is_rdi_only_context &&
+		event_info->res_id !=
+		CAM_ISP_HW_VFE_IN_CAMIF)
+		cam_ife_hw_mgr_handle_hw_dump_info(ife_hw_mgr_ctx, event_info);
+
+	if (err_type == CAM_VFE_IRQ_STATUS_VIOLATION)
 		error_event_data.error_type = CAM_ISP_HW_ERROR_VIOLATION;
 	else if (event_info->res_type == CAM_ISP_RESOURCE_VFE_IN)
 		error_event_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW;
@@ -11681,7 +11685,7 @@ static int cam_ife_hw_mgr_handle_hw_err(
 	if (rc || !recovery_data.no_of_context)
 		goto end;
 
-	if (event_info->err_type == CAM_VFE_IRQ_STATUS_VIOLATION)
+	if (err_type == CAM_VFE_IRQ_STATUS_VIOLATION)
 		recovery_data.error_type = CAM_ISP_HW_ERROR_VIOLATION;
 	else
 		recovery_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW;
@@ -11693,11 +11697,9 @@ end:
 }
 
 static int cam_ife_hw_mgr_handle_hw_rup(
-	void                                    *ctx,
-	void                                    *evt_info)
+	struct cam_ife_hw_mgr_ctx               *ife_hw_mgr_ctx,
+	struct cam_isp_hw_event_info            *event_info)
 {
-	struct cam_isp_hw_event_info            *event_info = evt_info;
-	struct cam_ife_hw_mgr_ctx               *ife_hw_mgr_ctx = ctx;
 	cam_hw_event_cb_func                     ife_hwr_irq_rup_cb;
 	struct cam_isp_hw_reg_update_event_data  rup_event_data;
 
@@ -11745,11 +11747,9 @@ static int cam_ife_hw_mgr_handle_hw_rup(
 }
 
 static int cam_ife_hw_mgr_handle_hw_epoch(
-	void                                 *ctx,
-	void                                 *evt_info)
+	struct cam_ife_hw_mgr_ctx            *ife_hw_mgr_ctx,
+	struct cam_isp_hw_event_info         *event_info)
 {
-	struct cam_isp_hw_event_info         *event_info = evt_info;
-	struct cam_ife_hw_mgr_ctx            *ife_hw_mgr_ctx = ctx;
 	cam_hw_event_cb_func                  ife_hw_irq_epoch_cb;
 	struct cam_isp_hw_epoch_event_data    epoch_done_event_data;
 
@@ -11821,18 +11821,13 @@ static int cam_ife_hw_mgr_handle_csid_camif_sof(
 }
 
 static int cam_ife_hw_mgr_handle_hw_sof(
-	void                                 *ctx,
-	void                                 *evt_info)
+	struct cam_ife_hw_mgr_ctx            *ife_hw_mgr_ctx,
+	struct cam_isp_hw_event_info         *event_info)
 {
-	struct cam_isp_hw_event_info         *event_info = evt_info;
-	struct cam_ife_hw_mgr_ctx            *ife_hw_mgr_ctx = ctx;
 	cam_hw_event_cb_func                  ife_hw_irq_sof_cb;
 	struct cam_isp_hw_sof_event_data      sof_done_event_data;
 	struct timespec64 ts;
 
-	if (event_info->hw_type == CAM_ISP_HW_TYPE_CSID)
-		return cam_ife_hw_mgr_handle_csid_camif_sof(ctx, event_info);
-
 	memset(&sof_done_event_data, 0, sizeof(sof_done_event_data));
 
 	ife_hw_irq_sof_cb = ife_hw_mgr_ctx->common.event_cb;
@@ -11902,11 +11897,9 @@ static int cam_ife_hw_mgr_handle_hw_sof(
 }
 
 static int cam_ife_hw_mgr_handle_hw_eof(
-	void                                 *ctx,
-	void                                 *evt_info)
+	struct cam_ife_hw_mgr_ctx            *ife_hw_mgr_ctx,
+	struct cam_isp_hw_event_info         *event_info)
 {
-	struct cam_isp_hw_event_info         *event_info = evt_info;
-	struct cam_ife_hw_mgr_ctx            *ife_hw_mgr_ctx = ctx;
 	cam_hw_event_cb_func                  ife_hw_irq_eof_cb;
 	struct cam_isp_hw_eof_event_data      eof_done_event_data;
 
@@ -11976,35 +11969,44 @@ static int cam_ife_hw_mgr_check_rdi_scratch_buf_done(
 }
 
 static int cam_ife_hw_mgr_handle_hw_buf_done(
-	void                                *ctx,
-	void                                *evt_info)
+	struct cam_ife_hw_mgr_ctx        *ife_hw_mgr_ctx,
+	struct cam_isp_hw_event_info     *event_info)
 {
 	cam_hw_event_cb_func                   ife_hwr_irq_wm_done_cb;
-	struct cam_ife_hw_mgr_ctx             *ife_hw_mgr_ctx = ctx;
 	struct cam_isp_hw_done_event_data      buf_done_event_data = {0};
-	struct cam_isp_hw_compdone_event_info *event_info = evt_info;
+	struct cam_isp_hw_compdone_event_info *compdone_evt_info = NULL;
 	int32_t                                rc = 0, i;
 
-	ife_hwr_irq_wm_done_cb = ife_hw_mgr_ctx->common.event_cb;
+	if (!event_info->event_data) {
+		CAM_ERR(CAM_ISP,
+			"No additional buf done data failed to process for HW: %u",
+			event_info->hw_type);
+		return -EINVAL;
+	}
 
-	buf_done_event_data.num_handles = event_info->num_res;
+	ife_hwr_irq_wm_done_cb = ife_hw_mgr_ctx->common.event_cb;
+	compdone_evt_info = (struct cam_isp_hw_compdone_event_info *)event_info->event_data;
+	buf_done_event_data.num_handles = compdone_evt_info->num_res;
 
-	for (i = 0; i < event_info->num_res; i++) {
-		buf_done_event_data.resource_handle[i] = event_info->res_id[i];
-		buf_done_event_data.last_consumed_addr[i] = event_info->last_consumed_addr[i];
+	for (i = 0; i < compdone_evt_info->num_res; i++) {
+		buf_done_event_data.resource_handle[i] =
+			compdone_evt_info->res_id[i];
+		buf_done_event_data.last_consumed_addr[i] =
+			compdone_evt_info->last_consumed_addr[i];
 
 		CAM_DBG(CAM_ISP, "Buf done for %s: %d res_id: 0x%x last consumed addr: 0x%x",
 		((event_info->hw_type == CAM_ISP_HW_TYPE_SFE) ? "SFE" : "IFE"),
-		event_info->hw_idx, event_info->res_id[i], event_info->last_consumed_addr[i]);
+		event_info->hw_idx, compdone_evt_info->res_id[i],
+		compdone_evt_info->last_consumed_addr[i]);
 
-		if (cam_ife_hw_mgr_is_shdr_fs_rdi_res(event_info->res_id[i],
+		if (cam_ife_hw_mgr_is_shdr_fs_rdi_res(compdone_evt_info->res_id[i],
 			ife_hw_mgr_ctx->flags.is_sfe_shdr,
 			ife_hw_mgr_ctx->flags.is_sfe_fs)) {
 			rc = cam_ife_hw_mgr_check_rdi_scratch_buf_done(
 				ife_hw_mgr_ctx->ctx_index,
 				ife_hw_mgr_ctx->sfe_info.scratch_config,
-				event_info->res_id[i],
-				event_info->last_consumed_addr[i]);
+				compdone_evt_info->res_id[i],
+				compdone_evt_info->last_consumed_addr[i]);
 			if (rc)
 				goto end;
 		}
@@ -12024,61 +12026,160 @@ end:
 	return 0;
 }
 
-static int cam_ife_hw_mgr_event_handler(
-	void                                *priv,
+static int cam_ife_hw_mgr_handle_ife_event(
+	struct cam_ife_hw_mgr_ctx           *ctx,
 	uint32_t                             evt_id,
-	void                                *evt_info)
+	struct cam_isp_hw_event_info        *event_info)
 {
-	int                                  rc = 0;
-	struct cam_ife_hw_mgr_ctx           *ctx;
-	struct cam_ife_hw_mgr               *hw_mgr;
-
-	if (!evt_info)
-		return -EINVAL;
-
-	if (!priv)
-		return -EINVAL;
+	int rc = 0;
 
-	ctx = (struct cam_ife_hw_mgr_ctx *)priv;
-	CAM_DBG(CAM_ISP, "Event ID 0x%x", evt_id);
-	hw_mgr = ctx->hw_mgr;
+	CAM_DBG(CAM_ISP, "Handle IFE[%u] %s event in ctx: %u",
+		event_info->hw_idx,
+		__cam_ife_hw_mgr_evt_type_to_string(evt_id),
+		ctx->ctx_index);
 
 	switch (evt_id) {
 	case CAM_ISP_HW_EVENT_SOF:
-		rc = cam_ife_hw_mgr_handle_hw_sof(priv, evt_info);
+		rc = cam_ife_hw_mgr_handle_hw_sof(ctx, event_info);
 		break;
 
 	case CAM_ISP_HW_EVENT_REG_UPDATE:
-		if (hw_mgr->csid_rup_en)
-			rc = cam_ife_hw_mgr_handle_csid_rup(priv, evt_info);
-		else
-			rc = cam_ife_hw_mgr_handle_hw_rup(priv, evt_info);
+		rc = cam_ife_hw_mgr_handle_hw_rup(ctx, event_info);
 		break;
 
 	case CAM_ISP_HW_EVENT_EPOCH:
-		rc = cam_ife_hw_mgr_handle_hw_epoch(priv, evt_info);
+		rc = cam_ife_hw_mgr_handle_hw_epoch(ctx, event_info);
 		break;
 
 	case CAM_ISP_HW_EVENT_EOF:
-		rc = cam_ife_hw_mgr_handle_hw_eof(priv, evt_info);
+		rc = cam_ife_hw_mgr_handle_hw_eof(ctx, event_info);
 		break;
 
 	case CAM_ISP_HW_EVENT_DONE:
-		rc = cam_ife_hw_mgr_handle_hw_buf_done(priv, evt_info);
+		rc = cam_ife_hw_mgr_handle_hw_buf_done(ctx, event_info);
 		break;
 
 	case CAM_ISP_HW_EVENT_ERROR:
-		rc = cam_ife_hw_mgr_handle_hw_err(evt_id, priv, evt_info);
+		rc = cam_ife_hw_mgr_handle_hw_err(ctx, event_info);
 		break;
 
 	default:
-		CAM_ERR(CAM_ISP, "Invalid event ID %d", evt_id);
+		CAM_ERR(CAM_ISP, "Event: %u not handled for IFE", evt_id);
+		rc = -EINVAL;
 		break;
 	}
 
 	return rc;
 }
 
+static int cam_ife_hw_mgr_handle_csid_event(
+	struct cam_ife_hw_mgr_ctx       *ctx,
+	uint32_t                         evt_id,
+	struct cam_isp_hw_event_info    *event_info)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ISP, "Handle CSID[%u] %s event in ctx: %u",
+		event_info->hw_idx,
+		__cam_ife_hw_mgr_evt_type_to_string(evt_id),
+		ctx->ctx_index);
+
+	switch (evt_id) {
+	case CAM_ISP_HW_EVENT_REG_UPDATE:
+		rc = cam_ife_hw_mgr_handle_csid_rup(ctx, event_info);
+		break;
+
+	case CAM_ISP_HW_EVENT_ERROR:
+		rc = cam_ife_hw_mgr_handle_csid_error(ctx, event_info);
+		break;
+
+	case CAM_ISP_HW_EVENT_SOF:
+		rc = cam_ife_hw_mgr_handle_csid_camif_sof(ctx, event_info);
+		break;
+
+	default:
+		CAM_ERR(CAM_ISP, "Event: %u not handled for CSID", evt_id);
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static int cam_ife_hw_mgr_handle_sfe_event(
+	struct cam_ife_hw_mgr_ctx       *ctx,
+	uint32_t                         evt_id,
+	struct cam_isp_hw_event_info    *event_info)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ISP, "Handle SFE[%u] %s event in ctx: %u",
+		event_info->hw_idx,
+		__cam_ife_hw_mgr_evt_type_to_string(evt_id),
+		ctx->ctx_index);
+
+	switch (evt_id) {
+	case CAM_ISP_HW_EVENT_ERROR:
+		rc = cam_ife_hw_mgr_handle_sfe_hw_error(ctx, event_info);
+		break;
+
+	case CAM_ISP_HW_EVENT_DONE:
+		rc = cam_ife_hw_mgr_handle_hw_buf_done(ctx, event_info);
+		break;
+
+	default:
+		CAM_WARN(CAM_ISP, "Event: %u not handled for SFE", evt_id);
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static int cam_ife_hw_mgr_event_handler(
+	void                                *priv,
+	uint32_t                             evt_id,
+	void                                *evt_info)
+{
+	int rc = -EINVAL;
+	struct cam_ife_hw_mgr_ctx           *ctx;
+	struct cam_isp_hw_event_info        *event_info;
+
+	if (!evt_info || !priv) {
+		CAM_ERR(CAM_ISP,
+			"Invalid data evt_info: %pK priv: %pK",
+			evt_info, priv);
+		return rc;
+	}
+
+	ctx = (struct cam_ife_hw_mgr_ctx *)priv;
+	event_info = (struct cam_isp_hw_event_info *)evt_info;
+
+	switch (event_info->hw_type) {
+	case CAM_ISP_HW_TYPE_CSID:
+		rc = cam_ife_hw_mgr_handle_csid_event(ctx, evt_id, event_info);
+		break;
+
+	case CAM_ISP_HW_TYPE_SFE:
+		rc = cam_ife_hw_mgr_handle_sfe_event(ctx, evt_id, event_info);
+		break;
+
+	case CAM_ISP_HW_TYPE_VFE:
+		rc = cam_ife_hw_mgr_handle_ife_event(ctx, evt_id, event_info);
+		break;
+
+	default:
+		break;
+	}
+
+	if (rc)
+		CAM_ERR(CAM_ISP, "Failed to handle %s [%u] event from hw %u in ctx %u rc %d",
+			__cam_ife_hw_mgr_evt_type_to_string(evt_id),
+			evt_id, event_info->hw_type, ctx->ctx_index, rc);
+
+	return rc;
+}
+
 static int cam_ife_hw_mgr_sort_dev_with_caps(
 	struct cam_ife_hw_mgr *ife_hw_mgr)
 {

+ 14 - 6
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -5309,6 +5309,7 @@ end:
 }
 
 static int cam_tfe_hw_mgr_handle_csid_event(
+	uint32_t                      err_type,
 	struct cam_isp_hw_event_info *event_info)
 {
 	struct cam_isp_hw_error_event_data  error_event_data = {0};
@@ -5317,13 +5318,13 @@ static int cam_tfe_hw_mgr_handle_csid_event(
 	/* this can be extended based on the types of error
 	 * received from CSID
 	 */
-	switch (event_info->err_type) {
+	switch (err_type) {
 	case CAM_ISP_HW_ERROR_CSID_FATAL: {
 
 		if (!g_tfe_hw_mgr.debug_cfg.enable_csid_recovery)
 			break;
 
-		error_event_data.error_type = event_info->err_type;
+		error_event_data.error_type = err_type;
 		error_event_data.error_code = CAM_REQ_MGR_CSID_FATAL_ERROR;
 		cam_tfe_hw_mgr_find_affected_ctx(&error_event_data,
 			event_info->hw_idx,
@@ -5339,13 +5340,20 @@ static int cam_tfe_hw_mgr_handle_csid_event(
 static int cam_tfe_hw_mgr_handle_hw_err(
 	void                                *evt_info)
 {
+	struct cam_isp_hw_error_event_info      *err_evt_info;
 	struct cam_isp_hw_event_info            *event_info = evt_info;
 	struct cam_isp_hw_error_event_data       error_event_data = {0};
 	struct cam_tfe_hw_event_recovery_data    recovery_data = {0};
 	int    rc = -EINVAL;
 	uint32_t core_idx;
 
-	if (event_info->err_type == CAM_TFE_IRQ_STATUS_VIOLATION)
+	if (!event_info->event_data) {
+		CAM_ERR(CAM_ISP, "No error event data failed to process");
+		return rc;
+	}
+
+	err_evt_info = (struct cam_isp_hw_error_event_info *)event_info->event_data;
+	if (err_evt_info->err_type == CAM_TFE_IRQ_STATUS_VIOLATION)
 		error_event_data.error_type = CAM_ISP_HW_ERROR_VIOLATION;
 	else if (event_info->res_type == CAM_ISP_RESOURCE_TFE_IN ||
 		event_info->res_type == CAM_ISP_RESOURCE_PIX_PATH)
@@ -5354,8 +5362,8 @@ static int cam_tfe_hw_mgr_handle_hw_err(
 		error_event_data.error_type = CAM_ISP_HW_ERROR_BUSIF_OVERFLOW;
 
 	spin_lock(&g_tfe_hw_mgr.ctx_lock);
-	if (event_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) {
-		rc = cam_tfe_hw_mgr_handle_csid_event(event_info);
+	if (err_evt_info->err_type == CAM_ISP_HW_ERROR_CSID_FATAL) {
+		rc = cam_tfe_hw_mgr_handle_csid_event(err_evt_info->err_type, event_info);
 		spin_unlock(&g_tfe_hw_mgr.ctx_lock);
 		return rc;
 	}
@@ -5381,7 +5389,7 @@ static int cam_tfe_hw_mgr_handle_hw_err(
 
 	if (g_tfe_hw_mgr.debug_cfg.enable_recovery) {
 		/* Trigger for recovery */
-		if (event_info->err_type == CAM_TFE_IRQ_STATUS_VIOLATION)
+		if (err_evt_info->err_type == CAM_TFE_IRQ_STATUS_VIOLATION)
 			recovery_data.error_type = CAM_ISP_HW_ERROR_VIOLATION;
 		else
 			recovery_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW;

+ 3 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c

@@ -3875,12 +3875,14 @@ static int cam_ife_csid_ver1_handle_event_err(
 	struct cam_ife_csid_ver1_evt_payload *evt_payload,
 	uint32_t err_type)
 {
+	struct cam_isp_hw_error_event_info err_evt_info;
 	struct cam_isp_hw_event_info event_info = {0};
 	int rc = 0;
 
 	event_info.hw_idx = evt_payload->hw_idx;
-	event_info.err_type = err_type;
+	err_evt_info.err_type = err_type;
 	event_info.hw_type = CAM_ISP_HW_TYPE_CSID;
+	event_info.event_data = (void *)&err_evt_info;
 
 	CAM_DBG(CAM_ISP, "CSID[%d] Error type %d",
 		csid_hw->hw_intf->hw_idx, err_type);

+ 9 - 5
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -899,8 +899,9 @@ static int cam_ife_csid_ver2_handle_event_err(
 	uint32_t                      err_type,
 	struct cam_isp_resource_node *res)
 {
-	struct cam_isp_hw_event_info            evt = {0};
-	struct cam_ife_csid_ver2_path_cfg      *path_cfg;
+	struct cam_isp_hw_error_event_info   err_evt_info;
+	struct cam_isp_hw_event_info         evt = {0};
+	struct cam_ife_csid_ver2_path_cfg   *path_cfg;
 
 	if (!csid_hw->event_cb) {
 		CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID[%u] event cb not registered",
@@ -911,7 +912,8 @@ static int cam_ife_csid_ver2_handle_event_err(
 	evt.hw_idx   = csid_hw->hw_intf->hw_idx;
 	evt.reg_val  = irq_status;
 	evt.hw_type  = CAM_ISP_HW_TYPE_CSID;
-	evt.err_type = err_type;
+	err_evt_info.err_type = err_type;
+	evt.event_data = (void *)&err_evt_info;
 
 	if (res) {
 		cam_ife_csid_ver2_print_debug_reg_status(csid_hw, res);
@@ -928,7 +930,8 @@ static int cam_ife_csid_ver2_handle_event_err(
 			csid_hw->hw_intf->hw_idx, err_type, irq_status);
 	}
 
-	evt.in_core_idx = cam_ife_csid_ver2_input_core_to_hw_idx(csid_hw->top_cfg.input_core_type);
+	evt.in_core_idx =
+		cam_ife_csid_ver2_input_core_to_hw_idx(csid_hw->top_cfg.input_core_type);
 
 	csid_hw->event_cb(csid_hw->token, CAM_ISP_HW_EVENT_ERROR, (void *)&evt);
 
@@ -1429,10 +1432,11 @@ static int cam_ife_csid_ver2_ipp_bottom_half(
 		goto end;
 	}
 
+	evt_info.hw_type  = CAM_ISP_HW_TYPE_CSID;
 	evt_info.hw_idx   = csid_hw->hw_intf->hw_idx;
 	evt_info.res_id   = CAM_IFE_PIX_PATH_RES_IPP;
 	evt_info.res_type = CAM_ISP_RESOURCE_PIX_PATH;
-	evt_info.reg_val = irq_status_ipp;
+	evt_info.reg_val  = irq_status_ipp;
 
 	if (irq_status_ipp & IFE_CSID_VER2_PATH_CAMIF_EOF) {
 		if (csid_hw->event_cb)

+ 30 - 24
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -271,6 +271,34 @@ struct cam_isp_blanking_config {
 	struct cam_isp_resource_node       *node_res;
 };
 
+/**
+ * struct cam_isp_hw_error_event_info:
+ *
+ * @brief:              Structure to pass error event details to hw mgr
+ *
+ * @err_type:           Type of error being reported
+ *
+ */
+struct cam_isp_hw_error_event_info {
+	uint32_t    err_type;
+};
+
+/**
+ * struct cam_isp_hw_compdone_event_info:
+ *
+ * @brief:              Structure to pass bufdone event details to hw mgr
+ *
+ * @num_res:            Number of valid resource IDs in this event
+ * @res_id:             Resource IDs to report buf dones
+ * @last_consumed_addr: Last consumed addr for resource ID at that index
+ *
+ */
+struct cam_isp_hw_compdone_event_info {
+	uint32_t num_res;
+	uint32_t res_id[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
+	uint32_t last_consumed_addr[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
+};
+
 /*
  * struct cam_isp_hw_event_info:
  *
@@ -280,10 +308,10 @@ struct cam_isp_blanking_config {
  * @is_secondary_evt:  Indicates if event was requested by hw mgr
  * @res_id:            Unique resource ID
  * @hw_idx:            IFE hw index
- * @err_type:          Error type if any
  * @reg_val:           Any critical register value captured during irq handling
  * @hw_type:           Hw Type sending the event
  * @in_core_idx:       Input core type if CSID error evt
+ * @event_data:        Any additional data specific to this event
  *
  */
 struct cam_isp_hw_event_info {
@@ -291,32 +319,10 @@ struct cam_isp_hw_event_info {
 	bool                           is_secondary_evt;
 	uint32_t                       res_id;
 	uint32_t                       hw_idx;
-	uint32_t                       err_type;
 	uint32_t                       reg_val;
 	uint32_t                       hw_type;
 	uint32_t                       in_core_idx;
-};
-
-/**
- * struct cam_isp_hw_compdone_event_info:
- *
- * @brief:              Structure to pass bufdone event details to hw mgr
- *
- * @res_type:           Type of IFE/SFE resource
- * @hw_idx:             IFE/SFE hw index
- * @num_res:            Number of valid resource IDs in this event
- * @hw_type:            Hw Type sending the event (IFE or SFE)
- * @res_id:             Resource IDs to report buf dones
- * @last_consumed_addr: Last consumed addr for resource ID at that index
- *
- */
-struct cam_isp_hw_compdone_event_info {
-	enum cam_isp_resource_type     res_type;
-	uint32_t                       hw_idx;
-	uint32_t                       hw_type;
-	uint32_t num_res;
-	uint32_t res_id[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
-	uint32_t last_consumed_addr[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
+	void                          *event_data;
 };
 
 /*

+ 4 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_rd.c

@@ -673,6 +673,7 @@ static int cam_sfe_bus_rd_handle_irq_bottom_half(
 	struct cam_sfe_bus_rd_priv            *bus_priv;
 	struct cam_sfe_bus_rd_common_data     *common_data = NULL;
 	struct cam_isp_hw_event_info           evt_info;
+	struct cam_isp_hw_error_event_info     err_evt_info;
 	uint32_t status = 0, constraint_violation = 0;
 
 	if (!handler_priv || !evt_payload_priv)
@@ -690,10 +691,12 @@ static int cam_sfe_bus_rd_handle_irq_bottom_half(
 			bus_priv->common_data.core_index,
 			constraint_violation);
 
+		evt_info.hw_type  = CAM_ISP_HW_TYPE_SFE;
 		evt_info.hw_idx = bus_priv->common_data.core_index;
 		evt_info.res_type = CAM_ISP_RESOURCE_SFE_RD;
 		evt_info.res_id = CAM_SFE_BUS_RD_MAX;
-		evt_info.err_type = CAM_SFE_IRQ_STATUS_VIOLATION;
+		err_evt_info.err_type = CAM_SFE_IRQ_STATUS_VIOLATION;
+		evt_info.event_data = (void *)&err_evt_info;
 
 		if (common_data->event_cb)
 			common_data->event_cb(NULL,

+ 11 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.c

@@ -1803,7 +1803,8 @@ static int cam_sfe_bus_handle_sfe_out_done_bottom_half(
 	struct cam_isp_resource_node           *sfe_out = handler_priv;
 	struct cam_sfe_bus_wr_out_data         *rsrc_data = sfe_out->res_priv;
 	struct cam_sfe_bus_wr_irq_evt_payload  *evt_payload = evt_payload_priv;
-	struct cam_isp_hw_compdone_event_info    evt_info = {0};
+	struct cam_isp_hw_event_info            evt_info;
+	struct cam_isp_hw_compdone_event_info   compdone_evt_info = {0};
 	void                                   *ctx = NULL;
 	uint32_t                       out_list[CAM_SFE_BUS_SFE_OUT_MAX];
 
@@ -1838,14 +1839,15 @@ static int cam_sfe_bus_handle_sfe_out_done_bottom_half(
 			goto end;
 		}
 
-		evt_info.num_res = num_out;
+		compdone_evt_info.num_res = num_out;
 		for (i = 0; i < num_out; i++) {
-			evt_info.res_id[i] = out_list[i];
+			compdone_evt_info.res_id[i] = out_list[i];
 			cam_sfe_bus_get_last_consumed_addr(
 				rsrc_data->bus_priv,
-				evt_info.res_id[i], &val);
-			evt_info.last_consumed_addr[i] = val;
+				compdone_evt_info.res_id[i], &val);
+			compdone_evt_info.last_consumed_addr[i] = val;
 		}
+		evt_info.event_data = (void *)&compdone_evt_info;
 		if (rsrc_data->common_data->event_cb)
 			rsrc_data->common_data->event_cb(ctx, evt_id,
 				(void *)&evt_info);
@@ -2147,11 +2149,14 @@ static int cam_sfe_bus_wr_irq_bottom_half(
 	cam_sfe_bus_wr_put_evt_payload(common_data, &evt_payload);
 
 	if (!skip_err_notify) {
+		struct cam_isp_hw_error_event_info err_evt_info;
+
 		evt_info.hw_idx = common_data->core_index;
 		evt_info.hw_type = CAM_ISP_HW_TYPE_SFE;
 		evt_info.res_type = CAM_ISP_RESOURCE_SFE_OUT;
 		evt_info.res_id = CAM_SFE_BUS_SFE_OUT_MAX;
-		evt_info.err_type = CAM_SFE_IRQ_STATUS_VIOLATION;
+		err_evt_info.err_type = CAM_SFE_IRQ_STATUS_VIOLATION;
+		evt_info.event_data = (void *)&err_evt_info;
 
 		if (common_data->event_cb) {
 			struct cam_isp_resource_node      *out_rsrc_node = NULL;

+ 4 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.c

@@ -1384,12 +1384,15 @@ static int cam_sfe_top_handle_err_irq_bottom_half(
 
 	if (irq_status[0] &
 		top_priv->common_data.common_reg_data->error_irq_mask) {
+		struct cam_isp_hw_error_event_info err_evt_info;
+
 		viol_sts = payload->violation_status;
 		CAM_INFO(CAM_SFE, "Violation status 0x%x",
 			viol_sts);
 		cam_sfe_top_print_top_irq_error(top_priv,
 			irq_status[0], viol_sts);
-		evt_info.err_type = CAM_SFE_IRQ_STATUS_VIOLATION;
+		err_evt_info.err_type = CAM_SFE_IRQ_STATUS_VIOLATION;
+		evt_info.event_data = (void *)&err_evt_info;
 		cam_sfe_top_print_debug_reg_info(top_priv);
 		if (top_priv->event_cb)
 			top_priv->event_cb(top_priv->priv_per_stream,

+ 3 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c

@@ -3109,6 +3109,7 @@ static int cam_tfe_csid_evt_bottom_half_handler(
 	struct cam_tfe_csid_hw *csid_hw;
 	struct cam_csid_evt_payload *evt_payload;
 	const struct cam_tfe_csid_reg_offset    *csid_reg;
+	struct cam_isp_hw_error_event_info err_evt_info;
 	struct cam_isp_hw_event_info event_info;
 	int i;
 	int rc = 0;
@@ -3175,13 +3176,14 @@ static int cam_tfe_csid_evt_bottom_half_handler(
 	 * which we want to offload to bottom half from
 	 * irq handlers
 	 */
-	event_info.err_type = evt_payload->evt_type;
+	err_evt_info.err_type = evt_payload->evt_type;
 	event_info.hw_idx = evt_payload->hw_idx;
 
 	switch (evt_payload->evt_type) {
 	case CAM_ISP_HW_ERROR_CSID_FATAL:
 		if (csid_hw->fatal_err_detected)
 			break;
+		event_info.event_data = (void *)&err_evt_info;
 		csid_hw->fatal_err_detected = true;
 		rc = csid_hw->event_cb(NULL,
 			CAM_ISP_HW_EVENT_ERROR, (void *)&event_info);

+ 4 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -456,6 +456,7 @@ static int cam_tfe_error_irq_bottom_half(
 	cam_hw_mgr_event_cb_func              event_cb,
 	void                                 *event_cb_priv)
 {
+	struct cam_isp_hw_error_event_info   err_evt_info;
 	struct cam_isp_hw_event_info         evt_info;
 	struct cam_tfe_hw_info              *hw_info;
 	uint32_t   error_detected = 0;
@@ -465,18 +466,18 @@ static int cam_tfe_error_irq_bottom_half(
 	evt_info.res_type = CAM_ISP_RESOURCE_TFE_IN;
 
 	if (evt_payload->irq_reg_val[0] & hw_info->error_irq_mask[0]) {
-		evt_info.err_type = CAM_TFE_IRQ_STATUS_OVERFLOW;
+		err_evt_info.err_type = CAM_TFE_IRQ_STATUS_OVERFLOW;
 		error_detected = 1;
 	}
 
 	if ((evt_payload->bus_irq_val[0] & hw_info->bus_error_irq_mask[0]) ||
 		(evt_payload->irq_reg_val[2] & hw_info->error_irq_mask[2])) {
-		evt_info.err_type = CAM_TFE_IRQ_STATUS_VIOLATION;
+		err_evt_info.err_type = CAM_TFE_IRQ_STATUS_VIOLATION;
 		error_detected = 1;
 	}
 
 	if (error_detected) {
-		evt_info.err_type = CAM_TFE_IRQ_STATUS_OVERFLOW;
+		evt_info.event_data = (void *)&err_evt_info;
 		top_priv->error_ts.tv_sec =
 			evt_payload->ts.mono_time.tv_sec;
 		top_priv->error_ts.tv_nsec =

+ 9 - 5
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c

@@ -1532,6 +1532,7 @@ static int cam_vfe_bus_err_bottom_half(void *handler_priv,
 
 	cam_vfe_bus_put_evt_payload(common_data, &evt_payload);
 
+	evt_info.hw_type = CAM_ISP_HW_TYPE_VFE;
 	evt_info.hw_idx = common_data->core_index;
 	evt_info.res_type = CAM_ISP_RESOURCE_VFE_OUT;
 	evt_info.res_id = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
@@ -2476,7 +2477,8 @@ static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
 	int rc = -EINVAL;
 	struct cam_isp_resource_node             *vfe_out = handler_priv;
 	struct cam_vfe_bus_ver2_vfe_out_data     *rsrc_data = vfe_out->res_priv;
-	struct cam_isp_hw_compdone_event_info      evt_info = {0};
+	struct cam_isp_hw_event_info              evt_info;
+	struct cam_isp_hw_compdone_event_info     compdone_evt_info = {0};
 	void                                     *ctx = NULL;
 	uint32_t                                  evt_id = 0;
 	uint32_t                                  comp_mask = 0;
@@ -2506,6 +2508,7 @@ static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
 	case CAM_VFE_IRQ_STATUS_SUCCESS:
 		evt_id = evt_payload->evt_id;
 
+		evt_info.hw_type = CAM_ISP_HW_TYPE_VFE;
 		evt_info.res_type = vfe_out->res_type;
 		evt_info.hw_idx   = vfe_out->hw_intf->hw_idx;
 		if (rsrc_data->comp_grp) {
@@ -2523,14 +2526,15 @@ static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
 				goto end;
 			}
 
-			evt_info.num_res = num_out;
+			compdone_evt_info.num_res = num_out;
 			for (i = 0; i < num_out; i++) {
-				evt_info.res_id[i] = out_list[i];
+				compdone_evt_info.res_id[i] = out_list[i];
 			}
 		} else {
-			evt_info.num_res = 1;
-			evt_info.res_id[0] = vfe_out->res_id;
+			compdone_evt_info.num_res = 1;
+			compdone_evt_info.res_id[0] = vfe_out->res_id;
 		}
+		evt_info.event_data = (void *)&compdone_evt_info;
 		if (rsrc_data->common_data->event_cb)
 			rsrc_data->common_data->event_cb(ctx,
 				evt_id, (void *)&evt_info);

+ 11 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c

@@ -742,6 +742,7 @@ static int cam_vfe_bus_ver3_handle_rup_bottom_half(void *handler_priv,
 
 	irq_status = payload->irq_reg_val[CAM_IFE_IRQ_BUS_VER3_REG_STATUS0];
 
+	evt_info.hw_type  = CAM_ISP_HW_TYPE_VFE;
 	evt_info.hw_idx = rsrc_data->common_data->core_index;
 	evt_info.res_type = CAM_ISP_RESOURCE_VFE_IN;
 
@@ -2403,7 +2404,8 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_bottom_half(
 	struct cam_isp_resource_node          *vfe_out = handler_priv;
 	struct cam_vfe_bus_ver3_vfe_out_data  *rsrc_data = vfe_out->res_priv;
 	struct cam_vfe_bus_irq_evt_payload    *evt_payload = evt_payload_priv;
-	struct cam_isp_hw_compdone_event_info  evt_info = {0};
+	struct cam_isp_hw_event_info           evt_info;
+	struct cam_isp_hw_compdone_event_info  compdone_evt_info = {0};
 	void                                  *ctx = NULL;
 	uint32_t                               evt_id = 0;
 	uint64_t                               comp_mask = 0;
@@ -2439,14 +2441,15 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_bottom_half(
 			goto end;
 		}
 
-		evt_info.num_res = num_out;
+		compdone_evt_info.num_res = num_out;
 		for (i = 0; i < num_out; i++) {
-			evt_info.res_id[i] = out_list[i];
-			evt_info.last_consumed_addr[i] =
+			compdone_evt_info.res_id[i] = out_list[i];
+			compdone_evt_info.last_consumed_addr[i] =
 				cam_vfe_bus_ver3_get_last_consumed_addr(
 				rsrc_data->bus_priv,
-				evt_info.res_id[i]);
+				compdone_evt_info.res_id[i]);
 		}
+		evt_info.event_data = (void *)&compdone_evt_info;
 		if (rsrc_data->common_data->event_cb)
 			rsrc_data->common_data->event_cb(ctx, evt_id,
 				(void *)&evt_info);
@@ -2860,6 +2863,7 @@ static int cam_vfe_bus_ver3_err_irq_bottom_half(
 	struct cam_vfe_bus_ver3_priv *bus_priv = handler_priv;
 	struct cam_vfe_bus_ver3_common_data *common_data;
 	struct cam_isp_hw_event_info evt_info;
+	struct cam_isp_hw_error_event_info err_evt_info;
 	uint32_t status = 0, image_size_violation = 0, ccif_violation = 0, constraint_violation = 0;
 
 	if (!handler_priv || !evt_payload_priv)
@@ -2901,8 +2905,9 @@ static int cam_vfe_bus_ver3_err_irq_bottom_half(
 	evt_info.hw_idx = common_data->core_index;
 	evt_info.res_type = CAM_ISP_RESOURCE_VFE_OUT;
 	evt_info.res_id = CAM_VFE_BUS_VER3_VFE_OUT_MAX;
-	evt_info.err_type = CAM_VFE_IRQ_STATUS_VIOLATION;
 	evt_info.hw_type = CAM_ISP_HW_TYPE_VFE;
+	err_evt_info.err_type = CAM_VFE_IRQ_STATUS_VIOLATION;
+	evt_info.event_data = (void *)&err_evt_info;
 
 	if (common_data->event_cb)
 		common_data->event_cb(common_data->priv, CAM_ISP_HW_EVENT_ERROR,

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver2.c

@@ -512,6 +512,7 @@ static int cam_vfe_camif_lite_handle_irq_bottom_half(
 	soc_private =
 		(struct cam_vfe_soc_private *)soc_info->soc_private;
 
+	evt_info.hw_type  = CAM_ISP_HW_TYPE_VFE;
 	evt_info.hw_idx   = camif_lite_node->hw_intf->hw_idx;
 	evt_info.res_id   = camif_lite_node->res_id;
 	evt_info.res_type = camif_lite_node->res_type;

+ 6 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c

@@ -1076,6 +1076,7 @@ static int cam_vfe_camif_lite_handle_irq_bottom_half(
 	struct cam_vfe_mux_camif_lite_data *camif_lite_priv;
 	struct cam_vfe_top_irq_evt_payload *payload;
 	struct cam_isp_hw_event_info evt_info;
+	struct cam_isp_hw_error_event_info err_evt_info;
 	struct cam_vfe_soc_private *soc_private = NULL;
 	uint32_t irq_status[CAM_IFE_IRQ_REGISTERS_MAX] = {0};
 	int i = 0;
@@ -1100,6 +1101,7 @@ static int cam_vfe_camif_lite_handle_irq_bottom_half(
 	for (i = 0; i < CAM_IFE_IRQ_REGISTERS_MAX; i++)
 		irq_status[i] = payload->irq_reg_val[i];
 
+	evt_info.hw_type  = CAM_ISP_HW_TYPE_VFE;
 	evt_info.hw_idx   = camif_lite_node->hw_intf->hw_idx;
 	evt_info.res_id   = camif_lite_node->res_id;
 	evt_info.res_type = camif_lite_node->res_type;
@@ -1166,7 +1168,8 @@ static int cam_vfe_camif_lite_handle_irq_bottom_half(
 		CAM_ERR(CAM_ISP, "VFE:%d Overflow",
 			camif_lite_node->hw_intf->hw_idx);
 
-		evt_info.err_type = CAM_VFE_IRQ_STATUS_OVERFLOW;
+		err_evt_info.err_type = CAM_VFE_IRQ_STATUS_OVERFLOW;
+		evt_info.event_data = (void *)&err_evt_info;
 		ktime_get_boottime_ts64(&ts);
 		CAM_INFO(CAM_ISP,
 			"current monotonic time stamp seconds %lld:%lld",
@@ -1215,7 +1218,8 @@ static int cam_vfe_camif_lite_handle_irq_bottom_half(
 		CAM_ERR(CAM_ISP, "VFE:%d Violation",
 			camif_lite_node->hw_intf->hw_idx);
 
-		evt_info.err_type = CAM_VFE_IRQ_STATUS_VIOLATION;
+		err_evt_info.err_type = CAM_VFE_IRQ_STATUS_VIOLATION;
+		evt_info.event_data = (void *)&err_evt_info;
 
 		if (camif_lite_priv->event_cb)
 			camif_lite_priv->event_cb(camif_lite_priv->priv,

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c

@@ -806,6 +806,7 @@ static int cam_vfe_camif_handle_irq_bottom_half(void *handler_priv,
 	soc_info = camif_priv->soc_info;
 	soc_private = (struct cam_vfe_soc_private *)soc_info->soc_private;
 
+	evt_info.hw_type  = CAM_ISP_HW_TYPE_VFE;
 	evt_info.hw_idx   = camif_node->hw_intf->hw_idx;
 	evt_info.res_id   = camif_node->res_id;
 	evt_info.res_type = camif_node->res_type;

+ 6 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c

@@ -1361,6 +1361,7 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
 	struct cam_vfe_mux_camif_ver3_data *camif_priv;
 	struct cam_vfe_top_irq_evt_payload *payload;
 	struct cam_isp_hw_event_info evt_info;
+	struct cam_isp_hw_error_event_info err_evt_info;
 	struct cam_hw_soc_info *soc_info = NULL;
 	struct cam_vfe_soc_private *soc_private = NULL;
 	uint32_t irq_status[CAM_IFE_IRQ_REGISTERS_MAX] = {0};
@@ -1386,6 +1387,7 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
 	for (i = 0; i < CAM_IFE_IRQ_REGISTERS_MAX; i++)
 		irq_status[i] = payload->irq_reg_val[i];
 
+	evt_info.hw_type  = CAM_ISP_HW_TYPE_VFE;
 	evt_info.hw_idx   = camif_node->hw_intf->hw_idx;
 	evt_info.res_id   = camif_node->res_id;
 	evt_info.res_type = camif_node->res_type;
@@ -1470,7 +1472,8 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
 			ts.tv_sec, ts.tv_nsec);
 
 		ret = CAM_VFE_IRQ_STATUS_OVERFLOW;
-		evt_info.err_type = CAM_VFE_IRQ_STATUS_OVERFLOW;
+		err_evt_info.err_type = CAM_VFE_IRQ_STATUS_OVERFLOW;
+		evt_info.event_data = (void *)&err_evt_info;
 
 		CAM_INFO(CAM_ISP, "ife_clk_src:%lld",
 			soc_private->ife_clk_src);
@@ -1503,7 +1506,8 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv,
 			ts.tv_sec, ts.tv_nsec);
 
 		ret = CAM_VFE_IRQ_STATUS_VIOLATION;
-		evt_info.err_type = CAM_VFE_IRQ_STATUS_VIOLATION;
+		err_evt_info.err_type = CAM_VFE_IRQ_STATUS_VIOLATION;
+		evt_info.event_data = (void *)&err_evt_info;
 
 		CAM_INFO(CAM_ISP, "ife_clk_src:%lld",
 			soc_private->ife_clk_src);

+ 1 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_fe_ver1.c

@@ -516,7 +516,6 @@ static int cam_vfe_fe_handle_irq_bottom_half(void *handler_priv,
 	struct cam_isp_resource_node         *fe_node;
 	struct cam_vfe_mux_fe_data           *fe_priv;
 	struct cam_vfe_top_irq_evt_payload   *payload;
-	struct cam_isp_hw_event_info          evt_info;
 	uint32_t                              irq_status0;
 	uint32_t                              irq_status1;
 
@@ -531,10 +530,6 @@ static int cam_vfe_fe_handle_irq_bottom_half(void *handler_priv,
 	irq_status0 = payload->irq_reg_val[CAM_IFE_IRQ_CAMIF_REG_STATUS0];
 	irq_status1 = payload->irq_reg_val[CAM_IFE_IRQ_CAMIF_REG_STATUS1];
 
-	evt_info.hw_idx = fe_node->hw_intf->hw_idx;
-	evt_info.res_id = fe_node->res_id;
-	evt_info.res_type = fe_node->res_type;
-
 	CAM_DBG(CAM_ISP, "event ID, irq_status_0 = 0x%x", irq_status0);
 
 	if (irq_status0 & fe_priv->reg_data->sof_irq_mask) {
@@ -574,8 +569,8 @@ static int cam_vfe_fe_handle_irq_bottom_half(void *handler_priv,
 	if (irq_status1 & fe_priv->reg_data->error_irq_mask1) {
 		CAM_DBG(CAM_ISP, "Received ERROR");
 		ret = CAM_ISP_HW_ERROR_OVERFLOW;
-		evt_info.err_type = CAM_VFE_IRQ_STATUS_OVERFLOW;
 		cam_vfe_fe_reg_dump(fe_node);
+		/* No HW mgr notification on error */
 	} else {
 		ret = CAM_ISP_HW_ERROR_NONE;
 	}

+ 4 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c

@@ -473,6 +473,7 @@ static int cam_vfe_rdi_handle_irq_bottom_half(void *handler_priv,
 	struct cam_vfe_mux_rdi_data         *rdi_priv;
 	struct cam_vfe_top_irq_evt_payload  *payload;
 	struct cam_isp_hw_event_info         evt_info;
+	struct cam_isp_hw_error_event_info	 err_evt_info;
 	uint32_t                             irq_status0;
 	uint32_t                             irq_status1;
 	uint32_t                             irq_rdi_status;
@@ -495,6 +496,7 @@ static int cam_vfe_rdi_handle_irq_bottom_half(void *handler_priv,
 	irq_status0 = payload->irq_reg_val[CAM_IFE_IRQ_CAMIF_REG_STATUS0];
 	irq_status1 = payload->irq_reg_val[CAM_IFE_IRQ_CAMIF_REG_STATUS1];
 
+	evt_info.hw_type  = CAM_ISP_HW_TYPE_VFE;
 	evt_info.hw_idx   = rdi_node->hw_intf->hw_idx;
 	evt_info.res_id   = rdi_node->res_id;
 	evt_info.res_type = rdi_node->res_type;
@@ -564,6 +566,8 @@ static int cam_vfe_rdi_handle_irq_bottom_half(void *handler_priv,
 			evt_info.res_id = CAM_ISP_IFE_OUT_RES_RDI_3;
 			}
 
+		err_evt_info.err_type = CAM_VFE_IRQ_STATUS_OVERFLOW;
+		evt_info.event_data = (void *)&err_evt_info;
 		if (rdi_priv->event_cb)
 			rdi_priv->event_cb(rdi_priv->priv,
 			CAM_ISP_HW_EVENT_ERROR,