فهرست منبع

msm: camera: common: Add component helper support in camera

Due to the asynchronous nature of platform probes, inter
dependency between drivers needs to be taken care during
kernel boot up. Component helper provides the facility of
adding matching drivers in a list ordered in the way we want
to bind those drivers. The CRM driver acts as component master
to make sure all slave drivers are bound before it returns
from its own bind call. Add support for serializing platform
probes through component framework.

CRs-Fixed: 2584631
Change-Id: I345da1d2b9cccf6021ac6fc899143013b7714ec4
Signed-off-by: Mukund Madhusudan Atre <[email protected]>
Mukund Madhusudan Atre 5 سال پیش
والد
کامیت
5cb000ee7f
44فایلهای تغییر یافته به همراه1818 افزوده شده و 607 حذف شده
  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. 34 5
      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
 
@@ -689,28 +690,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;
 
@@ -749,6 +738,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:
@@ -764,13 +763,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",

+ 34 - 5
drivers/cam_sensor_module/cam_cci/cam_cci_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_cci_dev.h"
 #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
 
@@ -340,12 +341,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);
@@ -409,18 +412,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);
@@ -428,6 +435,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;
 }
 
@@ -438,7 +467,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

@@ -375,10 +375,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 */