Parcourir la source

msm: camera: ife: Add new controller for RUP IRQ

Currently EPOCH IRQ handling is at a higher priority
compared to RUP IRQ as RUP is fired at bus level. If
RUP IRQ is not scheduled for handling by the time we
receive EPOCH IRQ, EPOCH IRQ will be processed first
and this will lead to missed SOF notification as the
active request list might be empty. This change sets
priority of both IRQs to the same by utilizing a new
IRQ controller that is tasked with handling RUP from
BUS. BUF_DONE is also subscribed to the same VFE top
level BUS_WR IRQ but with a lower priority. IRQs for
CAMIF Lite and RDI are subscribed to only if the ctx
is RDI only.

Change-Id: Id844ffe291e21ecfc7f7ed6fc53baf7e79dd2184
Signed-off-by: Venkat Chinta <[email protected]>
Signed-off-by: Mukund Madhusudan Atre <[email protected]>
Venkat Chinta il y a 6 ans
Parent
commit
54070a35f2

+ 28 - 8
drivers/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -53,6 +53,8 @@ struct cam_irq_evt_handler {
  * @clear_reg_offset:       Offset of IRQ CLEAR register
  * @status_reg_offset:      Offset of IRQ STATUS register
  * @top_half_enable_mask:   Array of enabled bit_mask sorted by priority
+ * @pclear_mask:            Partial mask to be cleared in case entire status
+ *                          register is not to be cleared
  */
 struct cam_irq_register_obj {
 	uint32_t                     index;
@@ -60,6 +62,7 @@ struct cam_irq_register_obj {
 	uint32_t                     clear_reg_offset;
 	uint32_t                     status_reg_offset;
 	uint32_t                     top_half_enable_mask[CAM_IRQ_PRIORITY_MAX];
+	uint32_t                     pclear_mask;
 };
 
 /**
@@ -84,6 +87,8 @@ struct cam_irq_register_obj {
  * @hdl_idx:                Unique identity of handler assigned on Subscribe.
  *                          Used to Unsubscribe.
  * @lock:                   Lock for use by controller
+ * @clear_all:              Flag to indicate whether to clear entire status
+ *                          register
  */
 struct cam_irq_controller {
 	const char                     *name;
@@ -98,6 +103,7 @@ struct cam_irq_controller {
 	uint32_t                        hdl_idx;
 	spinlock_t                      lock;
 	struct cam_irq_th_payload       th_payload;
+	bool                            clear_all;
 };
 
 int cam_irq_controller_deinit(void **irq_controller)
@@ -125,7 +131,8 @@ int cam_irq_controller_deinit(void **irq_controller)
 int cam_irq_controller_init(const char       *name,
 	void __iomem                         *mem_base,
 	struct cam_irq_controller_reg_info   *register_info,
-	void                                **irq_controller)
+	void                                **irq_controller,
+	bool                                  clear_all)
 {
 	struct cam_irq_controller *controller = NULL;
 	int i, rc = 0;
@@ -194,6 +201,7 @@ int cam_irq_controller_init(const char       *name,
 	controller->global_clear_bitmask = register_info->global_clear_bitmask;
 	controller->global_clear_offset  = register_info->global_clear_offset;
 	controller->mem_base             = mem_base;
+	controller->clear_all            = clear_all;
 
 	CAM_DBG(CAM_IRQ_CTRL, "global_clear_bitmask: 0x%x",
 		controller->global_clear_bitmask);
@@ -321,6 +329,9 @@ int cam_irq_controller_subscribe_irq(void *irq_controller,
 		controller->irq_register_arr[i].top_half_enable_mask[priority]
 			|= evt_bit_mask_arr[i];
 
+		controller->irq_register_arr[i].pclear_mask
+			|= evt_bit_mask_arr[i];
+
 		irq_mask = cam_io_r_mb(controller->mem_base +
 			controller->irq_register_arr[i].mask_reg_offset);
 		irq_mask |= evt_bit_mask_arr[i];
@@ -610,7 +621,8 @@ static void cam_irq_controller_th_processing(
 				evt_handler->bottom_half, &bh_cmd);
 			if (rc || !bh_cmd) {
 				CAM_ERR_RATE_LIMIT(CAM_ISP,
-					"No payload, IRQ handling frozen");
+					"No payload, IRQ handling frozen for %s",
+					controller->name);
 				continue;
 			}
 		}
@@ -689,11 +701,19 @@ irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv)
 	for (i = 0; i < controller->num_registers; i++) {
 		irq_register = &controller->irq_register_arr[i];
 		controller->irq_status_arr[i] = cam_io_r_mb(
-			controller->mem_base +
-			controller->irq_register_arr[i].status_reg_offset);
-		cam_io_w_mb(controller->irq_status_arr[i],
-			controller->mem_base +
-			controller->irq_register_arr[i].clear_reg_offset);
+			controller->mem_base + irq_register->status_reg_offset);
+
+		if (controller->clear_all)
+			cam_io_w_mb(controller->irq_status_arr[i],
+				controller->mem_base +
+				irq_register->clear_reg_offset);
+		else
+			cam_io_w_mb(
+				controller->irq_register_arr[i].pclear_mask &
+				controller->irq_status_arr[i],
+				controller->mem_base +
+				irq_register->clear_reg_offset);
+
 		CAM_DBG(CAM_IRQ_CTRL, "Read irq status%d (0x%x) = 0x%x", i,
 			controller->irq_register_arr[i].status_reg_offset,
 			controller->irq_status_arr[i]);

+ 4 - 2
drivers/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_IRQ_CONTROLLER_H_
@@ -131,6 +131,7 @@ struct cam_irq_bh_api {
  * @register_info:      Register Info structure associated with this Controller
  * @irq_controller:     Pointer to IRQ Controller that will be filled if
  *                      initialization is successful
+ * @clear_all:          Flag to indicate whether to clear entire status register
  *
  * @return:             0: Success
  *                      Negative: Failure
@@ -138,7 +139,8 @@ struct cam_irq_bh_api {
 int cam_irq_controller_init(const char       *name,
 	void __iomem                         *mem_base,
 	struct cam_irq_controller_reg_info   *register_info,
-	void                                **irq_controller);
+	void                                **irq_controller,
+	bool                                  clear_all);
 
 /*
  * cam_irq_controller_subscribe_irq()

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c

@@ -669,7 +669,8 @@ int cam_vfe_core_init(struct cam_vfe_hw_core_info  *core_info,
 
 	rc = cam_irq_controller_init(drv_name,
 		CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX),
-		vfe_hw_info->irq_reg_info, &core_info->vfe_irq_controller);
+		vfe_hw_info->irq_reg_info, &core_info->vfe_irq_controller,
+		true);
 	if (rc) {
 		CAM_ERR(CAM_ISP,
 			"Error, cam_irq_controller_init failed rc = %d", rc);

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_rd_ver1.c

@@ -1107,7 +1107,7 @@ int cam_vfe_bus_rd_ver1_init(
 
 	rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
 		&bus_rd_hw_info->common_reg.irq_reg_info,
-		&bus_priv->common_data.bus_irq_controller);
+		&bus_priv->common_data.bus_irq_controller, true);
 	if (rc) {
 		CAM_ERR(CAM_ISP, "cam_irq_controller_init failed");
 		goto free_bus_priv;

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

@@ -3622,7 +3622,7 @@ int cam_vfe_bus_ver2_init(
 
 	rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
 		&ver2_hw_info->common_reg.irq_reg_info,
-		&bus_priv->common_data.bus_irq_controller);
+		&bus_priv->common_data.bus_irq_controller, true);
 	if (rc) {
 		CAM_ERR(CAM_ISP, "cam_irq_controller_init failed");
 		goto free_bus_priv;

+ 79 - 18
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c

@@ -66,6 +66,7 @@ struct cam_vfe_bus_ver3_common_data {
 	void __iomem                               *mem_base;
 	struct cam_hw_intf                         *hw_intf;
 	void                                       *bus_irq_controller;
+	void                                       *rup_irq_controller;
 	void                                       *vfe_irq_controller;
 	struct cam_vfe_bus_ver3_reg_offset_common  *common_reg;
 	uint32_t                                    io_buf_update[
@@ -180,7 +181,8 @@ struct cam_vfe_bus_ver3_priv {
 	struct list_head                    free_comp_grp;
 	struct list_head                    used_comp_grp;
 
-	int                                 irq_handle;
+	int                                 bus_irq_handle;
+	int                                 rup_irq_handle;
 	int                                 error_irq_handle;
 	void                               *tasklet_info;
 };
@@ -2159,6 +2161,10 @@ static int cam_vfe_bus_ver3_start_vfe_out(
 		return -EFAULT;
 	}
 
+	if ((common_data->is_lite || source_group > CAM_VFE_BUS_VER3_SRC_GRP_0)
+		&& !vfe_out->rdi_only_ctx)
+		goto end;
+
 	if (!common_data->rup_irq_handle[source_group]) {
 		memset(rup_irq_reg_mask, 0, sizeof(rup_irq_reg_mask));
 		rup_irq_reg_mask[CAM_VFE_BUS_VER3_IRQ_REG0] |=
@@ -2171,8 +2177,8 @@ static int cam_vfe_bus_ver3_start_vfe_out(
 
 		common_data->rup_irq_handle[source_group] =
 			cam_irq_controller_subscribe_irq(
-				common_data->bus_irq_controller,
-				CAM_IRQ_PRIORITY_1,
+				common_data->rup_irq_controller,
+				CAM_IRQ_PRIORITY_0,
 				rup_irq_reg_mask,
 				vfe_out,
 				cam_vfe_bus_ver3_handle_rup_top_half,
@@ -2222,7 +2228,7 @@ static int cam_vfe_bus_ver3_stop_vfe_out(
 
 	if (common_data->rup_irq_handle[rsrc_data->source_group]) {
 		rc = cam_irq_controller_unsubscribe_irq(
-			common_data->bus_irq_controller,
+			common_data->rup_irq_controller,
 			common_data->rup_irq_handle[rsrc_data->source_group]);
 		common_data->rup_irq_handle[rsrc_data->source_group] = 0;
 	}
@@ -2460,19 +2466,32 @@ static void cam_vfe_bus_ver3_print_dimensions(
 		wm_data->en_cfg);
 }
 
-static int cam_vfe_bus_ver3_handle_irq(uint32_t    evt_id,
+static int cam_vfe_bus_ver3_handle_bus_irq(uint32_t    evt_id,
 	struct cam_irq_th_payload                 *th_payload)
 {
 	struct cam_vfe_bus_ver3_priv          *bus_priv;
 	int rc = 0;
 
-	bus_priv     = th_payload->handler_priv;
+	bus_priv = th_payload->handler_priv;
 	CAM_DBG(CAM_ISP, "Enter");
 	rc = cam_irq_controller_handle_irq(evt_id,
 		bus_priv->common_data.bus_irq_controller);
 	return (rc == IRQ_HANDLED) ? 0 : -EINVAL;
 }
 
+static int cam_vfe_bus_ver3_handle_rup_irq(uint32_t     evt_id,
+	struct cam_irq_th_payload                 *th_payload)
+{
+	struct cam_vfe_bus_ver3_priv          *bus_priv;
+	int rc = 0;
+
+	bus_priv = th_payload->handler_priv;
+	CAM_DBG(CAM_ISP, "Enter");
+	rc = cam_irq_controller_handle_irq(evt_id,
+		bus_priv->common_data.rup_irq_controller);
+	return (rc == IRQ_HANDLED) ? 0 : -EINVAL;
+}
+
 static int cam_vfe_bus_ver3_err_irq_top_half(uint32_t evt_id,
 	struct cam_irq_th_payload *th_payload)
 {
@@ -3539,19 +3558,35 @@ static int cam_vfe_bus_ver3_init_hw(void *hw_priv,
 
 	top_irq_reg_mask[0] = (1 << bus_priv->top_irq_shift);
 
-	bus_priv->irq_handle = cam_irq_controller_subscribe_irq(
+	bus_priv->bus_irq_handle = cam_irq_controller_subscribe_irq(
+		bus_priv->common_data.vfe_irq_controller,
+		CAM_IRQ_PRIORITY_4,
+		top_irq_reg_mask,
+		bus_priv,
+		cam_vfe_bus_ver3_handle_bus_irq,
+		NULL,
+		NULL,
+		NULL);
+
+	if (bus_priv->bus_irq_handle < 1) {
+		CAM_ERR(CAM_ISP, "Failed to subscribe BUS (buf_done) IRQ");
+		bus_priv->bus_irq_handle = 0;
+		return -EFAULT;
+	}
+
+	bus_priv->rup_irq_handle = cam_irq_controller_subscribe_irq(
 		bus_priv->common_data.vfe_irq_controller,
 		CAM_IRQ_PRIORITY_2,
 		top_irq_reg_mask,
 		bus_priv,
-		cam_vfe_bus_ver3_handle_irq,
+		cam_vfe_bus_ver3_handle_rup_irq,
 		NULL,
 		NULL,
 		NULL);
 
-	if (bus_priv->irq_handle < 1) {
-		CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
-		bus_priv->irq_handle = 0;
+	if (bus_priv->rup_irq_handle < 1) {
+		CAM_ERR(CAM_ISP, "Failed to subscribe BUS (rup) IRQ");
+		bus_priv->rup_irq_handle = 0;
 		return -EFAULT;
 	}
 
@@ -3609,11 +3644,18 @@ static int cam_vfe_bus_ver3_deinit_hw(void *hw_priv,
 		bus_priv->error_irq_handle = 0;
 	}
 
-	if (bus_priv->irq_handle) {
+	if (bus_priv->bus_irq_handle) {
+		rc = cam_irq_controller_unsubscribe_irq(
+			bus_priv->common_data.vfe_irq_controller,
+			bus_priv->bus_irq_handle);
+		bus_priv->bus_irq_handle = 0;
+	}
+
+	if (bus_priv->rup_irq_handle) {
 		rc = cam_irq_controller_unsubscribe_irq(
 			bus_priv->common_data.vfe_irq_controller,
-			bus_priv->irq_handle);
-		bus_priv->irq_handle = 0;
+			bus_priv->rup_irq_handle);
+		bus_priv->rup_irq_handle = 0;
 	}
 
 	spin_lock_irqsave(&bus_priv->common_data.spin_lock, flags);
@@ -3698,6 +3740,7 @@ int cam_vfe_bus_ver3_init(
 	struct cam_vfe_bus              *vfe_bus_local;
 	struct cam_vfe_bus_ver3_hw_info *ver3_hw_info = bus_hw_info;
 	struct cam_vfe_soc_private      *soc_private = NULL;
+	char rup_controller_name[12] = "";
 
 	CAM_DBG(CAM_ISP, "Enter");
 
@@ -3757,9 +3800,21 @@ int cam_vfe_bus_ver3_init(
 
 	rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
 		&ver3_hw_info->common_reg.irq_reg_info,
-		&bus_priv->common_data.bus_irq_controller);
+		&bus_priv->common_data.bus_irq_controller, true);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "cam_irq_controller_init failed");
+		CAM_ERR(CAM_ISP, "Init bus_irq_controller failed");
+		goto free_bus_priv;
+	}
+
+	strlcat(rup_controller_name, drv_name, sizeof(rup_controller_name));
+	strlcat(rup_controller_name, "_rup", sizeof(rup_controller_name));
+
+	rc = cam_irq_controller_init(rup_controller_name,
+		bus_priv->common_data.mem_base,
+		&ver3_hw_info->common_reg.irq_reg_info,
+		&bus_priv->common_data.rup_irq_controller, false);
+	if (rc) {
+		CAM_ERR(CAM_ISP, "Init rup_irq_controller failed");
 		goto free_bus_priv;
 	}
 
@@ -3812,7 +3867,7 @@ int cam_vfe_bus_ver3_init(
 	vfe_bus_local->hw_ops.stop         = cam_vfe_bus_ver3_stop_hw;
 	vfe_bus_local->hw_ops.init         = cam_vfe_bus_ver3_init_hw;
 	vfe_bus_local->hw_ops.deinit       = cam_vfe_bus_ver3_deinit_hw;
-	vfe_bus_local->top_half_handler    = cam_vfe_bus_ver3_handle_irq;
+	vfe_bus_local->top_half_handler    = NULL;
 	vfe_bus_local->bottom_half_handler = NULL;
 	vfe_bus_local->hw_ops.process_cmd  = __cam_vfe_bus_ver3_process_cmd;
 
@@ -3910,7 +3965,13 @@ int cam_vfe_bus_ver3_deinit(
 		&bus_priv->common_data.bus_irq_controller);
 	if (rc)
 		CAM_ERR(CAM_ISP,
-			"Deinit IRQ Controller failed rc=%d", rc);
+			"Deinit BUS IRQ Controller failed rc=%d", rc);
+
+	rc = cam_irq_controller_deinit(
+		&bus_priv->common_data.rup_irq_controller);
+	if (rc)
+		CAM_ERR(CAM_ISP,
+			"Deinit RUP IRQ Controller failed rc=%d", rc);
 
 	mutex_destroy(&bus_priv->common_data.bus_mutex);
 	kfree(vfe_bus_local->bus_priv);

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

@@ -287,7 +287,7 @@ static int cam_vfe_camif_lite_resource_start(
 	if (!rsrc_data->irq_err_handle) {
 		rsrc_data->irq_err_handle = cam_irq_controller_subscribe_irq(
 			rsrc_data->vfe_irq_controller,
-			CAM_IRQ_PRIORITY_1,
+			CAM_IRQ_PRIORITY_0,
 			err_irq_mask,
 			camif_lite_res,
 			cam_vfe_camif_lite_err_irq_top_half,
@@ -448,13 +448,13 @@ static int cam_vfe_camif_lite_handle_irq_bottom_half(
 	}
 
 	if (irq_status0 & camif_lite_priv->reg_data->dual_pd_reg_upd_irq_mask) {
-		CAM_DBG(CAM_ISP, "VFE:%d CAMIF Lite hReceived REG_UPDATE_ACK",
+		CAM_DBG(CAM_ISP, "VFE:%d CAMIF Lite Received REG_UPDATE_ACK",
 			evt_info.hw_idx);
 		ret = CAM_VFE_IRQ_STATUS_SUCCESS;
 	}
 
 	if (irq_status0 & camif_lite_priv->reg_data->lite_eof_irq_mask) {
-		CAM_DBG(CAM_ISP, "VF:%d CAMIF Lite Received EOF",
+		CAM_DBG(CAM_ISP, "VFE:%d CAMIF Lite Received EOF",
 			evt_info.hw_idx);
 		ret = CAM_VFE_IRQ_STATUS_SUCCESS;
 	}

+ 43 - 7
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c

@@ -33,6 +33,7 @@ struct cam_vfe_mux_camif_lite_data {
 	void                                        *priv;
 	int                                          irq_err_handle;
 	int                                          irq_handle;
+	int                                          sof_irq_handle;
 	void                                        *vfe_irq_controller;
 	struct list_head                             free_payload_list;
 	spinlock_t                                   spin_lock;
@@ -312,17 +313,17 @@ skip_core_cfg:
 	cam_io_w_mb(rsrc_data->reg_data->top_debug_cfg_en, rsrc_data->mem_base +
 		rsrc_data->common_reg->top_debug_cfg);
 
-	err_irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS0] =
-		rsrc_data->reg_data->error_irq_mask0;
-	err_irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS2] =
-		rsrc_data->reg_data->error_irq_mask2;
+	if (!camif_lite_res->rdi_only_ctx)
+		goto subscribe_err;
+
 	irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS1] =
-		rsrc_data->reg_data->subscribe_irq_mask1;
+		rsrc_data->reg_data->epoch0_irq_mask |
+		rsrc_data->reg_data->eof_irq_mask;
 
 	if (!rsrc_data->irq_handle) {
 		rsrc_data->irq_handle = cam_irq_controller_subscribe_irq(
 			rsrc_data->vfe_irq_controller,
-			CAM_IRQ_PRIORITY_0,
+			CAM_IRQ_PRIORITY_3,
 			irq_mask,
 			camif_lite_res,
 			camif_lite_res->top_half_handler,
@@ -336,16 +337,44 @@ skip_core_cfg:
 		}
 	}
 
+	irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS1] =
+			rsrc_data->reg_data->sof_irq_mask;
+
+	if (!rsrc_data->sof_irq_handle) {
+		rsrc_data->sof_irq_handle = cam_irq_controller_subscribe_irq(
+			rsrc_data->vfe_irq_controller,
+			CAM_IRQ_PRIORITY_1,
+			irq_mask,
+			camif_lite_res,
+			camif_lite_res->top_half_handler,
+			camif_lite_res->bottom_half_handler,
+			camif_lite_res->tasklet_info,
+			&tasklet_bh_api);
+		if (rsrc_data->sof_irq_handle < 1) {
+			CAM_ERR(CAM_ISP, "IRQ handle subscribe failure");
+			rc = -ENOMEM;
+			rsrc_data->sof_irq_handle = 0;
+		}
+	}
+
+subscribe_err:
+
+	err_irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS0] =
+		rsrc_data->reg_data->error_irq_mask0;
+	err_irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS2] =
+		rsrc_data->reg_data->error_irq_mask2;
+
 	if (!rsrc_data->irq_err_handle) {
 		rsrc_data->irq_err_handle = cam_irq_controller_subscribe_irq(
 			rsrc_data->vfe_irq_controller,
-			CAM_IRQ_PRIORITY_1,
+			CAM_IRQ_PRIORITY_0,
 			err_irq_mask,
 			camif_lite_res,
 			cam_vfe_camif_lite_err_irq_top_half,
 			camif_lite_res->bottom_half_handler,
 			camif_lite_res->tasklet_info,
 			&tasklet_bh_api);
+
 		if (rsrc_data->irq_err_handle < 1) {
 			CAM_ERR(CAM_ISP, "Error IRQ handle subscribe failure");
 			rc = -ENOMEM;
@@ -653,6 +682,13 @@ static int cam_vfe_camif_lite_resource_stop(
 		rsrc_data->irq_handle = 0;
 	}
 
+	if (rsrc_data->sof_irq_handle > 0) {
+		cam_irq_controller_unsubscribe_irq(
+			rsrc_data->vfe_irq_controller,
+			rsrc_data->sof_irq_handle);
+		rsrc_data->sof_irq_handle = 0;
+	}
+
 	if (rsrc_data->irq_err_handle > 0) {
 		cam_irq_controller_unsubscribe_irq(
 			rsrc_data->vfe_irq_controller,

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

@@ -436,7 +436,7 @@ static int cam_vfe_camif_resource_start(
 	if (!rsrc_data->irq_handle) {
 		rsrc_data->irq_handle = cam_irq_controller_subscribe_irq(
 			rsrc_data->vfe_irq_controller,
-			CAM_IRQ_PRIORITY_0,
+			CAM_IRQ_PRIORITY_1,
 			irq_mask,
 			camif_res,
 			camif_res->top_half_handler,
@@ -453,7 +453,7 @@ static int cam_vfe_camif_resource_start(
 	if (!rsrc_data->irq_err_handle) {
 		rsrc_data->irq_err_handle = cam_irq_controller_subscribe_irq(
 			rsrc_data->vfe_irq_controller,
-			CAM_IRQ_PRIORITY_1,
+			CAM_IRQ_PRIORITY_0,
 			err_irq_mask,
 			camif_res,
 			cam_vfe_camif_err_irq_top_half,

+ 42 - 8
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c

@@ -34,6 +34,7 @@ struct cam_vfe_mux_camif_ver3_data {
 	void                                *priv;
 	int                                  irq_err_handle;
 	int                                  irq_handle;
+	int                                  sof_irq_handle;
 	void                                *vfe_irq_controller;
 	struct cam_vfe_top_irq_evt_payload   evt_payload[CAM_VFE_CAMIF_EVT_MAX];
 	struct list_head                     free_payload_list;
@@ -364,12 +365,6 @@ static int cam_vfe_camif_ver3_resource_start(
 	memset(irq_mask, 0, sizeof(irq_mask));
 
 	rsrc_data = (struct cam_vfe_mux_camif_ver3_data *)camif_res->res_priv;
-	err_irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS0] =
-		rsrc_data->reg_data->error_irq_mask0;
-	err_irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS2] =
-		rsrc_data->reg_data->error_irq_mask2;
-	irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS1] =
-		rsrc_data->reg_data->subscribe_irq_mask1;
 
 	soc_private = rsrc_data->soc_info->soc_private;
 
@@ -488,16 +483,26 @@ static int cam_vfe_camif_ver3_resource_start(
 			rsrc_data->common_reg->diag_config);
 	}
 
+	err_irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS0] =
+		rsrc_data->reg_data->error_irq_mask0;
+	err_irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS2] =
+		rsrc_data->reg_data->error_irq_mask2;
+
+	irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS1] =
+		rsrc_data->reg_data->epoch0_irq_mask |
+		rsrc_data->reg_data->eof_irq_mask;
+
 	if (!rsrc_data->irq_handle) {
 		rsrc_data->irq_handle = cam_irq_controller_subscribe_irq(
 			rsrc_data->vfe_irq_controller,
-			CAM_IRQ_PRIORITY_0,
+			CAM_IRQ_PRIORITY_3,
 			irq_mask,
 			camif_res,
 			camif_res->top_half_handler,
 			camif_res->bottom_half_handler,
 			camif_res->tasklet_info,
 			&tasklet_bh_api);
+
 		if (rsrc_data->irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "IRQ handle subscribe failure");
 			rc = -ENOMEM;
@@ -505,16 +510,38 @@ static int cam_vfe_camif_ver3_resource_start(
 		}
 	}
 
+	irq_mask[CAM_IFE_IRQ_CAMIF_REG_STATUS1] =
+		rsrc_data->reg_data->sof_irq_mask;
+
+	if (!rsrc_data->sof_irq_handle) {
+		rsrc_data->sof_irq_handle = cam_irq_controller_subscribe_irq(
+			rsrc_data->vfe_irq_controller,
+			CAM_IRQ_PRIORITY_1,
+			irq_mask,
+			camif_res,
+			camif_res->top_half_handler,
+			camif_res->bottom_half_handler,
+			camif_res->tasklet_info,
+			&tasklet_bh_api);
+
+		if (rsrc_data->sof_irq_handle < 1) {
+			CAM_ERR(CAM_ISP, "SOF IRQ handle subscribe failure");
+			rc = -ENOMEM;
+			rsrc_data->sof_irq_handle = 0;
+		}
+	}
+
 	if (!rsrc_data->irq_err_handle) {
 		rsrc_data->irq_err_handle = cam_irq_controller_subscribe_irq(
 			rsrc_data->vfe_irq_controller,
-			CAM_IRQ_PRIORITY_1,
+			CAM_IRQ_PRIORITY_0,
 			err_irq_mask,
 			camif_res,
 			cam_vfe_camif_ver3_err_irq_top_half,
 			camif_res->bottom_half_handler,
 			camif_res->tasklet_info,
 			&tasklet_bh_api);
+
 		if (rsrc_data->irq_err_handle < 1) {
 			CAM_ERR(CAM_ISP, "Error IRQ handle subscribe failure");
 			rc = -ENOMEM;
@@ -645,6 +672,13 @@ static int cam_vfe_camif_ver3_resource_stop(
 		camif_priv->irq_handle = 0;
 	}
 
+	if (camif_priv->sof_irq_handle) {
+		cam_irq_controller_unsubscribe_irq(
+			camif_priv->vfe_irq_controller,
+			camif_priv->sof_irq_handle);
+		camif_priv->sof_irq_handle = 0;
+	}
+
 	if (camif_priv->irq_err_handle) {
 		cam_irq_controller_unsubscribe_irq(
 			camif_priv->vfe_irq_controller,

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

@@ -243,7 +243,7 @@ static int cam_vfe_rdi_resource_start(
 	if (!rsrc_data->irq_err_handle) {
 		rsrc_data->irq_err_handle = cam_irq_controller_subscribe_irq(
 			rsrc_data->vfe_irq_controller,
-			CAM_IRQ_PRIORITY_1,
+			CAM_IRQ_PRIORITY_0,
 			err_irq_mask,
 			rdi_res,
 			cam_vfe_rdi_err_irq_top_half,
@@ -263,7 +263,7 @@ static int cam_vfe_rdi_resource_start(
 	if (!rsrc_data->irq_handle) {
 		rsrc_data->irq_handle = cam_irq_controller_subscribe_irq(
 			rsrc_data->vfe_irq_controller,
-			CAM_IRQ_PRIORITY_0,
+			CAM_IRQ_PRIORITY_1,
 			irq_mask,
 			rdi_res,
 			rdi_res->top_half_handler,