msm: camera: common: Fixes the exit module code flow

Fixes exit call flow as a part of rmmod.

CRs-Fixed: 2675526
Change-Id: I47111a737cb06d9bb3d0a417a471c5c9fb545999
Signed-off-by: Jigarkumar Zala <jzala@codeaurora.org>
This commit is contained in:
Jigarkumar Zala
2020-04-07 14:26:03 -07:00
parent f65f27de96
commit 279dfebf8c
32 changed files with 391 additions and 89 deletions

View File

@@ -2206,10 +2206,19 @@ static void cam_hw_cdm_component_unbind(struct device *dev,
return; return;
} }
rc = cam_hw_cdm_deinit(cdm_hw, NULL, 0); if (cdm_hw->hw_state == CAM_HW_STATE_POWER_UP) {
rc = cam_hw_cdm_deinit(cdm_hw, NULL, 0);
if (rc) {
CAM_ERR(CAM_CDM, "Deinit failed for hw");
return;
}
}
rc = cam_cdm_intf_deregister_hw_cdm(cdm_hw_intf,
cdm_hw->soc_info.soc_private, CAM_HW_CDM, cdm_core->index);
if (rc) { if (rc) {
CAM_ERR(CAM_CDM, "Deinit failed for hw"); CAM_ERR(CAM_CDM,
return; "HW_CDM interface deregistration failed: rd: %d", rc);
} }
rc = cam_cpas_unregister_client(cdm_core->cpas_handle); rc = cam_cpas_unregister_client(cdm_core->cpas_handle);

View File

@@ -171,7 +171,8 @@ static int cam_icp_component_bind(struct device *dev,
hw_mgr_intf = kzalloc(sizeof(*hw_mgr_intf), GFP_KERNEL); hw_mgr_intf = kzalloc(sizeof(*hw_mgr_intf), GFP_KERNEL);
if (!hw_mgr_intf) { if (!hw_mgr_intf) {
rc = -EINVAL; rc = -ENOMEM;
CAM_ERR(CAM_ICP, "Memory allocation fail");
goto hw_alloc_fail; goto hw_alloc_fail;
} }
@@ -225,7 +226,6 @@ static void cam_icp_component_unbind(struct device *dev,
{ {
int i; int i;
struct v4l2_subdev *sd; struct v4l2_subdev *sd;
struct cam_subdev *subdev;
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
if (!pdev) { if (!pdev) {
@@ -239,15 +239,10 @@ static void cam_icp_component_unbind(struct device *dev,
return; return;
} }
subdev = v4l2_get_subdevdata(sd);
if (!subdev) {
CAM_ERR(CAM_ICP, "cam subdev is NULL");
return;
}
for (i = 0; i < CAM_ICP_CTX_MAX; i++) for (i = 0; i < CAM_ICP_CTX_MAX; i++)
cam_icp_context_deinit(&g_icp_dev.ctx_icp[i]); cam_icp_context_deinit(&g_icp_dev.ctx_icp[i]);
cam_icp_hw_mgr_deinit();
cam_node_deinit(g_icp_dev.node); cam_node_deinit(g_icp_dev.node);
cam_subdev_remove(&g_icp_dev.sd); cam_subdev_remove(&g_icp_dev.sd);
mutex_destroy(&g_icp_dev.icp_lock); mutex_destroy(&g_icp_dev.icp_lock);

View File

@@ -168,7 +168,7 @@ static int cam_a5_component_bind(struct device *dev,
} }
CAM_DBG(CAM_ICP, "soc info : %pK", CAM_DBG(CAM_ICP, "soc info : %pK",
(void *)&a5_dev->soc_info); (void *)&a5_dev->soc_info);
rc = cam_a5_register_cpas(&a5_dev->soc_info, rc = cam_a5_register_cpas(&a5_dev->soc_info,
core_info, a5_dev_intf->hw_idx); core_info, a5_dev_intf->hw_idx);
if (rc < 0) { if (rc < 0) {
@@ -185,6 +185,7 @@ static int cam_a5_component_bind(struct device *dev,
return 0; return 0;
cpas_reg_failed: cpas_reg_failed:
cam_a5_deinit_soc_resources(&a5_dev->soc_info);
init_soc_failure: init_soc_failure:
match_err: match_err:
kfree(a5_dev->core_info); kfree(a5_dev->core_info);
@@ -200,9 +201,21 @@ a5_dev_alloc_failure:
static void cam_a5_component_unbind(struct device *dev, static void cam_a5_component_unbind(struct device *dev,
struct device *master_dev, void *data) struct device *master_dev, void *data)
{ {
struct cam_hw_info *a5_dev = NULL;
struct cam_hw_intf *a5_dev_intf = NULL;
struct cam_a5_device_core_info *core_info = NULL;
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name); a5_dev_intf = platform_get_drvdata(pdev);
a5_dev = a5_dev_intf->hw_priv;
core_info = (struct cam_a5_device_core_info *)a5_dev->core_info;
cam_cpas_unregister_client(core_info->cpas_handle);
cam_a5_deinit_soc_resources(&a5_dev->soc_info);
memset(&cam_a5_soc_info, 0, sizeof(struct a5_soc_info));
kfree(a5_dev->core_info);
a5_dev->core_info = NULL;
kfree(a5_dev);
kfree(a5_dev_intf);
} }
const static struct component_ops cam_a5_component_ops = { const static struct component_ops cam_a5_component_ops = {
@@ -222,6 +235,12 @@ int cam_a5_probe(struct platform_device *pdev)
return rc; return rc;
} }
static int cam_a5_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &cam_a5_component_ops);
return 0;
}
static const struct of_device_id cam_a5_dt_match[] = { static const struct of_device_id cam_a5_dt_match[] = {
{ {
.compatible = "qcom,cam-a5", .compatible = "qcom,cam-a5",
@@ -233,6 +252,7 @@ MODULE_DEVICE_TABLE(of, cam_a5_dt_match);
struct platform_driver cam_a5_driver = { struct platform_driver cam_a5_driver = {
.probe = cam_a5_probe, .probe = cam_a5_probe,
.remove = cam_a5_remove,
.driver = { .driver = {
.name = "cam-a5", .name = "cam-a5",
.owner = THIS_MODULE, .owner = THIS_MODULE,

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // 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/io.h> #include <linux/io.h>
@@ -174,6 +174,15 @@ int cam_a5_init_soc_resources(struct cam_hw_soc_info *soc_info,
return rc; return rc;
} }
void cam_a5_deinit_soc_resources(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
rc = cam_soc_util_release_platform_resource(soc_info);
if (rc)
CAM_WARN(CAM_ICP, "release platform resources fail");
}
int cam_a5_enable_soc_resources(struct cam_hw_soc_info *soc_info) int cam_a5_enable_soc_resources(struct cam_hw_soc_info *soc_info)
{ {
int rc = 0; int rc = 0;

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* 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.
*/ */
#ifndef CAM_A5_SOC_H #ifndef CAM_A5_SOC_H
@@ -30,6 +30,8 @@ struct a5_soc_info {
int cam_a5_init_soc_resources(struct cam_hw_soc_info *soc_info, int cam_a5_init_soc_resources(struct cam_hw_soc_info *soc_info,
irq_handler_t a5_irq_handler, void *irq_data); irq_handler_t a5_irq_handler, void *irq_data);
void cam_a5_deinit_soc_resources(struct cam_hw_soc_info *soc_info);
int cam_a5_enable_soc_resources(struct cam_hw_soc_info *soc_info); int cam_a5_enable_soc_resources(struct cam_hw_soc_info *soc_info);
int cam_a5_disable_soc_resources(struct cam_hw_soc_info *soc_info); int cam_a5_disable_soc_resources(struct cam_hw_soc_info *soc_info);

View File

@@ -177,9 +177,21 @@ static int cam_bps_component_bind(struct device *dev,
static void cam_bps_component_unbind(struct device *dev, static void cam_bps_component_unbind(struct device *dev,
struct device *master_dev, void *data) struct device *master_dev, void *data)
{ {
struct cam_hw_info *bps_dev = NULL;
struct cam_hw_intf *bps_dev_intf = NULL;
struct cam_bps_device_core_info *core_info = NULL;
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name); CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name);
bps_dev_intf = platform_get_drvdata(pdev);
bps_dev = bps_dev_intf->hw_priv;
core_info = (struct cam_bps_device_core_info *)bps_dev->core_info;
cam_cpas_unregister_client(core_info->cpas_handle);
cam_bps_deinit_soc_resources(&bps_dev->soc_info);
kfree(bps_dev->core_info);
kfree(bps_dev);
kfree(bps_dev_intf);
} }
const static struct component_ops cam_bps_component_ops = { const static struct component_ops cam_bps_component_ops = {
@@ -199,6 +211,12 @@ int cam_bps_probe(struct platform_device *pdev)
return rc; return rc;
} }
static int cam_bps_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &cam_bps_component_ops);
return 0;
}
static const struct of_device_id cam_bps_dt_match[] = { static const struct of_device_id cam_bps_dt_match[] = {
{ {
.compatible = "qcom,cam-bps", .compatible = "qcom,cam-bps",
@@ -210,6 +228,7 @@ MODULE_DEVICE_TABLE(of, cam_bps_dt_match);
struct platform_driver cam_bps_driver = { struct platform_driver cam_bps_driver = {
.probe = cam_bps_probe, .probe = cam_bps_probe,
.remove = cam_bps_remove,
.driver = { .driver = {
.name = "cam-bps", .name = "cam-bps",
.owner = THIS_MODULE, .owner = THIS_MODULE,

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // 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/io.h> #include <linux/io.h>
@@ -52,6 +52,15 @@ int cam_bps_init_soc_resources(struct cam_hw_soc_info *soc_info,
return rc; return rc;
} }
void cam_bps_deinit_soc_resources(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
rc = cam_soc_util_release_platform_resource(soc_info);
if (rc)
CAM_WARN(CAM_ICP, "release platform resources fail");
}
int cam_bps_enable_soc_resources(struct cam_hw_soc_info *soc_info) int cam_bps_enable_soc_resources(struct cam_hw_soc_info *soc_info)
{ {
int rc = 0; int rc = 0;

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* 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.
*/ */
#ifndef _CAM_BPS_SOC_H_ #ifndef _CAM_BPS_SOC_H_
@@ -23,4 +23,5 @@ int cam_bps_transfer_gdsc_control(struct cam_hw_soc_info *soc_info);
int cam_bps_update_clk_rate(struct cam_hw_soc_info *soc_info, int cam_bps_update_clk_rate(struct cam_hw_soc_info *soc_info,
uint32_t clk_rate); uint32_t clk_rate);
int cam_bps_toggle_clk(struct cam_hw_soc_info *soc_info, bool clk_enable); int cam_bps_toggle_clk(struct cam_hw_soc_info *soc_info, bool clk_enable);
void cam_bps_deinit_soc_resources(struct cam_hw_soc_info *soc_info);
#endif /* _CAM_BPS_SOC_H_*/ #endif /* _CAM_BPS_SOC_H_*/

View File

@@ -1887,8 +1887,11 @@ static int cam_icp_hw_mgr_create_debugfs_entry(void)
int rc = 0; int rc = 0;
icp_hw_mgr.dentry = debugfs_create_dir("camera_icp", NULL); icp_hw_mgr.dentry = debugfs_create_dir("camera_icp", NULL);
if (!icp_hw_mgr.dentry) if (IS_ERR_OR_NULL(icp_hw_mgr.dentry)) {
CAM_ERR(CAM_ICP, "Debugfs entry dir: %s failed",
"camrea_icp");
return -ENOMEM; return -ENOMEM;
}
if (!debugfs_create_bool("icp_pc", if (!debugfs_create_bool("icp_pc",
0644, 0644,
@@ -5818,6 +5821,7 @@ static int cam_icp_mgr_alloc_devs(struct device_node *of_node)
sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL); sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL);
if (!icp_hw_mgr.devices[CAM_ICP_DEV_A5]) { if (!icp_hw_mgr.devices[CAM_ICP_DEV_A5]) {
rc = -ENOMEM; rc = -ENOMEM;
CAM_ERR(CAM_ICP, "a5 allocation fail: rc = %d", rc);
goto num_a5_failed; goto num_a5_failed;
} }
@@ -5834,6 +5838,7 @@ static int cam_icp_mgr_alloc_devs(struct device_node *of_node)
sizeof(struct cam_hw_intf *), GFP_KERNEL); sizeof(struct cam_hw_intf *), GFP_KERNEL);
if (!icp_hw_mgr.devices[CAM_ICP_DEV_IPE]) { if (!icp_hw_mgr.devices[CAM_ICP_DEV_IPE]) {
rc = -ENOMEM; rc = -ENOMEM;
CAM_ERR(CAM_ICP, "ipe device allocation fail : rc= %d", rc);
goto num_ipe_failed; goto num_ipe_failed;
} }
@@ -5846,6 +5851,7 @@ static int cam_icp_mgr_alloc_devs(struct device_node *of_node)
sizeof(struct cam_hw_intf *), GFP_KERNEL); sizeof(struct cam_hw_intf *), GFP_KERNEL);
if (!icp_hw_mgr.devices[CAM_ICP_DEV_BPS]) { if (!icp_hw_mgr.devices[CAM_ICP_DEV_BPS]) {
rc = -ENOMEM; rc = -ENOMEM;
CAM_ERR(CAM_ICP, "bps device allocation fail : rc= %d", rc);
goto num_bps_failed; goto num_bps_failed;
} }
@@ -5874,9 +5880,10 @@ static int cam_icp_mgr_init_devs(struct device_node *of_node)
struct cam_hw_intf *child_dev_intf = NULL; struct cam_hw_intf *child_dev_intf = NULL;
rc = cam_icp_mgr_alloc_devs(of_node); rc = cam_icp_mgr_alloc_devs(of_node);
if (rc) if (rc) {
CAM_ERR(CAM_ICP, "alloc_devs fail : rc = %d", rc);
return rc; return rc;
}
count = of_property_count_strings(of_node, "compat-hw-name"); count = of_property_count_strings(of_node, "compat-hw-name");
if (!count) { if (!count) {
CAM_ERR(CAM_ICP, "no compat hw found in dev tree, cnt = %d", CAM_ERR(CAM_ICP, "no compat hw found in dev tree, cnt = %d",
@@ -5972,25 +5979,31 @@ static int cam_icp_mgr_create_wq(void)
icp_hw_mgr.cmd_work_data = icp_hw_mgr.cmd_work_data =
kzalloc(sizeof(struct hfi_cmd_work_data) * ICP_WORKQ_NUM_TASK, kzalloc(sizeof(struct hfi_cmd_work_data) * ICP_WORKQ_NUM_TASK,
GFP_KERNEL); GFP_KERNEL);
if (!icp_hw_mgr.cmd_work_data) if (!icp_hw_mgr.cmd_work_data) {
CAM_ERR(CAM_ICP, "Mem reservation fail for cmd_work_data");
goto cmd_work_data_failed; goto cmd_work_data_failed;
}
icp_hw_mgr.msg_work_data = icp_hw_mgr.msg_work_data =
kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK, kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK,
GFP_KERNEL); GFP_KERNEL);
if (!icp_hw_mgr.msg_work_data) if (!icp_hw_mgr.msg_work_data) {
CAM_ERR(CAM_ICP, "Mem reservation fail for msg_work_data");
goto msg_work_data_failed; goto msg_work_data_failed;
}
icp_hw_mgr.timer_work_data = icp_hw_mgr.timer_work_data =
kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK, kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK,
GFP_KERNEL); GFP_KERNEL);
if (!icp_hw_mgr.timer_work_data) if (!icp_hw_mgr.timer_work_data) {
CAM_ERR(CAM_ICP, "Mem reservation fail for timer_work_data");
goto timer_work_data_failed; goto timer_work_data_failed;
}
rc = cam_icp_hw_mgr_create_debugfs_entry(); rc = cam_icp_hw_mgr_create_debugfs_entry();
if (rc) if (rc) {
CAM_ERR(CAM_ICP, "create_debugfs_entry fail= rc: %d", rc);
goto debugfs_create_failed; goto debugfs_create_failed;
}
for (i = 0; i < ICP_WORKQ_NUM_TASK; i++) for (i = 0; i < ICP_WORKQ_NUM_TASK; i++)
icp_hw_mgr.msg_work->task.pool[i].payload = icp_hw_mgr.msg_work->task.pool[i].payload =
&icp_hw_mgr.msg_work_data[i]; &icp_hw_mgr.msg_work_data[i];
@@ -6020,6 +6033,13 @@ cmd_work_failed:
return rc; return rc;
} }
void cam_icp_mgr_destroy_wq(void)
{
cam_req_mgr_workq_destroy(&icp_hw_mgr.timer_work);
cam_req_mgr_workq_destroy(&icp_hw_mgr.msg_work);
cam_req_mgr_workq_destroy(&icp_hw_mgr.cmd_work);
}
static int cam_icp_mgr_cmd(void *hw_mgr_priv, void *cmd_args) static int cam_icp_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
{ {
int rc = 0; int rc = 0;
@@ -6104,9 +6124,10 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
} }
rc = cam_icp_mgr_init_devs(of_node); rc = cam_icp_mgr_init_devs(of_node);
if (rc) if (rc) {
CAM_ERR(CAM_ICP, "cam_icp_mgr_init_devs fail: rc: %d", rc);
goto dev_init_failed; goto dev_init_failed;
}
rc = cam_smmu_get_handle("icp", &icp_hw_mgr.iommu_hdl); rc = cam_smmu_get_handle("icp", &icp_hw_mgr.iommu_hdl);
if (rc) { if (rc) {
CAM_ERR(CAM_ICP, "get mmu handle failed: %d", rc); CAM_ERR(CAM_ICP, "get mmu handle failed: %d", rc);
@@ -6120,8 +6141,10 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
} }
rc = cam_icp_mgr_create_wq(); rc = cam_icp_mgr_create_wq();
if (rc) if (rc) {
CAM_ERR(CAM_ICP, "cam_icp_mgr_create_wq fail: rc=%d", rc);
goto icp_wq_create_failed; goto icp_wq_create_failed;
}
if (iommu_hdl) if (iommu_hdl)
*iommu_hdl = icp_hw_mgr.iommu_hdl; *iommu_hdl = icp_hw_mgr.iommu_hdl;
@@ -6146,3 +6169,18 @@ dev_init_failed:
return rc; return rc;
} }
void cam_icp_hw_mgr_deinit(void)
{
int i = 0;
debugfs_remove_recursive(icp_hw_mgr.dentry);
icp_hw_mgr.dentry = NULL;
cam_icp_mgr_destroy_wq();
kfree(icp_hw_mgr.devices[CAM_ICP_DEV_BPS]);
kfree(icp_hw_mgr.devices[CAM_ICP_DEV_IPE]);
kfree(icp_hw_mgr.devices[CAM_ICP_DEV_A5]);
mutex_destroy(&icp_hw_mgr.hw_mgr_mutex);
for (i = 0; i < CAM_ICP_CTX_MAX; i++)
mutex_destroy(&icp_hw_mgr.ctx_data[i].ctx_mutex);
}

View File

@@ -33,6 +33,8 @@
int cam_icp_hw_mgr_init(struct device_node *of_node, int cam_icp_hw_mgr_init(struct device_node *of_node,
uint64_t *hw_mgr_hdl, int *iommu_hdl); uint64_t *hw_mgr_hdl, int *iommu_hdl);
void cam_icp_hw_mgr_deinit(void);
/** /**
* struct cam_icp_cpas_vote * struct cam_icp_cpas_vote
* @ahb_vote: AHB vote info * @ahb_vote: AHB vote info

View File

@@ -169,9 +169,20 @@ static int cam_ipe_component_bind(struct device *dev,
static void cam_ipe_component_unbind(struct device *dev, static void cam_ipe_component_unbind(struct device *dev,
struct device *master_dev, void *data) struct device *master_dev, void *data)
{ {
struct cam_hw_info *ipe_dev = NULL;
struct cam_hw_intf *ipe_dev_intf = NULL;
struct cam_ipe_device_core_info *core_info = NULL;
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name); CAM_DBG(CAM_ICP, "Unbinding component: %s", pdev->name);
ipe_dev_intf = platform_get_drvdata(pdev);
ipe_dev = ipe_dev_intf->hw_priv;
core_info = (struct cam_ipe_device_core_info *)ipe_dev->core_info;
cam_cpas_unregister_client(core_info->cpas_handle);
cam_ipe_deinit_soc_resources(&ipe_dev->soc_info);
kfree(ipe_dev->core_info);
kfree(ipe_dev);
kfree(ipe_dev_intf);
} }
@@ -192,6 +203,12 @@ int cam_ipe_probe(struct platform_device *pdev)
return rc; return rc;
} }
static int cam_ipe_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &cam_ipe_component_ops);
return 0;
}
static const struct of_device_id cam_ipe_dt_match[] = { static const struct of_device_id cam_ipe_dt_match[] = {
{ {
.compatible = "qcom,cam-ipe", .compatible = "qcom,cam-ipe",
@@ -203,6 +220,7 @@ MODULE_DEVICE_TABLE(of, cam_ipe_dt_match);
struct platform_driver cam_ipe_driver = { struct platform_driver cam_ipe_driver = {
.probe = cam_ipe_probe, .probe = cam_ipe_probe,
.remove = cam_ipe_remove,
.driver = { .driver = {
.name = "cam-ipe", .name = "cam-ipe",
.owner = THIS_MODULE, .owner = THIS_MODULE,

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // 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/io.h> #include <linux/io.h>
@@ -103,6 +103,15 @@ int cam_ipe_init_soc_resources(struct cam_hw_soc_info *soc_info,
return rc; return rc;
} }
void cam_ipe_deinit_soc_resources(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
rc = cam_soc_util_release_platform_resource(soc_info);
if (rc)
CAM_WARN(CAM_ICP, "release platform resources fail");
}
int cam_ipe_enable_soc_resources(struct cam_hw_soc_info *soc_info) int cam_ipe_enable_soc_resources(struct cam_hw_soc_info *soc_info)
{ {
int rc = 0; int rc = 0;

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* 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.
*/ */
#ifndef CAM_IPE_SOC_H #ifndef CAM_IPE_SOC_H
@@ -23,4 +23,5 @@ int cam_ipe_transfer_gdsc_control(struct cam_hw_soc_info *soc_info);
int cam_ipe_update_clk_rate(struct cam_hw_soc_info *soc_info, int cam_ipe_update_clk_rate(struct cam_hw_soc_info *soc_info,
uint32_t clk_rate); uint32_t clk_rate);
int cam_ipe_toggle_clk(struct cam_hw_soc_info *soc_info, bool clk_enable); int cam_ipe_toggle_clk(struct cam_hw_soc_info *soc_info, bool clk_enable);
void cam_ipe_deinit_soc_resources(struct cam_hw_soc_info *soc_info);
#endif /* CAM_IPE_SOC_H */ #endif /* CAM_IPE_SOC_H */

View File

@@ -5302,7 +5302,7 @@ static int cam_isp_context_debug_register(void)
isp_ctx_debug.dentry = debugfs_create_dir("camera_isp_ctx", isp_ctx_debug.dentry = debugfs_create_dir("camera_isp_ctx",
NULL); NULL);
if (!isp_ctx_debug.dentry) { if (IS_ERR_OR_NULL(isp_ctx_debug.dentry)) {
CAM_ERR(CAM_ISP, "failed to create dentry"); CAM_ERR(CAM_ISP, "failed to create dentry");
return -ENOMEM; return -ENOMEM;
} }
@@ -5383,7 +5383,8 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
for (i = 0; i < CAM_ISP_CTX_EVENT_MAX; i++) for (i = 0; i < CAM_ISP_CTX_EVENT_MAX; i++)
atomic64_set(&ctx->event_record_head[i], -1); atomic64_set(&ctx->event_record_head[i], -1);
cam_isp_context_debug_register(); if (!isp_ctx_debug.dentry)
cam_isp_context_debug_register();
err: err:
return rc; return rc;
@@ -5391,8 +5392,6 @@ err:
int cam_isp_context_deinit(struct cam_isp_context *ctx) int cam_isp_context_deinit(struct cam_isp_context *ctx)
{ {
int rc = 0;
if (ctx->base) if (ctx->base)
cam_context_deinit(ctx->base); cam_context_deinit(ctx->base);
@@ -5401,6 +5400,9 @@ int cam_isp_context_deinit(struct cam_isp_context *ctx)
__cam_isp_ctx_substate_val_to_type( __cam_isp_ctx_substate_val_to_type(
ctx->substate_activated)); ctx->substate_activated));
debugfs_remove_recursive(isp_ctx_debug.dentry);
isp_ctx_debug.dentry = NULL;
memset(ctx, 0, sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx));
return rc;
return 0;
} }

View File

@@ -175,7 +175,13 @@ static void cam_isp_dev_component_unbind(struct device *dev,
{ {
int rc = 0; int rc = 0;
int i; int i;
const char *compat_str = NULL;
struct platform_device *pdev = to_platform_device(dev);
rc = of_property_read_string_index(pdev->dev.of_node, "arch-compat", 0,
(const char **)&compat_str);
cam_isp_hw_mgr_deinit(compat_str);
/* clean up resources */ /* clean up resources */
for (i = 0; i < CAM_CTX_MAX; i++) { for (i = 0; i < CAM_CTX_MAX; i++) {
rc = cam_isp_context_deinit(&g_isp_dev.ctx_isp[i]); rc = cam_isp_context_deinit(&g_isp_dev.ctx_isp[i]);

View File

@@ -7867,3 +7867,27 @@ secure_fail:
g_ife_hw_mgr.mgr_common.img_iommu_hdl = -1; g_ife_hw_mgr.mgr_common.img_iommu_hdl = -1;
return rc; return rc;
} }
void cam_ife_hw_mgr_deinit(void)
{
int i = 0;
cam_req_mgr_workq_destroy(&g_ife_hw_mgr.workq);
debugfs_remove_recursive(g_ife_hw_mgr.debug_cfg.dentry);
g_ife_hw_mgr.debug_cfg.dentry = NULL;
for (i = 0; i < CAM_CTX_MAX; i++) {
cam_tasklet_deinit(
&g_ife_hw_mgr.mgr_common.tasklet_pool[i]);
kfree(g_ife_hw_mgr.ctx_pool[i].cdm_cmd);
g_ife_hw_mgr.ctx_pool[i].cdm_cmd = NULL;
g_ife_hw_mgr.ctx_pool[i].common.tasklet_info = NULL;
}
cam_smmu_destroy_handle(
g_ife_hw_mgr.mgr_common.img_iommu_hdl_secure);
g_ife_hw_mgr.mgr_common.img_iommu_hdl_secure = -1;
cam_smmu_destroy_handle(g_ife_hw_mgr.mgr_common.img_iommu_hdl);
g_ife_hw_mgr.mgr_common.img_iommu_hdl = -1;
}

View File

@@ -228,5 +228,6 @@ struct cam_ife_hw_event_recovery_data {
* *
*/ */
int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl); int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl);
void cam_ife_hw_mgr_deinit(void);
#endif /* _CAM_IFE_HW_MGR_H_ */ #endif /* _CAM_IFE_HW_MGR_H_ */

View File

@@ -25,3 +25,13 @@ int cam_isp_hw_mgr_init(const char *device_name_str,
return rc; return rc;
} }
void cam_isp_hw_mgr_deinit(const char *device_name_str)
{
if (strnstr(device_name_str, "ife", strlen(device_name_str)))
cam_ife_hw_mgr_deinit();
else if (strnstr(device_name_str, "tfe", strlen(device_name_str)))
cam_tfe_hw_mgr_deinit();
else
CAM_ERR(CAM_ISP, "Invalid ISP hw type :%s", device_name_str);
}

View File

@@ -5523,3 +5523,27 @@ secure_fail:
g_tfe_hw_mgr.mgr_common.img_iommu_hdl = -1; g_tfe_hw_mgr.mgr_common.img_iommu_hdl = -1;
return rc; return rc;
} }
void cam_tfe_hw_mgr_deinit(void)
{
int i = 0;
cam_req_mgr_workq_destroy(&g_tfe_hw_mgr.workq);
debugfs_remove_recursive(g_tfe_hw_mgr.debug_cfg.dentry);
g_tfe_hw_mgr.debug_cfg.dentry = NULL;
for (i = 0; i < CAM_CTX_MAX; i++) {
cam_tasklet_deinit(
&g_tfe_hw_mgr.mgr_common.tasklet_pool[i]);
kfree(g_tfe_hw_mgr.ctx_pool[i].cdm_cmd);
g_tfe_hw_mgr.ctx_pool[i].cdm_cmd = NULL;
g_tfe_hw_mgr.ctx_pool[i].common.tasklet_info = NULL;
}
cam_smmu_destroy_handle(
g_tfe_hw_mgr.mgr_common.img_iommu_hdl_secure);
g_tfe_hw_mgr.mgr_common.img_iommu_hdl_secure = -1;
cam_smmu_destroy_handle(g_tfe_hw_mgr.mgr_common.img_iommu_hdl);
g_tfe_hw_mgr.mgr_common.img_iommu_hdl = -1;
}

View File

@@ -195,12 +195,17 @@ struct cam_tfe_hw_event_recovery_data {
*/ */
#ifdef CONFIG_SPECTRA_TFE #ifdef CONFIG_SPECTRA_TFE
int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl); int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl);
void cam_tfe_hw_mgr_deinit(void);
#else #else
static inline int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, static inline int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf,
int *iommu_hdl) { int *iommu_hdl)
{
return -EINVAL; return -EINVAL;
} }
static inline void cam_tfe_hw_mgr_deinit(void)
{
}
#endif #endif
#endif /* _CAM_TFE_HW_MGR_H_ */ #endif /* _CAM_TFE_HW_MGR_H_ */

View File

@@ -371,4 +371,6 @@ struct cam_isp_start_args {
int cam_isp_hw_mgr_init(const char *device_name_str, int cam_isp_hw_mgr_init(const char *device_name_str,
struct cam_hw_mgr_intf *hw_mgr, int *iommu_hdl); struct cam_hw_mgr_intf *hw_mgr, int *iommu_hdl);
void cam_isp_hw_mgr_deinit(const char *device_name_str);
#endif /* __CAM_ISP_HW_MGR_INTF_H__ */ #endif /* __CAM_ISP_HW_MGR_INTF_H__ */

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // 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> #include <linux/slab.h>
#include "cam_ife_csid_soc.h" #include "cam_ife_csid_soc.h"
@@ -110,6 +110,9 @@ int cam_ife_csid_deinit_soc_resources(
CAM_ERR(CAM_ISP, "CPAS unregistration failed rc=%d", rc); CAM_ERR(CAM_ISP, "CPAS unregistration failed rc=%d", rc);
rc = cam_soc_util_release_platform_resource(soc_info); rc = cam_soc_util_release_platform_resource(soc_info);
if (rc)
CAM_WARN(CAM_ISP,
"soc release platform resource fail rc: %d", rc);
return rc; return rc;
} }

View File

@@ -208,11 +208,12 @@ int cam_vfe_deinit_soc_resources(struct cam_hw_soc_info *soc_info)
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"Error! Release platform resources failed rc=%d", rc); "Error! Release platform resources failed rc=%d", rc);
rc = cam_soc_util_clk_put(&soc_private->dsp_clk); if (soc_private->dsp_clk_index != -1) {
if (rc < 0) rc = cam_soc_util_clk_put(&soc_private->dsp_clk);
CAM_ERR(CAM_ISP, if (rc < 0)
"Error Put dsp clk failed rc=%d", rc); CAM_ERR(CAM_ISP,
"Error Put dsp clk failed rc=%d", rc);
}
kfree(soc_private); kfree(soc_private);
return rc; return rc;

View File

@@ -4220,6 +4220,7 @@ int cam_req_mgr_core_device_deinit(void)
} }
CAM_DBG(CAM_CRM, "g_crm_core_dev %pK", g_crm_core_dev); CAM_DBG(CAM_CRM, "g_crm_core_dev %pK", g_crm_core_dev);
cam_req_mgr_debug_unregister();
mutex_destroy(&g_crm_core_dev->crm_lock); mutex_destroy(&g_crm_core_dev->crm_lock);
kfree(g_crm_core_dev); kfree(g_crm_core_dev);
g_crm_core_dev = NULL; g_crm_core_dev = NULL;

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // 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 "cam_req_mgr_debug.h" #include "cam_req_mgr_debug.h"
@@ -8,6 +8,7 @@
#define MAX_SESS_INFO_LINE_BUFF_LEN 256 #define MAX_SESS_INFO_LINE_BUFF_LEN 256
static char sess_info_buffer[MAX_SESS_INFO_LINE_BUFF_LEN]; static char sess_info_buffer[MAX_SESS_INFO_LINE_BUFF_LEN];
static struct dentry *debugfs_root;
static int cam_req_mgr_debug_set_bubble_recovery(void *data, u64 val) static int cam_req_mgr_debug_set_bubble_recovery(void *data, u64 val)
{ {
@@ -112,28 +113,34 @@ static const struct file_operations session_info = {
int cam_req_mgr_debug_register(struct cam_req_mgr_core_device *core_dev) int cam_req_mgr_debug_register(struct cam_req_mgr_core_device *core_dev)
{ {
struct dentry *debugfs_root;
char dirname[32] = {0}; char dirname[32] = {0};
snprintf(dirname, sizeof(dirname), "cam_req_mgr"); snprintf(dirname, sizeof(dirname), "cam_req_mgr");
debugfs_root = debugfs_create_dir(dirname, NULL); debugfs_root = debugfs_create_dir(dirname, NULL);
if (!debugfs_root) if (IS_ERR_OR_NULL(debugfs_root)) {
return -ENOMEM; CAM_ERR(CAM_CRM, "Failed to create cam_req_mgr debugfs dir");
if (!debugfs_create_file("sessions_info", 0644,
debugfs_root, core_dev, &session_info))
return -ENOMEM;
if (!debugfs_create_file("bubble_recovery", 0644,
debugfs_root, core_dev, &bubble_recovery))
return -ENOMEM;
if (!debugfs_create_bool("recovery_on_apply_fail",
0644,
debugfs_root,
&core_dev->recovery_on_apply_fail)) {
return -ENOMEM; return -ENOMEM;
} }
if (!debugfs_create_file("sessions_info", 0644,
debugfs_root, core_dev, &session_info))
CAM_WARN(CAM_CRM,
"Failed to create sessions_info debugfs file");
if (!debugfs_create_file("bubble_recovery", 0644,
debugfs_root, core_dev, &bubble_recovery))
CAM_WARN(CAM_CRM,
"Failed to create bubble_recovery debugfs file");
if (!debugfs_create_bool("recovery_on_apply_fail",
0644, debugfs_root,
&core_dev->recovery_on_apply_fail))
CAM_WARN(CAM_CRM,
"Failed to create recovery_on_apply_fail debugfs bool");
return 0; return 0;
} }
void cam_req_mgr_debug_unregister(void)
{
if (!debugfs_root)
debugfs_remove_recursive(debugfs_root);
}

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*/ */
#ifndef _CAM_REQ_MGR_DEBUG_H_ #ifndef _CAM_REQ_MGR_DEBUG_H_
@@ -8,7 +8,9 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include "cam_req_mgr_core.h" #include "cam_req_mgr_core.h"
#include "cam_debug_util.h"
int cam_req_mgr_debug_register(struct cam_req_mgr_core_device *core_dev); int cam_req_mgr_debug_register(struct cam_req_mgr_core_device *core_dev);
void cam_req_mgr_debug_unregister(void);
#endif #endif

View File

@@ -519,6 +519,7 @@ static void cam_flash_component_unbind(struct device *dev,
cam_flash_shutdown(fctrl); cam_flash_shutdown(fctrl);
mutex_unlock(&fctrl->flash_mutex); mutex_unlock(&fctrl->flash_mutex);
cam_unregister_subdev(&(fctrl->v4l2_dev_str)); cam_unregister_subdev(&(fctrl->v4l2_dev_str));
cam_flash_put_source_node_data(fctrl);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
v4l2_set_subdevdata(&fctrl->v4l2_dev_str.sd, NULL); v4l2_set_subdevdata(&fctrl->v4l2_dev_str.sd, NULL);
kfree(fctrl); kfree(fctrl);
@@ -659,9 +660,9 @@ int32_t cam_flash_init_module(void)
int32_t rc = 0; int32_t rc = 0;
rc = platform_driver_register(&cam_flash_platform_driver); rc = platform_driver_register(&cam_flash_platform_driver);
if (rc == 0) { if (rc < 0) {
CAM_DBG(CAM_FLASH, "platform probe success"); CAM_ERR(CAM_FLASH, "platform probe failed rc: %d", rc);
return 0; return rc;
} }
rc = i2c_add_driver(&cam_flash_i2c_driver); rc = i2c_add_driver(&cam_flash_i2c_driver);

View File

@@ -8,6 +8,57 @@
#include "cam_flash_soc.h" #include "cam_flash_soc.h"
#include "cam_res_mgr_api.h" #include "cam_res_mgr_api.h"
void cam_flash_put_source_node_data(struct cam_flash_ctrl *fctrl)
{
uint32_t count = 0, i = 0;
struct cam_flash_private_soc *soc_private = NULL;
if (!fctrl) {
CAM_ERR(CAM_FLASH, "NULL flash control structure");
return;
}
soc_private = fctrl->soc_info.soc_private;
if (fctrl->switch_trigger) {
CAM_DBG(CAM_FLASH, "switch trigger: %s",
soc_private->switch_trigger_name);
cam_res_mgr_led_trigger_unregister(fctrl->switch_trigger);
}
if (fctrl->flash_num_sources) {
if (fctrl->flash_num_sources > CAM_FLASH_MAX_LED_TRIGGERS) {
CAM_ERR(CAM_FLASH, "Invalid LED count: %d", count);
return;
}
count = fctrl->flash_num_sources;
for (i = 0; i < count; i++) {
CAM_DBG(CAM_FLASH, "Flash default trigger %s",
soc_private->flash_trigger_name[i]);
cam_res_mgr_led_trigger_unregister(
fctrl->flash_trigger[i]);
}
}
if (fctrl->torch_num_sources) {
if (fctrl->torch_num_sources > CAM_FLASH_MAX_LED_TRIGGERS) {
CAM_ERR(CAM_FLASH, "Invalid LED count: %d", count);
return;
}
count = fctrl->torch_num_sources;
for (i = 0; i < count; i++) {
CAM_DBG(CAM_FLASH, "Flash default trigger %s",
soc_private->flash_trigger_name[i]);
cam_res_mgr_led_trigger_unregister(
fctrl->torch_trigger[i]);
}
}
}
static int32_t cam_get_source_node_info( static int32_t cam_get_source_node_info(
struct device_node *of_node, struct device_node *of_node,
struct cam_flash_ctrl *fctrl, struct cam_flash_ctrl *fctrl,

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* 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.
*/ */
#ifndef _CAM_FLASH_SOC_H_ #ifndef _CAM_FLASH_SOC_H_
@@ -11,4 +11,5 @@
int cam_flash_get_dt_data(struct cam_flash_ctrl *fctrl, int cam_flash_get_dt_data(struct cam_flash_ctrl *fctrl,
struct cam_hw_soc_info *soc_info); struct cam_hw_soc_info *soc_info);
void cam_flash_put_source_node_data(struct cam_flash_ctrl *fctrl);
#endif /*_CAM_FLASH_SOC_H_*/ #endif /*_CAM_FLASH_SOC_H_*/

View File

@@ -1072,24 +1072,39 @@ int cam_synx_sync_signal(int32_t sync_obj, uint32_t synx_status)
return rc; return rc;
} }
static int cam_sync_register_synx_bind_ops(void) static int cam_sync_register_synx_bind_ops(
struct synx_register_params *object)
{ {
int rc = 0; int rc = 0;
struct synx_register_params params;
params.name = CAM_SYNC_NAME; rc = synx_register_ops(object);
params.type = SYNX_TYPE_CSL;
params.ops.register_callback = cam_sync_register_callback;
params.ops.deregister_callback = cam_sync_deregister_callback;
params.ops.enable_signaling = cam_sync_get_obj_ref;
params.ops.signal = cam_synx_sync_signal;
rc = synx_register_ops(&params);
if (rc) if (rc)
CAM_ERR(CAM_SYNC, "synx registration fail with rc=%d", rc); CAM_ERR(CAM_SYNC, "synx registration fail with rc=%d", rc);
return rc; return rc;
} }
static void cam_sync_unregister_synx_bind_ops(
struct synx_register_params *object)
{
int rc = 0;
rc = synx_deregister_ops(object);
if (rc)
CAM_ERR(CAM_SYNC, "sync unregistration fail with %d", rc);
}
static void cam_sync_configure_synx_obj(struct synx_register_params *object)
{
struct synx_register_params *params = object;
params->name = CAM_SYNC_NAME;
params->type = SYNX_TYPE_CSL;
params->ops.register_callback = cam_sync_register_callback;
params->ops.deregister_callback = cam_sync_deregister_callback;
params->ops.enable_signaling = cam_sync_get_obj_ref;
params->ops.signal = cam_synx_sync_signal;
}
#endif #endif
static int cam_sync_component_bind(struct device *dev, static int cam_sync_component_bind(struct device *dev,
@@ -1167,8 +1182,9 @@ static int cam_sync_component_bind(struct device *dev,
trigger_cb_without_switch = false; trigger_cb_without_switch = false;
cam_sync_create_debugfs(); cam_sync_create_debugfs();
#if IS_REACHABLE(CONFIG_MSM_GLOBAL_SYNX) #if IS_REACHABLE(CONFIG_MSM_GLOBAL_SYNX)
CAM_INFO(CAM_SYNC, "Registering with synx driver"); CAM_DBG(CAM_SYNC, "Registering with synx driver");
rc = cam_sync_register_synx_bind_ops(); cam_sync_configure_synx_obj(&sync_dev->params);
rc = cam_sync_register_synx_bind_ops(&sync_dev->params);
if (rc) if (rc)
goto v4l2_fail; goto v4l2_fail;
#endif #endif
@@ -1195,6 +1211,9 @@ static void cam_sync_component_unbind(struct device *dev,
v4l2_device_unregister(sync_dev->vdev->v4l2_dev); v4l2_device_unregister(sync_dev->vdev->v4l2_dev);
cam_sync_media_controller_cleanup(sync_dev); cam_sync_media_controller_cleanup(sync_dev);
#if IS_REACHABLE(CONFIG_MSM_GLOBAL_SYNX)
cam_sync_unregister_synx_bind_ops(&sync_dev->params);
#endif
video_unregister_device(sync_dev->vdev); video_unregister_device(sync_dev->vdev);
video_device_release(sync_dev->vdev); video_device_release(sync_dev->vdev);
debugfs_remove_recursive(sync_dev->dentry); debugfs_remove_recursive(sync_dev->dentry);

View File

@@ -17,6 +17,10 @@
#include <media/v4l2-event.h> #include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h> #include <media/v4l2-ioctl.h>
#if IS_REACHABLE(CONFIG_MSM_GLOBAL_SYNX)
#include <synx_api.h>
#endif
#ifdef CONFIG_CAM_SYNC_DBG #ifdef CONFIG_CAM_SYNC_DBG
#define CDBG(fmt, args...) pr_err(fmt, ##args) #define CDBG(fmt, args...) pr_err(fmt, ##args)
#else #else
@@ -177,6 +181,7 @@ struct cam_signalable_info {
* @work_queue : Work queue used for dispatching kernel callbacks * @work_queue : Work queue used for dispatching kernel callbacks
* @cam_sync_eventq : Event queue used to dispatch user payloads to user space * @cam_sync_eventq : Event queue used to dispatch user payloads to user space
* @bitmap : Bitmap representation of all sync objects * @bitmap : Bitmap representation of all sync objects
* @params : Parameters for synx call back registration
*/ */
struct sync_device { struct sync_device {
struct video_device *vdev; struct video_device *vdev;
@@ -190,6 +195,9 @@ struct sync_device {
struct v4l2_fh *cam_sync_eventq; struct v4l2_fh *cam_sync_eventq;
spinlock_t cam_sync_eventq_lock; spinlock_t cam_sync_eventq_lock;
DECLARE_BITMAP(bitmap, CAM_SYNC_MAX_OBJS); DECLARE_BITMAP(bitmap, CAM_SYNC_MAX_OBJS);
#if IS_REACHABLE(CONFIG_MSM_GLOBAL_SYNX)
struct synx_register_params params;
#endif
}; };

View File

@@ -184,35 +184,35 @@ DEFINE_SIMPLE_ATTRIBUTE(cam_soc_util_clk_lvl_control,
static int cam_soc_util_create_clk_lvl_debugfs( static int cam_soc_util_create_clk_lvl_debugfs(
struct cam_hw_soc_info *soc_info) struct cam_hw_soc_info *soc_info)
{ {
struct dentry *dentry = NULL;
if (!soc_info) { if (!soc_info) {
CAM_ERR(CAM_UTIL, "soc info is NULL"); CAM_ERR(CAM_UTIL, "soc info is NULL");
return -EINVAL; return -EINVAL;
} }
if (soc_info->dentry) if (soc_info->dentry) {
CAM_DBG(CAM_UTIL, "Debubfs entry for %s already exist",
soc_info->dev_name);
return 0; return 0;
}
memset(debugfs_dir_name, 0, sizeof(debugfs_dir_name)); memset(debugfs_dir_name, 0, sizeof(debugfs_dir_name));
strlcat(debugfs_dir_name, "clk_dir_", sizeof(debugfs_dir_name)); strlcat(debugfs_dir_name, "clk_dir_", sizeof(debugfs_dir_name));
strlcat(debugfs_dir_name, soc_info->dev_name, sizeof(debugfs_dir_name)); strlcat(debugfs_dir_name, soc_info->dev_name, sizeof(debugfs_dir_name));
dentry = soc_info->dentry; soc_info->dentry = debugfs_create_dir(debugfs_dir_name, NULL);
dentry = debugfs_create_dir(debugfs_dir_name, NULL); if (IS_ERR_OR_NULL(soc_info->dentry)) {
if (!dentry) {
CAM_ERR(CAM_UTIL, "failed to create debug directory"); CAM_ERR(CAM_UTIL, "failed to create debug directory");
return -ENOMEM; return -ENOMEM;
} }
if (!debugfs_create_file("clk_lvl_options", 0444, if (!debugfs_create_file("clk_lvl_options", 0444,
dentry, soc_info, &cam_soc_util_clk_lvl_options)) { soc_info->dentry, soc_info, &cam_soc_util_clk_lvl_options)) {
CAM_ERR(CAM_UTIL, "failed to create clk_lvl_options"); CAM_ERR(CAM_UTIL, "failed to create clk_lvl_options");
goto err; goto err;
} }
if (!debugfs_create_file("clk_lvl_control", 0644, if (!debugfs_create_file("clk_lvl_control", 0644,
dentry, soc_info, &cam_soc_util_clk_lvl_control)) { soc_info->dentry, soc_info, &cam_soc_util_clk_lvl_control)) {
CAM_ERR(CAM_UTIL, "failed to create clk_lvl_control"); CAM_ERR(CAM_UTIL, "failed to create clk_lvl_control");
goto err; goto err;
} }
@@ -223,8 +223,10 @@ static int cam_soc_util_create_clk_lvl_debugfs(
return 0; return 0;
err: err:
debugfs_remove_recursive(dentry); CAM_ERR(CAM_UTIL, "Error in creating Debugfs Entry: %s",
dentry = NULL; soc_info->dev_name);
debugfs_remove_recursive(soc_info->dentry);
soc_info->dentry = NULL;
return -ENOMEM; return -ENOMEM;
} }