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 <matre@codeaurora.org>
This commit is contained in:
@@ -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");
|
||||
|
@@ -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",
|
||||
|
Reference in New Issue
Block a user