Browse Source

Merge "msm: camera: isp: Reduce IRQ top half IO operations" into camera-kernel.lnx.5.0

Savita Patted 3 năm trước cách đây
mục cha
commit
c39072a0f2
33 tập tin đã thay đổi với 637 bổ sung437 xóa
  1. 376 280
      drivers/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
  2. 52 11
      drivers/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.h
  3. 3 4
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid680.h
  4. 2 2
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid780.h
  5. 63 30
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c
  6. 2 2
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite680.h
  7. 2 2
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite780.h
  8. 3 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe680.h
  9. 2 3
      drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe_core.c
  10. 15 9
      drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_rd.c
  11. 14 6
      drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.c
  12. 5 6
      drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.c
  13. 4 4
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
  14. 3 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h
  15. 3 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170_150.h
  16. 3 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h
  17. 4 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h
  18. 2 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h
  19. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe680.h
  20. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe780.h
  21. 3 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h
  22. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h
  23. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite68x.h
  24. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite78x.h
  25. 6 4
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_rd_ver1.c
  26. 7 5
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
  27. 22 28
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c
  28. 4 6
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver2.c
  29. 7 7
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c
  30. 5 5
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
  31. 7 6
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c
  32. 6 6
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c
  33. 7 6
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c

+ 376 - 280
drivers/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c

@@ -29,6 +29,8 @@
  *                          Function used to enqueue the bottom_half event
  * @list_node:              list_head struct used for overall handler List
  * @th_list_node:           list_head struct used for top half handler List
+ * @index:                  Unique id of the event
+ * @group:                  Group to which the event belongs
  */
 struct cam_irq_evt_handler {
 	enum cam_irq_priority_level        priority;
@@ -41,6 +43,7 @@ struct cam_irq_evt_handler {
 	struct list_head                   list_node;
 	struct list_head                   th_list_node;
 	int                                index;
+	int                                group;
 };
 
 /**
@@ -53,8 +56,10 @@ 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
+ * @aggr_mask:              Aggregate mask to keep track of the overall mask
+ *                          after subscribe/unsubscribe calls
+ * @dependent_read_mask:    Mask to check if any dependent controllers' read needs to triggered
+ *                          from independent controller
  */
 struct cam_irq_register_obj {
 	uint32_t                     index;
@@ -62,7 +67,8 @@ 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;
+	uint32_t                     aggr_mask;
+	uint32_t                     dependent_read_mask[CAM_IRQ_MAX_DEPENDENTS];
 };
 
 /**
@@ -82,13 +88,18 @@ struct cam_irq_register_obj {
  *                          to take effect
  * @global_clear_bitmask:   Bitmask needed to be used in Global Clear register
  *                          for Clear IRQ cmd to take effect
+ * @clear_all_bitmask:      Bitmask that specifies which bits should be written to clear register
+ *                          when it is to be cleared forcefully
  * @evt_handler_list_head:  List of all event handlers
  * @th_list_head:           List of handlers sorted by priority
  * @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
+ * @th_payload:             Payload structure to be passed to top half handler
+ * @is_dependent:           Flag to indicate is this controller is dependent on another controller
+ * @dependent_controller:   Array of controllers that depend on this controller
+ * @delayed_global_clear:   Flag to indicate if this controller issues global clear after dependent
+ *                          controllers are handled
  */
 struct cam_irq_controller {
 	const char                     *name;
@@ -98,14 +109,142 @@ struct cam_irq_controller {
 	uint32_t                       *irq_status_arr;
 	uint32_t                        global_clear_offset;
 	uint32_t                        global_clear_bitmask;
+	uint32_t                        clear_all_bitmask;
 	struct list_head                evt_handler_list_head;
 	struct list_head                th_list_head[CAM_IRQ_PRIORITY_MAX];
 	uint32_t                        hdl_idx;
 	spinlock_t                      lock;
 	struct cam_irq_th_payload       th_payload;
-	bool                            clear_all;
+	bool                            is_dependent;
+	struct cam_irq_controller      *dependent_controller[CAM_IRQ_MAX_DEPENDENTS];
+	bool                            delayed_global_clear;
 };
 
+int cam_irq_controller_unregister_dependent(void *primary_controller, void *secondary_controller)
+{
+	struct cam_irq_controller *ctrl_primary, *ctrl_secondary;
+	int i, dep_idx;
+
+	if (!primary_controller || !secondary_controller) {
+		CAM_ERR(CAM_IRQ_CTRL, "invalid args: %pK, %pK", primary_controller,
+			secondary_controller);
+		return -EINVAL;
+	}
+
+	ctrl_primary = primary_controller;
+	ctrl_secondary = secondary_controller;
+
+	for (i = 0; i < CAM_IRQ_MAX_DEPENDENTS; i++) {
+		if (ctrl_primary->dependent_controller[i] == ctrl_secondary)
+			break;
+	}
+	if (i == CAM_IRQ_MAX_DEPENDENTS) {
+		CAM_ERR(CAM_IRQ_CTRL, "could not find %s as a dependent of %s)",
+			ctrl_secondary->name, ctrl_primary->name);
+		return -EINVAL;
+	}
+	dep_idx = i;
+
+	ctrl_primary->dependent_controller[dep_idx] = NULL;
+	for (i = 0; i < ctrl_primary->num_registers; i++)
+		ctrl_primary->irq_register_arr[i].dependent_read_mask[dep_idx] = 0;
+	ctrl_secondary->is_dependent = false;
+	ctrl_primary->delayed_global_clear = false;
+
+	CAM_DBG(CAM_IRQ_CTRL, "successfully unregistered %s as dependent of %s",
+		ctrl_secondary->name, ctrl_primary->name);
+
+	return 0;
+}
+
+int cam_irq_controller_register_dependent(void *primary_controller, void *secondary_controller,
+	uint32_t *mask)
+{
+	struct cam_irq_controller *ctrl_primary, *ctrl_secondary;
+	int i, dep_idx;
+
+	if (!primary_controller || !secondary_controller) {
+		CAM_ERR(CAM_IRQ_CTRL, "invalid args: %pK, %pK", primary_controller,
+			secondary_controller);
+		return -EINVAL;
+	}
+
+	ctrl_primary = primary_controller;
+	ctrl_secondary = secondary_controller;
+
+	for (i = 0; i < CAM_IRQ_MAX_DEPENDENTS; i++) {
+		if (!ctrl_primary->dependent_controller[i])
+			break;
+	}
+	if (i == CAM_IRQ_MAX_DEPENDENTS) {
+		CAM_ERR(CAM_IRQ_CTRL, "reached maximum dependents (%s - %s)",
+			ctrl_primary->name, ctrl_secondary->name);
+		return -ENOMEM;
+	}
+	dep_idx = i;
+
+	ctrl_primary->dependent_controller[dep_idx] = secondary_controller;
+	for (i = 0; i < ctrl_primary->num_registers; i++)
+		ctrl_primary->irq_register_arr[i].dependent_read_mask[dep_idx] = mask[i];
+	ctrl_secondary->is_dependent = true;
+
+	/**
+	 * NOTE: For dependent controllers that should not issue global clear command,
+	 * set their global_clear_offset to 0
+	 */
+	if (!ctrl_secondary->global_clear_offset)
+		ctrl_primary->delayed_global_clear = true;
+
+	CAM_DBG(CAM_IRQ_CTRL, "successfully registered %s as dependent of %s", ctrl_secondary->name,
+		ctrl_primary->name);
+	return 0;
+}
+
+static inline unsigned long cam_irq_controller_lock(
+	struct cam_irq_controller *controller)
+{
+	unsigned long flags = 0;
+
+	if (!in_irq())
+		spin_lock_irqsave(&controller->lock, flags);
+
+	return flags;
+}
+
+static inline void cam_irq_controller_unlock(
+	struct cam_irq_controller *controller,
+	unsigned long flags)
+{
+	if (!in_irq())
+		spin_unlock_irqrestore(&controller->lock, flags);
+}
+
+static inline void cam_irq_controller_clear_irq(
+	struct cam_irq_controller  *controller,
+	struct cam_irq_evt_handler *evt_handler)
+{
+	struct cam_irq_register_obj *irq_register;
+	int i;
+
+	/* Don't clear in IRQ context since global clear will be issued after
+	 * top half processing
+	 */
+	if (in_irq())
+		return;
+
+	for (i = 0; i < controller->num_registers; i++) {
+		irq_register = &controller->irq_register_arr[i];
+		cam_io_w_mb(evt_handler->evt_bit_mask_arr[i],
+				controller->mem_base +
+				irq_register->clear_reg_offset);
+	}
+
+	if (controller->global_clear_offset)
+		cam_io_w_mb(controller->global_clear_bitmask,
+				controller->mem_base +
+				controller->global_clear_offset);
+}
+
 int cam_irq_controller_deinit(void **irq_controller)
 {
 	struct cam_irq_controller *controller = *irq_controller;
@@ -136,8 +275,7 @@ 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,
-	bool                                  clear_all)
+	void                                **irq_controller)
 {
 	struct cam_irq_controller *controller = NULL;
 	int i, rc = 0;
@@ -205,8 +343,9 @@ int cam_irq_controller_init(const char       *name,
 	controller->num_registers        = register_info->num_registers;
 	controller->global_clear_bitmask = register_info->global_clear_bitmask;
 	controller->global_clear_offset  = register_info->global_clear_offset;
+	controller->clear_all_bitmask    = register_info->clear_all_bitmask;
 	controller->mem_base             = mem_base;
-	controller->clear_all            = clear_all;
+	controller->is_dependent         = false;
 
 	CAM_DBG(CAM_IRQ_CTRL, "global_clear_bitmask: 0x%x",
 		controller->global_clear_bitmask);
@@ -236,6 +375,46 @@ reg_alloc_error:
 	return rc;
 }
 
+static inline void __cam_irq_controller_disable_irq(
+	struct cam_irq_controller  *controller,
+	struct cam_irq_evt_handler *evt_handler)
+{
+	struct cam_irq_register_obj *irq_register;
+	uint32_t *update_mask;
+	int i, priority;
+
+	update_mask = evt_handler->evt_bit_mask_arr;
+	priority    = evt_handler->priority;
+
+	for (i = 0; i < controller->num_registers; i++) {
+		irq_register = &controller->irq_register_arr[i];
+		irq_register->top_half_enable_mask[priority] &= ~update_mask[i];
+		irq_register->aggr_mask &= ~update_mask[i];
+		cam_io_w_mb(irq_register->aggr_mask, controller->mem_base +
+			irq_register->mask_reg_offset);
+	}
+}
+
+static inline void __cam_irq_controller_enable_irq(
+	struct cam_irq_controller  *controller,
+	struct cam_irq_evt_handler *evt_handler)
+{
+	struct cam_irq_register_obj *irq_register;
+	uint32_t *update_mask;
+	int i, priority;
+
+	update_mask = evt_handler->evt_bit_mask_arr;
+	priority    = evt_handler->priority;
+
+	for (i = 0; i < controller->num_registers; i++) {
+		irq_register = &controller->irq_register_arr[i];
+		irq_register->top_half_enable_mask[priority] |= update_mask[i];
+		irq_register->aggr_mask |= update_mask[i];
+		cam_io_w_mb(irq_register->aggr_mask, controller->mem_base +
+			irq_register->mask_reg_offset);
+	}
+}
+
 int cam_irq_controller_subscribe_irq(void *irq_controller,
 	enum cam_irq_priority_level        priority,
 	uint32_t                          *evt_bit_mask_arr,
@@ -243,15 +422,14 @@ int cam_irq_controller_subscribe_irq(void *irq_controller,
 	CAM_IRQ_HANDLER_TOP_HALF           top_half_handler,
 	CAM_IRQ_HANDLER_BOTTOM_HALF        bottom_half_handler,
 	void                              *bottom_half,
-	struct cam_irq_bh_api             *irq_bh_api)
+	struct cam_irq_bh_api             *irq_bh_api,
+	enum cam_irq_event_group           evt_grp)
 {
 	struct cam_irq_controller  *controller  = irq_controller;
 	struct cam_irq_evt_handler *evt_handler = NULL;
 	int                         i;
 	int                         rc = 0;
-	uint32_t                    irq_mask;
 	unsigned long               flags = 0;
-	bool                        need_lock;
 
 	if (!controller || !handler_priv || !evt_bit_mask_arr) {
 		CAM_ERR(CAM_IRQ_CTRL,
@@ -319,6 +497,7 @@ int cam_irq_controller_subscribe_irq(void *irq_controller,
 	evt_handler->bottom_half_handler      = bottom_half_handler;
 	evt_handler->bottom_half              = bottom_half;
 	evt_handler->index                    = controller->hdl_idx++;
+	evt_handler->group                    = evt_grp;
 
 	if (irq_bh_api)
 		evt_handler->irq_bh_api       = *irq_bh_api;
@@ -327,31 +506,16 @@ int cam_irq_controller_subscribe_irq(void *irq_controller,
 	if (controller->hdl_idx > 0x3FFFFFFF)
 		controller->hdl_idx = 1;
 
-	need_lock = !in_irq();
-	if (need_lock)
-		spin_lock_irqsave(&controller->lock, flags);
-	for (i = 0; i < controller->num_registers; i++) {
-		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];
+	flags = cam_irq_controller_lock(controller);
 
-		cam_io_w_mb(irq_mask, controller->mem_base +
-			controller->irq_register_arr[i].mask_reg_offset);
-	}
+	__cam_irq_controller_enable_irq(controller, evt_handler);
 
 	list_add_tail(&evt_handler->list_node,
 		&controller->evt_handler_list_head);
 	list_add_tail(&evt_handler->th_list_node,
 		&controller->th_list_head[priority]);
 
-	if (need_lock)
-		spin_unlock_irqrestore(&controller->lock, flags);
+	cam_irq_controller_unlock(controller, flags);
 
 	return evt_handler->index;
 
@@ -362,58 +526,46 @@ free_evt_handler:
 	return rc;
 }
 
-int cam_irq_controller_enable_irq(void *irq_controller, uint32_t handle)
+static inline int cam_irq_controller_find_event_handle(struct cam_irq_controller *controller,
+	uint32_t handle, struct cam_irq_evt_handler **found_evt_handler)
 {
-	struct cam_irq_controller   *controller  = irq_controller;
-	struct cam_irq_evt_handler  *evt_handler = NULL;
-	struct cam_irq_evt_handler  *evt_handler_temp;
-	struct cam_irq_register_obj *irq_register = NULL;
-	enum cam_irq_priority_level priority;
-	unsigned long               flags = 0;
-	unsigned int                i;
-	uint32_t                    irq_mask;
-	uint32_t                    found = 0;
-	int                         rc = -EINVAL;
-	bool                        need_lock;
-
-	if (!controller)
-		return rc;
-
-	need_lock = !in_irq();
-	if (need_lock)
-		spin_lock_irqsave(&controller->lock, flags);
+	struct cam_irq_evt_handler  *evt_handler, *evt_handler_temp;
+	int rc = -EINVAL;
 
 	list_for_each_entry_safe(evt_handler, evt_handler_temp,
 		&controller->evt_handler_list_head, list_node) {
 		if (evt_handler->index == handle) {
-			CAM_DBG(CAM_IRQ_CTRL, "enable item %d", handle);
-			found = 1;
 			rc = 0;
+			*found_evt_handler = evt_handler;
 			break;
 		}
 	}
 
-	if (!found) {
-		if (need_lock)
-			spin_unlock_irqrestore(&controller->lock, flags);
+	return rc;
+}
+
+int cam_irq_controller_enable_irq(void *irq_controller, uint32_t handle)
+{
+	struct cam_irq_controller   *controller  = irq_controller;
+	struct cam_irq_evt_handler  *evt_handler = NULL;
+	unsigned long               flags = 0;
+	int                         rc = 0;
+
+	if (!controller)
 		return rc;
-	}
 
-	priority = evt_handler->priority;
-	for (i = 0; i < controller->num_registers; i++) {
-		irq_register = &controller->irq_register_arr[i];
-		irq_register->top_half_enable_mask[priority] |=
-			evt_handler->evt_bit_mask_arr[i];
+	flags = cam_irq_controller_lock(controller);
 
-		irq_mask = cam_io_r_mb(controller->mem_base +
-			irq_register->mask_reg_offset);
-		irq_mask |= evt_handler->evt_bit_mask_arr[i];
+	rc = cam_irq_controller_find_event_handle(controller, handle,
+		&evt_handler);
+	if (rc)
+		goto end;
 
-		cam_io_w_mb(irq_mask, controller->mem_base +
-		controller->irq_register_arr[i].mask_reg_offset);
-	}
-	if (need_lock)
-		spin_unlock_irqrestore(&controller->lock, flags);
+	CAM_DBG(CAM_IRQ_CTRL, "enable event %d", handle);
+	__cam_irq_controller_enable_irq(controller, evt_handler);
+
+end:
+	cam_irq_controller_unlock(controller, flags);
 
 	return rc;
 }
@@ -422,68 +574,25 @@ int cam_irq_controller_disable_irq(void *irq_controller, uint32_t handle)
 {
 	struct cam_irq_controller   *controller  = irq_controller;
 	struct cam_irq_evt_handler  *evt_handler = NULL;
-	struct cam_irq_evt_handler  *evt_handler_temp;
-	struct cam_irq_register_obj *irq_register;
-	enum cam_irq_priority_level priority;
 	unsigned long               flags = 0;
-	unsigned int                i;
-	uint32_t                    irq_mask;
-	uint32_t                    found = 0;
-	int                         rc = -EINVAL;
-	bool                        need_lock;
+	int                         rc = 0;
 
 	if (!controller)
 		return rc;
 
-	need_lock = !in_irq();
-	if (need_lock)
-		spin_lock_irqsave(&controller->lock, flags);
-
-	list_for_each_entry_safe(evt_handler, evt_handler_temp,
-		&controller->evt_handler_list_head, list_node) {
-		if (evt_handler->index == handle) {
-			CAM_DBG(CAM_IRQ_CTRL, "disable item %d", handle);
-			found = 1;
-			rc = 0;
-			break;
-		}
-	}
-
-	if (!found) {
-		if (need_lock)
-			spin_unlock_irqrestore(&controller->lock, flags);
-		return rc;
-	}
-
-	priority = evt_handler->priority;
-	for (i = 0; i < controller->num_registers; i++) {
-		irq_register = &controller->irq_register_arr[i];
-		irq_register->top_half_enable_mask[priority] &=
-			~(evt_handler->evt_bit_mask_arr[i]);
-
-		irq_mask = cam_io_r_mb(controller->mem_base +
-			irq_register->mask_reg_offset);
-		CAM_DBG(CAM_IRQ_CTRL, "irq_mask 0x%x before disable 0x%x",
-			irq_register->mask_reg_offset, irq_mask);
-		irq_mask &= ~(evt_handler->evt_bit_mask_arr[i]);
-
-		cam_io_w_mb(irq_mask, controller->mem_base +
-			irq_register->mask_reg_offset);
-		CAM_DBG(CAM_IRQ_CTRL, "irq_mask 0x%x after disable 0x%x",
-			irq_register->mask_reg_offset, irq_mask);
+	flags = cam_irq_controller_lock(controller);
 
-		/* Clear the IRQ bits of this handler */
-		cam_io_w_mb(evt_handler->evt_bit_mask_arr[i],
-			controller->mem_base +
-			irq_register->clear_reg_offset);
-	}
+	rc = cam_irq_controller_find_event_handle(controller, handle,
+		&evt_handler);
+	if (rc)
+		goto end;
 
-	if (controller->global_clear_offset)
-		cam_io_w_mb(controller->global_clear_bitmask,
-			controller->mem_base + controller->global_clear_offset);
+	CAM_DBG(CAM_IRQ_CTRL, "disable event %d", handle);
+	__cam_irq_controller_disable_irq(controller, evt_handler);
+	cam_irq_controller_clear_irq(controller, evt_handler);
 
-	if (need_lock)
-		spin_unlock_irqrestore(&controller->lock, flags);
+end:
+	cam_irq_controller_unlock(controller, flags);
 
 	return rc;
 }
@@ -493,63 +602,28 @@ int cam_irq_controller_unsubscribe_irq(void *irq_controller,
 {
 	struct cam_irq_controller   *controller  = irq_controller;
 	struct cam_irq_evt_handler  *evt_handler = NULL;
-	struct cam_irq_evt_handler  *evt_handler_temp;
-	struct cam_irq_register_obj *irq_register;
-	enum cam_irq_priority_level priority;
-	uint32_t                    i;
-	uint32_t                    found = 0;
-	uint32_t                    irq_mask;
 	unsigned long               flags = 0;
-	int                         rc = -EINVAL;
-	bool                        need_lock;
+	int                         rc = 0;
 
-	need_lock = !in_irq();
-	if (need_lock)
-		spin_lock_irqsave(&controller->lock, flags);
+	flags = cam_irq_controller_lock(controller);
 
-	list_for_each_entry_safe(evt_handler, evt_handler_temp,
-		&controller->evt_handler_list_head, list_node) {
-		if (evt_handler->index == handle) {
-			CAM_DBG(CAM_IRQ_CTRL, "unsubscribe item %d", handle);
-			list_del_init(&evt_handler->list_node);
-			list_del_init(&evt_handler->th_list_node);
-			found = 1;
-			rc = 0;
-			break;
-		}
-	}
 
-	if (found) {
-		priority = evt_handler->priority;
-		for (i = 0; i < controller->num_registers; i++) {
-			irq_register = &controller->irq_register_arr[i];
-			irq_register->top_half_enable_mask[priority] &=
-				~(evt_handler->evt_bit_mask_arr[i]);
+	rc = cam_irq_controller_find_event_handle(controller, handle,
+		&evt_handler);
+	if (rc)
+		goto end;
 
-			irq_mask = cam_io_r_mb(controller->mem_base +
-				irq_register->mask_reg_offset);
-			irq_mask &= ~(evt_handler->evt_bit_mask_arr[i]);
+	list_del_init(&evt_handler->list_node);
+	list_del_init(&evt_handler->th_list_node);
 
-			cam_io_w_mb(irq_mask, controller->mem_base +
-				irq_register->mask_reg_offset);
+	__cam_irq_controller_disable_irq(controller, evt_handler);
+	cam_irq_controller_clear_irq(controller, evt_handler);
 
-			/* Clear the IRQ bits of this handler */
-			cam_io_w_mb(evt_handler->evt_bit_mask_arr[i],
-				controller->mem_base +
-				irq_register->clear_reg_offset);
-			if (controller->global_clear_offset)
-				cam_io_w_mb(
-					controller->global_clear_bitmask,
-					controller->mem_base +
-					controller->global_clear_offset);
-		}
-
-		kfree(evt_handler->evt_bit_mask_arr);
-		kfree(evt_handler);
-	}
+	kfree(evt_handler->evt_bit_mask_arr);
+	kfree(evt_handler);
 
-	if (need_lock)
-		spin_unlock_irqrestore(&controller->lock, flags);
+end:
+	cam_irq_controller_unlock(controller, flags);
 
 	return rc;
 }
@@ -569,10 +643,14 @@ int cam_irq_controller_unsubscribe_irq(void *irq_controller,
  */
 static bool cam_irq_controller_match_bit_mask(
 	struct cam_irq_controller   *controller,
-	struct cam_irq_evt_handler  *evt_handler)
+	struct cam_irq_evt_handler  *evt_handler,
+	int                          evt_grp)
 {
 	int i;
 
+	if (evt_handler->group != evt_grp)
+		return false;
+
 	for (i = 0; i < controller->num_registers; i++) {
 		if (evt_handler->evt_bit_mask_arr[i] &
 			controller->irq_status_arr[i])
@@ -582,9 +660,10 @@ static bool cam_irq_controller_match_bit_mask(
 	return false;
 }
 
-static void cam_irq_controller_th_processing(
+static void __cam_irq_controller_th_processing(
 	struct cam_irq_controller      *controller,
-	struct list_head               *th_list_head)
+	struct list_head               *th_list_head,
+	int                             evt_grp)
 {
 	struct cam_irq_evt_handler     *evt_handler = NULL;
 	struct cam_irq_evt_handler     *evt_handler_tmp = NULL;
@@ -601,8 +680,7 @@ static void cam_irq_controller_th_processing(
 		return;
 
 	list_for_each_entry_safe(evt_handler, evt_handler_tmp, th_list_head, th_list_node) {
-		is_irq_match = cam_irq_controller_match_bit_mask(controller,
-			evt_handler);
+		is_irq_match = cam_irq_controller_match_bit_mask(controller, evt_handler, evt_grp);
 
 		if (!is_irq_match)
 			continue;
@@ -662,101 +740,153 @@ static void cam_irq_controller_th_processing(
 	CAM_DBG(CAM_IRQ_CTRL, "Exit");
 }
 
-irqreturn_t cam_irq_controller_clear_and_mask(int irq_num, void *priv)
+void cam_irq_controller_disable_all(void *priv)
 {
 	struct cam_irq_controller  *controller  = priv;
+	struct cam_irq_evt_handler  *evt_handler, *evt_handler_temp;
+	struct cam_irq_register_obj *irq_register;
+
 	uint32_t i = 0;
 
 	if (!controller)
-		return IRQ_NONE;
-
-	for (i = 0; i < controller->num_registers; i++) {
+		return;
 
-		cam_io_w_mb(0x0, controller->mem_base +
-			controller->irq_register_arr[i].clear_reg_offset);
+	for (i = 0; i < CAM_IRQ_PRIORITY_MAX; i++) {
+		list_for_each_entry_safe(evt_handler, evt_handler_temp,
+			&controller->th_list_head[i], th_list_node) {
+			list_del_init(&evt_handler->th_list_node);
+		}
 	}
 
-	if (controller->global_clear_offset)
-		cam_io_w_mb(controller->global_clear_bitmask,
-			controller->mem_base +
-			controller->global_clear_offset);
-
 	for (i = 0; i < controller->num_registers; i++) {
-		cam_io_w_mb(0x0, controller->mem_base +
-		controller->irq_register_arr[i].mask_reg_offset);
+		irq_register = &controller->irq_register_arr[i];
+		memset(irq_register->top_half_enable_mask, 0, CAM_IRQ_PRIORITY_MAX);
+		irq_register->aggr_mask = 0;
+		cam_io_w_mb(0x0, controller->mem_base + irq_register->mask_reg_offset);
+		cam_io_w_mb(controller->clear_all_bitmask, controller->mem_base +
+			irq_register->clear_reg_offset);
 	}
 
-	return IRQ_HANDLED;
+	if (controller->global_clear_offset && !controller->delayed_global_clear) {
+		cam_io_w_mb(controller->global_clear_bitmask,
+			controller->mem_base + controller->global_clear_offset);
+		CAM_DBG(CAM_IRQ_CTRL, "Global Clear done from %s",
+			controller->name);
+	}
 }
 
-irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv)
+static void __cam_irq_controller_read_registers(struct cam_irq_controller *controller)
 {
-	struct cam_irq_controller   *controller  = priv;
 	struct cam_irq_register_obj *irq_register;
-	bool         need_th_processing[CAM_IRQ_PRIORITY_MAX] = {false};
-	int          i;
-	int          j;
-
-	if (!controller)
-		return IRQ_NONE;
+	int i;
 
-	CAM_DBG(CAM_IRQ_CTRL,
-		"Locking: %s IRQ Controller: [%pK], lock handle: %pK",
-		controller->name, controller, &controller->lock);
-	spin_lock(&controller->lock);
 	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 + 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);
+		/* Skip register read if we are not going to process it */
+		if (!irq_register->aggr_mask) {
+			controller->irq_status_arr[i] = 0;
+			continue;
+		}
+
+		controller->irq_status_arr[i] = cam_io_r(controller->mem_base +
+			irq_register->status_reg_offset);
 
-		CAM_DBG(CAM_IRQ_CTRL, "Read irq status%d (0x%x) = 0x%x", i,
+		CAM_DBG(CAM_IRQ_CTRL, "(%s) Read irq status%d (0x%x) = 0x%x", controller->name, i,
 			controller->irq_register_arr[i].status_reg_offset,
 			controller->irq_status_arr[i]);
-		for (j = 0; j < CAM_IRQ_PRIORITY_MAX; j++) {
-			if (irq_register->top_half_enable_mask[j] &
-				controller->irq_status_arr[i])
-				need_th_processing[j] = true;
 
-			CAM_DBG(CAM_IRQ_CTRL,
-				"i %d j %d need_th_processing = %d",
-				i, j, need_th_processing[j]);
-		}
+		cam_io_w(controller->irq_status_arr[i],
+			controller->mem_base + irq_register->clear_reg_offset);
 	}
 
-	CAM_DBG(CAM_IRQ_CTRL, "Status Registers read Successful");
-
-	if (controller->global_clear_offset) {
+	if (controller->global_clear_offset && !controller->delayed_global_clear) {
 		cam_io_w_mb(controller->global_clear_bitmask,
 			controller->mem_base + controller->global_clear_offset);
-		for (i = 0; i < controller->num_registers; i++) {
-			irq_register = &controller->irq_register_arr[i];
-			if (controller->irq_status_arr[i])
-				cam_io_w_mb(0x0, controller->mem_base +
-					irq_register->clear_reg_offset);
+		CAM_DBG(CAM_IRQ_CTRL, "Global Clear done from %s",
+			controller->name);
+	}
+}
+
+static void cam_irq_controller_read_registers(struct cam_irq_controller *controller)
+{
+	struct cam_irq_register_obj *irq_register;
+	struct cam_irq_controller *dep_controller;
+	bool need_reg_read[CAM_IRQ_MAX_DEPENDENTS] = {false};
+	int i, j;
+
+	__cam_irq_controller_read_registers(controller);
+
+	for (i = 0; i < controller->num_registers; i++) {
+		irq_register = &controller->irq_register_arr[i];
+		for (j = 0; j < CAM_IRQ_MAX_DEPENDENTS; j++) {
+			if (irq_register->dependent_read_mask[j] & controller->irq_status_arr[i])
+				need_reg_read[j] = true;
+			CAM_DBG(CAM_IRQ_CTRL, "(%s) reg:%d dep:%d need_reg_read = %d",
+				controller->name, i, j, need_reg_read[j]);
 		}
+	}
 
-		CAM_DBG(CAM_IRQ_CTRL, "Global Clear done from %s",
+	for (j = 0; j < CAM_IRQ_MAX_DEPENDENTS; j++) {
+		if (need_reg_read[j]) {
+			dep_controller = controller->dependent_controller[j];
+			CAM_DBG(CAM_IRQ_CTRL, "Reading dependent registers for %s",
+				dep_controller->name);
+			spin_lock(&dep_controller->lock);
+			__cam_irq_controller_read_registers(dep_controller);
+			spin_unlock(&dep_controller->lock);
+		}
+	}
+
+	if (controller->global_clear_offset && controller->delayed_global_clear) {
+		cam_io_w_mb(controller->global_clear_bitmask,
+			controller->mem_base + controller->global_clear_offset);
+		CAM_DBG(CAM_IRQ_CTRL, "Delayed Global Clear done from %s",
 			controller->name);
 	}
+}
+
+static void cam_irq_controller_process_th(struct cam_irq_controller *controller, int evt_grp)
+{
+	struct cam_irq_register_obj *irq_register;
+	bool need_th_processing[CAM_IRQ_PRIORITY_MAX] = {false};
+	int i, j;
+
+
+	for (i = 0; i < controller->num_registers; i++) {
+		irq_register = &controller->irq_register_arr[i];
+		for (j = 0; j < CAM_IRQ_PRIORITY_MAX; j++) {
+			if (irq_register->top_half_enable_mask[j] & controller->irq_status_arr[i])
+				need_th_processing[j] = true;
+			CAM_DBG(CAM_IRQ_CTRL, "reg:%d priority:%d need_th_processing = %d",
+				i, j, need_th_processing[j]);
+		}
+	}
 
 	for (i = 0; i < CAM_IRQ_PRIORITY_MAX; i++) {
 		if (need_th_processing[i]) {
-			CAM_DBG(CAM_IRQ_CTRL, "Invoke TH processing");
-			cam_irq_controller_th_processing(controller,
-				&controller->th_list_head[i]);
+			CAM_DBG(CAM_IRQ_CTRL, "(%s) Invoke TH processing priority:%d",
+				controller->name, i);
+			__cam_irq_controller_th_processing(controller, &controller->th_list_head[i],
+				evt_grp);
 		}
 	}
+}
+
+irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv, int evt_grp)
+{
+	struct cam_irq_controller *controller  = priv;
+
+	if (unlikely(!controller))
+		return IRQ_NONE;
+
+	CAM_DBG(CAM_IRQ_CTRL,
+		"Locking: %s IRQ Controller: [%pK], lock handle: %pK",
+		controller->name, controller, &controller->lock);
+	spin_lock(&controller->lock);
+	if (!controller->is_dependent)
+		cam_irq_controller_read_registers(controller);
+	cam_irq_controller_process_th(controller, evt_grp);
 	spin_unlock(&controller->lock);
 	CAM_DBG(CAM_IRQ_CTRL,
 		"Unlocked: %s IRQ Controller: %pK, lock handle: %pK",
@@ -770,67 +900,33 @@ int cam_irq_controller_update_irq(void *irq_controller, uint32_t handle,
 {
 	struct cam_irq_controller   *controller  = irq_controller;
 	struct cam_irq_evt_handler  *evt_handler = NULL;
-	struct cam_irq_evt_handler  *evt_handler_temp;
-	struct cam_irq_register_obj *irq_register = NULL;
-	enum cam_irq_priority_level priority;
 	unsigned long               flags = 0;
 	unsigned int                i;
-	uint32_t                    found = 0;
-	int                         rc = -EINVAL;
-	bool                        need_lock;
+	int                         rc = 0;
 
 	if (!controller)
 		return rc;
 
-	need_lock = !in_irq();
-	if (need_lock)
-		spin_lock_irqsave(&controller->lock, flags);
-
-	list_for_each_entry_safe(evt_handler, evt_handler_temp,
-		&controller->evt_handler_list_head, list_node) {
-		if (evt_handler->index == handle) {
-			CAM_DBG(CAM_IRQ_CTRL, "enable item %d", handle);
-			found = 1;
-			rc = 0;
-			break;
-		}
-	}
+	flags = cam_irq_controller_lock(controller);
 
-	if (!found) {
-		if (need_lock)
-			spin_unlock_irqrestore(&controller->lock, flags);
-		return rc;
-	}
+	rc = cam_irq_controller_find_event_handle(controller, handle,
+		&evt_handler);
+	if (rc)
+		goto end;
 
-	priority = evt_handler->priority;
+	__cam_irq_controller_disable_irq(controller, evt_handler);
 	for (i = 0; i < controller->num_registers; i++) {
-
-		irq_register = &controller->irq_register_arr[i];
-
 		if (enable) {
-			irq_register->top_half_enable_mask[priority] |=
-								irq_mask[i];
 			evt_handler->evt_bit_mask_arr[i] |= irq_mask[i];
 		} else {
-			irq_register->top_half_enable_mask[priority] &=
-								~irq_mask[i];
 			evt_handler->evt_bit_mask_arr[i] &= ~irq_mask[i];
 		}
-
-		cam_io_w_mb(evt_handler->evt_bit_mask_arr[i],
-			controller->mem_base +
-			controller->irq_register_arr[i].mask_reg_offset);
-	}
-
-	if (!enable) {
-		if (controller->global_clear_offset)
-			cam_io_w_mb(controller->global_clear_bitmask,
-				controller->mem_base +
-				controller->global_clear_offset);
 	}
+	__cam_irq_controller_enable_irq(controller, evt_handler);
+	cam_irq_controller_clear_irq(controller, evt_handler);
 
-	if (need_lock)
-		spin_unlock_irqrestore(&controller->lock, flags);
+end:
+	cam_irq_controller_unlock(controller, flags);
 
 	return rc;
 }

+ 52 - 11
drivers/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.h

@@ -28,6 +28,18 @@ enum cam_irq_priority_level {
 	CAM_IRQ_PRIORITY_MAX,
 };
 
+/**
+ * enum cam_irq_event_group:
+ * @brief: Event groups to filter out events while handling. Use group 0 as default.
+ */
+enum cam_irq_event_group {
+	CAM_IRQ_EVT_GROUP_0,
+	CAM_IRQ_EVT_GROUP_1,
+	CAM_IRQ_EVT_GROUP_2,
+};
+
+#define CAM_IRQ_MAX_DEPENDENTS 1
+
 /*
  * struct cam_irq_register_set:
  * @Brief:                  Structure containing offsets of IRQ related
@@ -55,12 +67,15 @@ struct cam_irq_register_set {
  *                          to take effect
  * @global_clear_bitmask:   Bitmask needed to be used in Global Clear register
  *                          for Clear IRQ cmd to take effect
+ * @clear_all_bitmask:      Bitmask that specifies which bits should be written
+ *                          to clear register when it is to be cleared forcefully
  */
 struct cam_irq_controller_reg_info {
 	uint32_t                      num_registers;
 	struct cam_irq_register_set  *irq_reg_set;
 	uint32_t                      global_clear_offset;
 	uint32_t                      global_clear_bitmask;
+	uint32_t                      clear_all_bitmask;
 };
 
 /*
@@ -131,7 +146,6 @@ 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
@@ -139,8 +153,7 @@ 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,
-	bool                                  clear_all);
+	void                                **irq_controller);
 
 /*
  * cam_irq_controller_subscribe_irq()
@@ -160,6 +173,7 @@ int cam_irq_controller_init(const char       *name,
  *                       enqueue the event for further handling
  * @bottom_half_enqueue_func:
  *                       Function used to enqueue the bottom_half event
+ * @evt_grp:             Event group to which this event must belong to (use group 0 as default)
  *
  * @return:              Positive: Success. Value represents handle which is
  *                                 to be used to unsubscribe
@@ -172,7 +186,8 @@ int cam_irq_controller_subscribe_irq(void *irq_controller,
 	CAM_IRQ_HANDLER_TOP_HALF           top_half_handler,
 	CAM_IRQ_HANDLER_BOTTOM_HALF        bottom_half_handler,
 	void                              *bottom_half,
-	struct cam_irq_bh_api             *irq_bh_api);
+	struct cam_irq_bh_api             *irq_bh_api,
+	enum cam_irq_event_group           evt_grp);
 
 /*
  * cam_irq_controller_unsubscribe_irq()
@@ -219,7 +234,7 @@ int cam_irq_controller_deinit(void **irq_controller);
  *
  * @return:             IRQ_HANDLED/IRQ_NONE
  */
-irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv);
+irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv, int evt_grp);
 
 /*
  * cam_irq_controller_disable_irq()
@@ -258,19 +273,15 @@ int cam_irq_controller_disable_irq(void *irq_controller, uint32_t handle);
 int cam_irq_controller_enable_irq(void *irq_controller, uint32_t handle);
 
 /*
- * cam_irq_controller_clear_and_mask()
+ * cam_irq_controller_disable_all()
  *
  * @brief:              This function clears and masks all the irq bits
  *
- * @irq_num:            Number of IRQ line that was set that lead to this
- *                      function being called
  * @priv:               Private data registered with request_irq is passed back
  *                      here. This private data should be the irq_controller
  *                      structure.
- *
- * @return:             IRQ_HANDLED/IRQ_NONE
  */
-irqreturn_t cam_irq_controller_clear_and_mask(int irq_num, void *priv);
+void cam_irq_controller_disable_all(void *priv);
 
 /*
  * cam_irq_controller_update_irq()
@@ -292,4 +303,34 @@ irqreturn_t cam_irq_controller_clear_and_mask(int irq_num, void *priv);
  */
 int cam_irq_controller_update_irq(void *irq_controller, uint32_t handle,
 	bool enable, uint32_t *irq_mask);
+
+/**
+ * cam_irq_controller_register_dependent
+ * @brief:                 Register one IRQ controller as dependent for another IRQ controller
+ *
+ * @primary_controller:    Controller whose top half will invoke handle_irq function of secondary
+ *                         controller
+ * @secondary_controller:  Controller whose handle_irq function that will be invoked from primary
+ *                         controller
+ *
+ * @return:                0: successfully registered
+ *                         Negative: failed to register as dependent
+ */
+int cam_irq_controller_register_dependent(void *primary_controller, void *secondary_controller,
+	uint32_t *mask);
+
+/**
+ * cam_irq_controller_register_dependent
+ * @brief:                 Unregister previously registered dependent IRQ controller
+ *
+ * @primary_controller:    Controller whose top half will invoke handle_irq function of secondary
+ *                         controller
+ * @secondary_controller:  Controller whose handle_irq function that will be invoked from primary
+ *                         controller
+ *
+ * @return:                0: successfully unregistered
+ *                         Negative: failed to unregister dependent
+ */
+int cam_irq_controller_unregister_dependent(void *primary_controller, void *secondary_controller);
+
 #endif /* _CAM_IRQ_CONTROLLER_H_ */

+ 3 - 4
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid680.h

@@ -303,6 +303,7 @@ static struct cam_irq_controller_reg_info cam_ife_csid_680_irq_reg_info = {
 	.irq_reg_set = cam_ife_csid_680_irq_reg_set,
 	.global_clear_offset  = 0x00000014,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_irq_register_set cam_ife_csid_680_buf_done_irq_reg_set[1] = {
@@ -313,12 +314,10 @@ static struct cam_irq_register_set cam_ife_csid_680_buf_done_irq_reg_set[1] = {
 	},
 };
 
-static struct cam_irq_controller_reg_info
-	cam_ife_csid_680_buf_done_irq_reg_info = {
+static struct cam_irq_controller_reg_info cam_ife_csid_680_buf_done_irq_reg_info = {
 	.num_registers = 1,
 	.irq_reg_set = cam_ife_csid_680_buf_done_irq_reg_set,
-	.global_clear_offset  = 0x00000014,
-	.global_clear_bitmask = 0x00000001,
+	.global_clear_offset  = 0, /* intentionally set to zero */
 };
 
 static struct cam_ife_csid_ver2_path_reg_info

+ 2 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid780.h

@@ -331,6 +331,7 @@ static struct cam_irq_controller_reg_info cam_ife_csid_780_irq_reg_info = {
 	.irq_reg_set = cam_ife_csid_780_irq_reg_set,
 	.global_clear_offset  = 0x00000014,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_irq_register_set cam_ife_csid_780_buf_done_irq_reg_set[1] = {
@@ -345,8 +346,7 @@ static struct cam_irq_controller_reg_info
 	cam_ife_csid_780_buf_done_irq_reg_info = {
 	.num_registers = 1,
 	.irq_reg_set = cam_ife_csid_780_buf_done_irq_reg_set,
-	.global_clear_offset  = 0x00000014,
-	.global_clear_bitmask = 0x00000001,
+	.global_clear_offset  = 0, /* intentionally set to zero */
 };
 
 static struct cam_ife_csid_ver2_path_reg_info

+ 63 - 30
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -284,7 +284,7 @@ static int cam_ife_csid_ver2_handle_buf_done_irq(
 	csid_hw = th_payload->handler_priv;
 	CAM_DBG(CAM_ISP, "Enter");
 	rc = cam_irq_controller_handle_irq(evt_id,
-		csid_hw->buf_done_irq_controller);
+		csid_hw->buf_done_irq_controller, CAM_IRQ_EVT_GROUP_0);
 	return (rc == IRQ_HANDLED) ? 0 : -EINVAL;
 }
 
@@ -2983,7 +2983,8 @@ static inline int cam_ife_csid_ver2_subscribe_sof_for_discard(
 		top_half_handler,
 		bottom_half_handler,
 		csid_hw->tasklet,
-		&tasklet_bh_api);
+		&tasklet_bh_api,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (path_cfg->discard_irq_handle < 1) {
 		CAM_ERR(CAM_ISP,
@@ -3091,7 +3092,8 @@ static int cam_ife_csid_ver2_program_rdi_path(
 		cam_ife_csid_ver2_path_top_half,
 		cam_ife_csid_ver2_rdi_bottom_half,
 		csid_hw->tasklet,
-		&tasklet_bh_api);
+		&tasklet_bh_api,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (path_cfg->irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "CSID[%d] Subscribe Irq fail %d",
@@ -3119,7 +3121,8 @@ static int cam_ife_csid_ver2_program_rdi_path(
 			cam_ife_csid_ver2_path_err_top_half,
 			cam_ife_csid_ver2_rdi_bottom_half,
 			csid_hw->tasklet,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 	if (path_cfg->err_irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "CSID[%d] Subscribe Err Irq fail %d",
@@ -3211,7 +3214,8 @@ static int cam_ife_csid_ver2_program_ipp_path(
 				    cam_ife_csid_ver2_path_top_half,
 				    cam_ife_csid_ver2_ipp_bottom_half,
 				    csid_hw->tasklet,
-				    &tasklet_bh_api);
+				    &tasklet_bh_api,
+				    CAM_IRQ_EVT_GROUP_0);
 
 	if (path_cfg->irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "CSID[%d] Subscribe IPP Irq fail",
@@ -3239,7 +3243,8 @@ static int cam_ife_csid_ver2_program_ipp_path(
 		cam_ife_csid_ver2_path_err_top_half,
 		cam_ife_csid_ver2_ipp_bottom_half,
 		csid_hw->tasklet,
-		&tasklet_bh_api);
+		&tasklet_bh_api,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (path_cfg->err_irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "CSID[%d] Subscribe Err Irq fail %d",
@@ -3427,14 +3432,16 @@ static int cam_ife_csid_ver2_program_ppp_path(
 	irq_mask[path_cfg->irq_reg_idx] = val;
 	irq_mask[CAM_IFE_CSID_IRQ_REG_TOP] = path_reg->top_irq_mask;
 	path_cfg->irq_handle = cam_irq_controller_subscribe_irq(
-					csid_hw->csid_irq_controller,
-					CAM_IRQ_PRIORITY_1,
-					irq_mask,
-					res,
-					cam_ife_csid_ver2_path_top_half,
-					cam_ife_csid_ver2_ppp_bottom_half,
-					csid_hw->tasklet,
-					&tasklet_bh_api);
+				csid_hw->csid_irq_controller,
+				CAM_IRQ_PRIORITY_1,
+				irq_mask,
+				csid_hw,
+				cam_ife_csid_ver2_path_top_half,
+				cam_ife_csid_ver2_ppp_bottom_half,
+				csid_hw->tasklet,
+				&tasklet_bh_api,
+				CAM_IRQ_EVT_GROUP_0);
+
 
 	if (path_cfg->irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "CSID[%d] Subscribe PPP Irq fail",
@@ -3462,7 +3469,8 @@ static int cam_ife_csid_ver2_program_ppp_path(
 					cam_ife_csid_ver2_path_err_top_half,
 					cam_ife_csid_ver2_ipp_bottom_half,
 					csid_hw->tasklet,
-					&tasklet_bh_api);
+					&tasklet_bh_api,
+					CAM_IRQ_EVT_GROUP_0);
 
 	if (path_cfg->err_irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "CSID[%d] Subscribe Err Irq fail %d",
@@ -3613,7 +3621,8 @@ static int cam_ife_csid_ver2_enable_csi2(struct cam_ife_csid_ver2_hw *csid_hw)
 					    cam_ife_csid_ver2_rx_top_half,
 					    NULL,
 					    NULL,
-					    NULL);
+					    NULL,
+					    CAM_IRQ_EVT_GROUP_0);
 
 		if (csid_hw->rx_cfg.irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "CSID[%d] RX debug irq register fail",
@@ -3640,7 +3649,8 @@ static int cam_ife_csid_ver2_enable_csi2(struct cam_ife_csid_ver2_hw *csid_hw)
 				    cam_ife_csid_ver2_rx_err_top_half,
 				    cam_ife_csid_ver2_rx_err_bottom_half,
 				    csid_hw->tasklet,
-				    &tasklet_bh_api);
+				    &tasklet_bh_api,
+				    CAM_IRQ_EVT_GROUP_0);
 
 	if (csid_hw->rx_cfg.err_irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "CSID[%d] RX err irq register fail",
@@ -3789,7 +3799,8 @@ static int cam_ife_csid_ver2_enable_core(struct cam_ife_csid_ver2_hw *csid_hw)
 		cam_ife_csid_ver2_reset_irq_top_half,
 		NULL,
 		NULL,
-		NULL);
+		NULL,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (csid_hw->reset_irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "csid[%d] reset irq subscribe fail",
@@ -3819,7 +3830,7 @@ static int cam_ife_csid_ver2_enable_hw(
 	struct cam_hw_soc_info              *soc_info;
 	const struct cam_ife_csid_ver2_reg_info *csid_reg = NULL;
 	uint32_t  val;
-	int i;
+	int i, rc;
 	void __iomem *mem_base;
 	uint32_t buf_done_irq_mask[CAM_IFE_CSID_IRQ_REG_MAX] = {0};
 	uint32_t top_err_irq_mask[CAM_IFE_CSID_IRQ_REG_MAX] = {0};
@@ -3872,7 +3883,9 @@ static int cam_ife_csid_ver2_enable_hw(
 		cam_ife_csid_ver2_handle_buf_done_irq,
 		NULL,
 		NULL,
-		NULL);
+		NULL,
+		CAM_IRQ_EVT_GROUP_0);
+
 
 	if (csid_hw->buf_done_irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "csid[%d] buf done irq subscribe fail",
@@ -3890,16 +3903,24 @@ static int cam_ife_csid_ver2_enable_hw(
 		cam_ife_csid_ver2_top_err_irq_top_half,
 		cam_ife_csid_ver2_top_err_irq_bottom_half,
 		csid_hw->tasklet,
-		&tasklet_bh_api);
+		&tasklet_bh_api,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (csid_hw->top_err_irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "csid[%d] top error irq subscribe fail",
 			csid_hw->hw_intf->hw_idx);
-		cam_irq_controller_unsubscribe_irq(
-			csid_hw->csid_irq_controller,
+		rc = -EINVAL;
+		goto unsubscribe_buf_done;
+	}
+
+	rc = cam_irq_controller_register_dependent(csid_hw->csid_irq_controller,
+		csid_hw->buf_done_irq_controller, buf_done_irq_mask);
+
+	if (rc) {
+		cam_irq_controller_unsubscribe_irq(csid_hw->csid_irq_controller,
 			csid_hw->buf_done_irq_handle);
-		csid_hw->buf_done_irq_handle = 0;
-		return -EINVAL;
+		rc = -EINVAL;
+		goto unsubscribe_top_err;
 	}
 
 	csid_hw->flags.device_enabled = true;
@@ -3907,6 +3928,17 @@ static int cam_ife_csid_ver2_enable_hw(
 	CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
 		csid_hw->hw_intf->hw_idx, val);
 	return 0;
+
+
+unsubscribe_top_err:
+	cam_irq_controller_unsubscribe_irq(csid_hw->csid_irq_controller,
+		csid_hw->top_err_irq_handle);
+	csid_hw->top_err_irq_handle = 0;
+unsubscribe_buf_done:
+	cam_irq_controller_unsubscribe_irq(csid_hw->csid_irq_controller,
+		csid_hw->buf_done_irq_handle);
+	csid_hw->buf_done_irq_handle = 0;
+	return rc;
 }
 
 int cam_ife_csid_ver2_init_hw(void *hw_priv,
@@ -4230,6 +4262,9 @@ int cam_ife_csid_ver2_stop(void *hw_priv,
 			csid_hw->csid_irq_controller,
 			csid_hw->buf_done_irq_handle);
 		csid_hw->buf_done_irq_handle = 0;
+
+		cam_irq_controller_unregister_dependent(csid_hw->csid_irq_controller,
+			csid_hw->buf_done_irq_controller);
 	}
 
 	if (csid_hw->top_err_irq_handle) {
@@ -4918,7 +4953,7 @@ static irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
 		return IRQ_NONE;
 
 	return cam_irq_controller_handle_irq(irq_num,
-		csid_hw->csid_irq_controller);
+		csid_hw->csid_irq_controller, CAM_IRQ_EVT_GROUP_0);
 }
 
 static void cam_ife_csid_ver2_free_res(struct cam_ife_csid_ver2_hw *csid_hw)
@@ -5079,8 +5114,7 @@ static int cam_ife_csid_hw_init_irq(
 
 	rc = cam_irq_controller_init("csid",
 		mem_base, csid_reg->irq_reg_info,
-		&csid_hw->csid_irq_controller,
-		true);
+		&csid_hw->csid_irq_controller);
 
 	if (rc) {
 		CAM_ERR(CAM_ISP,
@@ -5091,8 +5125,7 @@ static int cam_ife_csid_hw_init_irq(
 	rc = cam_irq_controller_init("csid_buf_done",
 		mem_base,
 		csid_reg->buf_done_irq_reg_info,
-		&csid_hw->buf_done_irq_controller,
-		true);
+		&csid_hw->buf_done_irq_controller);
 
 	if (rc) {
 		CAM_ERR(CAM_ISP,

+ 2 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite680.h

@@ -286,6 +286,7 @@ static struct cam_irq_controller_reg_info cam_ife_csid_lite_680_irq_reg_info = {
 	.irq_reg_set = cam_ife_csid_lite_680_irq_reg_set,
 	.global_clear_offset  = 0x00000014,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_irq_register_set cam_ife_csid_lite_680_buf_done_irq_reg_set[1] = {
@@ -300,8 +301,7 @@ static struct cam_irq_controller_reg_info
 	cam_ife_csid_lite_680_buf_done_irq_reg_info = {
 	.num_registers = 1,
 	.irq_reg_set = cam_ife_csid_lite_680_buf_done_irq_reg_set,
-	.global_clear_offset  = 0x00000014,
-	.global_clear_bitmask = 0x00000001,
+	.global_clear_offset  = 0, /* intentionally set to zero */
 };
 
 static struct cam_ife_csid_ver2_common_reg_info

+ 2 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite780.h

@@ -315,6 +315,7 @@ static struct cam_irq_controller_reg_info cam_ife_csid_lite_780_irq_reg_info = {
 	.irq_reg_set = cam_ife_csid_lite_780_irq_reg_set,
 	.global_clear_offset  = 0x00000014,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_irq_register_set cam_ife_csid_lite_780_buf_done_irq_reg_set[1] = {
@@ -329,8 +330,7 @@ static struct cam_irq_controller_reg_info
 	cam_ife_csid_lite_780_buf_done_irq_reg_info = {
 	.num_registers = 1,
 	.irq_reg_set = cam_ife_csid_lite_780_buf_done_irq_reg_set,
-	.global_clear_offset  = 0x00000014,
-	.global_clear_bitmask = 0x00000001,
+	.global_clear_offset  = 0, /* intentionally set to zero */
 };
 
 static struct cam_ife_csid_ver2_common_reg_info

+ 3 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe680.h

@@ -438,6 +438,7 @@ static struct cam_sfe_bus_rd_hw_info sfe680_bus_rd_hw_info = {
 			.irq_reg_set          = sfe680_bus_rd_irq_reg,
 			.global_clear_offset  = 0x0000040C,
 			.global_clear_bitmask = 0x00000001,
+			.clear_all_bitmask = 0xFFFFFFFF,
 		},
 	},
 	.num_client = 3,
@@ -541,6 +542,7 @@ static struct cam_sfe_bus_wr_hw_info sfe680_bus_wr_hw_info = {
 			.irq_reg_set          = sfe680_bus_wr_irq_reg,
 			.global_clear_offset  = 0x00000830,
 			.global_clear_bitmask = 0x00000001,
+			.clear_all_bitmask = 0xFFFFFFFF,
 		},
 	},
 	.num_client = 13,
@@ -1210,6 +1212,7 @@ static struct cam_irq_controller_reg_info sfe680_top_irq_reg_info = {
 	.irq_reg_set = sfe680_top_irq_reg_set,
 	.global_clear_offset  = 0x0000001C,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 struct cam_sfe_hw_info cam_sfe680_hw_info = {

+ 2 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe_core.c

@@ -396,7 +396,7 @@ irqreturn_t cam_sfe_irq(int irq_num, void *data)
 	core_info = (struct cam_sfe_hw_core_info *)sfe_hw->core_info;
 
 	return cam_irq_controller_handle_irq(irq_num,
-		core_info->sfe_irq_controller);
+		core_info->sfe_irq_controller, CAM_IRQ_EVT_GROUP_0);
 }
 
 int cam_sfe_core_init(
@@ -409,8 +409,7 @@ int cam_sfe_core_init(
 
 	rc = cam_irq_controller_init(drv_name,
 		CAM_SOC_GET_REG_MAP_START(soc_info, SFE_CORE_BASE_IDX),
-		sfe_hw_info->irq_reg_info, &core_info->sfe_irq_controller,
-		true);
+		sfe_hw_info->irq_reg_info, &core_info->sfe_irq_controller);
 	if (rc) {
 		CAM_ERR(CAM_SFE, "SFE irq controller init failed");
 		return rc;

+ 15 - 9
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_rd.c

@@ -362,7 +362,7 @@ static int cam_sfe_bus_rd_handle_irq(
 	CAM_DBG(CAM_SFE, "Top Bus RD IRQ Received");
 
 	rc = cam_irq_controller_handle_irq(evt_id,
-		bus_priv->common_data.bus_irq_controller);
+		bus_priv->common_data.bus_irq_controller, CAM_IRQ_EVT_GROUP_0);
 
 	return (rc == IRQ_HANDLED) ? 0 : -EINVAL;
 }
@@ -657,10 +657,7 @@ static int cam_sfe_bus_rd_handle_irq_top_half(uint32_t evt_id,
 		CAM_ERR(CAM_SFE, "SFE:%d constraint violation:0x%x",
 			bus_priv->common_data.core_index,
 			evt_payload->constraint_violation);
-		cam_irq_controller_disable_irq(
-			bus_priv->common_data.bus_irq_controller,
-			 bus_priv->error_irq_handle);
-		cam_irq_controller_clear_and_mask(evt_id,
+		cam_irq_controller_disable_all(
 			bus_priv->common_data.bus_irq_controller);
 	}
 
@@ -722,7 +719,8 @@ static int cam_sfe_bus_subscribe_error_irq(
 		cam_sfe_bus_rd_handle_irq,
 		NULL,
 		NULL,
-		NULL);
+		NULL,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (bus_priv->irq_handle < 1) {
 		CAM_ERR(CAM_SFE,
@@ -731,6 +729,9 @@ static int cam_sfe_bus_subscribe_error_irq(
 		return -EFAULT;
 	}
 
+	cam_irq_controller_register_dependent(bus_priv->common_data.sfe_irq_controller,
+		bus_priv->common_data.bus_irq_controller, sfe_top_irq_mask);
+
 	if (bus_priv->tasklet_info != NULL) {
 		bus_priv->error_irq_handle = cam_irq_controller_subscribe_irq(
 			bus_priv->common_data.bus_irq_controller,
@@ -740,7 +741,8 @@ static int cam_sfe_bus_subscribe_error_irq(
 			cam_sfe_bus_rd_handle_irq_top_half,
 			cam_sfe_bus_rd_handle_irq_bottom_half,
 			bus_priv->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (bus_priv->error_irq_handle < 1) {
 			CAM_ERR(CAM_SFE, "Failed to subscribe error IRQ");
@@ -977,7 +979,8 @@ static int cam_sfe_bus_start_bus_rd(
 			cam_sfe_bus_rd_out_done_top_half,
 			cam_sfe_bus_rd_out_done_bottom_half,
 			sfe_bus_rd->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (sfe_bus_rd->irq_handle < 1) {
 			CAM_ERR(CAM_SFE,
@@ -1039,6 +1042,9 @@ static int cam_sfe_bus_stop_bus_rd(
 			if (rc)
 				CAM_ERR(CAM_SFE, "Failed to unsubscribe top irq");
 			bus_priv->irq_handle = 0;
+			cam_irq_controller_unregister_dependent(
+				bus_priv->common_data.sfe_irq_controller,
+				bus_priv->common_data.bus_irq_controller);
 		}
 
 		if (bus_priv->error_irq_handle) {
@@ -1725,7 +1731,7 @@ int cam_sfe_bus_rd_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, true);
+		&bus_priv->common_data.bus_irq_controller);
 	if (rc) {
 		CAM_ERR(CAM_SFE, "IRQ controller init failed");
 		goto free_bus_priv;

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

@@ -1587,7 +1587,8 @@ static int cam_sfe_bus_start_sfe_out(
 		sfe_out->top_half_handler,
 		sfe_out->bottom_half_handler,
 		sfe_out->tasklet_info,
-		&tasklet_bh_api);
+		&tasklet_bh_api,
+		CAM_IRQ_EVT_GROUP_0);
 	if (sfe_out->irq_handle < 1) {
 		CAM_ERR(CAM_SFE, "Subscribe IRQ failed for sfe out_res: %d",
 			sfe_out->res_id);
@@ -1657,6 +1658,9 @@ static int cam_sfe_bus_stop_sfe_out(
 			if (rc)
 				CAM_WARN(CAM_SFE, "failed to unsubscribe top irq");
 			bus_priv->bus_irq_handle = 0;
+			cam_irq_controller_unregister_dependent(
+				bus_priv->common_data.sfe_irq_controller,
+				bus_priv->common_data.bus_irq_controller);
 		}
 
 		bus_priv->common_data.err_irq_subscribe = false;
@@ -2015,7 +2019,7 @@ static int cam_sfe_bus_wr_handle_bus_irq(uint32_t    evt_id,
 
 	bus_priv = th_payload->handler_priv;
 	rc = cam_irq_controller_handle_irq(evt_id,
-		bus_priv->common_data.bus_irq_controller);
+		bus_priv->common_data.bus_irq_controller, CAM_IRQ_EVT_GROUP_0);
 	return (rc == IRQ_HANDLED) ? 0 : -EINVAL;
 }
 
@@ -2176,7 +2180,8 @@ static int cam_sfe_bus_subscribe_error_irq(
 		cam_sfe_bus_wr_handle_bus_irq,
 		NULL,
 		NULL,
-		NULL);
+		NULL,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (bus_priv->bus_irq_handle < 1) {
 		CAM_ERR(CAM_SFE, "Failed to subscribe BUS TOP IRQ");
@@ -2184,6 +2189,9 @@ static int cam_sfe_bus_subscribe_error_irq(
 		return -EFAULT;
 	}
 
+	cam_irq_controller_register_dependent(bus_priv->common_data.sfe_irq_controller,
+		bus_priv->common_data.bus_irq_controller, top_irq_reg_mask);
+
 	if (bus_priv->tasklet_info != NULL) {
 		bus_priv->error_irq_handle = cam_irq_controller_subscribe_irq(
 			bus_priv->common_data.bus_irq_controller,
@@ -2193,7 +2201,8 @@ static int cam_sfe_bus_subscribe_error_irq(
 			cam_sfe_bus_wr_err_irq_top_half,
 			cam_sfe_bus_wr_irq_bottom_half,
 			bus_priv->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (bus_priv->error_irq_handle < 1) {
 			CAM_ERR(CAM_SFE, "Failed to subscribe BUS Error IRQ");
@@ -3178,8 +3187,7 @@ int cam_sfe_bus_wr_init(
 	rc = cam_irq_controller_init(drv_name,
 		bus_priv->common_data.mem_base,
 		&hw_info->common_reg.irq_reg_info,
-		&bus_priv->common_data.bus_irq_controller,
-		false);
+		&bus_priv->common_data.bus_irq_controller);
 	if (rc) {
 		CAM_ERR(CAM_SFE, "Init bus_irq_controller failed");
 		goto free_sfe_out;

+ 5 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.c

@@ -1212,10 +1212,7 @@ static int cam_sfe_top_handle_err_irq_top_half(
 
 	base = top_priv->common_data.soc_info->reg_map[SFE_CORE_BASE_IDX].mem_base;
 	if (irq_status & top_priv->common_data.common_reg_data->error_irq_mask) {
-		cam_irq_controller_disable_irq(
-			top_priv->common_data.sfe_irq_controller,
-			top_priv->error_irq_handle);
-		cam_irq_controller_clear_and_mask(evt_id,
+		cam_irq_controller_disable_all(
 			top_priv->common_data.sfe_irq_controller);
 	}
 
@@ -1596,7 +1593,8 @@ int cam_sfe_top_start(
 			cam_sfe_top_handle_err_irq_top_half,
 			cam_sfe_top_handle_err_irq_bottom_half,
 			sfe_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (top_priv->error_irq_handle < 1) {
 			CAM_ERR(CAM_SFE, "Failed to subscribe Top IRQ");
@@ -1622,7 +1620,8 @@ int cam_sfe_top_start(
 				cam_sfe_top_handle_irq_top_half,
 				cam_sfe_top_handle_irq_bottom_half,
 				sfe_res->tasklet_info,
-				&tasklet_bh_api);
+				&tasklet_bh_api,
+				CAM_IRQ_EVT_GROUP_0);
 
 			if (path_data->sof_eof_handle < 1) {
 				CAM_ERR(CAM_SFE,

+ 4 - 4
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c

@@ -253,7 +253,7 @@ int cam_vfe_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size)
 		top_reset_irq_reg_mask,
 		vfe_hw,
 		cam_vfe_reset_irq_top_half,
-		NULL, NULL, NULL);
+		NULL, NULL, NULL, CAM_IRQ_EVT_GROUP_0);
 
 	if (irq_info->reset_irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "subscribe irq controller failed");
@@ -572,7 +572,7 @@ irqreturn_t cam_vfe_irq(int irq_num, void *data)
 	core_info = (struct cam_vfe_hw_core_info *)vfe_hw->core_info;
 
 	return cam_irq_controller_handle_irq(irq_num,
-		core_info->vfe_irq_controller);
+		core_info->vfe_irq_controller, CAM_IRQ_EVT_GROUP_0);
 }
 
 int cam_vfe_core_init(struct cam_vfe_hw_core_info  *core_info,
@@ -593,8 +593,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_hw_info->top_irq_reg, &core_info->vfe_irq_controller,
-		true);
+		vfe_hw_info->irq_hw_info->top_irq_reg,
+		&core_info->vfe_irq_controller);
 	if (rc) {
 		CAM_ERR(CAM_ISP,
 			"Error, cam_irq_controller_init failed rc = %d", rc);

+ 3 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_VFE170_H_
@@ -30,6 +30,7 @@ static struct cam_irq_controller_reg_info vfe170_top_irq_reg_info = {
 	.irq_reg_set = vfe170_top_irq_reg_set,
 	.global_clear_offset  = 0x00000058,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_vfe_camif_ver2_reg vfe170_camif_reg = {
@@ -266,6 +267,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe170_bus_hw_info = {
 			.irq_reg_set          = vfe170_bus_irq_reg,
 			.global_clear_offset  = 0x00002068,
 			.global_clear_bitmask = 0x00000001,
+			.clear_all_bitmask = 0xFFFFFFFF,
 		},
 		.comp_error_status            = 0x0000206C,
 		.comp_ovrwr_status            = 0x00002070,

+ 3 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170_150.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_VFE170_150_H_
@@ -30,6 +30,7 @@ static struct cam_irq_controller_reg_info vfe170_150_top_irq_reg_info = {
 	.irq_reg_set = vfe170_150_top_irq_reg_set,
 	.global_clear_offset  = 0x00000058,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_vfe_camif_ver2_reg vfe170_150_camif_reg = {
@@ -234,6 +235,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe170_150_bus_hw_info = {
 			.irq_reg_set          = vfe170_150_bus_irq_reg,
 			.global_clear_offset  = 0x00002068,
 			.global_clear_bitmask = 0x00000001,
+			.clear_all_bitmask = 0xFFFFFFFF,
 		},
 		.comp_error_status            = 0x0000206C,
 		.comp_ovrwr_status            = 0x00002070,

+ 3 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_VFE175_H_
@@ -31,6 +31,7 @@ static struct cam_irq_controller_reg_info vfe175_top_irq_reg_info = {
 	.irq_reg_set = vfe175_top_irq_reg_set,
 	.global_clear_offset  = 0x00000058,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_vfe_camif_ver2_reg vfe175_camif_reg = {
@@ -325,6 +326,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe175_bus_hw_info = {
 			.irq_reg_set          = vfe175_bus_irq_reg,
 			.global_clear_offset  = 0x00002068,
 			.global_clear_bitmask = 0x00000001,
+			.clear_all_bitmask = 0xFFFFFFFF,
 		},
 		.comp_error_status            = 0x0000206C,
 		.comp_ovrwr_status            = 0x00002070,

+ 4 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_VFE175_130_H_
@@ -40,6 +40,7 @@ static struct cam_irq_controller_reg_info vfe175_130_top_irq_reg_info = {
 	.irq_reg_set = vfe175_130_top_irq_reg_set,
 	.global_clear_offset  = 0x00000058,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_vfe_camif_ver2_reg vfe175_130_camif_reg = {
@@ -397,6 +398,7 @@ static struct cam_vfe_bus_rd_ver1_hw_info vfe175_130_bus_rd_hw_info = {
 			.irq_reg_set          = vfe175_130_bus_rd_irq_reg,
 			.global_clear_offset  = 0x00005018,
 			.global_clear_bitmask = 0x00000001,
+			.clear_all_bitmask = 0xFFFFFFFF,
 		},
 	},
 	.num_client = 1,
@@ -436,6 +438,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe175_130_bus_hw_info = {
 			.irq_reg_set          = vfe175_130_bus_irq_reg,
 			.global_clear_offset  = 0x00002068,
 			.global_clear_bitmask = 0x00000001,
+			.clear_all_bitmask = 0xFFFFFFFF,
 		},
 		.comp_error_status            = 0x0000206C,
 		.comp_ovrwr_status            = 0x00002070,

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h

@@ -37,6 +37,7 @@ static struct cam_irq_controller_reg_info vfe480_top_irq_reg_info = {
 	.irq_reg_set = vfe480_top_irq_reg_set,
 	.global_clear_offset  = 0x00000038,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_vfe_camif_ver3_pp_clc_reg vfe480_camif_reg = {
@@ -1630,6 +1631,7 @@ static struct cam_vfe_bus_rd_ver1_hw_info vfe480_bus_rd_hw_info = {
 			.irq_reg_set          = vfe480_bus_rd_irq_reg,
 			.global_clear_offset  = 0x0000A818,
 			.global_clear_bitmask = 0x00000001,
+			.clear_all_bitmask = 0xFFFFFFFF,
 		},
 	},
 	.num_client = 1,

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe680.h

@@ -464,6 +464,7 @@ static struct cam_irq_controller_reg_info vfe680_top_irq_reg_info = {
 	.irq_reg_set = vfe680_top_irq_reg_set,
 	.global_clear_offset  = 0x00000030,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_vfe_top_ver4_reg_offset_common vfe680_top_common_reg = {

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe780.h

@@ -490,6 +490,7 @@ static struct cam_irq_controller_reg_info vfe780_top_irq_reg_info = {
 	.irq_reg_set = vfe780_top_irq_reg_set,
 	.global_clear_offset  = 0x00000030,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_vfe_top_ver4_reg_offset_common vfe780_top_common_reg = {

+ 3 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_VFE_LITE17X_H_
@@ -29,6 +29,7 @@ static struct cam_irq_controller_reg_info vfe17x_top_irq_reg_info = {
 	.irq_reg_set = vfe17x_top_irq_reg_set,
 	.global_clear_offset  = 0x00000058,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_vfe_top_ver2_reg_offset_common vfe17x_top_common_reg = {
@@ -154,6 +155,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe17x_bus_hw_info = {
 			.irq_reg_set          = vfe17x_bus_irq_reg,
 			.global_clear_offset  = 0x00002068,
 			.global_clear_bitmask = 0x00000001,
+			.clear_all_bitmask = 0xFFFFFFFF,
 		},
 		.comp_error_status            = 0x0000206C,
 		.comp_ovrwr_status            = 0x00002070,

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h

@@ -34,6 +34,7 @@ static struct cam_irq_controller_reg_info vfe48x_top_irq_reg_info = {
 	.irq_reg_set = vfe48x_top_irq_reg_set,
 	.global_clear_offset  = 0x00000024,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_vfe_top_ver3_reg_offset_common vfe48x_top_common_reg = {

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite68x.h

@@ -74,6 +74,7 @@ static struct cam_irq_controller_reg_info vfe68x_top_irq_reg_info = {
 	.irq_reg_set = vfe68x_top_irq_reg_set,
 	.global_clear_offset  = 0x00001038,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_vfe_top_ver4_reg_offset_common vfe68x_top_common_reg = {

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite78x.h

@@ -74,6 +74,7 @@ static struct cam_irq_controller_reg_info vfe_lite78x_top_irq_reg_info = {
 	.irq_reg_set = vfe_lite78x_top_irq_reg_set,
 	.global_clear_offset  = 0x00001038,
 	.global_clear_bitmask = 0x00000001,
+	.clear_all_bitmask = 0xFFFFFFFF,
 };
 
 static struct cam_vfe_top_ver4_reg_offset_common vfe_lite78x_top_common_reg = {

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

@@ -702,7 +702,8 @@ static int cam_vfe_bus_start_vfe_bus_rd(
 		cam_vfe_bus_rd_handle_irq_top_half,
 		cam_vfe_bus_rd_handle_irq_bottom_half,
 		vfe_bus_rd->tasklet_info,
-		&tasklet_bh_api);
+		&tasklet_bh_api,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (rsrc_data->irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "Failed to subscribe BUS RD IRQ");
@@ -849,7 +850,7 @@ static int cam_vfe_bus_rd_ver1_handle_irq(uint32_t    evt_id,
 	CAM_DBG(CAM_ISP, "Top Bus RD IRQ Received");
 
 	rc = cam_irq_controller_handle_irq(evt_id,
-		bus_priv->common_data.bus_irq_controller);
+		bus_priv->common_data.bus_irq_controller, CAM_IRQ_EVT_GROUP_0);
 
 	return (rc == IRQ_HANDLED) ? 0 : -EINVAL;
 }
@@ -1123,7 +1124,8 @@ static int cam_vfe_bus_init_hw(void *hw_priv,
 		cam_vfe_bus_rd_ver1_handle_irq,
 		NULL,
 		NULL,
-		NULL);
+		NULL,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (bus_priv->irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
@@ -1260,7 +1262,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, true);
+		&bus_priv->common_data.bus_irq_controller);
 	if (rc) {
 		CAM_ERR(CAM_ISP, "cam_irq_controller_init failed");
 		goto free_bus_priv;

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

@@ -2371,7 +2371,7 @@ static int cam_vfe_bus_start_vfe_out(
 		common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
 		bus_irq_reg_mask, vfe_out, vfe_out->top_half_handler,
 		vfe_out->bottom_half_handler, vfe_out->tasklet_info,
-		&tasklet_bh_api);
+		&tasklet_bh_api, CAM_IRQ_EVT_GROUP_0);
 
 	if (vfe_out->irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "Subscribe IRQ failed for res_id %d",
@@ -2635,7 +2635,7 @@ static int cam_vfe_bus_ver2_handle_irq(uint32_t    evt_id,
 	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);
+		bus_priv->common_data.bus_irq_controller, CAM_IRQ_EVT_GROUP_0);
 	return (rc == IRQ_HANDLED) ? 0 : -EINVAL;
 }
 
@@ -3596,7 +3596,8 @@ static int cam_vfe_bus_init_hw(void *hw_priv,
 		cam_vfe_bus_ver2_handle_irq,
 		NULL,
 		NULL,
-		NULL);
+		NULL,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (bus_priv->irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
@@ -3613,7 +3614,8 @@ static int cam_vfe_bus_init_hw(void *hw_priv,
 			cam_vfe_bus_error_irq_top_half,
 			cam_vfe_bus_err_bottom_half,
 			bus_priv->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (bus_priv->error_irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "Failed to subscribe BUS error IRQ %d",
@@ -3913,7 +3915,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, true);
+		&bus_priv->common_data.bus_irq_controller);
 	if (rc) {
 		CAM_ERR(CAM_ISP, "cam_irq_controller_init failed");
 		goto free_bus_priv;

+ 22 - 28
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c

@@ -79,7 +79,6 @@ 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;
 	void                                       *buf_done_controller;
 	void                                       *priv;
@@ -2180,7 +2179,8 @@ static int cam_vfe_bus_ver3_start_vfe_out(
 		vfe_out->top_half_handler,
 		vfe_out->bottom_half_handler,
 		vfe_out->tasklet_info,
-		&tasklet_bh_api);
+		&tasklet_bh_api,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (vfe_out->irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "Subscribe IRQ failed for VFE out_res %d",
@@ -2206,14 +2206,15 @@ static int cam_vfe_bus_ver3_start_vfe_out(
 
 		common_data->rup_irq_handle[source_group] =
 			cam_irq_controller_subscribe_irq(
-				common_data->rup_irq_controller,
+				common_data->bus_irq_controller,
 				CAM_IRQ_PRIORITY_0,
 				rup_irq_reg_mask,
 				vfe_out,
 				cam_vfe_bus_ver3_handle_rup_top_half,
 				cam_vfe_bus_ver3_handle_rup_bottom_half,
 				vfe_out->tasklet_info,
-				&tasklet_bh_api);
+				&tasklet_bh_api,
+				CAM_IRQ_EVT_GROUP_1);
 
 		if (common_data->rup_irq_handle[source_group] < 1) {
 			CAM_ERR(CAM_ISP, "Failed to subscribe RUP IRQ");
@@ -2257,7 +2258,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->rup_irq_controller,
+			common_data->bus_irq_controller,
 			common_data->rup_irq_handle[rsrc_data->source_group]);
 		common_data->rup_irq_handle[rsrc_data->source_group] = 0;
 	}
@@ -2717,7 +2718,7 @@ static int cam_vfe_bus_ver3_handle_bus_irq(uint32_t    evt_id,
 	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);
+		bus_priv->common_data.bus_irq_controller, CAM_IRQ_EVT_GROUP_0);
 	return (rc == IRQ_HANDLED) ? 0 : -EINVAL;
 }
 
@@ -2730,7 +2731,7 @@ static int cam_vfe_bus_ver3_handle_rup_irq(uint32_t     evt_id,
 	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);
+		bus_priv->common_data.bus_irq_controller, CAM_IRQ_EVT_GROUP_1);
 	return (rc == IRQ_HANDLED) ? 0 : -EINVAL;
 }
 
@@ -2894,6 +2895,8 @@ static void cam_vfe_bus_ver3_unsubscribe_init_irq(
 			CAM_WARN(CAM_ISP, "failed to unsubscribe top irq");
 
 		bus_priv->bus_irq_handle = 0;
+		cam_irq_controller_unregister_dependent(bus_priv->common_data.vfe_irq_controller,
+		bus_priv->common_data.bus_irq_controller);
 	}
 
 	if (bus_priv->rup_irq_handle) {
@@ -2918,6 +2921,11 @@ static int cam_vfe_bus_ver3_subscribe_init_irq(
 	/* Subscribe top IRQ */
 	top_irq_reg_mask[0] = (1 << bus_priv->top_irq_shift);
 
+	cam_irq_controller_register_dependent(
+		bus_priv->common_data.vfe_irq_controller,
+		bus_priv->common_data.bus_irq_controller,
+		top_irq_reg_mask);
+
 	bus_priv->bus_irq_handle = cam_irq_controller_subscribe_irq(
 		bus_priv->common_data.vfe_irq_controller,
 		CAM_IRQ_PRIORITY_4,
@@ -2926,7 +2934,8 @@ static int cam_vfe_bus_ver3_subscribe_init_irq(
 		cam_vfe_bus_ver3_handle_bus_irq,
 		NULL,
 		NULL,
-		NULL);
+		NULL,
+		CAM_IRQ_EVT_GROUP_0);
 
 	if (bus_priv->bus_irq_handle < 1) {
 		CAM_ERR(CAM_ISP, "Failed to subscribe BUS (buf_done) IRQ");
@@ -2944,7 +2953,8 @@ static int cam_vfe_bus_ver3_subscribe_init_irq(
 			cam_vfe_bus_ver3_err_irq_top_half,
 			cam_vfe_bus_ver3_err_irq_bottom_half,
 			bus_priv->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (bus_priv->error_irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "Failed to subscribe BUS Error IRQ");
@@ -2962,7 +2972,8 @@ static int cam_vfe_bus_ver3_subscribe_init_irq(
 			cam_vfe_bus_ver3_handle_rup_irq,
 			NULL,
 			NULL,
-			NULL);
+			NULL,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (bus_priv->rup_irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "Failed to subscribe BUS (rup) IRQ");
@@ -4118,23 +4129,12 @@ 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, false);
+		&bus_priv->common_data.bus_irq_controller);
 	if (rc) {
 		CAM_ERR(CAM_ISP, "Init bus_irq_controller failed");
 		goto free_vfe_out;
 	}
 
-	if (bus_priv->common_data.supported_irq & CAM_VFE_HW_IRQ_CAP_RUP) {
-		rc = cam_irq_controller_init("vfe_bus_rup",
-			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_vfe_out;
-		}
-	}
-
 	INIT_LIST_HEAD(&bus_priv->free_comp_grp);
 	INIT_LIST_HEAD(&bus_priv->used_comp_grp);
 
@@ -4270,12 +4270,6 @@ int cam_vfe_bus_ver3_deinit(
 		CAM_ERR(CAM_ISP,
 			"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);
-
 	kfree(bus_priv->comp_grp);
 	kfree(bus_priv->vfe_out);
 

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

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -115,10 +115,7 @@ static int cam_vfe_camif_lite_err_irq_top_half(
 			th_payload->evt_status_arr[1]);
 		CAM_ERR(CAM_ISP, "Stopping further IRQ processing from VFE:%d",
 			camif_lite_node->hw_intf->hw_idx);
-		cam_irq_controller_disable_irq(
-			camif_lite_priv->vfe_irq_controller,
-			camif_lite_priv->irq_err_handle);
-		cam_irq_controller_clear_and_mask(evt_id,
+		cam_irq_controller_disable_all(
 			camif_lite_priv->vfe_irq_controller);
 		error_flag = true;
 	}
@@ -300,7 +297,8 @@ static int cam_vfe_camif_lite_resource_start(
 			cam_vfe_camif_lite_err_irq_top_half,
 			camif_lite_res->bottom_half_handler,
 			camif_lite_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 		if (rsrc_data->irq_err_handle < 1) {
 			CAM_ERR(CAM_ISP, "Error IRQ handle subscribe failure");
 			rc = -ENOMEM;

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

@@ -128,10 +128,7 @@ static int cam_vfe_camif_lite_err_irq_top_half(
 			th_payload->evt_status_arr[2]);
 		CAM_ERR(CAM_ISP, "Stopping further IRQ processing from VFE:%d",
 			camif_lite_node->hw_intf->hw_idx);
-		cam_irq_controller_disable_irq(
-			camif_lite_priv->vfe_irq_controller,
-			camif_lite_priv->irq_err_handle);
-		cam_irq_controller_clear_and_mask(evt_id,
+		cam_irq_controller_disable_all(
 			camif_lite_priv->vfe_irq_controller);
 		error_flag = true;
 	}
@@ -348,7 +345,8 @@ skip_core_cfg:
 			camif_lite_res->top_half_handler,
 			camif_lite_res->bottom_half_handler,
 			camif_lite_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 		if (rsrc_data->irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "IRQ handle subscribe failure");
 			rc = -ENOMEM;
@@ -368,7 +366,8 @@ skip_core_cfg:
 			camif_lite_res->top_half_handler,
 			camif_lite_res->bottom_half_handler,
 			camif_lite_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 		if (rsrc_data->sof_irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "IRQ handle subscribe failure");
 			rc = -ENOMEM;
@@ -392,7 +391,8 @@ subscribe_err:
 			cam_vfe_camif_lite_err_irq_top_half,
 			camif_lite_res->bottom_half_handler,
 			camif_lite_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (rsrc_data->irq_err_handle < 1) {
 			CAM_ERR(CAM_ISP, "Error IRQ handle subscribe failure");

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

@@ -132,9 +132,7 @@ static int cam_vfe_camif_err_irq_top_half(
 			th_payload->evt_status_arr[1]);
 		CAM_ERR(CAM_ISP, "Stopping further IRQ processing from vfe=%d",
 			camif_node->hw_intf->hw_idx);
-		cam_irq_controller_disable_irq(camif_priv->vfe_irq_controller,
-			camif_priv->irq_err_handle);
-		cam_irq_controller_clear_and_mask(evt_id,
+		cam_irq_controller_disable_all(
 			camif_priv->vfe_irq_controller);
 		error_flag = true;
 	}
@@ -489,7 +487,8 @@ static int cam_vfe_camif_resource_start(
 			camif_res->top_half_handler,
 			camif_res->bottom_half_handler,
 			camif_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 		if (rsrc_data->irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "IRQ handle subscribe failure");
 			rc = -ENOMEM;
@@ -507,7 +506,8 @@ subscribe_err:
 			cam_vfe_camif_err_irq_top_half,
 			camif_res->bottom_half_handler,
 			camif_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 		if (rsrc_data->irq_err_handle < 1) {
 			CAM_ERR(CAM_ISP, "Error IRQ handle subscribe failure");
 			rc = -ENOMEM;

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

@@ -136,9 +136,7 @@ static int cam_vfe_camif_ver3_err_irq_top_half(
 			th_payload->evt_status_arr[2]);
 		CAM_ERR(CAM_ISP, "Stopping further IRQ processing from VFE:%d",
 			camif_node->hw_intf->hw_idx);
-		cam_irq_controller_disable_irq(camif_priv->vfe_irq_controller,
-			camif_priv->irq_err_handle);
-		cam_irq_controller_clear_and_mask(evt_id,
+		cam_irq_controller_disable_all(
 			camif_priv->vfe_irq_controller);
 		error_flag = true;
 	}
@@ -555,7 +553,8 @@ static int cam_vfe_camif_ver3_resource_start(
 			camif_res->top_half_handler,
 			camif_res->bottom_half_handler,
 			camif_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (rsrc_data->irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "IRQ handle subscribe failure");
@@ -579,7 +578,8 @@ static int cam_vfe_camif_ver3_resource_start(
 			camif_res->top_half_handler,
 			camif_res->bottom_half_handler,
 			camif_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (rsrc_data->sof_irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "SOF IRQ handle subscribe failure");
@@ -598,7 +598,8 @@ subscribe_err:
 			cam_vfe_camif_ver3_err_irq_top_half,
 			camif_res->bottom_half_handler,
 			camif_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (rsrc_data->irq_err_handle < 1) {
 			CAM_ERR(CAM_ISP, "Error IRQ handle subscribe failure");

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

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -178,9 +178,7 @@ static int cam_vfe_rdi_err_irq_top_half(
 			th_payload->evt_status_arr[1]);
 		CAM_ERR(CAM_ISP, "Stopping further IRQ processing from vfe=%d",
 			rdi_node->hw_intf->hw_idx);
-		cam_irq_controller_disable_irq(rdi_priv->vfe_irq_controller,
-			rdi_priv->irq_err_handle);
-		cam_irq_controller_clear_and_mask(evt_id,
+		cam_irq_controller_disable_all(
 			rdi_priv->vfe_irq_controller);
 		error_flag = true;
 	}
@@ -323,7 +321,8 @@ static int cam_vfe_rdi_resource_start(
 			cam_vfe_rdi_err_irq_top_half,
 			rdi_res->bottom_half_handler,
 			rdi_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 		if (rsrc_data->irq_err_handle < 1) {
 			CAM_ERR(CAM_ISP, "Error IRQ handle subscribe failure");
 			rc = -ENOMEM;
@@ -351,7 +350,8 @@ static int cam_vfe_rdi_resource_start(
 			rdi_res->top_half_handler,
 			rdi_res->bottom_half_handler,
 			rdi_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 		if (rsrc_data->irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "IRQ handle subscribe failure");
 			rc = -ENOMEM;

+ 7 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c

@@ -1166,9 +1166,7 @@ static int cam_vfe_ver4_err_irq_top_half(
 			th_payload->evt_status_arr[0]);
 		CAM_ERR(CAM_ISP, "Stopping further IRQ processing from VFE:%d",
 			vfe_res->hw_intf->hw_idx);
-		cam_irq_controller_disable_irq(vfe_priv->vfe_irq_controller,
-			vfe_priv->irq_err_handle);
-		cam_irq_controller_clear_and_mask(evt_id,
+		cam_irq_controller_disable_all(
 			vfe_priv->vfe_irq_controller);
 		error_flag = true;
 	}
@@ -1293,7 +1291,8 @@ skip_core_cfg:
 			vfe_res->top_half_handler,
 			vfe_res->bottom_half_handler,
 			vfe_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (rsrc_data->irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "IRQ handle subscribe failure");
@@ -1314,7 +1313,8 @@ skip_core_cfg:
 			vfe_res->top_half_handler,
 			vfe_res->bottom_half_handler,
 			vfe_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (rsrc_data->sof_irq_handle < 1) {
 			CAM_ERR(CAM_ISP, "SOF IRQ handle subscribe failure");
@@ -1335,7 +1335,8 @@ subscribe_err:
 			cam_vfe_ver4_err_irq_top_half,
 			vfe_res->bottom_half_handler,
 			vfe_res->tasklet_info,
-			&tasklet_bh_api);
+			&tasklet_bh_api,
+			CAM_IRQ_EVT_GROUP_0);
 
 		if (rsrc_data->irq_err_handle < 1) {
 			CAM_ERR(CAM_ISP, "Error IRQ handle subscribe failure");