Pārlūkot izejas kodu

msm: camera: utils: Add support for multiple IRQ lines per device

Update SOC util to be able to parse multiple irq names from DT and,
request, enable, disable multiple irq lines per soc.

All IRQ lines per SOC will have the same handler but different data,
so ISR will have their own private data to differentiate source of irq
in the same handling function.

CRs-Fixed: 3395596
Change-Id: Id9ca1cd3ef105d732a82decd7c8078bd29668326
Signed-off-by: Sokchetra Eung <[email protected]>
Sokchetra Eung 2 gadi atpakaļ
vecāks
revīzija
740de40e65
26 mainītis faili ar 317 papildinājumiem un 185 dzēšanām
  1. 5 1
      drivers/cam_cdm/cam_cdm_hw_core.c
  2. 7 4
      drivers/cam_cpas/cam_cpas_soc.c
  3. 8 5
      drivers/cam_cre/cam_cre_hw_mgr/cre_hw/cre_soc.c
  4. 8 5
      drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw1/cam_custom_sub_mod_soc.c
  5. 7 4
      drivers/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c
  6. 8 5
      drivers/cam_icp/icp_hw/bps_hw/bps_soc.c
  7. 7 3
      drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.c
  8. 8 5
      drivers/cam_icp/icp_hw/ipe_hw/ipe_soc.c
  9. 8 4
      drivers/cam_icp/icp_hw/ofe_hw/ofe_soc.c
  10. 7 4
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c
  11. 8 5
      drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.c
  12. 8 5
      drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe_soc.c
  13. 8 6
      drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_soc.c
  14. 6 4
      drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.c
  15. 8 5
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
  16. 7 4
      drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.c
  17. 7 4
      drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.c
  18. 7 4
      drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c
  19. 8 5
      drivers/cam_ope/ope_hw_mgr/ope_hw/ope_soc.c
  20. 2 2
      drivers/cam_sensor_module/cam_cci/cam_cci_dev.c
  21. 6 2
      drivers/cam_sensor_module/cam_cci/cam_cci_soc.c
  22. 6 2
      drivers/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
  23. 7 5
      drivers/cam_sensor_module/cam_tpg/cam_tpg_dev.c
  24. 14 11
      drivers/cam_utils/cam_compat.c
  25. 125 69
      drivers/cam_utils/cam_soc_util.c
  26. 17 12
      drivers/cam_utils/cam_soc_util.h

+ 5 - 1
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -2244,6 +2244,7 @@ static int cam_hw_cdm_component_bind(struct device *dev,
 	struct cam_cpas_register_params cpas_parms;
 	char cdm_name[128], work_q_name[128];
 	struct platform_device *pdev = to_platform_device(dev);
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	cdm_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
 	if (!cdm_hw_intf)
@@ -2358,8 +2359,11 @@ static int cam_hw_cdm_component_bind(struct device *dev,
 		CAM_DBG(CAM_CDM, "wq %s", work_q_name);
 	}
 
+	for (i = 0; i < cdm_hw->soc_info.irq_count; i++)
+		irq_data[i] = cdm_hw;
+
 	rc = cam_soc_util_request_platform_resource(&cdm_hw->soc_info,
-			cam_hw_cdm_irq, cdm_hw);
+			cam_hw_cdm_irq, &(irq_data[0]));
 	if (rc) {
 		CAM_ERR(CAM_CDM,
 			"Failed to request platform resource for %s%u",

+ 7 - 4
drivers/cam_cpas/cam_cpas_soc.c

@@ -1702,8 +1702,9 @@ cleanup_clients:
 int cam_cpas_soc_init_resources(struct cam_hw_soc_info *soc_info,
 	irq_handler_t irq_handler, struct cam_hw_info *cpas_hw)
 {
-	int rc = 0;
+	int rc = 0, i;
 	struct cam_cpas_private_soc *soc_private;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	rc = cam_soc_util_get_dt_properties(soc_info);
 	if (rc) {
@@ -1711,13 +1712,15 @@ int cam_cpas_soc_init_resources(struct cam_hw_soc_info *soc_info,
 		return rc;
 	}
 
-	if ((soc_info->irq_num > 0) && !irq_handler) {
+	if (soc_info->irq_count > 0 && !irq_handler) {
 		CAM_ERR(CAM_CPAS, "Invalid IRQ handler");
 		return -EINVAL;
 	}
 
-	rc = cam_soc_util_request_platform_resource(soc_info, irq_handler,
-		cpas_hw);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = cpas_hw;
+
+	rc = cam_soc_util_request_platform_resource(soc_info, irq_handler, &(irq_data[0]));
 	if (rc) {
 		CAM_ERR(CAM_CPAS, "failed in request_platform_resource, rc=%d",
 			rc);

+ 8 - 5
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/cre_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/io.h>
@@ -15,17 +15,20 @@
 #include "cam_debug_util.h"
 
 int cam_cre_init_soc_resources(struct cam_hw_soc_info *soc_info,
-	irq_handler_t cre_irq_handler, void *irq_data)
+	irq_handler_t cre_irq_handler, void *data)
 {
-	int rc;
+	int rc, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	rc = cam_soc_util_get_dt_properties(soc_info);
 	if (rc)
 		return rc;
 
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
+
 	rc = cam_soc_util_request_platform_resource(soc_info,
-		cre_irq_handler,
-		irq_data);
+		cre_irq_handler, &(irq_data[0]));
 	if (rc)
 		CAM_ERR(CAM_CRE, "init soc failed %d", rc);
 

+ 8 - 5
drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw1/cam_custom_sub_mod_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -10,11 +10,12 @@
 #include "cam_debug_util.h"
 
 int cam_custom_hw_sub_mod_init_soc_resources(struct cam_hw_soc_info *soc_info,
-	irq_handler_t irq_handler, void *irq_data)
+	irq_handler_t irq_handler, void *data)
 {
-	int                               rc = 0;
+	int                               rc = 0, i;
 	struct cam_custom_hw_soc_private *soc_private = NULL;
 	struct cam_cpas_register_params   cpas_register_param;
+	void                             *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	rc = cam_soc_util_get_dt_properties(soc_info);
 	if (rc < 0) {
@@ -32,8 +33,10 @@ int cam_custom_hw_sub_mod_init_soc_resources(struct cam_hw_soc_info *soc_info,
 	}
 	soc_info->soc_private = soc_private;
 
-	rc = cam_soc_util_request_platform_resource(soc_info, irq_handler,
-		irq_data);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
+
+	rc = cam_soc_util_request_platform_resource(soc_info, irq_handler, &(irq_data[0]));
 	if (rc < 0) {
 		CAM_ERR(CAM_CUSTOM,
 			"Error! Request platform resources failed rc=%d", rc);

+ 7 - 4
drivers/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/device.h>
@@ -180,7 +180,8 @@ int cam_fd_soc_init_resources(struct cam_hw_soc_info *soc_info,
 {
 	struct cam_fd_soc_private *soc_private;
 	struct cam_cpas_register_params cpas_register_param;
-	int rc;
+	int rc, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	rc = cam_soc_util_get_dt_properties(soc_info);
 	if (rc) {
@@ -188,8 +189,10 @@ int cam_fd_soc_init_resources(struct cam_hw_soc_info *soc_info,
 		return rc;
 	}
 
-	rc = cam_soc_util_request_platform_resource(soc_info, irq_handler,
-		private_data);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = private_data;
+
+	rc = cam_soc_util_request_platform_resource(soc_info, irq_handler, &(irq_data[0]));
 	if (rc) {
 		CAM_ERR(CAM_FD, "Failed in request_platform_resource rc=%d",
 			rc);

+ 8 - 5
drivers/cam_icp/icp_hw/bps_hw/bps_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/io.h>
@@ -26,12 +26,15 @@ static int cam_bps_get_dt_properties(struct cam_hw_soc_info *soc_info)
 
 static int cam_bps_request_platform_resource(
 	struct cam_hw_soc_info *soc_info,
-	irq_handler_t bps_irq_handler, void *irq_data)
+	irq_handler_t bps_irq_handler, void *data)
 {
-	int rc = 0;
+	int rc = 0, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
-	rc = cam_soc_util_request_platform_resource(soc_info, bps_irq_handler,
-		irq_data);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
+
+	rc = cam_soc_util_request_platform_resource(soc_info, bps_irq_handler, &(irq_data[0]));
 
 	return rc;
 }

+ 7 - 3
drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/interrupt.h>
@@ -200,13 +200,17 @@ static int cam_icp_soc_dt_properties_get(struct cam_hw_soc_info *soc_info)
 int cam_icp_soc_resources_init(struct cam_hw_soc_info *soc_info,
 	irq_handler_t handler, void *data)
 {
-	int rc;
+	int rc, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	rc = cam_icp_soc_dt_properties_get(soc_info);
 	if (rc)
 		return rc;
 
-	rc = cam_soc_util_request_platform_resource(soc_info, handler, data);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
+
+	rc = cam_soc_util_request_platform_resource(soc_info, handler, &(irq_data[0]));
 	if (rc) {
 		CAM_ERR(CAM_ICP,
 			"request for soc platform resource failed rc=%d", rc);

+ 8 - 5
drivers/cam_icp/icp_hw/ipe_hw/ipe_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/io.h>
@@ -77,12 +77,15 @@ static int cam_ipe_get_dt_properties(struct cam_hw_soc_info *soc_info)
 
 static int cam_ipe_request_platform_resource(
 	struct cam_hw_soc_info *soc_info,
-	irq_handler_t ipe_irq_handler, void *irq_data)
+	irq_handler_t ipe_irq_handler, void *data)
 {
-	int rc = 0;
+	int rc, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
-	rc = cam_soc_util_request_platform_resource(soc_info, ipe_irq_handler,
-		irq_data);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
+
+	rc = cam_soc_util_request_platform_resource(soc_info, ipe_irq_handler, &(irq_data[0]));
 
 	return rc;
 }

+ 8 - 4
drivers/cam_icp/icp_hw/ofe_hw/ofe_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/io.h>
@@ -26,12 +26,16 @@ static int cam_ofe_get_dt_properties(struct cam_hw_soc_info *soc_info)
 
 static int cam_ofe_request_platform_resource(
 	struct cam_hw_soc_info *soc_info,
-	irq_handler_t ofe_irq_handler, void *irq_data)
+	irq_handler_t ofe_irq_handler, void *data)
 {
-	int rc = 0;
+	int rc = 0, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
+
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
 
 	rc = cam_soc_util_request_platform_resource(soc_info,
-		ofe_irq_handler, irq_data);
+		ofe_irq_handler, &(irq_data[0]));
 
 	return rc;
 }

+ 7 - 4
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c

@@ -50,12 +50,15 @@ static int cam_ife_csid_get_dt_properties(struct cam_hw_soc_info *soc_info)
 static int cam_ife_csid_request_platform_resource(
 	struct cam_hw_soc_info *soc_info,
 	irq_handler_t csid_irq_handler,
-	void *irq_data)
+	void *data)
 {
-	int rc = 0;
+	int rc = 0, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
+
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
 
-	rc = cam_soc_util_request_platform_resource(soc_info, csid_irq_handler,
-		irq_data);
+	rc = cam_soc_util_request_platform_resource(soc_info, csid_irq_handler, &(irq_data[0]));
 	if (rc)
 		return rc;
 

+ 8 - 5
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/iopoll.h>
@@ -276,9 +276,10 @@ err:
 }
 
 int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info,
-	irq_handler_t ppi_irq_handler, void *irq_data)
+	irq_handler_t ppi_irq_handler, void *data)
 {
-	int rc = 0;
+	int rc = 0, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	rc = cam_soc_util_get_dt_properties(soc_info);
 	if (rc) {
@@ -286,8 +287,10 @@ int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info,
 		goto end;
 	}
 
-	rc = cam_soc_util_request_platform_resource(soc_info, ppi_irq_handler,
-		irq_data);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
+
+	rc = cam_soc_util_request_platform_resource(soc_info, ppi_irq_handler, &(irq_data[0]));
 	if (rc) {
 		CAM_ERR(CAM_ISP,
 			"PPI: Error Request platform resources failed rc=%d",

+ 8 - 5
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/cam_sfe_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -49,12 +49,15 @@ end:
 
 static int cam_sfe_request_platform_resource(
 	struct cam_hw_soc_info *soc_info,
-	irq_handler_t irq_handler_func, void *irq_data)
+	irq_handler_t irq_handler_func, void *data)
 {
-	int rc = 0;
+	int rc = 0, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
+
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
 
-	rc = cam_soc_util_request_platform_resource(soc_info, irq_handler_func,
-		irq_data);
+	rc = cam_soc_util_request_platform_resource(soc_info, irq_handler_func, &(irq_data[0]));
 	if (rc)
 		CAM_ERR(CAM_SFE,
 			"Error Request platform resource failed rc=%d", rc);

+ 8 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 #include <linux/slab.h>
 #include "cam_tfe_csid_soc.h"
@@ -10,11 +10,12 @@
 
 
 int cam_tfe_csid_init_soc_resources(struct cam_hw_soc_info *soc_info,
-	irq_handler_t csid_irq_handler, void *irq_data)
+	irq_handler_t csid_irq_handler, void *data)
 {
-	int rc = 0;
+	int rc = 0, i;
 	struct cam_cpas_register_params   cpas_register_param;
 	struct cam_tfe_csid_soc_private      *soc_private;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	soc_private = kzalloc(sizeof(struct cam_tfe_csid_soc_private),
 		GFP_KERNEL);
@@ -28,10 +29,11 @@ int cam_tfe_csid_init_soc_resources(struct cam_hw_soc_info *soc_info,
 	if (rc < 0)
 		return rc;
 
-	/* Need to see if we want post process the clock list */
-	rc = cam_soc_util_request_platform_resource(soc_info, csid_irq_handler,
-		irq_data);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
 
+	/* Need to see if we want post process the clock list */
+	rc = cam_soc_util_request_platform_resource(soc_info, csid_irq_handler, &(irq_data[0]));
 	if (rc < 0) {
 		CAM_ERR(CAM_ISP,
 			"Error Request platform resources failed rc=%d", rc);

+ 6 - 4
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -24,11 +24,12 @@ static bool cam_tfe_cpas_cb(uint32_t client_handle, void *userdata,
 }
 
 int cam_tfe_init_soc_resources(struct cam_hw_soc_info *soc_info,
-	irq_handler_t tfe_irq_handler, void *irq_data)
+	irq_handler_t tfe_irq_handler, void *data)
 {
 	struct cam_tfe_soc_private       *soc_private;
 	struct cam_cpas_register_params   cpas_register_param;
 	int    rc = 0,  i = 0, num_pid = 0;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	soc_private = kzalloc(sizeof(struct cam_tfe_soc_private),
 		GFP_KERNEL);
@@ -70,9 +71,10 @@ clk_option:
 	if (rc)
 		CAM_WARN(CAM_ISP, "Option clk get failed with rc %d", rc);
 
-	rc = cam_soc_util_request_platform_resource(soc_info, tfe_irq_handler,
-		irq_data);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
 
+	rc = cam_soc_util_request_platform_resource(soc_info, tfe_irq_handler, &(irq_data[0]));
 	if (rc < 0) {
 		CAM_ERR(CAM_ISP,
 			"Error! Request platform resources failed rc=%d", rc);

+ 8 - 5
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -114,12 +114,15 @@ end:
 
 static int cam_vfe_request_platform_resource(
 	struct cam_hw_soc_info *soc_info,
-	irq_handler_t vfe_irq_handler, void *irq_data)
+	irq_handler_t vfe_irq_handler, void *data)
 {
-	int rc = 0;
+	int rc = 0, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
-	rc = cam_soc_util_request_platform_resource(soc_info, vfe_irq_handler,
-		irq_data);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
+
+	rc = cam_soc_util_request_platform_resource(soc_info, vfe_irq_handler, &(irq_data[0]));
 	if (rc)
 		CAM_ERR(CAM_ISP,
 			"Error! Request platform resource failed rc=%d", rc);

+ 7 - 4
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/io.h>
@@ -15,12 +15,13 @@
 #include "cam_debug_util.h"
 
 int cam_jpeg_dma_init_soc_resources(struct cam_hw_soc_info *soc_info,
-	irq_handler_t jpeg_dma_irq_handler, void *irq_data)
+	irq_handler_t jpeg_dma_irq_handler, void *data)
 {
 	struct cam_jpeg_dma_soc_private  *soc_private;
 	struct platform_device *pdev = NULL;
 	int num_pid = 0, i = 0;
 	int rc;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	soc_private = kzalloc(sizeof(struct cam_jpeg_dma_soc_private),
 		GFP_KERNEL);
@@ -35,9 +36,11 @@ int cam_jpeg_dma_init_soc_resources(struct cam_hw_soc_info *soc_info,
 	if (rc)
 		return rc;
 
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
+
 	rc = cam_soc_util_request_platform_resource(soc_info,
-		jpeg_dma_irq_handler,
-		irq_data);
+		jpeg_dma_irq_handler, &(irq_data[0]));
 	if (rc)
 		CAM_ERR(CAM_JPEG, "init soc failed %d", rc);
 

+ 7 - 4
drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/io.h>
@@ -15,12 +15,13 @@
 #include "cam_debug_util.h"
 
 int cam_jpeg_enc_init_soc_resources(struct cam_hw_soc_info *soc_info,
-	irq_handler_t jpeg_enc_irq_handler, void *irq_data)
+	irq_handler_t jpeg_enc_irq_handler, void *data)
 {
 	struct cam_jpeg_enc_soc_private  *soc_private;
 	struct platform_device *pdev = NULL;
 	int num_pid = 0, i = 0;
 	int rc;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	soc_private = kzalloc(sizeof(struct cam_jpeg_enc_soc_private),
 		GFP_KERNEL);
@@ -34,9 +35,11 @@ int cam_jpeg_enc_init_soc_resources(struct cam_hw_soc_info *soc_info,
 	if (rc)
 		return rc;
 
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
+
 	rc = cam_soc_util_request_platform_resource(soc_info,
-		jpeg_enc_irq_handler,
-		irq_data);
+		jpeg_enc_irq_handler, &(irq_data[0]));
 	if (rc)
 		CAM_ERR(CAM_JPEG, "init soc failed %d", rc);
 

+ 7 - 4
drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/device.h>
@@ -90,7 +90,8 @@ int cam_lrme_soc_init_resources(struct cam_hw_soc_info *soc_info,
 {
 	struct cam_lrme_soc_private *soc_private;
 	struct cam_cpas_register_params cpas_register_param;
-	int rc;
+	int rc, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	rc = cam_soc_util_get_dt_properties(soc_info);
 	if (rc) {
@@ -98,8 +99,10 @@ int cam_lrme_soc_init_resources(struct cam_hw_soc_info *soc_info,
 		return rc;
 	}
 
-	rc = cam_soc_util_request_platform_resource(soc_info, irq_handler,
-		private_data);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = private_data;
+
+	rc = cam_soc_util_request_platform_resource(soc_info, irq_handler, &(irq_data[0]));
 	if (rc) {
 		CAM_ERR(CAM_LRME, "Failed in request_platform_resource rc=%d",
 			rc);

+ 8 - 5
drivers/cam_ope/ope_hw_mgr/ope_hw/ope_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/io.h>
@@ -42,12 +42,15 @@ static int cam_ope_get_dt_properties(struct cam_hw_soc_info *soc_info)
 
 static int cam_ope_request_platform_resource(
 	struct cam_hw_soc_info *soc_info,
-	irq_handler_t ope_irq_handler, void *irq_data)
+	irq_handler_t ope_irq_handler, void *data)
 {
-	int rc = 0;
+	int rc = 0, i;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
-	rc = cam_soc_util_request_platform_resource(soc_info, ope_irq_handler,
-		irq_data);
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = data;
+
+	rc = cam_soc_util_request_platform_resource(soc_info, ope_irq_handler, &(irq_data[0]));
 
 	return rc;
 }

+ 2 - 2
drivers/cam_sensor_module/cam_cci/cam_cci_dev.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "cam_cci_dev.h"
@@ -383,7 +383,7 @@ static int cam_cci_irq_routine(struct v4l2_subdev *sd, u32 status,
 	struct cam_hw_soc_info *soc_info =
 		&cci_dev->soc_info;
 
-	ret = cam_cci_irq(soc_info->irq_num, cci_dev);
+	ret = cam_cci_irq(soc_info->irq_num[0], cci_dev);
 	*handled = true;
 	return 0;
 }

+ 6 - 2
drivers/cam_sensor_module/cam_cci/cam_cci_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "cam_cci_dev.h"
@@ -389,6 +389,7 @@ int cam_cci_parse_dt_info(struct platform_device *pdev,
 	int rc = 0, i = 0;
 	struct cam_hw_soc_info *soc_info =
 		&new_cci_dev->soc_info;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	rc = cam_soc_util_get_dt_properties(soc_info);
 	if (rc < 0) {
@@ -398,8 +399,11 @@ int cam_cci_parse_dt_info(struct platform_device *pdev,
 
 	new_cci_dev->ref_count = 0;
 
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = new_cci_dev;
+
 	rc = cam_soc_util_request_platform_resource(soc_info,
-		cam_cci_irq, new_cci_dev);
+		cam_cci_irq, &(irq_data[0]));
 	if (rc < 0) {
 		CAM_ERR(CAM_CCI, "requesting platform resources failed:%d", rc);
 		return -EINVAL;

+ 6 - 2
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "cam_csiphy_soc.h"
@@ -279,6 +279,7 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
 	char      *csi_3p_clk_name = "csi_phy_3p_clk";
 	char      *csi_3p_clk_src_name = "csiphy_3p_clk_src";
 	struct cam_hw_soc_info   *soc_info;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	soc_info = &csiphy_dev->soc_info;
 
@@ -368,8 +369,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
 	csiphy_dev->csiphy_max_clk =
 		soc_info->clk_rate[0][soc_info->src_clk_idx];
 
+	for (i = 0; i < soc_info->irq_count; i++)
+		irq_data[i] = csiphy_dev;
+
 	rc = cam_soc_util_request_platform_resource(&csiphy_dev->soc_info,
-		cam_csiphy_irq, csiphy_dev);
+		cam_csiphy_irq, &(irq_data[0]));
 
 	return rc;
 }

+ 7 - 5
drivers/cam_sensor_module/cam_tpg/cam_tpg_dev.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "cam_tpg_dev.h"
@@ -167,9 +167,10 @@ static int tpg_subdev_init(struct cam_tpg_device *tpg_dev,
 static int tpg_soc_info_init(struct cam_tpg_device *tpg_dev,
 		struct device *dev)
 {
-	int32_t rc = 0;
+	int32_t rc = 0, i;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *of_node = NULL;
+	void *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV] = {0};
 
 	if (!dev || !tpg_dev)
 		return -EINVAL;
@@ -193,10 +194,11 @@ static int tpg_soc_info_init(struct cam_tpg_device *tpg_dev,
 		return rc;
 	}
 
+	for (i = 0; i < tpg_dev->soc_info.irq_count; i++)
+		irq_data[i] = tpg_dev;
+
 	rc = cam_soc_util_request_platform_resource(
-			&tpg_dev->soc_info,
-			cam_tpg_irq_handler,
-			tpg_dev);
+		&tpg_dev->soc_info, cam_tpg_irq_handler, &(irq_data[0]));
 	if (rc)
 		CAM_ERR(CAM_TPG, "unable to request platfrom resources");
 	else

+ 14 - 11
drivers/cam_utils/cam_compat.c

@@ -683,9 +683,9 @@ int cam_compat_util_get_irq(struct cam_hw_soc_info *soc_info)
 {
 	int rc = 0;
 
-	soc_info->irq_num = platform_get_irq(soc_info->pdev, 0);
-	if (soc_info->irq_num < 0) {
-		rc = soc_info->irq_num;
+	soc_info->irq_num[0] = platform_get_irq(soc_info->pdev, 0);
+	if (soc_info->irq_num[0] < 0) {
+		rc = soc_info->irq_num[0];
 		return rc;
 	}
 
@@ -734,16 +734,19 @@ int cam_eeprom_spi_driver_remove(struct spi_device *sdev)
 
 int cam_compat_util_get_irq(struct cam_hw_soc_info *soc_info)
 {
-	int rc = 0;
+	int rc = 0, i;
 
-	soc_info->irq_line =
-		platform_get_resource_byname(soc_info->pdev,
-		IORESOURCE_IRQ, soc_info->irq_name);
-	if (!soc_info->irq_line) {
-		rc = -ENODEV;
-		return rc;
+	for (i = 0; i < soc_info->irq_count; i++) {
+		soc_info->irq_line[i] = platform_get_resource_byname(soc_info->pdev,
+			IORESOURCE_IRQ, soc_info->irq_name[i]);
+		if (!soc_info->irq_line[i]) {
+			CAM_ERR(CAM_UTIL, "Failed to get IRQ line for irq: %s of %s",
+				soc_info->irq_name[i], soc_info->dev_name);
+			rc = -ENODEV;
+			return rc;
+		}
+		soc_info->irq_num[i] = soc_info->irq_line[i]->start;
 	}
-	soc_info->irq_num = soc_info->irq_line->start;
 
 	return rc;
 }

+ 125 - 69
drivers/cam_utils/cam_soc_util.c

@@ -966,36 +966,54 @@ static int cam_soc_util_get_clk_level_to_apply(
 
 int cam_soc_util_irq_enable(struct cam_hw_soc_info *soc_info)
 {
+	int i, rc = 0;
+
 	if (!soc_info) {
 		CAM_ERR(CAM_UTIL, "Invalid arguments");
 		return -EINVAL;
 	}
 
-	if (soc_info->irq_num < 0) {
-		CAM_ERR(CAM_UTIL, "No IRQ line available");
-		return -ENODEV;
+	for (i = 0; i < soc_info->irq_count; i++) {
+		if (soc_info->irq_num[i] < 0) {
+			CAM_ERR(CAM_UTIL, "No IRQ line available for irq: %s dev: %s",
+				soc_info->irq_name[i], soc_info->dev_name);
+			rc = -ENODEV;
+			goto disable_irq;
+		}
+
+		enable_irq(soc_info->irq_num[i]);
 	}
 
-	enable_irq(soc_info->irq_num);
+	return rc;
+
+disable_irq:
+	for (i = i - 1; i >= 0; i--)
+		disable_irq(soc_info->irq_num[i]);
 
-	return 0;
+	return rc;
 }
 
 int cam_soc_util_irq_disable(struct cam_hw_soc_info *soc_info)
 {
+	int i, rc = 0;
+
 	if (!soc_info) {
 		CAM_ERR(CAM_UTIL, "Invalid arguments");
 		return -EINVAL;
 	}
 
-	if (soc_info->irq_num < 0) {
-		CAM_ERR(CAM_UTIL, "No IRQ line available");
-		return -ENODEV;
-	}
+	for (i = 0; i < soc_info->irq_count; i++) {
+		if (soc_info->irq_num[i] < 0) {
+			CAM_ERR(CAM_UTIL, "No IRQ line available irq: %s dev:",
+				soc_info->irq_name[i], soc_info->dev_name);
+			rc = -ENODEV;
+			continue;
+		}
 
-	disable_irq(soc_info->irq_num);
+		disable_irq(soc_info->irq_num[i]);
+	}
 
-	return 0;
+	return rc;
 }
 
 long cam_soc_util_get_clk_round_rate(struct cam_hw_soc_info *soc_info,
@@ -2084,10 +2102,8 @@ static int cam_soc_util_get_gpio_info(struct cam_hw_soc_info *soc_info)
 	CAM_DBG(CAM_UTIL, "gpio count %d", gpio_array_size);
 
 	gpio_array = kcalloc(gpio_array_size, sizeof(uint16_t), GFP_KERNEL);
-	if (!gpio_array) {
-		rc = -ENOMEM;
-		goto err;
-	}
+	if (!gpio_array)
+		goto free_gpio_conf;
 
 	for (i = 0; i < gpio_array_size; i++) {
 		gpio_array[i] = of_get_gpio(of_node, i);
@@ -2095,23 +2111,21 @@ static int cam_soc_util_get_gpio_info(struct cam_hw_soc_info *soc_info)
 	}
 
 	gconf = kzalloc(sizeof(*gconf), GFP_KERNEL);
-	if (!gconf) {
-		rc = -ENOMEM;
-		goto free_gpio_array;
-	}
+	if (!gconf)
+		return -ENOMEM;
 
 	rc = cam_soc_util_get_dt_gpio_req_tbl(of_node, gconf, gpio_array,
 		gpio_array_size);
 	if (rc) {
 		CAM_ERR(CAM_UTIL, "failed in msm_camera_get_dt_gpio_req_tbl");
-		goto free_gpio_conf;
+		goto free_gpio_array;
 	}
 
 	gconf->cam_gpio_common_tbl = kcalloc(gpio_array_size,
 				sizeof(struct gpio), GFP_KERNEL);
 	if (!gconf->cam_gpio_common_tbl) {
 		rc = -ENOMEM;
-		goto free_gpio_conf;
+		goto free_gpio_array;
 	}
 
 	for (i = 0; i < gpio_array_size; i++)
@@ -2123,12 +2137,12 @@ static int cam_soc_util_get_gpio_info(struct cam_hw_soc_info *soc_info)
 
 	return rc;
 
-free_gpio_conf:
-	kfree(gconf);
 free_gpio_array:
 	kfree(gpio_array);
-err:
+free_gpio_conf:
+	kfree(gconf);
 	soc_info->gpio_data = NULL;
+
 	return rc;
 }
 
@@ -2201,6 +2215,7 @@ static int cam_soc_util_get_dt_regulator_info
 	if (count != -EINVAL) {
 		if (count <= 0) {
 			CAM_ERR(CAM_UTIL, "no regulators found");
+			count = 0;
 			return -EINVAL;
 		}
 
@@ -2322,34 +2337,54 @@ int cam_soc_util_get_dt_properties(struct cam_hw_soc_info *soc_info)
 		}
 	}
 
-	rc = of_property_read_string_index(of_node, "interrupt-names", 0,
-		&soc_info->irq_name);
-	if (rc) {
-		CAM_DBG(CAM_UTIL, "No interrupt line preset for: %s",
-			soc_info->dev_name);
+	count = of_property_count_strings(of_node, "interrupt-names");
+	if (count <= 0) {
+		CAM_DBG(CAM_UTIL, "No interrupt line present for: %s", soc_info->dev_name);
+		soc_info->irq_count = 0;
 	} else {
+		if (count > CAM_SOC_MAX_IRQ_LINES_PER_DEV) {
+			CAM_ERR(CAM_UTIL,
+				"Number of interrupt: %d exceeds maximum allowable interrupts: %d",
+				count, CAM_SOC_MAX_IRQ_LINES_PER_DEV);
+			return -EINVAL;
+		}
+
+		soc_info->irq_count = count;
+		for (i = 0; i < soc_info->irq_count; i++) {
+			rc = of_property_read_string_index(of_node, "interrupt-names",
+				i, &soc_info->irq_name[i]);
+			if (rc) {
+				CAM_ERR(CAM_UTIL, "failed to read interrupt name at %d", i);
+				return rc;
+			}
+		}
+
 		rc = cam_compat_util_get_irq(soc_info);
 		if (rc < 0) {
-			CAM_ERR(CAM_UTIL, "get irq resource failed: %d", rc);
+			CAM_ERR(CAM_UTIL, "get irq resource failed: %d for: %s",
+				rc, soc_info->dev_name);
 #ifndef CONFIG_CAM_PRESIL
 			return rc;
 #else
 			/* Pre-sil for new devices not present on old */
-			soc_info->irq_line =
-				&dummy_irq_line[next_dummy_irq_line_num++];
-			CAM_DBG(CAM_PRESIL, "interrupt line for dev %s irq name %s number %d",
-				soc_info->dev_name, soc_info->irq_name,
-				soc_info->irq_line->start);
+			for (i = 0; i < soc_info->irq_count; i++) {
+				soc_info->irq_line[i] =
+					&dummy_irq_line[next_dummy_irq_line_num++];
+				CAM_DBG(CAM_PRESIL,
+					"interrupt line for dev %s irq name %s number %d",
+					soc_info->dev_name, soc_info->irq_name[i],
+					soc_info->irq_line[i]->start);
+			}
 #endif
 		}
 	}
 
-
 	rc = of_property_read_string_index(of_node, "compatible", 0,
 		(const char **)&soc_info->compatible);
 	if (rc) {
 		CAM_DBG(CAM_UTIL, "No compatible string present for: %s",
 			soc_info->dev_name);
+		rc = 0;
 	}
 
 	soc_info->is_nrt_dev = false;
@@ -2868,7 +2903,7 @@ int cam_soc_util_request_irq(struct device *dev,
 
 int cam_soc_util_request_platform_resource(
 	struct cam_hw_soc_info *soc_info,
-	irq_handler_t handler, void *irq_data)
+	irq_handler_t handler, void **irq_data)
 {
 	int i = 0, rc = 0;
 
@@ -2877,6 +2912,12 @@ int cam_soc_util_request_platform_resource(
 		return -EINVAL;
 	}
 
+	if (unlikely(soc_info->irq_count >= CAM_SOC_MAX_IRQ_LINES_PER_DEV)) {
+		CAM_ERR(CAM_UTIL, "Invalid irq count: %u Max IRQ per device: %d",
+			soc_info->irq_count, CAM_SOC_MAX_IRQ_LINES_PER_DEV);
+		return -EINVAL;
+	}
+
 	for (i = 0; i < soc_info->num_mem_block; i++) {
 
 		soc_info->reg_map[i].mem_base = cam_soc_util_get_mem_base(
@@ -2912,20 +2953,18 @@ int cam_soc_util_request_platform_resource(
 			goto put_regulator;
 	}
 
-	if (soc_info->irq_num > 0) {
-
-		rc = cam_soc_util_request_irq(soc_info->dev,
-			soc_info->irq_num,
-			handler, IRQF_TRIGGER_RISING,
-			soc_info->irq_name, irq_data,
-			soc_info->mem_block[0]->start);
+	for (i = 0; i < soc_info->irq_count; i++) {
+		rc = cam_soc_util_request_irq(soc_info->dev, soc_info->irq_num[i],
+			handler, IRQF_TRIGGER_RISING, soc_info->irq_name[i],
+				irq_data[i], soc_info->mem_block[0]->start);
 		if (rc) {
-			CAM_ERR(CAM_UTIL, "irq request fail");
+			CAM_ERR(CAM_UTIL, "irq request fail for irq name: %s dev: %s",
+				soc_info->irq_name[i], soc_info->dev_name);
 			rc = -EBUSY;
-			goto put_regulator;
+			goto put_irq;
 		}
 
-		soc_info->irq_data = irq_data;
+		soc_info->irq_data[i] = irq_data[i];
 	}
 
 	/* Get Clock */
@@ -3019,10 +3058,12 @@ put_clk:
 		}
 	}
 
-	if (soc_info->irq_num > 0) {
-		disable_irq(soc_info->irq_num);
-		devm_free_irq(soc_info->dev,
-			soc_info->irq_num, irq_data);
+put_irq:
+	if (i == -1)
+		i = soc_info->irq_count;
+	for (i = i - 1; i >= 0; i--) {
+		if (soc_info->irq_num[i] > 0)
+			disable_irq(soc_info->irq_num[i]);
 	}
 
 put_regulator:
@@ -3092,19 +3133,22 @@ int cam_soc_util_release_platform_resource(struct cam_hw_soc_info *soc_info)
 		soc_info->reg_map[i].size = 0;
 	}
 
-	if (soc_info->irq_num > 0) {
-		if (cam_presil_mode_enabled()) {
-			if (cam_soc_util_is_presil_address_space(soc_info->mem_block[0]->start)) {
-				b_ret = cam_presil_unsubscribe_device_irq(
-					soc_info->irq_line->start);
-				CAM_DBG(CAM_PRESIL, "UnSubscribe IRQ: Ret=%d NUM=%d Name=%s",
-					b_ret, soc_info->irq_line->start, soc_info->irq_name);
+	for (i = soc_info->irq_count; i >= 0; i--) {
+		if (soc_info->irq_num[i] > 0) {
+			if (cam_presil_mode_enabled()) {
+				if (cam_soc_util_is_presil_address_space(
+					soc_info->mem_block[0]->start)) {
+					b_ret = cam_presil_unsubscribe_device_irq(
+						soc_info->irq_line[i]->start);
+					CAM_DBG(CAM_PRESIL,
+						"UnSubscribe IRQ: Ret=%d NUM=%d Name=%s",
+						b_ret, soc_info->irq_line[i]->start,
+						soc_info->irq_name[i]);
+				}
 			}
-		}
 
-		disable_irq(soc_info->irq_num);
-		devm_free_irq(soc_info->dev,
-			soc_info->irq_num, soc_info->irq_data);
+			disable_irq(soc_info->irq_num[i]);
+		}
 	}
 
 	cam_soc_util_release_pinctrl(soc_info);
@@ -3119,9 +3163,9 @@ int cam_soc_util_release_platform_resource(struct cam_hw_soc_info *soc_info)
 
 int cam_soc_util_enable_platform_resource(struct cam_hw_soc_info *soc_info,
 	int cesta_client_idx, bool enable_clocks, enum cam_vote_level clk_level,
-	bool enable_irq)
+	bool irq_enable)
 {
-	int rc = 0;
+	int rc = 0, i;
 
 	if (!soc_info)
 		return -EINVAL;
@@ -3138,15 +3182,27 @@ int cam_soc_util_enable_platform_resource(struct cam_hw_soc_info *soc_info,
 			goto disable_regulator;
 	}
 
-	if (enable_irq) {
-		rc  = cam_soc_util_irq_enable(soc_info);
-		if (rc)
-			goto disable_clk;
+	if (irq_enable) {
+		for (i = 0; i < soc_info->irq_count; i++) {
+			if (soc_info->irq_num[i] < 0) {
+				CAM_ERR(CAM_UTIL, "No IRQ line available for irq: %s dev: %s",
+					soc_info->irq_name[i], soc_info->dev_name);
+				rc = -ENODEV;
+				goto disable_irq;
+			}
+
+			enable_irq(soc_info->irq_num[i]);
+		}
 	}
 
 	return rc;
 
-disable_clk:
+disable_irq:
+	if (irq_enable) {
+		for (i = i - 1; i >= 0; i--)
+			disable_irq(soc_info->irq_num[i]);
+	}
+
 	if (enable_clocks)
 		cam_soc_util_clk_disable_default(soc_info, cesta_client_idx);
 

+ 17 - 12
drivers/cam_utils/cam_soc_util.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_SOC_UTIL_H_
@@ -48,6 +48,9 @@
 /* maximum number of pinctrl mapping */
 #define CAM_SOC_MAX_PINCTRL_MAP     2
 
+/* maximum number of irq per device */
+#define CAM_SOC_MAX_IRQ_LINES_PER_DEV 2
+
 /* DDR device types */
 #define DDR_TYPE_LPDDR4        6
 #define DDR_TYPE_LPDDR4X       7
@@ -178,11 +181,12 @@ struct cam_soc_gpio_data {
  * @index:                  Instance id for the camera device
  * @dev_name:               Device Name
  * @is_nrt_dev:             Whether this is a non-real time device
- * @irq_name:               Name of the irq associated with the device
+ * @irq_name:               Array of irq name associated with the device
  * @label_name:             label name
- * @irq_line:               Irq resource
- * @irq_num:                Irq number
- * @irq_data:               Private data that is passed when IRQ is requested
+ * @irq_line:               Array of Irq resources
+ * @irq_num:                Array of Irq numbers
+ * @irq_data:               Array of Irq Private data that are passed when IRQs are requested
+ * @irq_count:              The number of IRQ lines associated with the device
  * @compatible:             Compatible string associated with the device
  * @num_mem_block:          Number of entry in the "reg-names"
  * @mem_block_name:         Array of the reg block name
@@ -247,11 +251,12 @@ struct cam_hw_soc_info {
 	uint32_t                        index;
 	const char                     *dev_name;
 	bool                            is_nrt_dev;
-	const char                     *irq_name;
+	const char                     *irq_name[CAM_SOC_MAX_IRQ_LINES_PER_DEV];
 	const char                     *label_name;
-	struct resource                *irq_line;
-	int                             irq_num;
-	void                           *irq_data;
+	struct resource                *irq_line[CAM_SOC_MAX_IRQ_LINES_PER_DEV];
+	int                             irq_num[CAM_SOC_MAX_IRQ_LINES_PER_DEV];
+	void                           *irq_data[CAM_SOC_MAX_IRQ_LINES_PER_DEV];
+	uint32_t                        irq_count;
 	const char                     *compatible;
 
 	uint32_t                        num_mem_block;
@@ -425,7 +430,7 @@ int cam_soc_util_get_dt_properties(struct cam_hw_soc_info *soc_info);
  * @return:             Success or failure
  */
 int cam_soc_util_request_platform_resource(struct cam_hw_soc_info *soc_info,
-	irq_handler_t handler, void *irq_data);
+	irq_handler_t handler, void **irq_data);
 
 /**
  * cam_soc_util_release_platform_resource()
@@ -452,7 +457,7 @@ int cam_soc_util_release_platform_resource(struct cam_hw_soc_info *soc_info);
  * @clk_level:          Clock level to be applied.
  *                      Applicable only if enable_clocks is true
  *                          Valid range : 0 to (CAM_MAX_VOTE - 1)
- * @enable_irq:         Boolean flag:
+ * @irq_enable:         Boolean flag:
  *                          TRUE: Enable IRQ in soc_info Now.
  *                          False: Don't enable IRQ Now. Driver will
  *                                 enable independently.
@@ -461,7 +466,7 @@ int cam_soc_util_release_platform_resource(struct cam_hw_soc_info *soc_info);
  */
 int cam_soc_util_enable_platform_resource(struct cam_hw_soc_info *soc_info,
 	int cesta_client_idx, bool enable_clocks, enum cam_vote_level clk_level,
-	bool enable_irq);
+	bool irq_enable);
 
 /**
  * cam_soc_util_disable_platform_resource()