Browse Source

Merge "msm: camera: common: Add component helper support in camera" into camera-kernel.lnx.4.0

Camera Software Integration 5 years ago
parent
commit
ba20c111ed
44 changed files with 1817 additions and 606 deletions
  1. 36 10
      drivers/cam_cdm/cam_cdm_hw_core.c
  2. 33 7
      drivers/cam_cdm/cam_cdm_intf.c
  3. 32 7
      drivers/cam_cpas/cam_cpas_intf.c
  4. 51 26
      drivers/cam_cust/cam_custom_dev.c
  5. 40 12
      drivers/cam_cust/cam_custom_hw_mgr/cam_custom_csid/cam_custom_csid_dev.c
  6. 35 7
      drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw1/cam_custom_sub_mod_dev.c
  7. 31 6
      drivers/cam_fd/cam_fd_dev.c
  8. 33 8
      drivers/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c
  9. 35 8
      drivers/cam_icp/cam_icp_subdev.c
  10. 33 4
      drivers/cam_icp/icp_hw/a5_hw/a5_dev.c
  11. 32 4
      drivers/cam_icp/icp_hw/bps_hw/bps_dev.c
  12. 34 5
      drivers/cam_icp/icp_hw/ipe_hw/ipe_dev.c
  13. 49 24
      drivers/cam_isp/cam_isp_dev.c
  14. 2 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid17x.c
  15. 33 7
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.c
  16. 2 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite17x.c
  17. 2 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.c
  18. 2 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe.c
  19. 37 13
      drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_dev.c
  20. 32 9
      drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_dev.c
  21. 2 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_v1.c
  22. 40 15
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.c
  23. 3 2
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe.c
  24. 49 23
      drivers/cam_jpeg/cam_jpeg_dev.c
  25. 80 51
      drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c
  26. 77 50
      drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c
  27. 31 6
      drivers/cam_lrme/cam_lrme_dev.c
  28. 32 6
      drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_dev.c
  29. 37 10
      drivers/cam_ope/cam_ope_subdev.c
  30. 32 3
      drivers/cam_ope/ope_hw_mgr/ope_hw/ope_dev.c
  31. 72 19
      drivers/cam_req_mgr/cam_req_mgr_dev.c
  32. 108 81
      drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.c
  33. 33 4
      drivers/cam_sensor_module/cam_cci/cam_cci_dev.c
  34. 0 4
      drivers/cam_sensor_module/cam_cci/cam_cci_soc.c
  35. 39 12
      drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c
  36. 33 6
      drivers/cam_sensor_module/cam_eeprom/cam_eeprom_dev.c
  37. 53 27
      drivers/cam_sensor_module/cam_flash/cam_flash_dev.c
  38. 33 7
      drivers/cam_sensor_module/cam_ois/cam_ois_dev.c
  39. 30 4
      drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c
  40. 92 65
      drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.c
  41. 151 46
      drivers/cam_smmu/cam_smmu_api.c
  42. 30 3
      drivers/cam_sync/cam_sync.c
  43. 105 0
      drivers/camera_main.c
  44. 71 0
      drivers/camera_main.h

+ 36 - 10
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -22,6 +22,7 @@
 #include "cam_cdm_hw_reg_1_1.h"
 #include "cam_cdm_hw_reg_1_2.h"
 #include "cam_cdm_hw_reg_2_0.h"
+#include "camera_main.h"
 
 #define CAM_CDM_BL_FIFO_WAIT_TIMEOUT 2000
 #define CAM_CDM_DBG_GEN_IRQ_USR_DATA 0xff
@@ -1571,7 +1572,8 @@ int cam_hw_cdm_deinit(void *hw_priv,
 	return rc;
 }
 
-int cam_hw_cdm_probe(struct platform_device *pdev)
+static int cam_hw_cdm_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc, len = 0, i, j;
 	struct cam_hw_info *cdm_hw = NULL;
@@ -1582,6 +1584,7 @@ int cam_hw_cdm_probe(struct platform_device *pdev)
 	struct cam_ahb_vote ahb_vote;
 	struct cam_axi_vote axi_vote = {0};
 	char cdm_name[128], work_q_name[128];
+	struct platform_device *pdev = to_platform_device(dev);
 
 	cdm_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
 	if (!cdm_hw_intf)
@@ -1794,7 +1797,7 @@ int cam_hw_cdm_probe(struct platform_device *pdev)
 	cdm_hw->open_count--;
 	mutex_unlock(&cdm_hw->hw_mutex);
 
-	CAM_DBG(CAM_CDM, "%s probe successful", cdm_core->name);
+	CAM_DBG(CAM_CDM, "%s component bound successfully", cdm_core->name);
 
 	return rc;
 
@@ -1833,17 +1836,19 @@ release_mem:
 	return rc;
 }
 
-int cam_hw_cdm_remove(struct platform_device *pdev)
+static void cam_hw_cdm_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc = -EBUSY, i;
 	struct cam_hw_info *cdm_hw = NULL;
 	struct cam_hw_intf *cdm_hw_intf = NULL;
 	struct cam_cdm *cdm_core = NULL;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	cdm_hw_intf = platform_get_drvdata(pdev);
 	if (!cdm_hw_intf) {
 		CAM_ERR(CAM_CDM, "Failed to get dev private data");
-		return rc;
+		return;
 	}
 
 	cdm_hw = cdm_hw_intf->hw_priv;
@@ -1851,7 +1856,7 @@ int cam_hw_cdm_remove(struct platform_device *pdev)
 		CAM_ERR(CAM_CDM,
 			"Failed to get hw private data for type=%d idx=%d",
 			cdm_hw_intf->hw_type, cdm_hw_intf->hw_idx);
-		return rc;
+		return;
 	}
 
 	cdm_core = cdm_hw->core_info;
@@ -1859,26 +1864,26 @@ int cam_hw_cdm_remove(struct platform_device *pdev)
 		CAM_ERR(CAM_CDM,
 			"Failed to get hw core data for type=%d idx=%d",
 			cdm_hw_intf->hw_type, cdm_hw_intf->hw_idx);
-		return rc;
+		return;
 	}
 
 	if (cdm_hw->open_count != 0) {
 		CAM_ERR(CAM_CDM, "Hw open count invalid type=%d idx=%d cnt=%d",
 			cdm_hw_intf->hw_type, cdm_hw_intf->hw_idx,
 			cdm_hw->open_count);
-		return rc;
+		return;
 	}
 
 	rc = cam_hw_cdm_deinit(cdm_hw, NULL, 0);
 	if (rc) {
 		CAM_ERR(CAM_CDM, "Deinit failed for hw");
-		return rc;
+		return;
 	}
 
 	rc = cam_cpas_unregister_client(cdm_core->cpas_handle);
 	if (rc) {
 		CAM_ERR(CAM_CDM, "CPAS unregister failed");
-		return rc;
+		return;
 	}
 
 	if (cam_soc_util_release_platform_resource(&cdm_hw->soc_info))
@@ -1899,11 +1904,32 @@ int cam_hw_cdm_remove(struct platform_device *pdev)
 	kfree(cdm_hw_intf);
 	kfree(cdm_hw->core_info);
 	kfree(cdm_hw);
+}
+
+const static struct component_ops cam_hw_cdm_component_ops = {
+	.bind = cam_hw_cdm_component_bind,
+	.unbind = cam_hw_cdm_component_unbind,
+};
 
+int cam_hw_cdm_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_CDM, "Adding HW CDM component");
+	rc = component_add(&pdev->dev, &cam_hw_cdm_component_ops);
+	if (rc)
+		CAM_ERR(CAM_CDM, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+int cam_hw_cdm_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_hw_cdm_component_ops);
 	return 0;
 }
 
-static struct platform_driver cam_hw_cdm_driver = {
+struct platform_driver cam_hw_cdm_driver = {
 	.probe = cam_hw_cdm_probe,
 	.remove = cam_hw_cdm_remove,
 	.driver = {

+ 33 - 7
drivers/cam_cdm/cam_cdm_intf.c

@@ -16,6 +16,7 @@
 #include "cam_soc_util.h"
 #include "cam_cdm_soc.h"
 #include "cam_cdm_core_common.h"
+#include "camera_main.h"
 
 static struct cam_cdm_intf_mgr cdm_mgr;
 static DEFINE_MUTEX(cam_cdm_mgr_lock);
@@ -563,9 +564,11 @@ int cam_cdm_intf_deregister_hw_cdm(struct cam_hw_intf *hw,
 	return rc;
 }
 
-static int cam_cdm_intf_probe(struct platform_device *pdev)
+static int cam_cdm_intf_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int i, rc;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	rc = cam_cdm_intf_mgr_soc_get_dt_properties(pdev, &cdm_mgr);
 	if (rc) {
@@ -599,18 +602,20 @@ static int cam_cdm_intf_probe(struct platform_device *pdev)
 		mutex_unlock(&cam_cdm_mgr_lock);
 	}
 
-	CAM_DBG(CAM_CDM, "CDM Intf probe done");
+	CAM_DBG(CAM_CDM, "CDM Intf component bound successfully");
 
 	return rc;
 }
 
-static int cam_cdm_intf_remove(struct platform_device *pdev)
+static void cam_cdm_intf_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
-	int i, rc = -EBUSY;
+	int i;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	if (get_cdm_mgr_refcount()) {
 		CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
-		return rc;
+		return;
 	}
 
 	if (cam_virtual_cdm_remove(pdev)) {
@@ -639,14 +644,35 @@ static int cam_cdm_intf_remove(struct platform_device *pdev)
 		cdm_mgr.nodes[i].refcount = 0;
 	}
 	cdm_mgr.probe_done = false;
-	rc = 0;
 
 end:
 	mutex_unlock(&cam_cdm_mgr_lock);
+}
+
+const static struct component_ops cam_cdm_intf_component_ops = {
+	.bind = cam_cdm_intf_component_bind,
+	.unbind = cam_cdm_intf_component_unbind,
+};
+
+static int cam_cdm_intf_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_CDM, "Adding CDM INTF component");
+	rc = component_add(&pdev->dev, &cam_cdm_intf_component_ops);
+	if (rc)
+		CAM_ERR(CAM_CDM, "failed to add component rc: %d", rc);
+
 	return rc;
 }
 
-static struct platform_driver cam_cdm_intf_driver = {
+static int cam_cdm_intf_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_cdm_intf_component_ops);
+	return 0;
+}
+
+struct platform_driver cam_cdm_intf_driver = {
 	.probe = cam_cdm_intf_probe,
 	.remove = cam_cdm_intf_remove,
 	.driver = {

+ 32 - 7
drivers/cam_cpas/cam_cpas_intf.c

@@ -17,6 +17,7 @@
 #include "cam_subdev.h"
 #include "cam_cpas_hw_intf.h"
 #include "cam_cpas_soc.h"
+#include "camera_main.h"
 
 #define CAM_CPAS_DEV_NAME    "cam-cpas"
 #define CAM_CPAS_INTF_INITIALIZED() (g_cpas_intf && g_cpas_intf->probe_done)
@@ -651,14 +652,16 @@ static int cam_cpas_subdev_register(struct platform_device *pdev)
 	return rc;
 }
 
-static int cam_cpas_dev_probe(struct platform_device *pdev)
+static int cam_cpas_dev_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_cpas_hw_caps *hw_caps;
 	struct cam_hw_intf *hw_intf;
 	int rc;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	if (g_cpas_intf) {
-		CAM_ERR(CAM_CPAS, "cpas dev proble already done");
+		CAM_ERR(CAM_CPAS, "cpas component already binded");
 		return -EALREADY;
 	}
 
@@ -695,7 +698,7 @@ static int cam_cpas_dev_probe(struct platform_device *pdev)
 
 	g_cpas_intf->probe_done = true;
 	CAM_DBG(CAM_CPAS,
-		"CPAS INTF Probe success %d, %d.%d.%d, %d.%d.%d, 0x%x",
+		"Component bound successfully %d, %d.%d.%d, %d.%d.%d, 0x%x",
 		hw_caps->camera_family, hw_caps->camera_version.major,
 		hw_caps->camera_version.minor, hw_caps->camera_version.incr,
 		hw_caps->cpas_version.major, hw_caps->cpas_version.minor,
@@ -709,15 +712,16 @@ error_destroy_mem:
 	mutex_destroy(&g_cpas_intf->intf_lock);
 	kfree(g_cpas_intf);
 	g_cpas_intf = NULL;
-	CAM_ERR(CAM_CPAS, "CPAS probe failed");
+	CAM_ERR(CAM_CPAS, "CPAS component bind failed");
 	return rc;
 }
 
-static int cam_cpas_dev_remove(struct platform_device *dev)
+static void cam_cpas_dev_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	if (!CAM_CPAS_INTF_INITIALIZED()) {
 		CAM_ERR(CAM_CPAS, "cpas intf not initialized");
-		return -ENODEV;
+		return;
 	}
 
 	mutex_lock(&g_cpas_intf->intf_lock);
@@ -728,7 +732,28 @@ static int cam_cpas_dev_remove(struct platform_device *dev)
 	mutex_destroy(&g_cpas_intf->intf_lock);
 	kfree(g_cpas_intf);
 	g_cpas_intf = NULL;
+}
+
+const static struct component_ops cam_cpas_dev_component_ops = {
+	.bind = cam_cpas_dev_component_bind,
+	.unbind = cam_cpas_dev_component_unbind,
+};
 
+static int cam_cpas_dev_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_CPAS, "Adding CPAS INTF component");
+	rc = component_add(&pdev->dev, &cam_cpas_dev_component_ops);
+	if (rc)
+		CAM_ERR(CAM_CPAS, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int cam_cpas_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_cpas_dev_component_ops);
 	return 0;
 }
 
@@ -737,7 +762,7 @@ static const struct of_device_id cam_cpas_dt_match[] = {
 	{}
 };
 
-static struct platform_driver cam_cpas_driver = {
+struct platform_driver cam_cpas_driver = {
 	.probe = cam_cpas_dev_probe,
 	.remove = cam_cpas_dev_remove,
 	.driver = {

+ 51 - 26
drivers/cam_cust/cam_custom_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/delay.h>
@@ -20,6 +20,7 @@
 #include "cam_node.h"
 #include "cam_debug_util.h"
 #include "cam_smmu_api.h"
+#include "camera_main.h"
 
 static struct cam_custom_dev g_custom_dev;
 
@@ -92,34 +93,15 @@ static const struct v4l2_subdev_internal_ops cam_custom_subdev_internal_ops = {
 	.open = cam_custom_subdev_open,
 };
 
-static int cam_custom_dev_remove(struct platform_device *pdev)
-{
-	int rc = 0;
-	int i;
-
-	/* clean up resources */
-	for (i = 0; i < CAM_CUSTOM_HW_MAX_INSTANCES; i++) {
-		rc = cam_custom_dev_context_deinit(&g_custom_dev.ctx_custom[i]);
-		if (rc)
-			CAM_ERR(CAM_CUSTOM,
-				"Custom context %d deinit failed", i);
-	}
-
-	rc = cam_subdev_remove(&g_custom_dev.sd);
-	if (rc)
-		CAM_ERR(CAM_CUSTOM, "Unregister failed");
-
-	memset(&g_custom_dev, 0, sizeof(g_custom_dev));
-	return 0;
-}
-
-static int cam_custom_dev_probe(struct platform_device *pdev)
+static int cam_custom_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc = -EINVAL;
 	int i;
 	struct cam_hw_mgr_intf         hw_mgr_intf;
-	struct cam_node               *node;
+	struct cam_node                *node;
 	int iommu_hdl = -1;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	g_custom_dev.sd.internal_ops = &cam_custom_subdev_internal_ops;
 
@@ -163,7 +145,7 @@ static int cam_custom_dev_probe(struct platform_device *pdev)
 
 	mutex_init(&g_custom_dev.custom_dev_mutex);
 
-	CAM_DBG(CAM_CUSTOM, "Camera custom HW probe complete");
+	CAM_DBG(CAM_CUSTOM, "%s component bound successfully", pdev->name);
 
 	return 0;
 unregister:
@@ -172,8 +154,51 @@ err:
 	return rc;
 }
 
+static void cam_custom_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	int rc = 0;
+	int i;
+
+	/* clean up resources */
+	for (i = 0; i < CAM_CUSTOM_HW_MAX_INSTANCES; i++) {
+		rc = cam_custom_dev_context_deinit(&g_custom_dev.ctx_custom[i]);
+		if (rc)
+			CAM_ERR(CAM_CUSTOM,
+				"Custom context %d deinit failed", i);
+	}
+
+	rc = cam_subdev_remove(&g_custom_dev.sd);
+	if (rc)
+		CAM_ERR(CAM_CUSTOM, "Unregister failed");
+
+	memset(&g_custom_dev, 0, sizeof(g_custom_dev));
+}
+
+const static struct component_ops cam_custom_component_ops = {
+	.bind = cam_custom_component_bind,
+	.unbind = cam_custom_component_unbind,
+};
+
+static int cam_custom_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_custom_component_ops);
+	return 0;
+}
+
+static int cam_custom_dev_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_CUSTOM, "Adding Custom HW component");
+	rc = component_add(&pdev->dev, &cam_custom_component_ops);
+	if (rc)
+		CAM_ERR(CAM_CUSTOM, "failed to add component rc: %d", rc);
+
+	return rc;
+}
 
-static struct platform_driver custom_driver = {
+struct platform_driver custom_driver = {
 	.probe = cam_custom_dev_probe,
 	.remove = cam_custom_dev_remove,
 	.driver = {

+ 40 - 12
drivers/cam_cust/cam_custom_hw_mgr/cam_custom_csid/cam_custom_csid_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -14,6 +14,7 @@
 #include "cam_hw_intf.h"
 #include "cam_custom_csid480.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 #define CAM_CUSTOM_CSID_DRV_NAME  "custom_csid"
 
@@ -27,16 +28,18 @@ static struct cam_ife_csid_hw_info cam_custom_csid480_hw_info = {
 	.hw_dts_version = CAM_CSID_VERSION_V480,
 };
 
-static int cam_custom_csid_probe(struct platform_device *pdev)
+static int cam_custom_csid_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 
-	struct cam_hw_intf             *csid_hw_intf;
-	struct cam_hw_info             *csid_hw_info;
-	struct cam_ife_csid_hw         *csid_dev = NULL;
+	struct cam_hw_intf	       *csid_hw_intf;
+	struct cam_hw_info	       *csid_hw_info;
+	struct cam_ife_csid_hw	       *csid_dev = NULL;
 	const struct of_device_id      *match_dev = NULL;
 	struct cam_ife_csid_hw_info    *csid_hw_data = NULL;
-	uint32_t                        csid_dev_idx;
-	int                             rc = 0;
+	uint32_t			csid_dev_idx;
+	int				rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	csid_hw_intf = kzalloc(sizeof(*csid_hw_intf), GFP_KERNEL);
 	if (!csid_hw_intf) {
@@ -90,14 +93,15 @@ static int cam_custom_csid_probe(struct platform_device *pdev)
 		goto free_dev;
 
 	platform_set_drvdata(pdev, csid_dev);
-	CAM_DBG(CAM_CUSTOM, "CSID:%d probe successful for dev %s",
-		csid_hw_intf->hw_idx, csid_dev_name);
 
 	if (csid_hw_intf->hw_idx < CAM_IFE_CSID_HW_NUM_MAX)
 		cam_custom_csid_hw_list[csid_hw_intf->hw_idx] = csid_hw_intf;
 	else
 		goto free_dev;
 
+	CAM_DBG(CAM_CUSTOM, "CSID:%d component bound successfully",
+		csid_hw_intf->hw_idx);
+
 	return 0;
 
 free_dev:
@@ -110,17 +114,19 @@ err:
 	return rc;
 }
 
-static int cam_custom_csid_remove(struct platform_device *pdev)
+static void cam_custom_csid_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_ife_csid_hw         *csid_dev = NULL;
 	struct cam_hw_intf             *csid_hw_intf;
 	struct cam_hw_info             *csid_hw_info;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	csid_dev = (struct cam_ife_csid_hw *)platform_get_drvdata(pdev);
 	csid_hw_intf = csid_dev->hw_intf;
 	csid_hw_info = csid_dev->hw_info;
 
-	CAM_DBG(CAM_CUSTOM, "CSID:%d remove",
+	CAM_DBG(CAM_CUSTOM, "CSID:%d component unbind",
 		csid_dev->hw_intf->hw_idx);
 
 	cam_ife_csid_hw_deinit(csid_dev);
@@ -129,6 +135,28 @@ static int cam_custom_csid_remove(struct platform_device *pdev)
 	kfree(csid_dev);
 	kfree(csid_hw_info);
 	kfree(csid_hw_intf);
+}
+
+const static struct component_ops cam_custom_csid_component_ops = {
+	.bind = cam_custom_csid_component_bind,
+	.unbind = cam_custom_csid_component_unbind,
+};
+
+static int cam_custom_csid_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_CUSTOM, "Adding Custom CSID component");
+	rc = component_add(&pdev->dev, &cam_custom_csid_component_ops);
+	if (rc)
+		CAM_ERR(CAM_CUSTOM, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int cam_custom_csid_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_custom_csid_component_ops);
 	return 0;
 }
 
@@ -142,7 +170,7 @@ static const struct of_device_id cam_custom_csid_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, cam_custom_csid_dt_match);
 
-static struct platform_driver cam_custom_csid_driver = {
+struct platform_driver cam_custom_csid_driver = {
 	.probe = cam_custom_csid_probe,
 	.driver = {
 		.name = "qcom,custom-csid",

+ 35 - 7
drivers/cam_cust/cam_custom_hw_mgr/cam_custom_hw1/cam_custom_sub_mod_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -11,6 +11,7 @@
 #include "cam_custom_sub_mod_core.h"
 #include "cam_custom_sub_mod_soc.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 static struct cam_hw_intf *cam_custom_hw_sub_mod_list
 	[CAM_CUSTOM_SUB_MOD_MAX_INSTANCES] = {0, 0};
@@ -39,12 +40,14 @@ int cam_custom_hw_sub_mod_init(struct cam_hw_intf **custom_hw, uint32_t hw_idx)
 	return 0;
 }
 
-int cam_custom_hw_sub_mod_probe(struct platform_device *pdev)
+static int cam_custom_hw_sub_mod_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
-	struct cam_hw_info                  *hw = NULL;
-	struct cam_hw_intf                  *hw_intf = NULL;
+	struct cam_hw_info		    *hw = NULL;
+	struct cam_hw_intf		    *hw_intf = NULL;
 	struct cam_custom_sub_mod_core_info *core_info = NULL;
-	int                                rc = 0;
+	int				   rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
 	if (!hw_intf)
@@ -114,7 +117,7 @@ int cam_custom_hw_sub_mod_probe(struct platform_device *pdev)
 	/* needs to be invoked when custom hw is in place */
 	//cam_custom_hw_sub_mod_init_hw(hw, NULL, 0);
 
-	CAM_DBG(CAM_CUSTOM, "Custom hw_idx[%d] probe successful",
+	CAM_DBG(CAM_CUSTOM, "HW idx:%d component bound successfully");
 		hw_intf->hw_idx);
 	return rc;
 
@@ -127,6 +130,31 @@ free_hw_intf:
 	return rc;
 }
 
+static void cam_custom_hw_sub_mod_component_unbind(
+	struct device *dev, struct device *master_dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	CAM_DBG(CAM_CUSTOM, "Unbinding component: %s", pdev->name);
+}
+
+const static struct component_ops cam_custom_hw_sub_mod_component_ops = {
+	.bind = cam_custom_hw_sub_mod_component_bind,
+	.unbind = cam_custom_hw_sub_mod_component_unbind,
+};
+
+int cam_custom_hw_sub_mod_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_CUSTOM, "Adding Custom HW sub module component");
+	rc = component_add(&pdev->dev, &cam_custom_hw_sub_mod_component_ops);
+	if (rc)
+		CAM_ERR(CAM_CUSTOM, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
 static const struct of_device_id cam_custom_hw_sub_mod_dt_match[] = {
 	{
 		.compatible = "qcom,cam_custom_hw_sub_mod",
@@ -137,7 +165,7 @@ static const struct of_device_id cam_custom_hw_sub_mod_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, cam_custom_hw_sub_mod_dt_match);
 
-static struct platform_driver cam_custom_hw_sub_mod_driver = {
+struct platform_driver cam_custom_hw_sub_mod_driver = {
 	.probe = cam_custom_hw_sub_mod_probe,
 	.driver = {
 		.name = CAM_CUSTOM_SUB_MOD_NAME,

+ 31 - 6
drivers/cam_fd/cam_fd_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/device.h>
@@ -14,6 +14,7 @@
 #include "cam_fd_context.h"
 #include "cam_fd_hw_mgr.h"
 #include "cam_fd_hw_mgr_intf.h"
+#include "camera_main.h"
 
 #define CAM_FD_DEV_NAME "cam-fd"
 
@@ -87,12 +88,14 @@ static const struct v4l2_subdev_internal_ops cam_fd_subdev_internal_ops = {
 	.close = cam_fd_dev_close,
 };
 
-static int cam_fd_dev_probe(struct platform_device *pdev)
+static int cam_fd_dev_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc;
 	int i;
 	struct cam_hw_mgr_intf hw_mgr_intf;
 	struct cam_node *node;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	g_fd_dev.sd.internal_ops = &cam_fd_subdev_internal_ops;
 
@@ -131,8 +134,7 @@ static int cam_fd_dev_probe(struct platform_device *pdev)
 
 	mutex_init(&g_fd_dev.lock);
 	g_fd_dev.probe_done = true;
-
-	CAM_DBG(CAM_FD, "Camera FD probe complete");
+	CAM_DBG(CAM_FD, "Component bound successfully");
 
 	return 0;
 
@@ -148,9 +150,11 @@ unregister_subdev:
 	return rc;
 }
 
-static int cam_fd_dev_remove(struct platform_device *pdev)
+static void cam_fd_dev_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int i, rc;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	for (i = 0; i < CAM_CTX_MAX; i++) {
 		rc = cam_fd_context_deinit(&g_fd_dev.fd_ctx[i]);
@@ -169,10 +173,31 @@ static int cam_fd_dev_remove(struct platform_device *pdev)
 
 	mutex_destroy(&g_fd_dev.lock);
 	g_fd_dev.probe_done = false;
+}
+
+const static struct component_ops cam_fd_dev_component_ops = {
+	.bind = cam_fd_dev_component_bind,
+	.unbind = cam_fd_dev_component_unbind,
+};
+
+static int cam_fd_dev_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_FD, "Adding FD dev component");
+	rc = component_add(&pdev->dev, &cam_fd_dev_component_ops);
+	if (rc)
+		CAM_ERR(CAM_FD, "failed to add component rc: %d", rc);
 
 	return rc;
 }
 
+static int cam_fd_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_fd_dev_component_ops);
+	return 0;
+}
+
 static const struct of_device_id cam_fd_dt_match[] = {
 	{
 		.compatible = "qcom,cam-fd"
@@ -180,7 +205,7 @@ static const struct of_device_id cam_fd_dt_match[] = {
 	{}
 };
 
-static struct platform_driver cam_fd_driver = {
+struct platform_driver cam_fd_driver = {
 	.probe = cam_fd_dev_probe,
 	.remove = cam_fd_dev_remove,
 	.driver = {

+ 33 - 8
drivers/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/platform_device.h>
@@ -17,10 +17,12 @@
 #include "cam_fd_hw_v41.h"
 #include "cam_fd_hw_v501.h"
 #include "cam_fd_hw_v600.h"
+#include "camera_main.h"
 
 static char fd_dev_name[8];
 
-static int cam_fd_hw_dev_probe(struct platform_device *pdev)
+static int cam_fd_hw_dev_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_hw_info *fd_hw;
 	struct cam_hw_intf *fd_hw_intf;
@@ -31,6 +33,7 @@ static int cam_fd_hw_dev_probe(struct platform_device *pdev)
 	uint32_t hw_idx;
 	struct cam_fd_hw_init_args init_args;
 	struct cam_fd_hw_deinit_args deinit_args;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	fd_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
 	if (!fd_hw_intf)
@@ -129,7 +132,8 @@ static int cam_fd_hw_dev_probe(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, fd_hw_intf);
-	CAM_DBG(CAM_FD, "FD-%d probe successful", fd_hw_intf->hw_idx);
+	CAM_DBG(CAM_FD, "FD:%d component bound successfully",
+		fd_hw_intf->hw_idx);
 
 	return rc;
 
@@ -148,30 +152,30 @@ free_memory:
 	return rc;
 }
 
-static int cam_fd_hw_dev_remove(struct platform_device *pdev)
+static void cam_fd_hw_dev_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc = 0;
 	struct cam_hw_intf *fd_hw_intf;
 	struct cam_hw_info *fd_hw;
 	struct cam_fd_core *fd_core;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	fd_hw_intf = platform_get_drvdata(pdev);
 	if (!fd_hw_intf) {
 		CAM_ERR(CAM_FD, "Invalid fd_hw_intf from pdev");
-		return -EINVAL;
+		return;
 	}
 
 	fd_hw = fd_hw_intf->hw_priv;
 	if (!fd_hw) {
 		CAM_ERR(CAM_FD, "Invalid fd_hw from fd_hw_intf");
-		rc = -ENODEV;
 		goto free_fd_hw_intf;
 	}
 
 	fd_core = (struct cam_fd_core *)fd_hw->core_info;
 	if (!fd_core) {
 		CAM_ERR(CAM_FD, "Invalid fd_core from fd_hw");
-		rc = -EINVAL;
 		goto deinit_platform_res;
 	}
 
@@ -187,10 +191,31 @@ deinit_platform_res:
 
 free_fd_hw_intf:
 	kfree(fd_hw_intf);
+}
+
+const static struct component_ops cam_fd_hw_dev_component_ops = {
+	.bind = cam_fd_hw_dev_component_bind,
+	.unbind = cam_fd_hw_dev_component_unbind,
+};
+
+static int cam_fd_hw_dev_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_FD, "Adding FD HW dev component");
+	rc = component_add(&pdev->dev, &cam_fd_hw_dev_component_ops);
+	if (rc)
+		CAM_ERR(CAM_FD, "failed to add component rc: %d", rc);
 
 	return rc;
 }
 
+static int cam_fd_hw_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_fd_hw_dev_component_ops);
+	return 0;
+}
+
 static const struct of_device_id cam_fd_hw_dt_match[] = {
 	{
 		.compatible = "qcom,fd41",
@@ -208,7 +233,7 @@ static const struct of_device_id cam_fd_hw_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cam_fd_hw_dt_match);
 
-static struct platform_driver cam_fd_hw_driver = {
+struct platform_driver cam_fd_hw_driver = {
 	.probe = cam_fd_hw_dev_probe,
 	.remove = cam_fd_hw_dev_remove,
 	.driver = {

+ 35 - 8
drivers/cam_icp/cam_icp_subdev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/delay.h>
@@ -29,6 +29,7 @@
 #include "cam_icp_hw_mgr_intf.h"
 #include "cam_debug_util.h"
 #include "cam_smmu_api.h"
+#include "camera_main.h"
 
 #define CAM_ICP_DEV_NAME        "cam-icp"
 
@@ -143,12 +144,14 @@ const struct v4l2_subdev_internal_ops cam_icp_subdev_internal_ops = {
 	.close = cam_icp_subdev_close,
 };
 
-static int cam_icp_probe(struct platform_device *pdev)
+static int cam_icp_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc = 0, i = 0;
 	struct cam_node *node;
 	struct cam_hw_mgr_intf *hw_mgr_intf;
 	int iommu_hdl = -1;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	if (!pdev) {
 		CAM_ERR(CAM_ICP, "pdev is NULL");
@@ -202,7 +205,7 @@ static int cam_icp_probe(struct platform_device *pdev)
 	g_icp_dev.open_cnt = 0;
 	mutex_init(&g_icp_dev.icp_lock);
 
-	CAM_DBG(CAM_ICP, "ICP probe complete");
+	CAM_DBG(CAM_ICP, "Component bound successfully");
 
 	return rc;
 
@@ -217,39 +220,63 @@ probe_fail:
 	return rc;
 }
 
-static int cam_icp_remove(struct platform_device *pdev)
+static void cam_icp_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int i;
 	struct v4l2_subdev *sd;
 	struct cam_subdev *subdev;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	if (!pdev) {
 		CAM_ERR(CAM_ICP, "pdev is NULL");
-		return -ENODEV;
+		return;
 	}
 
 	sd = platform_get_drvdata(pdev);
 	if (!sd) {
 		CAM_ERR(CAM_ICP, "V4l2 subdev is NULL");
-		return -ENODEV;
+		return;
 	}
 
 	subdev = v4l2_get_subdevdata(sd);
 	if (!subdev) {
 		CAM_ERR(CAM_ICP, "cam subdev is NULL");
-		return -ENODEV;
+		return;
 	}
 
 	for (i = 0; i < CAM_ICP_CTX_MAX; i++)
 		cam_icp_context_deinit(&g_icp_dev.ctx_icp[i]);
+
 	cam_node_deinit(g_icp_dev.node);
 	cam_subdev_remove(&g_icp_dev.sd);
 	mutex_destroy(&g_icp_dev.icp_lock);
+}
 
+const static struct component_ops cam_icp_component_ops = {
+	.bind = cam_icp_component_bind,
+	.unbind = cam_icp_component_unbind,
+};
+
+static int cam_icp_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ICP, "Adding ICP component");
+	rc = component_add(&pdev->dev, &cam_icp_component_ops);
+	if (rc)
+		CAM_ERR(CAM_ICP, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int cam_icp_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_icp_component_ops);
 	return 0;
 }
 
-static struct platform_driver cam_icp_driver = {
+struct platform_driver cam_icp_driver = {
 	.probe = cam_icp_probe,
 	.remove = cam_icp_remove,
 	.driver = {

+ 33 - 4
drivers/cam_icp/icp_hw/a5_hw/a5_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -17,6 +17,7 @@
 #include "cam_icp_hw_mgr_intf.h"
 #include "cam_cpas_api.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 struct a5_soc_info cam_a5_soc_info;
 EXPORT_SYMBOL(cam_a5_soc_info);
@@ -100,7 +101,8 @@ int cam_a5_register_cpas(struct cam_hw_soc_info *soc_info,
 	return rc;
 }
 
-int cam_a5_probe(struct platform_device *pdev)
+static int cam_a5_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc = 0;
 	struct cam_hw_info *a5_dev = NULL;
@@ -108,6 +110,7 @@ int cam_a5_probe(struct platform_device *pdev)
 	const struct of_device_id *match_dev = NULL;
 	struct cam_a5_device_core_info *core_info = NULL;
 	struct cam_a5_device_hw_info *hw_info = NULL;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	a5_dev_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
 	if (!a5_dev_intf)
@@ -177,7 +180,7 @@ int cam_a5_probe(struct platform_device *pdev)
 	spin_lock_init(&a5_dev->hw_lock);
 	init_completion(&a5_dev->hw_complete);
 
-	CAM_DBG(CAM_ICP, "A5%d probe successful",
+	CAM_DBG(CAM_ICP, "A5:%d component bound successfully",
 		a5_dev_intf->hw_idx);
 	return 0;
 
@@ -191,6 +194,32 @@ a5_dev_alloc_failure:
 	kfree(a5_dev_intf);
 
 	return rc;
+
+}
+
+static void cam_a5_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name);
+}
+
+const static struct component_ops cam_a5_component_ops = {
+	.bind = cam_a5_component_bind,
+	.unbind = cam_a5_component_unbind,
+};
+
+int cam_a5_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ICP, "Adding A5 component");
+	rc = component_add(&pdev->dev, &cam_a5_component_ops);
+	if (rc)
+		CAM_ERR(CAM_ICP, "failed to add component rc: %d", rc);
+
+	return rc;
 }
 
 static const struct of_device_id cam_a5_dt_match[] = {
@@ -202,7 +231,7 @@ static const struct of_device_id cam_a5_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cam_a5_dt_match);
 
-static struct platform_driver cam_a5_driver = {
+struct platform_driver cam_a5_driver = {
 	.probe = cam_a5_probe,
 	.driver = {
 		.name = "cam-a5",

+ 32 - 4
drivers/cam_icp/icp_hw/bps_hw/bps_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -17,6 +17,7 @@
 #include "cam_icp_hw_mgr_intf.h"
 #include "cam_cpas_api.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 static struct cam_bps_device_hw_info cam_bps_hw_info = {
 	.hw_idx = 0,
@@ -84,7 +85,8 @@ int cam_bps_register_cpas(struct cam_hw_soc_info *soc_info,
 	return rc;
 }
 
-int cam_bps_probe(struct platform_device *pdev)
+static int cam_bps_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_hw_info            *bps_dev = NULL;
 	struct cam_hw_intf            *bps_dev_intf = NULL;
@@ -92,6 +94,7 @@ int cam_bps_probe(struct platform_device *pdev)
 	struct cam_bps_device_core_info   *core_info = NULL;
 	struct cam_bps_device_hw_info     *hw_info = NULL;
 	int                                rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	bps_dev_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
 	if (!bps_dev_intf)
@@ -165,12 +168,37 @@ int cam_bps_probe(struct platform_device *pdev)
 	mutex_init(&bps_dev->hw_mutex);
 	spin_lock_init(&bps_dev->hw_lock);
 	init_completion(&bps_dev->hw_complete);
-	CAM_DBG(CAM_ICP, "BPS%d probe successful",
+	CAM_DBG(CAM_ICP, "BPS:%d component bound successfully",
 		bps_dev_intf->hw_idx);
 
 	return rc;
 }
 
+static void cam_bps_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name);
+}
+
+const static struct component_ops cam_bps_component_ops = {
+	.bind = cam_bps_component_bind,
+	.unbind = cam_bps_component_unbind,
+};
+
+int cam_bps_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ICP, "Adding BPS component");
+	rc = component_add(&pdev->dev, &cam_bps_component_ops);
+	if (rc)
+		CAM_ERR(CAM_ICP, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
 static const struct of_device_id cam_bps_dt_match[] = {
 	{
 		.compatible = "qcom,cam-bps",
@@ -180,7 +208,7 @@ static const struct of_device_id cam_bps_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cam_bps_dt_match);
 
-static struct platform_driver cam_bps_driver = {
+struct platform_driver cam_bps_driver = {
 	.probe = cam_bps_probe,
 	.driver = {
 		.name = "cam-bps",

+ 34 - 5
drivers/cam_icp/icp_hw/ipe_hw/ipe_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -17,6 +17,7 @@
 #include "cam_icp_hw_mgr_intf.h"
 #include "cam_cpas_api.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 static struct cam_ipe_device_hw_info cam_ipe_hw_info[] = {
 	{
@@ -58,7 +59,8 @@ int cam_ipe_register_cpas(struct cam_hw_soc_info *soc_info,
 	return rc;
 }
 
-int cam_ipe_probe(struct platform_device *pdev)
+static int cam_ipe_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_hw_info            *ipe_dev = NULL;
 	struct cam_hw_intf            *ipe_dev_intf = NULL;
@@ -69,6 +71,7 @@ int cam_ipe_probe(struct platform_device *pdev)
 	struct cam_cpas_query_cap query;
 	uint32_t cam_caps;
 	uint32_t hw_idx;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	of_property_read_u32(pdev->dev.of_node,
 		"cell-index", &hw_idx);
@@ -104,7 +107,7 @@ int cam_ipe_probe(struct platform_device *pdev)
 	ipe_dev_intf->hw_ops.process_cmd = cam_ipe_process_cmd;
 	ipe_dev_intf->hw_type = CAM_ICP_DEV_IPE;
 
-	CAM_DBG(CAM_ICP, "type %d index %d",
+	CAM_DBG(CAM_ICP, "IPE component bind type %d index %d",
 		ipe_dev_intf->hw_type,
 		ipe_dev_intf->hw_idx);
 
@@ -157,12 +160,38 @@ int cam_ipe_probe(struct platform_device *pdev)
 	spin_lock_init(&ipe_dev->hw_lock);
 	init_completion(&ipe_dev->hw_complete);
 
-	CAM_DBG(CAM_ICP, "IPE%d probe successful",
+	CAM_DBG(CAM_ICP, "IPE:%d component bound successfully",
 		ipe_dev_intf->hw_idx);
 
 	return rc;
 }
 
+static void cam_ipe_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name);
+}
+
+
+const static struct component_ops cam_ipe_component_ops = {
+	.bind = cam_ipe_component_bind,
+	.unbind = cam_ipe_component_unbind,
+};
+
+int cam_ipe_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ICP, "Adding IPE component");
+	rc = component_add(&pdev->dev, &cam_ipe_component_ops);
+	if (rc)
+		CAM_ERR(CAM_ICP, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
 static const struct of_device_id cam_ipe_dt_match[] = {
 	{
 		.compatible = "qcom,cam-ipe",
@@ -172,7 +201,7 @@ static const struct of_device_id cam_ipe_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cam_ipe_dt_match);
 
-static struct platform_driver cam_ipe_driver = {
+struct platform_driver cam_ipe_driver = {
 	.probe = cam_ipe_probe,
 	.driver = {
 		.name = "cam-ipe",

+ 49 - 24
drivers/cam_isp/cam_isp_dev.c

@@ -18,6 +18,7 @@
 #include "cam_node.h"
 #include "cam_debug_util.h"
 #include "cam_smmu_api.h"
+#include "camera_main.h"
 
 static struct cam_isp_dev g_isp_dev;
 
@@ -90,28 +91,8 @@ static const struct v4l2_subdev_internal_ops cam_isp_subdev_internal_ops = {
 	.open = cam_isp_subdev_open,
 };
 
-static int cam_isp_dev_remove(struct platform_device *pdev)
-{
-	int rc = 0;
-	int i;
-
-	/* clean up resources */
-	for (i = 0; i < CAM_CTX_MAX; i++) {
-		rc = cam_isp_context_deinit(&g_isp_dev.ctx_isp[i]);
-		if (rc)
-			CAM_ERR(CAM_ISP, "ISP context %d deinit failed",
-				 i);
-	}
-
-	rc = cam_subdev_remove(&g_isp_dev.sd);
-	if (rc)
-		CAM_ERR(CAM_ISP, "Unregister failed");
-
-	memset(&g_isp_dev, 0, sizeof(g_isp_dev));
-	return 0;
-}
-
-static int cam_isp_dev_probe(struct platform_device *pdev)
+static int cam_isp_dev_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc = -1;
 	int i;
@@ -119,6 +100,7 @@ static int cam_isp_dev_probe(struct platform_device *pdev)
 	struct cam_node               *node;
 	const char                    *compat_str = NULL;
 	uint32_t                       isp_device_type;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	int iommu_hdl = -1;
 
@@ -179,7 +161,7 @@ static int cam_isp_dev_probe(struct platform_device *pdev)
 
 	mutex_init(&g_isp_dev.isp_mutex);
 
-	CAM_INFO(CAM_ISP, "Camera ISP probe complete");
+	CAM_INFO(CAM_ISP, "ISP HW component bound successfully");
 
 	return 0;
 unregister:
@@ -188,8 +170,51 @@ err:
 	return rc;
 }
 
+static void cam_isp_dev_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	int rc = 0;
+	int i;
+
+	/* clean up resources */
+	for (i = 0; i < CAM_CTX_MAX; i++) {
+		rc = cam_isp_context_deinit(&g_isp_dev.ctx_isp[i]);
+		if (rc)
+			CAM_ERR(CAM_ISP, "ISP context %d deinit failed",
+				 i);
+	}
+
+	rc = cam_subdev_remove(&g_isp_dev.sd);
+	if (rc)
+		CAM_ERR(CAM_ISP, "Unregister failed rc: %d", rc);
+
+	memset(&g_isp_dev, 0, sizeof(g_isp_dev));
+}
+
+const static struct component_ops cam_isp_dev_component_ops = {
+	.bind = cam_isp_dev_component_bind,
+	.unbind = cam_isp_dev_component_unbind,
+};
+
+static int cam_isp_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_isp_dev_component_ops);
+	return 0;
+}
+
+static int cam_isp_dev_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ISP, "Adding ISP dev component");
+	rc = component_add(&pdev->dev, &cam_isp_dev_component_ops);
+	if (rc)
+		CAM_ERR(CAM_ISP, "failed to add component rc: %d", rc);
+
+	return rc;
+}
 
-static struct platform_driver isp_driver = {
+struct platform_driver isp_driver = {
 	.probe = cam_isp_dev_probe,
 	.remove = cam_isp_dev_remove,
 	.driver = {

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid17x.c

@@ -11,6 +11,7 @@
 #include "cam_ife_csid175_200.h"
 #include "cam_ife_csid480.h"
 #include "cam_ife_csid_dev.h"
+#include "camera_main.h"
 
 #define CAM_CSID_DRV_NAME                    "csid_17x"
 #define CAM_CSID_VERSION_V170                 0x10070000
@@ -63,7 +64,7 @@ static const struct of_device_id cam_ife_csid17x_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, cam_ife_csid17x_dt_match);
 
-static struct platform_driver cam_ife_csid17x_driver = {
+struct platform_driver cam_ife_csid17x_driver = {
 	.probe = cam_ife_csid_probe,
 	.remove = cam_ife_csid_remove,
 	.driver = {

+ 33 - 7
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -10,15 +10,16 @@
 #include "cam_ife_csid_dev.h"
 #include "cam_ife_csid_hw_intf.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 static struct cam_hw_intf *cam_ife_csid_hw_list[CAM_IFE_CSID_HW_NUM_MAX] = {
 	0, 0, 0, 0};
 
 static char csid_dev_name[8];
 
-int cam_ife_csid_probe(struct platform_device *pdev)
+static int cam_ife_csid_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
-
 	struct cam_hw_intf             *csid_hw_intf;
 	struct cam_hw_info             *csid_hw_info;
 	struct cam_ife_csid_hw         *csid_dev = NULL;
@@ -26,8 +27,9 @@ int cam_ife_csid_probe(struct platform_device *pdev)
 	struct cam_ife_csid_hw_info    *csid_hw_data = NULL;
 	uint32_t                        csid_dev_idx;
 	int                             rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
-	CAM_DBG(CAM_ISP, "probe called");
+	CAM_DBG(CAM_ISP, "Binding IFE CSID component");
 
 	csid_hw_intf = kzalloc(sizeof(*csid_hw_intf), GFP_KERNEL);
 	if (!csid_hw_intf) {
@@ -81,7 +83,7 @@ int cam_ife_csid_probe(struct platform_device *pdev)
 		goto free_dev;
 
 	platform_set_drvdata(pdev, csid_dev);
-	CAM_DBG(CAM_ISP, "CSID:%d probe successful",
+	CAM_DBG(CAM_ISP, "CSID:%d component bound successfully",
 		csid_hw_intf->hw_idx);
 
 
@@ -102,17 +104,19 @@ err:
 	return rc;
 }
 
-int cam_ife_csid_remove(struct platform_device *pdev)
+static void cam_ife_csid_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_ife_csid_hw         *csid_dev = NULL;
 	struct cam_hw_intf             *csid_hw_intf;
 	struct cam_hw_info             *csid_hw_info;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	csid_dev = (struct cam_ife_csid_hw *)platform_get_drvdata(pdev);
 	csid_hw_intf = csid_dev->hw_intf;
 	csid_hw_info = csid_dev->hw_info;
 
-	CAM_DBG(CAM_ISP, "CSID:%d remove",
+	CAM_DBG(CAM_ISP, "CSID:%d component unbind",
 		csid_dev->hw_intf->hw_idx);
 
 	cam_ife_csid_hw_deinit(csid_dev);
@@ -121,6 +125,28 @@ int cam_ife_csid_remove(struct platform_device *pdev)
 	kfree(csid_dev);
 	kfree(csid_hw_info);
 	kfree(csid_hw_intf);
+}
+
+const static struct component_ops cam_ife_csid_component_ops = {
+	.bind = cam_ife_csid_component_bind,
+	.unbind = cam_ife_csid_component_unbind,
+};
+
+int cam_ife_csid_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ISP, "Adding IFE CSID component");
+	rc = component_add(&pdev->dev, &cam_ife_csid_component_ops);
+	if (rc)
+		CAM_ERR(CAM_ISP, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+int cam_ife_csid_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_ife_csid_component_ops);
 	return 0;
 }
 

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_lite17x.c

@@ -8,6 +8,7 @@
 #include "cam_ife_csid_lite480.h"
 #include "cam_ife_csid_core.h"
 #include "cam_ife_csid_dev.h"
+#include "camera_main.h"
 
 #define CAM_CSID_LITE_DRV_NAME                    "csid_lite"
 
@@ -40,7 +41,7 @@ static const struct of_device_id cam_ife_csid_lite_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cam_ife_csid_lite_dt_match);
 
-static struct platform_driver cam_ife_csid_lite_driver = {
+struct platform_driver cam_ife_csid_lite_driver = {
 	.probe = cam_ife_csid_probe,
 	.remove = cam_ife_csid_remove,
 	.driver = {

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.c

@@ -8,6 +8,7 @@
 #include "cam_tfe_csid_core.h"
 #include "cam_tfe_csid530.h"
 #include "cam_tfe_csid_dev.h"
+#include "camera_main.h"
 
 #define CAM_TFE_CSID_DRV_NAME                    "csid_530"
 #define CAM_TFE_CSID_VERSION_V530                 0x50030000
@@ -27,7 +28,7 @@ static const struct of_device_id cam_tfe_csid530_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, cam_tfe_csid530_dt_match);
 
-static struct platform_driver cam_tfe_csid530_driver = {
+struct platform_driver cam_tfe_csid530_driver = {
 	.probe = cam_tfe_csid_probe,
 	.remove = cam_tfe_csid_remove,
 	.driver = {

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe.c

@@ -8,6 +8,7 @@
 #include "cam_tfe_hw_intf.h"
 #include "cam_tfe_core.h"
 #include "cam_tfe_dev.h"
+#include "camera_main.h"
 
 static const struct of_device_id cam_tfe_dt_match[] = {
 	{
@@ -18,7 +19,7 @@ static const struct of_device_id cam_tfe_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cam_tfe_dt_match);
 
-static struct platform_driver cam_tfe_driver = {
+struct platform_driver cam_tfe_driver = {
 	.probe = cam_tfe_probe,
 	.remove = cam_tfe_remove,
 	.driver = {

+ 37 - 13
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_dev.c

@@ -10,12 +10,14 @@
 #include "cam_tfe_core.h"
 #include "cam_tfe_soc.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 static struct cam_hw_intf *cam_tfe_hw_list[CAM_TFE_HW_NUM_MAX] = {0, 0, 0};
 
 static char tfe_dev_name[8];
 
-int cam_tfe_probe(struct platform_device *pdev)
+static int cam_tfe_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_hw_info                *tfe_hw = NULL;
 	struct cam_hw_intf                *tfe_hw_intf = NULL;
@@ -23,6 +25,7 @@ int cam_tfe_probe(struct platform_device *pdev)
 	struct cam_tfe_hw_core_info       *core_info = NULL;
 	struct cam_tfe_hw_info            *hw_info = NULL;
 	int                                rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	tfe_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
 	if (!tfe_hw_intf) {
@@ -60,7 +63,7 @@ int cam_tfe_probe(struct platform_device *pdev)
 	tfe_hw_intf->hw_ops.process_cmd = cam_tfe_process_cmd;
 	tfe_hw_intf->hw_type = CAM_ISP_HW_TYPE_TFE;
 
-	CAM_DBG(CAM_ISP, "type %d index %d",
+	CAM_DBG(CAM_ISP, "TFE component bind,type %d index %d",
 		tfe_hw_intf->hw_type, tfe_hw_intf->hw_idx);
 
 	platform_set_drvdata(pdev, tfe_hw_intf);
@@ -110,8 +113,8 @@ int cam_tfe_probe(struct platform_device *pdev)
 	cam_tfe_init_hw(tfe_hw, NULL, 0);
 	cam_tfe_deinit_hw(tfe_hw, NULL, 0);
 
-	CAM_DBG(CAM_ISP, "TFE%d probe successful", tfe_hw_intf->hw_idx);
-
+	CAM_DBG(CAM_ISP, "TFE:%d component bound successfully",
+		tfe_hw_intf->hw_idx);
 	return rc;
 
 deinit_soc:
@@ -127,17 +130,19 @@ end:
 	return rc;
 }
 
-int cam_tfe_remove(struct platform_device *pdev)
+static void cam_tfe_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
-	struct cam_hw_info                *tfe_hw = NULL;
-	struct cam_hw_intf                *tfe_hw_intf = NULL;
-	struct cam_tfe_hw_core_info       *core_info = NULL;
-	int                                rc = 0;
+	struct cam_hw_info		  *tfe_hw = NULL;
+	struct cam_hw_intf		  *tfe_hw_intf = NULL;
+	struct cam_tfe_hw_core_info	  *core_info = NULL;
+	int				   rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	tfe_hw_intf = platform_get_drvdata(pdev);
 	if (!tfe_hw_intf) {
 		CAM_ERR(CAM_ISP, "Error! No data in pdev");
-		return -EINVAL;
+		return;
 	}
 
 	CAM_DBG(CAM_ISP, "type %d index %d",
@@ -149,14 +154,12 @@ int cam_tfe_remove(struct platform_device *pdev)
 	tfe_hw = tfe_hw_intf->hw_priv;
 	if (!tfe_hw) {
 		CAM_ERR(CAM_ISP, "Error! HW data is NULL");
-		rc = -ENODEV;
 		goto free_tfe_hw_intf;
 	}
 
 	core_info = (struct cam_tfe_hw_core_info *)tfe_hw->core_info;
 	if (!core_info) {
 		CAM_ERR(CAM_ISP, "Error! core data NULL");
-		rc = -EINVAL;
 		goto deinit_soc;
 	}
 
@@ -174,14 +177,35 @@ deinit_soc:
 	mutex_destroy(&tfe_hw->hw_mutex);
 	kfree(tfe_hw);
 
-	CAM_DBG(CAM_ISP, "TFE%d remove successful", tfe_hw_intf->hw_idx);
+	CAM_DBG(CAM_ISP, "TFE%d component unbound", tfe_hw_intf->hw_idx);
 
 free_tfe_hw_intf:
 	kfree(tfe_hw_intf);
+}
+
+const static struct component_ops cam_tfe_component_ops = {
+	.bind = cam_tfe_component_bind,
+	.unbind = cam_tfe_component_unbind,
+};
+
+int cam_tfe_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ISP, "Adding TFE component");
+	rc = component_add(&pdev->dev, &cam_tfe_component_ops);
+	if (rc)
+		CAM_ERR(CAM_ISP, "failed to add component rc: %d", rc);
 
 	return rc;
 }
 
+int cam_tfe_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_tfe_component_ops);
+	return 0;
+}
+
 int cam_tfe_hw_init(struct cam_hw_intf **tfe_hw, uint32_t hw_idx)
 {
 	int rc = 0;

+ 32 - 9
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_dev.c

@@ -10,15 +10,16 @@
 #include "cam_top_tpg_dev.h"
 #include "cam_top_tpg_hw_intf.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 static struct cam_hw_intf *cam_top_tpg_hw_list[CAM_TOP_TPG_HW_NUM_MAX] = {
 	0, 0};
 
 static char tpg_dev_name[8];
 
-int cam_top_tpg_probe(struct platform_device *pdev)
+static int cam_top_tpg_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
-
 	struct cam_hw_intf             *tpg_hw_intf;
 	struct cam_hw_info             *tpg_hw_info;
 	struct cam_top_tpg_hw          *tpg_dev = NULL;
@@ -26,8 +27,9 @@ int cam_top_tpg_probe(struct platform_device *pdev)
 	struct cam_top_tpg_hw_info     *tpg_hw_data = NULL;
 	uint32_t                        tpg_dev_idx;
 	int                             rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
-	CAM_DBG(CAM_ISP, "probe called");
+	CAM_DBG(CAM_ISP, "Binding TPG component");
 
 	tpg_hw_intf = kzalloc(sizeof(*tpg_hw_intf), GFP_KERNEL);
 	if (!tpg_hw_intf) {
@@ -81,10 +83,9 @@ int cam_top_tpg_probe(struct platform_device *pdev)
 		goto free_dev;
 
 	platform_set_drvdata(pdev, tpg_dev);
-	CAM_DBG(CAM_ISP, "TPG:%d probe successful",
+	CAM_DBG(CAM_ISP, "TPG: %d component binded successfully",
 		tpg_hw_intf->hw_idx);
 
-
 	if (tpg_hw_intf->hw_idx < CAM_TOP_TPG_HW_NUM_MAX)
 		cam_top_tpg_hw_list[tpg_hw_intf->hw_idx] = tpg_hw_intf;
 	else
@@ -102,25 +103,47 @@ err:
 	return rc;
 }
 
-int cam_top_tpg_remove(struct platform_device *pdev)
+static void cam_top_tpg_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_top_tpg_hw          *tpg_dev = NULL;
 	struct cam_hw_intf             *tpg_hw_intf;
 	struct cam_hw_info             *tpg_hw_info;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	tpg_dev = (struct cam_top_tpg_hw *)platform_get_drvdata(pdev);
 	tpg_hw_intf = tpg_dev->hw_intf;
 	tpg_hw_info = tpg_dev->hw_info;
 
-	CAM_DBG(CAM_ISP, "TPG:%d remove",
-		tpg_dev->hw_intf->hw_idx);
-
+	CAM_DBG(CAM_ISP, "TPG:%d component unbound", tpg_dev->hw_intf->hw_idx);
 	cam_top_tpg_hw_deinit(tpg_dev);
 
 	/*release the tpg device memory */
 	kfree(tpg_dev);
 	kfree(tpg_hw_info);
 	kfree(tpg_hw_intf);
+}
+
+const static struct component_ops cam_top_tpg_component_ops = {
+	.bind = cam_top_tpg_component_bind,
+	.unbind = cam_top_tpg_component_unbind,
+};
+
+int cam_top_tpg_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ISP, "Adding TPG component");
+	rc = component_add(&pdev->dev, &cam_top_tpg_component_ops);
+	if (rc)
+		CAM_ERR(CAM_ISP, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+int cam_top_tpg_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_top_tpg_component_ops);
 	return 0;
 }
 

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_v1.c

@@ -8,6 +8,7 @@
 #include "cam_top_tpg_core.h"
 #include "cam_top_tpg_v1.h"
 #include "cam_top_tpg_dev.h"
+#include "camera_main.h"
 
 #define CAM_TOP_TPG_DRV_NAME                    "tpg_v1"
 #define CAM_TOP_TPG_VERSION_V1                  0x10000000
@@ -29,7 +30,7 @@ static const struct of_device_id cam_top_tpg_v1_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, cam_top_tpg_v1_dt_match);
 
-static struct platform_driver cam_top_tpg_v1_driver = {
+struct platform_driver cam_top_tpg_v1_driver = {
 	.probe = cam_top_tpg_probe,
 	.remove = cam_top_tpg_remove,
 	.driver = {

+ 40 - 15
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_dev.c

@@ -1,12 +1,14 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 
 #include <linux/slab.h>
 #include <linux/mod_devicetable.h>
 #include <linux/of_device.h>
+#include <linux/component.h>
+
 #include "cam_vfe_dev.h"
 #include "cam_vfe_core.h"
 #include "cam_vfe_soc.h"
@@ -16,7 +18,8 @@ static struct cam_hw_intf *cam_vfe_hw_list[CAM_VFE_HW_NUM_MAX] = {0, 0, 0, 0};
 
 static char vfe_dev_name[8];
 
-int cam_vfe_probe(struct platform_device *pdev)
+static int cam_vfe_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_hw_info                *vfe_hw = NULL;
 	struct cam_hw_intf                *vfe_hw_intf = NULL;
@@ -24,6 +27,7 @@ int cam_vfe_probe(struct platform_device *pdev)
 	struct cam_vfe_hw_core_info       *core_info = NULL;
 	struct cam_vfe_hw_info            *hw_info = NULL;
 	int                                rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	vfe_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
 	if (!vfe_hw_intf) {
@@ -61,7 +65,7 @@ int cam_vfe_probe(struct platform_device *pdev)
 	vfe_hw_intf->hw_ops.process_cmd = cam_vfe_process_cmd;
 	vfe_hw_intf->hw_type = CAM_ISP_HW_TYPE_VFE;
 
-	CAM_DBG(CAM_ISP, "type %d index %d",
+	CAM_DBG(CAM_ISP, "VFE component bind, type %d index %d",
 		vfe_hw_intf->hw_type, vfe_hw_intf->hw_idx);
 
 	platform_set_drvdata(pdev, vfe_hw_intf);
@@ -110,8 +114,8 @@ int cam_vfe_probe(struct platform_device *pdev)
 	cam_vfe_init_hw(vfe_hw, NULL, 0);
 	cam_vfe_deinit_hw(vfe_hw, NULL, 0);
 
-	CAM_DBG(CAM_ISP, "VFE%d probe successful", vfe_hw_intf->hw_idx);
-
+	CAM_DBG(CAM_ISP, "VFE:%d component bound successfully",
+		vfe_hw_intf->hw_idx);
 	return rc;
 
 deinit_soc:
@@ -127,20 +131,22 @@ end:
 	return rc;
 }
 
-int cam_vfe_remove(struct platform_device *pdev)
+static void cam_vfe_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
-	struct cam_hw_info                *vfe_hw = NULL;
-	struct cam_hw_intf                *vfe_hw_intf = NULL;
-	struct cam_vfe_hw_core_info       *core_info = NULL;
-	int                                rc = 0;
+	struct cam_hw_info		  *vfe_hw = NULL;
+	struct cam_hw_intf		  *vfe_hw_intf = NULL;
+	struct cam_vfe_hw_core_info	  *core_info = NULL;
+	int				   rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	vfe_hw_intf = platform_get_drvdata(pdev);
 	if (!vfe_hw_intf) {
 		CAM_ERR(CAM_ISP, "Error! No data in pdev");
-		return -EINVAL;
+		return;
 	}
 
-	CAM_DBG(CAM_ISP, "type %d index %d",
+	CAM_DBG(CAM_ISP, "VFE component unbind, type %d index %d",
 		vfe_hw_intf->hw_type, vfe_hw_intf->hw_idx);
 
 	if (vfe_hw_intf->hw_idx < CAM_VFE_HW_NUM_MAX)
@@ -149,14 +155,12 @@ int cam_vfe_remove(struct platform_device *pdev)
 	vfe_hw = vfe_hw_intf->hw_priv;
 	if (!vfe_hw) {
 		CAM_ERR(CAM_ISP, "Error! HW data is NULL");
-		rc = -ENODEV;
 		goto free_vfe_hw_intf;
 	}
 
 	core_info = (struct cam_vfe_hw_core_info *)vfe_hw->core_info;
 	if (!core_info) {
 		CAM_ERR(CAM_ISP, "Error! core data NULL");
-		rc = -EINVAL;
 		goto deinit_soc;
 	}
 
@@ -174,14 +178,35 @@ deinit_soc:
 	mutex_destroy(&vfe_hw->hw_mutex);
 	kfree(vfe_hw);
 
-	CAM_DBG(CAM_ISP, "VFE%d remove successful", vfe_hw_intf->hw_idx);
+	CAM_DBG(CAM_ISP, "VFE%d component unbound", vfe_hw_intf->hw_idx);
 
 free_vfe_hw_intf:
 	kfree(vfe_hw_intf);
+}
+
+const static struct component_ops cam_vfe_component_ops = {
+	.bind = cam_vfe_component_bind,
+	.unbind = cam_vfe_component_unbind,
+};
+
+int cam_vfe_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ISP, "Adding VFE component");
+	rc = component_add(&pdev->dev, &cam_vfe_component_ops);
+	if (rc)
+		CAM_ERR(CAM_ISP, "failed to add component rc: %d", rc);
 
 	return rc;
 }
 
+int cam_vfe_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_vfe_component_ops);
+	return 0;
+}
+
 int cam_vfe_hw_init(struct cam_hw_intf **vfe_hw, uint32_t hw_idx)
 {
 	int rc = 0;

+ 3 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -14,6 +14,7 @@
 #include "cam_vfe_hw_intf.h"
 #include "cam_vfe_core.h"
 #include "cam_vfe_dev.h"
+#include "camera_main.h"
 
 static const struct of_device_id cam_vfe_dt_match[] = {
 	{
@@ -56,7 +57,7 @@ static const struct of_device_id cam_vfe_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cam_vfe_dt_match);
 
-static struct platform_driver cam_vfe_driver = {
+struct platform_driver cam_vfe_driver = {
 	.probe = cam_vfe_probe,
 	.remove = cam_vfe_remove,
 	.driver = {

+ 49 - 23
drivers/cam_jpeg/cam_jpeg_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/delay.h>
@@ -15,6 +15,7 @@
 #include "cam_jpeg_dev.h"
 #include "cam_debug_util.h"
 #include "cam_smmu_api.h"
+#include "camera_main.h"
 
 #define CAM_JPEG_DEV_NAME "cam-jpeg"
 
@@ -92,32 +93,15 @@ static const struct v4l2_subdev_internal_ops cam_jpeg_subdev_internal_ops = {
 	.open = cam_jpeg_subdev_open,
 };
 
-static int cam_jpeg_dev_remove(struct platform_device *pdev)
-{
-	int rc;
-	int i;
-
-	for (i = 0; i < CAM_JPEG_CTX_MAX; i++) {
-		rc = cam_jpeg_context_deinit(&g_jpeg_dev.ctx_jpeg[i]);
-		if (rc)
-			CAM_ERR(CAM_JPEG, "JPEG context %d deinit failed %d",
-				i, rc);
-	}
-
-	rc = cam_subdev_remove(&g_jpeg_dev.sd);
-	if (rc)
-		CAM_ERR(CAM_JPEG, "Unregister failed %d", rc);
-
-	return rc;
-}
-
-static int cam_jpeg_dev_probe(struct platform_device *pdev)
+static int cam_jpeg_dev_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc;
 	int i;
 	struct cam_hw_mgr_intf hw_mgr_intf;
 	struct cam_node *node;
 	int iommu_hdl = -1;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	g_jpeg_dev.sd.internal_ops = &cam_jpeg_subdev_internal_ops;
 	rc = cam_subdev_probe(&g_jpeg_dev.sd, pdev, CAM_JPEG_DEV_NAME,
@@ -159,7 +143,7 @@ static int cam_jpeg_dev_probe(struct platform_device *pdev)
 
 	mutex_init(&g_jpeg_dev.jpeg_mutex);
 
-	CAM_INFO(CAM_JPEG, "Camera JPEG probe complete");
+	CAM_INFO(CAM_JPEG, "Component bound successfully");
 
 	return rc;
 
@@ -174,7 +158,49 @@ err:
 	return rc;
 }
 
-static struct platform_driver jpeg_driver = {
+static void cam_jpeg_dev_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	int rc;
+	int i;
+
+	for (i = 0; i < CAM_CTX_MAX; i++) {
+		rc = cam_jpeg_context_deinit(&g_jpeg_dev.ctx_jpeg[i]);
+		if (rc)
+			CAM_ERR(CAM_JPEG, "JPEG context %d deinit failed %d",
+				i, rc);
+	}
+
+	rc = cam_subdev_remove(&g_jpeg_dev.sd);
+	if (rc)
+		CAM_ERR(CAM_JPEG, "Unregister failed %d", rc);
+}
+
+const static struct component_ops cam_jpeg_dev_component_ops = {
+	.bind = cam_jpeg_dev_component_bind,
+	.unbind = cam_jpeg_dev_component_unbind,
+};
+
+static int cam_jpeg_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_jpeg_dev_component_ops);
+	return 0;
+}
+
+static int cam_jpeg_dev_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_JPEG, "Adding JPEG component");
+	rc = component_add(&pdev->dev, &cam_jpeg_dev_component_ops);
+	if (rc)
+		CAM_ERR(CAM_JPEG, "failed to add component rc: %d", rc);
+
+	return rc;
+
+}
+
+struct platform_driver jpeg_driver = {
 	.probe = cam_jpeg_dev_probe,
 	.remove = cam_jpeg_dev_remove,
 	.driver = {

+ 80 - 51
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -18,6 +18,7 @@
 #include "cam_jpeg_hw_mgr_intf.h"
 #include "cam_cpas_api.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 static struct cam_jpeg_dma_device_hw_info cam_jpeg_dma_hw_info = {
 	.reserved = 0,
@@ -60,54 +61,8 @@ static int cam_jpeg_dma_unregister_cpas(
 	return rc;
 }
 
-static int cam_jpeg_dma_remove(struct platform_device *pdev)
-{
-	struct cam_hw_info *jpeg_dma_dev = NULL;
-	struct cam_hw_intf *jpeg_dma_dev_intf = NULL;
-	struct cam_jpeg_dma_device_core_info *core_info = NULL;
-	int rc;
-
-	jpeg_dma_dev_intf = platform_get_drvdata(pdev);
-	if (!jpeg_dma_dev_intf) {
-		CAM_ERR(CAM_JPEG, "error No data in pdev");
-		return -EINVAL;
-	}
-
-	jpeg_dma_dev = jpeg_dma_dev_intf->hw_priv;
-	if (!jpeg_dma_dev) {
-		CAM_ERR(CAM_JPEG, "error HW data is NULL");
-		rc = -ENODEV;
-		goto free_jpeg_hw_intf;
-	}
-
-	core_info = (struct cam_jpeg_dma_device_core_info *)
-		jpeg_dma_dev->core_info;
-	if (!core_info) {
-		CAM_ERR(CAM_JPEG, "error core data NULL");
-		goto deinit_soc;
-	}
-
-	rc = cam_jpeg_dma_unregister_cpas(core_info);
-	if (rc)
-		CAM_ERR(CAM_JPEG, " unreg failed to reg cpas %d", rc);
-
-	mutex_destroy(&core_info->core_mutex);
-	kfree(core_info);
-
-deinit_soc:
-	rc = cam_soc_util_release_platform_resource(&jpeg_dma_dev->soc_info);
-	if (rc)
-		CAM_ERR(CAM_JPEG, "Failed to deinit soc rc=%d", rc);
-
-	mutex_destroy(&jpeg_dma_dev->hw_mutex);
-	kfree(jpeg_dma_dev);
-
-free_jpeg_hw_intf:
-	kfree(jpeg_dma_dev_intf);
-	return rc;
-}
-
-static int cam_jpeg_dma_probe(struct platform_device *pdev)
+static int cam_jpeg_dma_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_hw_info *jpeg_dma_dev = NULL;
 	struct cam_hw_intf *jpeg_dma_dev_intf = NULL;
@@ -115,6 +70,7 @@ static int cam_jpeg_dma_probe(struct platform_device *pdev)
 	struct cam_jpeg_dma_device_core_info *core_info = NULL;
 	struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
 	int rc;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	jpeg_dma_dev_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
 	if (!jpeg_dma_dev_intf)
@@ -179,7 +135,8 @@ static int cam_jpeg_dma_probe(struct platform_device *pdev)
 	spin_lock_init(&jpeg_dma_dev->hw_lock);
 	init_completion(&jpeg_dma_dev->hw_complete);
 
-	CAM_DBG(CAM_JPEG, " hwidx %d", jpeg_dma_dev_intf->hw_idx);
+	CAM_DBG(CAM_JPEG, "JPEG:%d component bound successfully",
+		jpeg_dma_dev_intf->hw_idx);
 
 	return rc;
 
@@ -196,6 +153,78 @@ error_alloc_dev:
 	return rc;
 }
 
+static void cam_jpeg_dma_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct cam_hw_info *jpeg_dma_dev = NULL;
+	struct cam_hw_intf *jpeg_dma_dev_intf = NULL;
+	struct cam_jpeg_dma_device_core_info *core_info = NULL;
+	int rc;
+	struct platform_device *pdev = to_platform_device(dev);
+
+	jpeg_dma_dev_intf = platform_get_drvdata(pdev);
+	if (!jpeg_dma_dev_intf) {
+		CAM_ERR(CAM_JPEG, "error No data in pdev");
+		return;
+	}
+
+	jpeg_dma_dev = jpeg_dma_dev_intf->hw_priv;
+	if (!jpeg_dma_dev) {
+		CAM_ERR(CAM_JPEG, "error HW data is NULL");
+		goto free_jpeg_hw_intf;
+	}
+
+	core_info = (struct cam_jpeg_dma_device_core_info *)
+		jpeg_dma_dev->core_info;
+	if (!core_info) {
+		CAM_ERR(CAM_JPEG, "error core data NULL");
+		goto deinit_soc;
+	}
+
+	rc = cam_jpeg_dma_unregister_cpas(core_info);
+	if (rc)
+		CAM_ERR(CAM_JPEG, " unreg failed to reg cpas %d", rc);
+
+	mutex_destroy(&core_info->core_mutex);
+	kfree(core_info);
+
+deinit_soc:
+	rc = cam_soc_util_release_platform_resource(&jpeg_dma_dev->soc_info);
+	if (rc)
+		CAM_ERR(CAM_JPEG, "Failed to deinit soc rc=%d", rc);
+
+	mutex_destroy(&jpeg_dma_dev->hw_mutex);
+	kfree(jpeg_dma_dev);
+
+free_jpeg_hw_intf:
+	kfree(jpeg_dma_dev_intf);
+	return;
+
+}
+
+const static struct component_ops cam_jpeg_dma_component_ops = {
+	.bind = cam_jpeg_dma_component_bind,
+	.unbind = cam_jpeg_dma_component_unbind,
+};
+
+static int cam_jpeg_dma_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_jpeg_dma_component_ops);
+	return 0;
+}
+
+static int cam_jpeg_dma_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_JPEG, "Adding JPEG dma component");
+	rc = component_add(&pdev->dev, &cam_jpeg_dma_component_ops);
+	if (rc)
+		CAM_ERR(CAM_JPEG, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
 static const struct of_device_id cam_jpeg_dma_dt_match[] = {
 	{
 		.compatible = "qcom,cam_jpeg_dma",
@@ -205,7 +234,7 @@ static const struct of_device_id cam_jpeg_dma_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cam_jpeg_dma_dt_match);
 
-static struct platform_driver cam_jpeg_dma_driver = {
+struct platform_driver cam_jpeg_dma_driver = {
 	.probe = cam_jpeg_dma_probe,
 	.remove = cam_jpeg_dma_remove,
 	.driver = {

+ 77 - 50
drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -19,6 +19,7 @@
 #include "cam_cpas_api.h"
 #include "cam_debug_util.h"
 #include "cam_jpeg_enc_hw_info_ver_4_2_0.h"
+#include "camera_main.h"
 
 static int cam_jpeg_enc_register_cpas(struct cam_hw_soc_info *soc_info,
 	struct cam_jpeg_enc_device_core_info *core_info,
@@ -57,54 +58,8 @@ static int cam_jpeg_enc_unregister_cpas(
 	return rc;
 }
 
-static int cam_jpeg_enc_remove(struct platform_device *pdev)
-{
-	struct cam_hw_info *jpeg_enc_dev = NULL;
-	struct cam_hw_intf *jpeg_enc_dev_intf = NULL;
-	struct cam_jpeg_enc_device_core_info *core_info = NULL;
-	int rc;
-
-	jpeg_enc_dev_intf = platform_get_drvdata(pdev);
-	if (!jpeg_enc_dev_intf) {
-		CAM_ERR(CAM_JPEG, "error No data in pdev");
-		return -EINVAL;
-	}
-
-	jpeg_enc_dev = jpeg_enc_dev_intf->hw_priv;
-	if (!jpeg_enc_dev) {
-		CAM_ERR(CAM_JPEG, "error HW data is NULL");
-		rc = -ENODEV;
-		goto free_jpeg_hw_intf;
-	}
-
-	core_info = (struct cam_jpeg_enc_device_core_info *)
-		jpeg_enc_dev->core_info;
-	if (!core_info) {
-		CAM_ERR(CAM_JPEG, "error core data NULL");
-		goto deinit_soc;
-	}
-
-	rc = cam_jpeg_enc_unregister_cpas(core_info);
-	if (rc)
-		CAM_ERR(CAM_JPEG, " unreg failed to reg cpas %d", rc);
-
-	mutex_destroy(&core_info->core_mutex);
-	kfree(core_info);
-
-deinit_soc:
-	rc = cam_soc_util_release_platform_resource(&jpeg_enc_dev->soc_info);
-	if (rc)
-		CAM_ERR(CAM_JPEG, "Failed to deinit soc rc=%d", rc);
-
-	mutex_destroy(&jpeg_enc_dev->hw_mutex);
-	kfree(jpeg_enc_dev);
-
-free_jpeg_hw_intf:
-	kfree(jpeg_enc_dev_intf);
-	return rc;
-}
-
-static int cam_jpeg_enc_probe(struct platform_device *pdev)
+static int cam_jpeg_enc_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_hw_info *jpeg_enc_dev = NULL;
 	struct cam_hw_intf *jpeg_enc_dev_intf = NULL;
@@ -112,6 +67,7 @@ static int cam_jpeg_enc_probe(struct platform_device *pdev)
 	struct cam_jpeg_enc_device_core_info *core_info = NULL;
 	struct cam_jpeg_enc_device_hw_info *hw_info = NULL;
 	int rc;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	jpeg_enc_dev_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
 	if (!jpeg_enc_dev_intf)
@@ -178,6 +134,7 @@ static int cam_jpeg_enc_probe(struct platform_device *pdev)
 	mutex_init(&jpeg_enc_dev->hw_mutex);
 	spin_lock_init(&jpeg_enc_dev->hw_lock);
 	init_completion(&jpeg_enc_dev->hw_complete);
+	CAM_DBG(CAM_JPEG, "Encoder component bound successfully");
 
 	return rc;
 
@@ -195,6 +152,76 @@ error_alloc_dev:
 	return rc;
 }
 
+static void cam_jpeg_enc_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct cam_hw_info *jpeg_enc_dev = NULL;
+	struct cam_hw_intf *jpeg_enc_dev_intf = NULL;
+	struct cam_jpeg_enc_device_core_info *core_info = NULL;
+	int rc;
+	struct platform_device *pdev = to_platform_device(dev);
+
+	jpeg_enc_dev_intf = platform_get_drvdata(pdev);
+	if (!jpeg_enc_dev_intf) {
+		CAM_ERR(CAM_JPEG, "error No data in pdev");
+		return;
+	}
+
+	jpeg_enc_dev = jpeg_enc_dev_intf->hw_priv;
+	if (!jpeg_enc_dev) {
+		CAM_ERR(CAM_JPEG, "error HW data is NULL");
+		goto free_jpeg_hw_intf;
+	}
+
+	core_info = (struct cam_jpeg_enc_device_core_info *)
+		jpeg_enc_dev->core_info;
+	if (!core_info) {
+		CAM_ERR(CAM_JPEG, "error core data NULL");
+		goto deinit_soc;
+	}
+
+	rc = cam_jpeg_enc_unregister_cpas(core_info);
+	if (rc)
+		CAM_ERR(CAM_JPEG, " unreg failed to reg cpas %d", rc);
+
+	mutex_destroy(&core_info->core_mutex);
+	kfree(core_info);
+
+deinit_soc:
+	rc = cam_soc_util_release_platform_resource(&jpeg_enc_dev->soc_info);
+	if (rc)
+		CAM_ERR(CAM_JPEG, "Failed to deinit soc rc=%d", rc);
+
+	mutex_destroy(&jpeg_enc_dev->hw_mutex);
+	kfree(jpeg_enc_dev);
+
+free_jpeg_hw_intf:
+	kfree(jpeg_enc_dev_intf);
+}
+
+const static struct component_ops cam_jpeg_enc_component_ops = {
+	.bind = cam_jpeg_enc_component_bind,
+	.unbind = cam_jpeg_enc_component_unbind,
+};
+
+static int cam_jpeg_enc_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_jpeg_enc_component_ops);
+	return 0;
+}
+
+static int cam_jpeg_enc_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_JPEG, "Adding JPEG component");
+	rc = component_add(&pdev->dev, &cam_jpeg_enc_component_ops);
+	if (rc)
+		CAM_ERR(CAM_JPEG, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
 static const struct of_device_id cam_jpeg_enc_dt_match[] = {
 	{
 		.compatible = "qcom,cam_jpeg_enc",
@@ -204,7 +231,7 @@ static const struct of_device_id cam_jpeg_enc_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cam_jpeg_enc_dt_match);
 
-static struct platform_driver cam_jpeg_enc_driver = {
+struct platform_driver cam_jpeg_enc_driver = {
 	.probe = cam_jpeg_enc_probe,
 	.remove = cam_jpeg_enc_remove,
 	.driver = {

+ 31 - 6
drivers/cam_lrme/cam_lrme_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/device.h>
@@ -14,6 +14,7 @@
 #include "cam_lrme_context.h"
 #include "cam_lrme_hw_mgr.h"
 #include "cam_lrme_hw_mgr_intf.h"
+#include "camera_main.h"
 
 #define CAM_LRME_DEV_NAME "cam-lrme"
 
@@ -110,12 +111,14 @@ static const struct v4l2_subdev_internal_ops cam_lrme_subdev_internal_ops = {
 	.close = cam_lrme_dev_close,
 };
 
-static int cam_lrme_dev_probe(struct platform_device *pdev)
+static int cam_lrme_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc;
 	int i;
 	struct cam_hw_mgr_intf hw_mgr_intf;
 	struct cam_node *node;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	g_lrme_dev = kzalloc(sizeof(struct cam_lrme_dev), GFP_KERNEL);
 	if (!g_lrme_dev) {
@@ -157,7 +160,7 @@ static int cam_lrme_dev_probe(struct platform_device *pdev)
 		goto deinit_ctx;
 	}
 
-	CAM_DBG(CAM_LRME, "%s probe complete", g_lrme_dev->sd.name);
+	CAM_DBG(CAM_LRME, "Component bound successfully");
 
 	return 0;
 
@@ -175,7 +178,8 @@ free_mem:
 	return rc;
 }
 
-static int cam_lrme_dev_remove(struct platform_device *pdev)
+static void cam_lrme_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int i;
 	int rc = 0;
@@ -192,15 +196,36 @@ static int cam_lrme_dev_remove(struct platform_device *pdev)
 
 	rc = cam_subdev_remove(&g_lrme_dev->sd);
 	if (rc)
-		CAM_ERR(CAM_LRME, "Unregister failed");
+		CAM_ERR(CAM_LRME, "Unregister failed rc: %d", rc);
 
 	mutex_destroy(&g_lrme_dev->lock);
 	kfree(g_lrme_dev);
 	g_lrme_dev = NULL;
+}
+
+const static struct component_ops cam_lrme_component_ops = {
+	.bind = cam_lrme_component_bind,
+	.unbind = cam_lrme_component_unbind,
+};
+
+static int cam_lrme_dev_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_LRME, "Adding LRME component");
+	rc = component_add(&pdev->dev, &cam_lrme_component_ops);
+	if (rc)
+		CAM_ERR(CAM_LRME, "failed to add component rc: %d", rc);
 
 	return rc;
 }
 
+static int cam_lrme_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_lrme_component_ops);
+	return 0;
+}
+
 static const struct of_device_id cam_lrme_dt_match[] = {
 	{
 		.compatible = "qcom,cam-lrme"
@@ -208,7 +233,7 @@ static const struct of_device_id cam_lrme_dt_match[] = {
 	{}
 };
 
-static struct platform_driver cam_lrme_driver = {
+struct platform_driver cam_lrme_driver = {
 	.probe = cam_lrme_dev_probe,
 	.remove = cam_lrme_dev_remove,
 	.driver = {

+ 32 - 6
drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_dev.c

@@ -20,6 +20,7 @@
 #include "cam_lrme_hw_mgr.h"
 #include "cam_mem_mgr_api.h"
 #include "cam_smmu_api.h"
+#include "camera_main.h"
 
 static int cam_lrme_hw_dev_util_cdm_acquire(struct cam_lrme_core *lrme_core,
 	struct cam_hw_info *lrme_hw)
@@ -77,7 +78,8 @@ error:
 	return rc;
 }
 
-static int cam_lrme_hw_dev_probe(struct platform_device *pdev)
+static int cam_lrme_hw_dev_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_hw_info *lrme_hw;
 	struct cam_hw_intf lrme_hw_intf;
@@ -85,6 +87,7 @@ static int cam_lrme_hw_dev_probe(struct platform_device *pdev)
 	const struct of_device_id *match_dev = NULL;
 	struct cam_lrme_hw_info *hw_info;
 	int rc, i;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	lrme_hw = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
 	if (!lrme_hw) {
@@ -205,7 +208,8 @@ static int cam_lrme_hw_dev_probe(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, lrme_hw);
-	CAM_DBG(CAM_LRME, "LRME-%d probe successful", lrme_hw_intf.hw_idx);
+	CAM_DBG(CAM_LRME, "HW:%d component bound successfully",
+		lrme_hw_intf.hw_idx);
 
 	return rc;
 
@@ -229,22 +233,23 @@ free_memory:
 	return rc;
 }
 
-static int cam_lrme_hw_dev_remove(struct platform_device *pdev)
+static void cam_lrme_hw_dev_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc = 0;
 	struct cam_hw_info *lrme_hw;
 	struct cam_lrme_core *lrme_core;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	lrme_hw = platform_get_drvdata(pdev);
 	if (!lrme_hw) {
 		CAM_ERR(CAM_LRME, "Invalid lrme_hw from fd_hw_intf");
-		return -ENODEV;
+		return;
 	}
 
 	lrme_core = (struct cam_lrme_core *)lrme_hw->core_info;
 	if (!lrme_core) {
 		CAM_ERR(CAM_LRME, "Invalid lrme_core from fd_hw");
-		rc = -EINVAL;
 		goto deinit_platform_res;
 	}
 
@@ -263,10 +268,31 @@ deinit_platform_res:
 
 	mutex_destroy(&lrme_hw->hw_mutex);
 	kfree(lrme_hw);
+}
+
+const static struct component_ops cam_lrme_hw_dev_component_ops = {
+	.bind = cam_lrme_hw_dev_component_bind,
+	.unbind = cam_lrme_hw_dev_component_unbind,
+};
+
+static int cam_lrme_hw_dev_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_LRME, "Adding LRME HW component");
+	rc = component_add(&pdev->dev, &cam_lrme_hw_dev_component_ops);
+	if (rc)
+		CAM_ERR(CAM_LRME, "failed to add component rc: %d", rc);
 
 	return rc;
 }
 
+static int cam_lrme_hw_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_lrme_hw_dev_component_ops);
+	return 0;
+}
+
 static const struct of_device_id cam_lrme_hw_dt_match[] = {
 	{
 		.compatible = "qcom,lrme",
@@ -277,7 +303,7 @@ static const struct of_device_id cam_lrme_hw_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, cam_lrme_hw_dt_match);
 
-static struct platform_driver cam_lrme_hw_driver = {
+struct platform_driver cam_lrme_hw_driver = {
 	.probe = cam_lrme_hw_dev_probe,
 	.remove = cam_lrme_hw_dev_remove,
 	.driver = {

+ 37 - 10
drivers/cam_ope/cam_ope_subdev.c

@@ -29,6 +29,7 @@
 #include "cam_hw_mgr_intf.h"
 #include "cam_debug_util.h"
 #include "cam_smmu_api.h"
+#include "camera_main.h"
 
 #define OPE_DEV_NAME        "cam-ope"
 
@@ -140,14 +141,16 @@ const struct v4l2_subdev_internal_ops cam_ope_subdev_internal_ops = {
 	.close = cam_ope_subdev_close,
 };
 
-static int cam_ope_subdev_probe(struct platform_device *pdev)
+static int cam_ope_subdev_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc = 0, i = 0;
 	struct cam_node *node;
 	struct cam_hw_mgr_intf *hw_mgr_intf;
 	int iommu_hdl = -1;
+	struct platform_device *pdev = to_platform_device(dev);
 
-	CAM_DBG(CAM_OPE, "OPE subdev probe start");
+	CAM_DBG(CAM_OPE, "Binding OPE subdev component");
 	if (!pdev) {
 		CAM_ERR(CAM_OPE, "pdev is NULL");
 		return -EINVAL;
@@ -200,7 +203,7 @@ static int cam_ope_subdev_probe(struct platform_device *pdev)
 	g_ope_dev.open_cnt = 0;
 	mutex_init(&g_ope_dev.ope_lock);
 
-	CAM_DBG(CAM_OPE, "OPE subdev probe complete");
+	CAM_DBG(CAM_OPE, "Subdev component bound successfully");
 
 	return rc;
 
@@ -214,35 +217,59 @@ hw_alloc_fail:
 	return rc;
 }
 
-static int cam_ope_subdev_remove(struct platform_device *pdev)
+static void cam_ope_subdev_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int i;
 	struct v4l2_subdev *sd;
 	struct cam_subdev *subdev;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	if (!pdev) {
 		CAM_ERR(CAM_OPE, "pdev is NULL");
-		return -ENODEV;
+		return;
 	}
 
 	sd = platform_get_drvdata(pdev);
 	if (!sd) {
 		CAM_ERR(CAM_OPE, "V4l2 subdev is NULL");
-		return -ENODEV;
+		return;
 	}
 
 	subdev = v4l2_get_subdevdata(sd);
 	if (!subdev) {
 		CAM_ERR(CAM_OPE, "cam subdev is NULL");
-		return -ENODEV;
+		return;
 	}
 
 	for (i = 0; i < OPE_CTX_MAX; i++)
 		cam_ope_context_deinit(&g_ope_dev.ctx_ope[i]);
+
 	cam_node_deinit(g_ope_dev.node);
 	cam_subdev_remove(&g_ope_dev.sd);
 	mutex_destroy(&g_ope_dev.ope_lock);
+}
 
+const static struct component_ops cam_ope_subdev_component_ops = {
+	.bind = cam_ope_subdev_component_bind,
+	.unbind = cam_ope_subdev_component_unbind,
+};
+
+static int cam_ope_subdev_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_OPE, "Adding OPE subdev component");
+	rc = component_add(&pdev->dev, &cam_ope_subdev_component_ops);
+	if (rc)
+		CAM_ERR(CAM_OPE, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int cam_ope_subdev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_ope_subdev_component_ops);
 	return 0;
 }
 
@@ -252,7 +279,7 @@ static const struct of_device_id cam_ope_dt_match[] = {
 };
 
 
-static struct platform_driver cam_ope_driver = {
+struct platform_driver cam_ope_subdev_driver = {
 	.probe = cam_ope_subdev_probe,
 	.remove = cam_ope_subdev_remove,
 	.driver = {
@@ -264,12 +291,12 @@ static struct platform_driver cam_ope_driver = {
 
 int cam_ope_subdev_init_module(void)
 {
-	return platform_driver_register(&cam_ope_driver);
+	return platform_driver_register(&cam_ope_subdev_driver);
 }
 
 void cam_ope_subdev_exit_module(void)
 {
-	platform_driver_unregister(&cam_ope_driver);
+	platform_driver_unregister(&cam_ope_subdev_driver);
 }
 
 MODULE_DESCRIPTION("MSM OPE driver");

+ 32 - 3
drivers/cam_ope/ope_hw_mgr/ope_hw/ope_dev.c

@@ -19,6 +19,7 @@
 #include "cam_debug_util.h"
 #include "ope_hw_100.h"
 #include "ope_dev_intf.h"
+#include "camera_main.h"
 
 static struct cam_ope_device_hw_info ope_hw_info;
 static struct ope_dev_soc ope_soc_info;
@@ -105,7 +106,8 @@ int cam_ope_register_cpas(struct cam_hw_soc_info *soc_info,
 	return rc;
 }
 
-int cam_ope_probe(struct platform_device *pdev)
+static int cam_ope_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_hw_intf                *ope_dev_intf = NULL;
 	struct cam_hw_info                *ope_dev = NULL;
@@ -115,6 +117,7 @@ int cam_ope_probe(struct platform_device *pdev)
 	uint32_t hw_idx;
 	struct cam_ope_dev_probe ope_probe;
 	struct cam_ope_cpas_vote cpas_vote;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	of_property_read_u32(pdev->dev.of_node,
 		"cell-index", &hw_idx);
@@ -225,7 +228,7 @@ int cam_ope_probe(struct platform_device *pdev)
 	spin_lock_init(&ope_dev->hw_lock);
 	init_completion(&ope_dev->hw_complete);
 
-	CAM_DBG(CAM_OPE, "OPE%d probe successful",
+	CAM_DBG(CAM_OPE, "OPE:%d component bound successfully"
 		ope_dev_intf->hw_idx);
 	return rc;
 
@@ -242,6 +245,32 @@ ope_dev_alloc_failed:
 	return rc;
 }
 
+static void cam_ope_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	CAM_DBG(CAM_OPE, "Unbinding component: %s", pdev->name);
+}
+
+
+const static struct component_ops cam_ope_component_ops = {
+	.bind = cam_ope_component_bind,
+	.unbind = cam_ope_component_unbind,
+};
+
+int cam_ope_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_OPE, "Adding OPE component");
+	rc = component_add(&pdev->dev, &cam_vfe_component_ops);
+	if (rc)
+		CAM_ERR(CAM_OPE, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
 static const struct of_device_id cam_ope_dt_match[] = {
 	{
 		.compatible = "qcom,ope",
@@ -251,7 +280,7 @@ static const struct of_device_id cam_ope_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cam_ope_dt_match);
 
-static struct platform_driver cam_ope_driver = {
+struct platform_driver cam_ope_driver = {
 	.probe = cam_ope_probe,
 	.driver = {
 		.name = "ope",

+ 72 - 19
drivers/cam_req_mgr/cam_req_mgr_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -24,6 +24,7 @@
 #include "cam_mem_mgr.h"
 #include "cam_debug_util.h"
 #include "cam_common_util.h"
+#include "camera_main.h"
 
 #define CAM_REQ_MGR_EVENT_MAX 30
 
@@ -713,28 +714,16 @@ int cam_unregister_subdev(struct cam_subdev *csd)
 }
 EXPORT_SYMBOL(cam_unregister_subdev);
 
-static int cam_req_mgr_remove(struct platform_device *pdev)
+static int cam_req_mgr_component_master_bind(struct device *dev)
 {
-	cam_req_mgr_core_device_deinit();
-	cam_req_mgr_util_deinit();
-	cam_media_device_cleanup();
-	cam_video_device_cleanup();
-	cam_v4l2_device_cleanup();
-	mutex_destroy(&g_dev.dev_lock);
-	g_dev.state = false;
-
-	return 0;
-}
-
-static int cam_req_mgr_probe(struct platform_device *pdev)
-{
-	int rc;
+	int rc = 0;
 
-	rc = cam_v4l2_device_setup(&pdev->dev);
+	CAM_DBG(CAM_CRM, "Master bind called");
+	rc = cam_v4l2_device_setup(dev);
 	if (rc)
 		return rc;
 
-	rc = cam_media_device_setup(&pdev->dev);
+	rc = cam_media_device_setup(dev);
 	if (rc)
 		goto media_setup_fail;
 
@@ -773,6 +762,16 @@ static int cam_req_mgr_probe(struct platform_device *pdev)
 	}
 
 	g_dev.state = true;
+
+	CAM_DBG(CAM_CRM, "Binding all slave components");
+	rc = component_bind_all(dev, NULL);
+	if (rc) {
+		CAM_ERR(CAM_CRM,
+			"Error in binding all components rc: %d, Camera initialization failed!",
+			rc);
+		goto req_mgr_core_fail;
+	}
+
 	return rc;
 
 req_mgr_core_fail:
@@ -788,13 +787,67 @@ media_setup_fail:
 	return rc;
 }
 
+static void cam_req_mgr_component_master_unbind(struct device *dev)
+{
+	/* Unbinding all slave components first */
+	component_unbind_all(dev, NULL);
+
+	/* Now proceed with unbinding master */
+	cam_req_mgr_core_device_deinit();
+	cam_req_mgr_util_deinit();
+	cam_media_device_cleanup();
+	cam_video_device_cleanup();
+	cam_v4l2_device_cleanup();
+	mutex_destroy(&g_dev.dev_lock);
+	g_dev.state = false;
+}
+
+static const struct component_master_ops cam_req_mgr_component_master_ops = {
+	.bind = cam_req_mgr_component_master_bind,
+	.unbind = cam_req_mgr_component_master_unbind,
+};
+
+static int cam_req_mgr_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &cam_req_mgr_component_master_ops);
+	return 0;
+}
+
+static int cam_req_mgr_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct component_match *match_list = NULL;
+	struct device *dev = &pdev->dev;
+
+	rc = camera_component_match_add_drivers(dev, &match_list);
+	if (rc) {
+		CAM_ERR(CAM_CRM,
+			"Unable to match components, probe failed rc: %d",
+			rc);
+		goto end;
+	}
+
+	/* Supply match_list to master for handing over control */
+	rc = component_master_add_with_match(dev,
+		&cam_req_mgr_component_master_ops, match_list);
+	if (rc) {
+		CAM_ERR(CAM_CRM,
+			"Unable to add master, probe failed rc: %d",
+			rc);
+		goto end;
+	}
+
+end:
+	return rc;
+}
+
 static const struct of_device_id cam_req_mgr_dt_match[] = {
 	{.compatible = "qcom,cam-req-mgr"},
 	{}
 };
 MODULE_DEVICE_TABLE(of, cam_req_mgr_dt_match);
 
-static struct platform_driver cam_req_mgr_driver = {
+struct platform_driver cam_req_mgr_driver = {
 	.probe = cam_req_mgr_probe,
 	.remove = cam_req_mgr_remove,
 	.driver = {

+ 108 - 81
drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include "cam_actuator_dev.h"
@@ -8,6 +8,7 @@
 #include "cam_actuator_soc.h"
 #include "cam_actuator_core.h"
 #include "cam_trace.h"
+#include "camera_main.h"
 
 static long cam_actuator_subdev_ioctl(struct v4l2_subdev *sd,
 	unsigned int cmd, void *arg)
@@ -222,86 +223,14 @@ free_ctrl:
 	return rc;
 }
 
-static int32_t cam_actuator_platform_remove(struct platform_device *pdev)
+static int cam_actuator_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
-	int32_t rc = 0;
-	struct cam_actuator_ctrl_t      *a_ctrl;
-	struct cam_actuator_soc_private *soc_private;
-	struct cam_sensor_power_ctrl_t  *power_info;
-
-	a_ctrl = platform_get_drvdata(pdev);
-	if (!a_ctrl) {
-		CAM_ERR(CAM_ACTUATOR, "Actuator device is NULL");
-		return 0;
-	}
-
-	CAM_INFO(CAM_ACTUATOR, "platform remove invoked");
-	mutex_lock(&(a_ctrl->actuator_mutex));
-	cam_actuator_shutdown(a_ctrl);
-	mutex_unlock(&(a_ctrl->actuator_mutex));
-	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));
-
-	soc_private =
-		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
-	power_info = &soc_private->power_info;
-
-	kfree(a_ctrl->io_master_info.cci_client);
-	a_ctrl->io_master_info.cci_client = NULL;
-	kfree(a_ctrl->soc_info.soc_private);
-	a_ctrl->soc_info.soc_private = NULL;
-	kfree(a_ctrl->i2c_data.per_frame);
-	a_ctrl->i2c_data.per_frame = NULL;
-	v4l2_set_subdevdata(&a_ctrl->v4l2_dev_str.sd, NULL);
-	platform_set_drvdata(pdev, NULL);
-	devm_kfree(&pdev->dev, a_ctrl);
-
-	return rc;
-}
-
-static int32_t cam_actuator_driver_i2c_remove(struct i2c_client *client)
-{
-	struct cam_actuator_ctrl_t      *a_ctrl =
-		i2c_get_clientdata(client);
-	struct cam_actuator_soc_private *soc_private;
-	struct cam_sensor_power_ctrl_t  *power_info;
-
-	/* Handle I2C Devices */
-	if (!a_ctrl) {
-		CAM_ERR(CAM_ACTUATOR, "Actuator device is NULL");
-		return -EINVAL;
-	}
-
-	CAM_INFO(CAM_ACTUATOR, "i2c remove invoked");
-	mutex_lock(&(a_ctrl->actuator_mutex));
-	cam_actuator_shutdown(a_ctrl);
-	mutex_unlock(&(a_ctrl->actuator_mutex));
-	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));
-	soc_private =
-		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
-	power_info = &soc_private->power_info;
-
-	/*Free Allocated Mem */
-	kfree(a_ctrl->i2c_data.per_frame);
-	a_ctrl->i2c_data.per_frame = NULL;
-	a_ctrl->soc_info.soc_private = NULL;
-	v4l2_set_subdevdata(&a_ctrl->v4l2_dev_str.sd, NULL);
-	kfree(a_ctrl);
-
-	return 0;
-}
-
-static const struct of_device_id cam_actuator_driver_dt_match[] = {
-	{.compatible = "qcom,actuator"},
-	{}
-};
-
-static int32_t cam_actuator_driver_platform_probe(
-	struct platform_device *pdev)
-{
-	int32_t                         rc = 0;
-	int32_t                         i = 0;
-	struct cam_actuator_ctrl_t      *a_ctrl = NULL;
-	struct cam_actuator_soc_private *soc_private = NULL;
+	int32_t                          rc = 0;
+	int32_t                          i = 0;
+	struct cam_actuator_ctrl_t       *a_ctrl = NULL;
+	struct cam_actuator_soc_private  *soc_private = NULL;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	/* Create actuator control structure */
 	a_ctrl = devm_kzalloc(&pdev->dev,
@@ -372,6 +301,7 @@ static int32_t cam_actuator_driver_platform_probe(
 
 	platform_set_drvdata(pdev, a_ctrl);
 	a_ctrl->cam_act_state = CAM_ACTUATOR_INIT;
+	CAM_DBG(CAM_ACTUATOR, "Component bound successfully");
 
 	return rc;
 
@@ -386,9 +316,106 @@ free_ctrl:
 	return rc;
 }
 
+static void cam_actuator_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct cam_actuator_ctrl_t      *a_ctrl;
+	struct cam_actuator_soc_private *soc_private;
+	struct cam_sensor_power_ctrl_t  *power_info;
+	struct platform_device *pdev = to_platform_device(dev);
+
+	a_ctrl = platform_get_drvdata(pdev);
+	if (!a_ctrl) {
+		CAM_ERR(CAM_ACTUATOR, "Actuator device is NULL");
+		return;
+	}
+
+	mutex_lock(&(a_ctrl->actuator_mutex));
+	cam_actuator_shutdown(a_ctrl);
+	mutex_unlock(&(a_ctrl->actuator_mutex));
+	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));
+
+	soc_private =
+		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
+	power_info = &soc_private->power_info;
+
+	kfree(a_ctrl->io_master_info.cci_client);
+	a_ctrl->io_master_info.cci_client = NULL;
+	kfree(a_ctrl->soc_info.soc_private);
+	a_ctrl->soc_info.soc_private = NULL;
+	kfree(a_ctrl->i2c_data.per_frame);
+	a_ctrl->i2c_data.per_frame = NULL;
+	v4l2_set_subdevdata(&a_ctrl->v4l2_dev_str.sd, NULL);
+	platform_set_drvdata(pdev, NULL);
+	devm_kfree(&pdev->dev, a_ctrl);
+	CAM_INFO(CAM_ACTUATOR, "Actuator component unbinded");
+}
+
+const static struct component_ops cam_actuator_component_ops = {
+	.bind = cam_actuator_component_bind,
+	.unbind = cam_actuator_component_unbind,
+};
+
+static int32_t cam_actuator_platform_remove(
+	struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_actuator_component_ops);
+	return 0;
+}
+
+static int32_t cam_actuator_driver_i2c_remove(struct i2c_client *client)
+{
+	struct cam_actuator_ctrl_t      *a_ctrl =
+		i2c_get_clientdata(client);
+	struct cam_actuator_soc_private *soc_private;
+	struct cam_sensor_power_ctrl_t  *power_info;
+
+	/* Handle I2C Devices */
+	if (!a_ctrl) {
+		CAM_ERR(CAM_ACTUATOR, "Actuator device is NULL");
+		return -EINVAL;
+	}
+
+	CAM_INFO(CAM_ACTUATOR, "i2c remove invoked");
+	mutex_lock(&(a_ctrl->actuator_mutex));
+	cam_actuator_shutdown(a_ctrl);
+	mutex_unlock(&(a_ctrl->actuator_mutex));
+	cam_unregister_subdev(&(a_ctrl->v4l2_dev_str));
+	soc_private =
+		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
+	power_info = &soc_private->power_info;
+
+	/*Free Allocated Mem */
+	kfree(a_ctrl->i2c_data.per_frame);
+	a_ctrl->i2c_data.per_frame = NULL;
+	a_ctrl->soc_info.soc_private = NULL;
+	v4l2_set_subdevdata(&a_ctrl->v4l2_dev_str.sd, NULL);
+	kfree(a_ctrl);
+
+	return 0;
+}
+
+static const struct of_device_id cam_actuator_driver_dt_match[] = {
+	{.compatible = "qcom,actuator"},
+	{}
+};
+
+static int32_t cam_actuator_driver_platform_probe(
+	struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_ACTUATOR, "Adding sensor actuator component");
+	rc = component_add(&pdev->dev, &cam_actuator_component_ops);
+	if (rc)
+		CAM_ERR(CAM_ICP, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
 MODULE_DEVICE_TABLE(of, cam_actuator_driver_dt_match);
 
-static struct platform_driver cam_actuator_platform_driver = {
+struct platform_driver cam_actuator_platform_driver = {
 	.probe = cam_actuator_driver_platform_probe,
 	.driver = {
 		.name = "qcom,actuator",

+ 33 - 4
drivers/cam_sensor_module/cam_cci/cam_cci_dev.c

@@ -7,6 +7,7 @@
 #include "cam_req_mgr_dev.h"
 #include "cam_cci_soc.h"
 #include "cam_cci_core.h"
+#include "camera_main.h"
 
 #define CCI_MAX_DELAY 1000000
 
@@ -366,12 +367,14 @@ static const struct v4l2_subdev_ops cci_subdev_ops = {
 
 static const struct v4l2_subdev_internal_ops cci_subdev_intern_ops;
 
-static int cam_cci_platform_probe(struct platform_device *pdev)
+static int cam_cci_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_cpas_register_params cpas_parms;
 	struct cci_device *new_cci_dev;
 	struct cam_hw_soc_info *soc_info = NULL;
 	int rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	new_cci_dev = kzalloc(sizeof(struct cci_device),
 		GFP_KERNEL);
@@ -435,18 +438,22 @@ static int cam_cci_platform_probe(struct platform_device *pdev)
 		CAM_ERR(CAM_CCI, "CPAS registration failed");
 		goto cci_no_resource;
 	}
+
 	CAM_DBG(CAM_CCI, "CPAS registration successful handle=%d",
 		cpas_parms.client_handle);
 	new_cci_dev->cpas_handle = cpas_parms.client_handle;
-
+	CAM_DBG(CAM_CCI, "Component bound successfully");
 	return rc;
 cci_no_resource:
 	kfree(new_cci_dev);
 	return rc;
 }
 
-static int cam_cci_device_remove(struct platform_device *pdev)
+static void cam_cci_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
+	struct platform_device *pdev = to_platform_device(dev);
+
 	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
 	struct cci_device *cci_dev =
 		v4l2_get_subdevdata(subdev);
@@ -454,6 +461,28 @@ static int cam_cci_device_remove(struct platform_device *pdev)
 	cam_cpas_unregister_client(cci_dev->cpas_handle);
 	cam_cci_soc_remove(pdev, cci_dev);
 	devm_kfree(&pdev->dev, cci_dev);
+}
+
+const static struct component_ops cam_cci_component_ops = {
+	.bind = cam_cci_component_bind,
+	.unbind = cam_cci_component_unbind,
+};
+
+static int cam_cci_platform_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_CCI, "Adding CCI component");
+	rc = component_add(&pdev->dev, &cam_cci_component_ops);
+	if (rc)
+		CAM_ERR(CAM_CCI, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int cam_cci_device_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_cci_component_ops);
 	return 0;
 }
 
@@ -464,7 +493,7 @@ static const struct of_device_id cam_cci_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, cam_cci_dt_match);
 
-static struct platform_driver cci_driver = {
+struct platform_driver cci_driver = {
 	.probe = cam_cci_platform_probe,
 	.remove = cam_cci_device_remove,
 	.driver = {

+ 0 - 4
drivers/cam_sensor_module/cam_cci/cam_cci_soc.c

@@ -378,10 +378,6 @@ int cam_cci_parse_dt_info(struct platform_device *pdev,
 	cam_cci_init_cci_params(new_cci_dev);
 	cam_cci_init_clk_params(new_cci_dev);
 
-	rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
-	if (rc)
-		CAM_ERR(CAM_CCI, "failed to add child nodes, rc=%d", rc);
-
 	for (i = 0; i < MASTER_MAX; i++) {
 		new_cci_dev->write_wq[i] = create_singlethread_workqueue(
 			"cam_cci_wq");

+ 39 - 12
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include "cam_csiphy_dev.h"
@@ -8,6 +8,7 @@
 #include "cam_csiphy_soc.h"
 #include "cam_csiphy_core.h"
 #include <media/cam_sensor.h>
+#include "camera_main.h"
 
 static long cam_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
 	unsigned int cmd, void *arg)
@@ -104,11 +105,13 @@ static const struct v4l2_subdev_internal_ops csiphy_subdev_intern_ops = {
 	.close = cam_csiphy_subdev_close,
 };
 
-static int32_t cam_csiphy_platform_probe(struct platform_device *pdev)
+static int cam_csiphy_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	struct cam_cpas_register_params cpas_parms;
 	struct csiphy_device *new_csiphy_dev;
-	int32_t              rc = 0;
+	int32_t               rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	new_csiphy_dev = devm_kzalloc(&pdev->dev,
 		sizeof(struct csiphy_device), GFP_KERNEL);
@@ -183,10 +186,12 @@ static int32_t cam_csiphy_platform_probe(struct platform_device *pdev)
 		CAM_ERR(CAM_CSIPHY, "CPAS registration failed rc: %d", rc);
 		goto csiphy_no_resource;
 	}
+
 	CAM_DBG(CAM_CSIPHY, "CPAS registration successful handle=%d",
 		cpas_parms.client_handle);
 	new_csiphy_dev->cpas_handle = cpas_parms.client_handle;
-
+	CAM_DBG(CAM_CSIPHY, "%s component bound successfully",
+		pdev->name);
 	return rc;
 csiphy_no_resource:
 	mutex_destroy(&new_csiphy_dev->mutex);
@@ -195,15 +200,15 @@ csiphy_no_resource:
 	return rc;
 }
 
-
-static int32_t cam_csiphy_device_remove(struct platform_device *pdev)
+static void cam_csiphy_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
-	struct v4l2_subdev *subdev =
-		platform_get_drvdata(pdev);
-	struct csiphy_device *csiphy_dev =
-		v4l2_get_subdevdata(subdev);
+	struct platform_device *pdev = to_platform_device(dev);
 
-	CAM_INFO(CAM_CSIPHY, "device remove invoked");
+	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
+	struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(subdev);
+
+	CAM_INFO(CAM_CSIPHY, "Unbind CSIPHY component");
 	cam_cpas_unregister_client(csiphy_dev->cpas_handle);
 	cam_csiphy_soc_release(csiphy_dev);
 	mutex_lock(&csiphy_dev->mutex);
@@ -215,7 +220,29 @@ static int32_t cam_csiphy_device_remove(struct platform_device *pdev)
 	platform_set_drvdata(pdev, NULL);
 	v4l2_set_subdevdata(&(csiphy_dev->v4l2_dev_str.sd), NULL);
 	devm_kfree(&pdev->dev, csiphy_dev);
+}
 
+const static struct component_ops cam_csiphy_component_ops = {
+	.bind = cam_csiphy_component_bind,
+	.unbind = cam_csiphy_component_unbind,
+};
+
+static int32_t cam_csiphy_platform_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_CSIPHY, "Adding CSIPHY component");
+	rc = component_add(&pdev->dev, &cam_csiphy_component_ops);
+	if (rc)
+		CAM_ERR(CAM_CSIPHY, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+
+static int32_t cam_csiphy_device_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_csiphy_component_ops);
 	return 0;
 }
 
@@ -226,7 +253,7 @@ static const struct of_device_id cam_csiphy_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, cam_csiphy_dt_match);
 
-static struct platform_driver csiphy_driver = {
+struct platform_driver csiphy_driver = {
 	.probe = cam_csiphy_platform_probe,
 	.remove = cam_csiphy_device_remove,
 	.driver = {

+ 33 - 6
drivers/cam_sensor_module/cam_eeprom/cam_eeprom_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include "cam_eeprom_dev.h"
@@ -8,6 +8,7 @@
 #include "cam_eeprom_soc.h"
 #include "cam_eeprom_core.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 static long cam_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
 	unsigned int cmd, void *arg)
@@ -409,12 +410,13 @@ static int cam_eeprom_spi_driver_remove(struct spi_device *sdev)
 	return 0;
 }
 
-static int32_t cam_eeprom_platform_driver_probe(
-	struct platform_device *pdev)
+static int cam_eeprom_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int32_t                         rc = 0;
 	struct cam_eeprom_ctrl_t       *e_ctrl = NULL;
 	struct cam_eeprom_soc_private  *soc_private = NULL;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	e_ctrl = kzalloc(sizeof(struct cam_eeprom_ctrl_t), GFP_KERNEL);
 	if (!e_ctrl)
@@ -469,6 +471,7 @@ static int32_t cam_eeprom_platform_driver_probe(
 	e_ctrl->bridge_intf.ops.apply_req = NULL;
 	platform_set_drvdata(pdev, e_ctrl);
 	e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
+	CAM_DBG(CAM_EEPROM, "Component bound successfully");
 
 	return rc;
 free_soc:
@@ -481,16 +484,18 @@ free_e_ctrl:
 	return rc;
 }
 
-static int cam_eeprom_platform_driver_remove(struct platform_device *pdev)
+static void cam_eeprom_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int                        i;
 	struct cam_eeprom_ctrl_t  *e_ctrl;
 	struct cam_hw_soc_info    *soc_info;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	e_ctrl = platform_get_drvdata(pdev);
 	if (!e_ctrl) {
 		CAM_ERR(CAM_EEPROM, "eeprom device is NULL");
-		return -EINVAL;
+		return;
 	}
 
 	CAM_INFO(CAM_EEPROM, "Platform driver remove invoked");
@@ -509,7 +514,29 @@ static int cam_eeprom_platform_driver_remove(struct platform_device *pdev)
 	platform_set_drvdata(pdev, NULL);
 	v4l2_set_subdevdata(&e_ctrl->v4l2_dev_str.sd, NULL);
 	kfree(e_ctrl);
+}
 
+const static struct component_ops cam_eeprom_component_ops = {
+	.bind = cam_eeprom_component_bind,
+	.unbind = cam_eeprom_component_unbind,
+};
+
+static int32_t cam_eeprom_platform_driver_probe(
+	struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_EEPROM, "Adding EEPROM Sensor component");
+	rc = component_add(&pdev->dev, &cam_eeprom_component_ops);
+	if (rc)
+		CAM_ERR(CAM_EEPROM, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int cam_eeprom_platform_driver_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_eeprom_component_ops);
 	return 0;
 }
 
@@ -521,7 +548,7 @@ static const struct of_device_id cam_eeprom_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, cam_eeprom_dt_match);
 
-static struct platform_driver cam_eeprom_platform_driver = {
+struct platform_driver cam_eeprom_platform_driver = {
 	.driver = {
 		.name = "qcom,eeprom",
 		.owner = THIS_MODULE,

+ 53 - 27
drivers/cam_sensor_module/cam_flash/cam_flash_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -8,6 +8,7 @@
 #include "cam_flash_soc.h"
 #include "cam_flash_core.h"
 #include "cam_common_util.h"
+#include "camera_main.h"
 
 static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
 		void *arg, struct cam_flash_private_soc *soc_private)
@@ -302,28 +303,6 @@ static long cam_flash_subdev_do_ioctl(struct v4l2_subdev *sd,
 }
 #endif
 
-static int cam_flash_platform_remove(struct platform_device *pdev)
-{
-	struct cam_flash_ctrl *fctrl;
-
-	fctrl = platform_get_drvdata(pdev);
-	if (!fctrl) {
-		CAM_ERR(CAM_FLASH, "Flash device is NULL");
-		return 0;
-	}
-
-	CAM_INFO(CAM_FLASH, "Platform remove invoked");
-	mutex_lock(&fctrl->flash_mutex);
-	cam_flash_shutdown(fctrl);
-	mutex_unlock(&fctrl->flash_mutex);
-	cam_unregister_subdev(&(fctrl->v4l2_dev_str));
-	platform_set_drvdata(pdev, NULL);
-	v4l2_set_subdevdata(&fctrl->v4l2_dev_str.sd, NULL);
-	kfree(fctrl);
-
-	return 0;
-}
-
 static int32_t cam_flash_i2c_driver_remove(struct i2c_client *client)
 {
 	int32_t rc = 0;
@@ -397,13 +376,15 @@ static int cam_flash_init_subdev(struct cam_flash_ctrl *fctrl)
 	return rc;
 }
 
-static int32_t cam_flash_platform_probe(struct platform_device *pdev)
+static int cam_flash_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int32_t rc = 0, i = 0;
 	struct cam_flash_ctrl *fctrl = NULL;
 	struct device_node *of_parent = NULL;
+	struct platform_device *pdev = to_platform_device(dev);
 
-	CAM_DBG(CAM_FLASH, "Enter");
+	CAM_DBG(CAM_FLASH, "Binding flash component");
 	if (!pdev->dev.of_node) {
 		CAM_ERR(CAM_FLASH, "of_node NULL");
 		return -EINVAL;
@@ -503,7 +484,7 @@ static int32_t cam_flash_platform_probe(struct platform_device *pdev)
 	mutex_init(&(fctrl->flash_mutex));
 
 	fctrl->flash_state = CAM_FLASH_STATE_INIT;
-	CAM_DBG(CAM_FLASH, "Probe success");
+	CAM_DBG(CAM_FLASH, "Component bound successfully");
 	return rc;
 
 free_cci_resource:
@@ -520,6 +501,51 @@ free_resource:
 	return rc;
 }
 
+static void cam_flash_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct cam_flash_ctrl *fctrl;
+	struct platform_device *pdev = to_platform_device(dev);
+
+	fctrl = platform_get_drvdata(pdev);
+	if (!fctrl) {
+		CAM_ERR(CAM_FLASH, "Flash device is NULL");
+		return;
+	}
+
+	mutex_lock(&fctrl->flash_mutex);
+	cam_flash_shutdown(fctrl);
+	mutex_unlock(&fctrl->flash_mutex);
+	cam_unregister_subdev(&(fctrl->v4l2_dev_str));
+	platform_set_drvdata(pdev, NULL);
+	v4l2_set_subdevdata(&fctrl->v4l2_dev_str.sd, NULL);
+	kfree(fctrl);
+	CAM_INFO(CAM_FLASH, "Flash Sensor component unbind");
+}
+
+const static struct component_ops cam_flash_component_ops = {
+	.bind = cam_flash_component_bind,
+	.unbind = cam_flash_component_unbind,
+};
+
+static int cam_flash_platform_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_flash_component_ops);
+	return 0;
+}
+
+static int32_t cam_flash_platform_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_FLASH, "Adding Flash Sensor component");
+	rc = component_add(&pdev->dev, &cam_flash_component_ops);
+	if (rc)
+		CAM_ERR(CAM_FLASH, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
 static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client,
 	const struct i2c_device_id *id)
 {
@@ -601,7 +627,7 @@ free_ctrl:
 
 MODULE_DEVICE_TABLE(of, cam_flash_dt_match);
 
-static struct platform_driver cam_flash_platform_driver = {
+struct platform_driver cam_flash_platform_driver = {
 	.probe = cam_flash_platform_probe,
 	.remove = cam_flash_platform_remove,
 	.driver = {

+ 33 - 7
drivers/cam_sensor_module/cam_ois/cam_ois_dev.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include "cam_ois_dev.h"
@@ -8,6 +8,7 @@
 #include "cam_ois_soc.h"
 #include "cam_ois_core.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 static long cam_ois_subdev_ioctl(struct v4l2_subdev *sd,
 	unsigned int cmd, void *arg)
@@ -244,12 +245,13 @@ static int cam_ois_i2c_driver_remove(struct i2c_client *client)
 	return 0;
 }
 
-static int32_t cam_ois_platform_driver_probe(
-	struct platform_device *pdev)
+static int cam_ois_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int32_t                         rc = 0;
 	struct cam_ois_ctrl_t          *o_ctrl = NULL;
 	struct cam_ois_soc_private     *soc_private = NULL;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	o_ctrl = kzalloc(sizeof(struct cam_ois_ctrl_t), GFP_KERNEL);
 	if (!o_ctrl)
@@ -300,7 +302,7 @@ static int32_t cam_ois_platform_driver_probe(
 
 	platform_set_drvdata(pdev, o_ctrl);
 	o_ctrl->cam_ois_state = CAM_OIS_INIT;
-
+	CAM_DBG(CAM_OIS, "Component bound successfully");
 	return rc;
 unreg_subdev:
 	cam_unregister_subdev(&(o_ctrl->v4l2_dev_str));
@@ -313,18 +315,20 @@ free_o_ctrl:
 	return rc;
 }
 
-static int cam_ois_platform_driver_remove(struct platform_device *pdev)
+static void cam_ois_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int                             i;
 	struct cam_ois_ctrl_t          *o_ctrl;
 	struct cam_ois_soc_private     *soc_private;
 	struct cam_sensor_power_ctrl_t *power_info;
 	struct cam_hw_soc_info         *soc_info;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	o_ctrl = platform_get_drvdata(pdev);
 	if (!o_ctrl) {
 		CAM_ERR(CAM_OIS, "ois device is NULL");
-		return -EINVAL;
+		return;
 	}
 
 	CAM_INFO(CAM_OIS, "platform driver remove invoked");
@@ -346,7 +350,29 @@ static int cam_ois_platform_driver_remove(struct platform_device *pdev)
 	platform_set_drvdata(pdev, NULL);
 	v4l2_set_subdevdata(&o_ctrl->v4l2_dev_str.sd, NULL);
 	kfree(o_ctrl);
+}
+
+const static struct component_ops cam_ois_component_ops = {
+	.bind = cam_ois_component_bind,
+	.unbind = cam_ois_component_unbind,
+};
+
+static int32_t cam_ois_platform_driver_probe(
+	struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_OIS, "Adding OIS Sensor component");
+	rc = component_add(&pdev->dev, &cam_ois_component_ops);
+	if (rc)
+		CAM_ERR(CAM_OIS, "failed to add component rc: %d", rc);
 
+	return rc;
+}
+
+static int cam_ois_platform_driver_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_ois_component_ops);
 	return 0;
 }
 
@@ -358,7 +384,7 @@ static const struct of_device_id cam_ois_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, cam_ois_dt_match);
 
-static struct platform_driver cam_ois_platform_driver = {
+struct platform_driver cam_ois_platform_driver = {
 	.driver = {
 		.name = "qcom,ois",
 		.owner = THIS_MODULE,

+ 30 - 4
drivers/cam_sensor_module/cam_res_mgr/cam_res_mgr.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/init.h>
@@ -12,6 +12,7 @@
 #include "cam_debug_util.h"
 #include "cam_res_mgr_api.h"
 #include "cam_res_mgr_private.h"
+#include "camera_main.h"
 
 static struct cam_res_mgr *cam_res;
 
@@ -664,9 +665,11 @@ static int cam_res_mgr_parse_dt(struct device *dev)
 	return rc;
 }
 
-static int cam_res_mgr_probe(struct platform_device *pdev)
+static int cam_res_mgr_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	cam_res = kzalloc(sizeof(*cam_res), GFP_KERNEL);
 	if (!cam_res)
@@ -692,17 +695,40 @@ static int cam_res_mgr_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&cam_res->gpio_res_list);
 	INIT_LIST_HEAD(&cam_res->flash_res_list);
 
+	CAM_DBG(CAM_RES, "Component bound successfully");
 	return 0;
 }
 
-static int cam_res_mgr_remove(struct platform_device *pdev)
+static void cam_res_mgr_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	if (cam_res) {
 		cam_res_mgr_free_res();
 		kfree(cam_res);
 		cam_res = NULL;
 	}
+}
+
+const static struct component_ops cam_res_mgr_component_ops = {
+	.bind = cam_res_mgr_component_bind,
+	.unbind = cam_res_mgr_component_unbind,
+};
 
+static int cam_res_mgr_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_RES, "Adding Res mgr component");
+	rc = component_add(&pdev->dev, &cam_res_mgr_component_ops);
+	if (rc)
+		CAM_ERR(CAM_RES, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int cam_res_mgr_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_res_mgr_component_ops);
 	return 0;
 }
 
@@ -712,7 +738,7 @@ static const struct of_device_id cam_res_mgr_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cam_res_mgr_dt_match);
 
-static struct platform_driver cam_res_mgr_driver = {
+struct platform_driver cam_res_mgr_driver = {
 	.probe = cam_res_mgr_probe,
 	.remove = cam_res_mgr_remove,
 	.driver = {

+ 92 - 65
drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.c

@@ -1,12 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #include "cam_sensor_dev.h"
 #include "cam_req_mgr_dev.h"
 #include "cam_sensor_soc.h"
 #include "cam_sensor_core.h"
+#include "camera_main.h"
 
 static long cam_sensor_subdev_ioctl(struct v4l2_subdev *sd,
 	unsigned int cmd, void *arg)
@@ -201,73 +202,13 @@ free_s_ctrl:
 	return rc;
 }
 
-static int cam_sensor_platform_remove(struct platform_device *pdev)
-{
-	int                        i;
-	struct cam_sensor_ctrl_t  *s_ctrl;
-	struct cam_hw_soc_info    *soc_info;
-
-	s_ctrl = platform_get_drvdata(pdev);
-	if (!s_ctrl) {
-		CAM_ERR(CAM_SENSOR, "sensor device is NULL");
-		return 0;
-	}
-
-	CAM_INFO(CAM_SENSOR, "platform remove invoked");
-	mutex_lock(&(s_ctrl->cam_sensor_mutex));
-	cam_sensor_shutdown(s_ctrl);
-	mutex_unlock(&(s_ctrl->cam_sensor_mutex));
-	cam_unregister_subdev(&(s_ctrl->v4l2_dev_str));
-	soc_info = &s_ctrl->soc_info;
-	for (i = 0; i < soc_info->num_clk; i++)
-		devm_clk_put(soc_info->dev, soc_info->clk[i]);
-
-	kfree(s_ctrl->i2c_data.per_frame);
-	platform_set_drvdata(pdev, NULL);
-	v4l2_set_subdevdata(&(s_ctrl->v4l2_dev_str.sd), NULL);
-	devm_kfree(&pdev->dev, s_ctrl);
-
-	return 0;
-}
-
-static int cam_sensor_driver_i2c_remove(struct i2c_client *client)
-{
-	int                        i;
-	struct cam_sensor_ctrl_t  *s_ctrl = i2c_get_clientdata(client);
-	struct cam_hw_soc_info    *soc_info;
-
-	if (!s_ctrl) {
-		CAM_ERR(CAM_SENSOR, "sensor device is NULL");
-		return 0;
-	}
-
-	CAM_INFO(CAM_SENSOR, "i2c remove invoked");
-	mutex_lock(&(s_ctrl->cam_sensor_mutex));
-	cam_sensor_shutdown(s_ctrl);
-	mutex_unlock(&(s_ctrl->cam_sensor_mutex));
-	cam_unregister_subdev(&(s_ctrl->v4l2_dev_str));
-	soc_info = &s_ctrl->soc_info;
-	for (i = 0; i < soc_info->num_clk; i++)
-		devm_clk_put(soc_info->dev, soc_info->clk[i]);
-
-	kfree(s_ctrl->i2c_data.per_frame);
-	v4l2_set_subdevdata(&(s_ctrl->v4l2_dev_str.sd), NULL);
-	kfree(s_ctrl);
-
-	return 0;
-}
-
-static const struct of_device_id cam_sensor_driver_dt_match[] = {
-	{.compatible = "qcom,cam-sensor"},
-	{}
-};
-
-static int32_t cam_sensor_driver_platform_probe(
-	struct platform_device *pdev)
+static int cam_sensor_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int32_t rc = 0, i = 0;
 	struct cam_sensor_ctrl_t *s_ctrl = NULL;
 	struct cam_hw_soc_info *soc_info = NULL;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	/* Create sensor control structure */
 	s_ctrl = devm_kzalloc(&pdev->dev,
@@ -330,6 +271,7 @@ static int32_t cam_sensor_driver_platform_probe(
 	s_ctrl->sensordata->power_info.dev = &pdev->dev;
 	platform_set_drvdata(pdev, s_ctrl);
 	s_ctrl->sensor_state = CAM_SENSOR_INIT;
+	CAM_DBG(CAM_SENSOR, "Component bound successfully");
 
 	return rc;
 unreg_subdev:
@@ -339,9 +281,94 @@ free_s_ctrl:
 	return rc;
 }
 
+static void cam_sensor_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	int                        i;
+	struct cam_sensor_ctrl_t  *s_ctrl;
+	struct cam_hw_soc_info    *soc_info;
+	struct platform_device *pdev = to_platform_device(dev);
+
+	s_ctrl = platform_get_drvdata(pdev);
+	if (!s_ctrl) {
+		CAM_ERR(CAM_SENSOR, "sensor device is NULL");
+		return;
+	}
+
+	CAM_INFO(CAM_SENSOR, "platform remove invoked");
+	mutex_lock(&(s_ctrl->cam_sensor_mutex));
+	cam_sensor_shutdown(s_ctrl);
+	mutex_unlock(&(s_ctrl->cam_sensor_mutex));
+	cam_unregister_subdev(&(s_ctrl->v4l2_dev_str));
+	soc_info = &s_ctrl->soc_info;
+	for (i = 0; i < soc_info->num_clk; i++)
+		devm_clk_put(soc_info->dev, soc_info->clk[i]);
+
+	kfree(s_ctrl->i2c_data.per_frame);
+	platform_set_drvdata(pdev, NULL);
+	v4l2_set_subdevdata(&(s_ctrl->v4l2_dev_str.sd), NULL);
+	devm_kfree(&pdev->dev, s_ctrl);
+}
+
+const static struct component_ops cam_sensor_component_ops = {
+	.bind = cam_sensor_component_bind,
+	.unbind = cam_sensor_component_unbind,
+};
+
+static int cam_sensor_platform_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_sensor_component_ops);
+	return 0;
+}
+
+static int cam_sensor_driver_i2c_remove(struct i2c_client *client)
+{
+	int                        i;
+	struct cam_sensor_ctrl_t  *s_ctrl = i2c_get_clientdata(client);
+	struct cam_hw_soc_info    *soc_info;
+
+	if (!s_ctrl) {
+		CAM_ERR(CAM_SENSOR, "sensor device is NULL");
+		return 0;
+	}
+
+	CAM_DBG(CAM_SENSOR, "i2c remove invoked");
+	mutex_lock(&(s_ctrl->cam_sensor_mutex));
+	cam_sensor_shutdown(s_ctrl);
+	mutex_unlock(&(s_ctrl->cam_sensor_mutex));
+	cam_unregister_subdev(&(s_ctrl->v4l2_dev_str));
+	soc_info = &s_ctrl->soc_info;
+	for (i = 0; i < soc_info->num_clk; i++)
+		devm_clk_put(soc_info->dev, soc_info->clk[i]);
+
+	kfree(s_ctrl->i2c_data.per_frame);
+	v4l2_set_subdevdata(&(s_ctrl->v4l2_dev_str.sd), NULL);
+	kfree(s_ctrl);
+
+	return 0;
+}
+
+static const struct of_device_id cam_sensor_driver_dt_match[] = {
+	{.compatible = "qcom,cam-sensor"},
+	{}
+};
+
+static int32_t cam_sensor_driver_platform_probe(
+	struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_SENSOR, "Adding Sensor component");
+	rc = component_add(&pdev->dev, &cam_sensor_component_ops);
+	if (rc)
+		CAM_ERR(CAM_SENSOR, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
 MODULE_DEVICE_TABLE(of, cam_sensor_driver_dt_match);
 
-static struct platform_driver cam_sensor_platform_driver = {
+struct platform_driver cam_sensor_platform_driver = {
 	.probe = cam_sensor_driver_platform_probe,
 	.driver = {
 		.name = "qcom,camera",

+ 151 - 46
drivers/cam_smmu/cam_smmu_api.c

@@ -22,6 +22,7 @@
 #include "cam_compat.h"
 #include "cam_smmu_api.h"
 #include "cam_debug_util.h"
+#include "camera_main.h"
 
 #define SHARED_MEM_POOL_GRANULARITY 16
 
@@ -3639,56 +3640,156 @@ err:
 	return -ENOMEM;
 }
 
+static int cam_smmu_fw_dev_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	icp_fw.fw_dev = &pdev->dev;
+	icp_fw.fw_kva = NULL;
+	icp_fw.fw_hdl = 0;
+
+	CAM_DBG(CAM_SMMU, "FW dev component bound successfully");
+	return 0;
+}
+
+static void cam_smmu_fw_dev_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	CAM_DBG(CAM_SMMU, "Unbinding component: %s", pdev->name);
+}
+
+const static struct component_ops cam_smmu_fw_dev_component_ops = {
+	.bind = cam_smmu_fw_dev_component_bind,
+	.unbind = cam_smmu_fw_dev_component_unbind,
+};
+
+static int cam_smmu_cb_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	int rc = 0;
+	struct platform_device *pdev = to_platform_device(dev);
+
+	rc = cam_populate_smmu_context_banks(dev, CAM_ARM_SMMU);
+	if (rc < 0) {
+		CAM_ERR(CAM_SMMU, "Error: populating context banks");
+		cam_smmu_release_cb(pdev);
+		return -ENOMEM;
+	}
+
+	CAM_DBG(CAM_SMMU, "CB component bound successfully");
+	return 0;
+}
+
+static void cam_smmu_cb_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	CAM_DBG(CAM_SMMU, "Unbinding component: %s", pdev->name);
+}
+
+const static struct component_ops cam_smmu_cb_component_ops = {
+	.bind = cam_smmu_cb_component_bind,
+	.unbind = cam_smmu_cb_component_unbind,
+};
+
+static int cam_smmu_cb_qsmmu_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	int rc = 0;
+
+	rc = cam_populate_smmu_context_banks(dev, CAM_QSMMU);
+	if (rc < 0) {
+		CAM_ERR(CAM_SMMU, "Failed in populating context banks");
+		return -ENOMEM;
+	}
+
+	CAM_DBG(CAM_SMMU, "QSMMU CB component bound successfully");
+	return 0;
+}
+
+static void cam_smmu_cb_qsmmu_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	CAM_DBG(CAM_SMMU, "Unbinding component: %s", pdev->name);
+}
+
+const static struct component_ops cam_smmu_cb_qsmmu_component_ops = {
+	.bind = cam_smmu_cb_qsmmu_component_bind,
+	.unbind = cam_smmu_cb_qsmmu_component_unbind,
+};
+
+static int cam_smmu_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	INIT_WORK(&iommu_cb_set.smmu_work, cam_smmu_page_fault_work);
+	mutex_init(&iommu_cb_set.payload_list_lock);
+	INIT_LIST_HEAD(&iommu_cb_set.payload_list);
+	cam_smmu_create_debug_fs();
+
+	CAM_DBG(CAM_SMMU, "Main component bound successfully");
+	return 0;
+}
+
+static void cam_smmu_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	/* release all the context banks and memory allocated */
+	cam_smmu_reset_iommu_table(CAM_SMMU_TABLE_DEINIT);
+	if (dev && dev->dma_parms) {
+		devm_kfree(dev, dev->dma_parms);
+		dev->dma_parms = NULL;
+	}
+
+	cam_smmu_release_cb(pdev);
+	debugfs_remove_recursive(iommu_cb_set.dentry);
+	iommu_cb_set.dentry = NULL;
+}
+
+const static struct component_ops cam_smmu_component_ops = {
+	.bind = cam_smmu_component_bind,
+	.unbind = cam_smmu_component_unbind,
+};
+
 static int cam_smmu_probe(struct platform_device *pdev)
 {
 	int rc = 0;
 	struct device *dev = &pdev->dev;
 
 	dev->dma_parms = NULL;
+	CAM_DBG(CAM_SMMU, "Adding SMMU component: %s", pdev->name);
 	if (of_device_is_compatible(dev->of_node, "qcom,msm-cam-smmu")) {
 		rc = cam_alloc_smmu_context_banks(dev);
 		if (rc < 0) {
-			CAM_ERR(CAM_SMMU, "Error: allocating context banks");
-			return -ENOMEM;
-		}
-	}
-	if (of_device_is_compatible(dev->of_node, "qcom,msm-cam-smmu-cb")) {
-		rc = cam_populate_smmu_context_banks(dev, CAM_ARM_SMMU);
-		if (rc < 0) {
-			CAM_ERR(CAM_SMMU, "Error: populating context banks");
-			cam_smmu_release_cb(pdev);
+			CAM_ERR(CAM_SMMU, "Failed in allocating context banks");
 			return -ENOMEM;
 		}
-		return rc;
-	}
-	if (of_device_is_compatible(dev->of_node, "qcom,qsmmu-cam-cb")) {
-		rc = cam_populate_smmu_context_banks(dev, CAM_QSMMU);
-		if (rc < 0) {
-			CAM_ERR(CAM_SMMU, "Error: populating context banks");
-			return -ENOMEM;
-		}
-		return rc;
-	}
-
-	if (of_device_is_compatible(dev->of_node, "qcom,msm-cam-smmu-fw-dev")) {
-		icp_fw.fw_dev = &pdev->dev;
-		icp_fw.fw_kva = NULL;
-		icp_fw.fw_hdl = 0;
-		return rc;
-	}
 
-	/* probe through all the subdevices */
-	rc = of_platform_populate(pdev->dev.of_node, msm_cam_smmu_dt_match,
-				NULL, &pdev->dev);
-	if (rc < 0) {
-		CAM_ERR(CAM_SMMU, "Error: populating devices");
+		rc = component_add(&pdev->dev, &cam_smmu_component_ops);
+	} else if (of_device_is_compatible(dev->of_node,
+		"qcom,msm-cam-smmu-cb")) {
+		rc = component_add(&pdev->dev, &cam_smmu_cb_component_ops);
+	} else if (of_device_is_compatible(dev->of_node, "qcom,qsmmu-cam-cb")) {
+		rc = component_add(&pdev->dev,
+			&cam_smmu_cb_qsmmu_component_ops);
+	} else if (of_device_is_compatible(dev->of_node,
+		"qcom,msm-cam-smmu-fw-dev")) {
+		rc = component_add(&pdev->dev, &cam_smmu_fw_dev_component_ops);
 	} else {
-		INIT_WORK(&iommu_cb_set.smmu_work, cam_smmu_page_fault_work);
-		mutex_init(&iommu_cb_set.payload_list_lock);
-		INIT_LIST_HEAD(&iommu_cb_set.payload_list);
+		CAM_ERR(CAM_SMMU, "Unrecognized child device: %s", pdev->name);
+		rc = -ENODEV;
 	}
 
-	cam_smmu_create_debug_fs();
+	if (rc < 0)
+		CAM_ERR(CAM_SMMU, "failed to add component rc: %d", rc);
+
 	return rc;
 }
 
@@ -3696,22 +3797,26 @@ static int cam_smmu_remove(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 
-	/* release all the context banks and memory allocated */
-	cam_smmu_reset_iommu_table(CAM_SMMU_TABLE_DEINIT);
-	if (dev && dev->dma_parms) {
-		devm_kfree(dev, dev->dma_parms);
-		dev->dma_parms = NULL;
+	CAM_DBG(CAM_SMMU, "Removing SMMU component: %s", pdev->name);
+	if (of_device_is_compatible(dev->of_node, "qcom,msm-cam-smmu")) {
+		component_del(&pdev->dev, &cam_smmu_component_ops);
+	} else if (of_device_is_compatible(dev->of_node,
+		"qcom,msm-cam-smmu-cb")) {
+		component_del(&pdev->dev, &cam_smmu_cb_component_ops);
+	} else if (of_device_is_compatible(dev->of_node, "qcom,qsmmu-cam-cb")) {
+		component_del(&pdev->dev, &cam_smmu_cb_qsmmu_component_ops);
+	} else if (of_device_is_compatible(dev->of_node,
+		"qcom,msm-cam-smmu-fw-dev")) {
+		component_del(&pdev->dev, &cam_smmu_fw_dev_component_ops);
+	} else {
+		CAM_ERR(CAM_SMMU, "Unrecognized child device: %s", pdev->name);
+		return -ENODEV;
 	}
 
-	if (of_device_is_compatible(pdev->dev.of_node, "qcom,msm-cam-smmu"))
-		cam_smmu_release_cb(pdev);
-
-	debugfs_remove_recursive(iommu_cb_set.dentry);
-	iommu_cb_set.dentry = NULL;
 	return 0;
 }
 
-static struct platform_driver cam_smmu_driver = {
+struct platform_driver cam_smmu_driver = {
 	.probe = cam_smmu_probe,
 	.remove = cam_smmu_remove,
 	.driver = {

+ 30 - 3
drivers/cam_sync/cam_sync.c

@@ -12,6 +12,7 @@
 #include "cam_sync_util.h"
 #include "cam_debug_util.h"
 #include "cam_common_util.h"
+#include "camera_main.h"
 
 #ifdef CONFIG_MSM_GLOBAL_SYNX
 #include <synx_api.h>
@@ -1016,10 +1017,12 @@ static void cam_sync_register_synx_bind_ops(void)
 }
 #endif
 
-static int cam_sync_probe(struct platform_device *pdev)
+static int cam_sync_component_bind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int rc;
 	int idx;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	sync_dev = kzalloc(sizeof(*sync_dev), GFP_KERNEL);
 	if (!sync_dev)
@@ -1091,6 +1094,7 @@ static int cam_sync_probe(struct platform_device *pdev)
 #ifdef CONFIG_MSM_GLOBAL_SYNX
 	cam_sync_register_synx_bind_ops();
 #endif
+	CAM_DBG(CAM_SYNC, "Component bound successfully");
 	return rc;
 
 v4l2_fail:
@@ -1105,7 +1109,8 @@ vdev_fail:
 	return rc;
 }
 
-static int cam_sync_remove(struct platform_device *pdev)
+static void cam_sync_component_unbind(struct device *dev,
+	struct device *master_dev, void *data)
 {
 	int i;
 
@@ -1117,9 +1122,31 @@ static int cam_sync_remove(struct platform_device *pdev)
 
 	for (i = 0; i < CAM_SYNC_MAX_OBJS; i++)
 		spin_lock_init(&sync_dev->row_spinlocks[i]);
+
 	kfree(sync_dev);
 	sync_dev = NULL;
+}
 
+const static struct component_ops cam_sync_component_ops = {
+	.bind = cam_sync_component_bind,
+	.unbind = cam_sync_component_unbind,
+};
+
+static int cam_sync_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+
+	CAM_DBG(CAM_SYNC, "Adding Sync component");
+	rc = component_add(&pdev->dev, &cam_sync_component_ops);
+	if (rc)
+		CAM_ERR(CAM_SYNC, "failed to add component rc: %d", rc);
+
+	return rc;
+}
+
+static int cam_sync_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &cam_sync_component_ops);
 	return 0;
 }
 
@@ -1130,7 +1157,7 @@ static const struct of_device_id cam_sync_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, cam_sync_dt_match);
 
-static struct platform_driver cam_sync_driver = {
+struct platform_driver cam_sync_driver = {
 	.probe = cam_sync_probe,
 	.remove = cam_sync_remove,
 	.driver = {

+ 105 - 0
drivers/camera_main.c

@@ -53,6 +53,7 @@
 #include "cam_top_tpg_v1.h"
 #include "cam_tfe_dev.h"
 #include "cam_tfe_csid530.h"
+#include "camera_main.h"
 
 struct camera_submodule_component {
 	int (*init)(void);
@@ -205,6 +206,110 @@ static const struct camera_submodule submodule_table[] = {
 	}
 };
 
+/*
+ * Drivers to be bound by component framework in this order with
+ * CRM as master
+ */
+static struct platform_driver *const cam_component_drivers[] = {
+/* BASE */
+	&cam_sync_driver,
+	&cam_smmu_driver,
+	&cam_cpas_driver,
+	&cam_cdm_intf_driver,
+	&cam_hw_cdm_driver,
+#ifdef CONFIG_SPECTRA_ISP
+	&cam_ife_csid17x_driver,
+	&cam_ife_csid_lite_driver,
+	&cam_vfe_driver,
+	&isp_driver,
+#endif
+#ifdef CONFIG_SPECTRA_TFE
+	&cam_top_tpg_v1_driver,
+	&cam_tfe_driver,
+	&cam_tfe_csid530_driver,
+#endif
+#ifdef CONFIG_SPECTRA_SENSOR
+	&cam_res_mgr_driver,
+	&cci_driver,
+	&csiphy_driver,
+	&cam_actuator_platform_driver,
+	&cam_sensor_platform_driver,
+	&cam_eeprom_platform_driver,
+	&cam_ois_platform_driver,
+#if IS_REACHABLE(CONFIG_LEDS_QPNP_FLASH_V2)
+	&cam_flash_platform_driver,
+#endif
+#endif
+#ifdef CONFIG_SPECTRA_ICP
+	&cam_a5_driver,
+	&cam_ipe_driver,
+	&cam_bps_driver,
+	&cam_icp_driver,
+#endif
+#ifdef CONFIG_SPECTRA_OPE
+	&cam_ope_driver,
+	&cam_ope_subdev_driver,
+#endif
+#ifdef CONFIG_SPECTRA_JPEG
+	&cam_jpeg_enc_driver,
+	&cam_jpeg_dma_driver,
+	&jpeg_driver,
+#endif
+#ifdef CONFIG_SPECTRA_FD
+	&cam_fd_hw_driver,
+	&cam_fd_driver,
+#endif
+#ifdef CONFIG_SPECTRA_LRME
+	&cam_lrme_hw_driver,
+	&cam_lrme_driver,
+#endif
+#ifdef CONFIG_SPECTRA_CUSTOM
+	&cam_custom_hw_sub_mod_driver,
+	&cam_custom_csid_driver,
+	&custom_driver,
+#endif
+};
+
+/* Callback to compare device from match list before adding as component */
+static int camera_component_compare_dev(struct device *dev, void *data)
+{
+	return dev == data;
+}
+
+/* Add component matches to list for master of aggregate driver */
+int camera_component_match_add_drivers(struct device *master_dev,
+	struct component_match **match_list)
+{
+	int i, rc = 0;
+	struct platform_device *pdev = NULL;
+
+	if (!master_dev || !match_list) {
+		CAM_ERR(CAM_UTIL, "Invalid parameters for component match add");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(cam_component_drivers); i++) {
+		struct device_driver *drv = &cam_component_drivers[i]->driver;
+		struct device *start_dev = NULL, *match_dev;
+
+		while ((match_dev = bus_find_device(&platform_bus_type,
+			start_dev, drv, (void *)platform_bus_type.match))) {
+			put_device(start_dev);
+			pdev = to_platform_device(match_dev);
+			CAM_DBG(CAM_UTIL, "Adding matched component:%s",
+				pdev->name);
+			component_match_add(master_dev, match_list,
+				camera_component_compare_dev, match_dev);
+			start_dev = match_dev;
+		}
+		put_device(start_dev);
+	}
+
+end:
+	return rc;
+}
+
 static int camera_verify_submodules(void)
 {
 	int rc = 0;

+ 71 - 0
drivers/camera_main.h

@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef CAMERA_MAIN_H
+#define CAMERA_MAIN_H
+
+#include <linux/platform_device.h>
+#include <linux/component.h>
+
+extern struct platform_driver cam_sync_driver;
+extern struct platform_driver cam_smmu_driver;
+extern struct platform_driver cam_cpas_driver;
+extern struct platform_driver cam_cdm_intf_driver;
+extern struct platform_driver cam_hw_cdm_driver;
+#ifdef CONFIG_SPECTRA_ISP
+extern struct platform_driver cam_ife_csid17x_driver;
+extern struct platform_driver cam_ife_csid_lite_driver;
+extern struct platform_driver cam_vfe_driver;
+extern struct platform_driver isp_driver;
+#endif
+#ifdef CONFIG_SPECTRA_TFE
+extern struct platform_driver cam_top_tpg_v1_driver;
+extern struct platform_driver cam_tfe_driver;
+extern struct platform_driver cam_tfe_csid530_driver;
+#endif
+#ifdef CONFIG_SPECTRA_SENSOR
+extern struct platform_driver cam_res_mgr_driver;
+extern struct platform_driver cci_driver;
+extern struct platform_driver csiphy_driver;
+extern struct platform_driver cam_actuator_platform_driver;
+extern struct platform_driver cam_sensor_platform_driver;
+extern struct platform_driver cam_eeprom_platform_driver;
+extern struct platform_driver cam_ois_platform_driver;
+#if IS_REACHABLE(CONFIG_LEDS_QPNP_FLASH_V2)
+extern struct platform_driver cam_flash_platform_driver;
+#endif
+#endif
+#ifdef CONFIG_SPECTRA_ICP
+extern struct platform_driver cam_a5_driver;
+extern struct platform_driver cam_ipe_driver;
+extern struct platform_driver cam_bps_driver;
+extern struct platform_driver cam_icp_driver;
+#endif
+#ifdef CONFIG_SPECTRA_OPE
+extern struct platform_driver cam_ope_driver;
+extern struct platform_driver cam_ope_subdev_driver;
+#endif
+#ifdef CONFIG_SPECTRA_JPEG
+extern struct platform_driver cam_jpeg_enc_driver;
+extern struct platform_driver cam_jpeg_dma_driver;
+extern struct platform_driver jpeg_driver;
+#endif
+#ifdef CONFIG_SPECTRA_FD
+extern struct platform_driver cam_fd_hw_driver;
+extern struct platform_driver cam_fd_driver;
+#endif
+#ifdef CONFIG_SPECTRA_LRME
+extern struct platform_driver cam_lrme_hw_driver;
+extern struct platform_driver cam_lrme_driver;
+#endif
+#ifdef CONFIG_SPECTRA_CUSTOM
+extern struct platform_driver cam_custom_hw_sub_mod_driver;
+extern struct platform_driver cam_custom_csid_driver;
+extern struct platform_driver custom_driver;
+#endif
+
+int camera_component_match_add_drivers(struct device *dev,
+	struct component_match **match_list);
+#endif /* CAMERA_MAIN_H */