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>
此提交包含在:
Jigarkumar Zala
2020-04-07 14:26:03 -07:00
父節點 f65f27de96
當前提交 279dfebf8c
共有 32 個檔案被更改,包括 391 行新增89 行删除

查看文件

@@ -2206,10 +2206,19 @@ static void cam_hw_cdm_component_unbind(struct device *dev,
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) {
CAM_ERR(CAM_CDM, "Deinit failed for hw");
return;
CAM_ERR(CAM_CDM,
"HW_CDM interface deregistration failed: rd: %d", rc);
}
rc = cam_cpas_unregister_client(cdm_core->cpas_handle);

查看文件

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

查看文件

@@ -168,7 +168,7 @@ static int cam_a5_component_bind(struct device *dev,
}
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,
core_info, a5_dev_intf->hw_idx);
if (rc < 0) {
@@ -185,6 +185,7 @@ static int cam_a5_component_bind(struct device *dev,
return 0;
cpas_reg_failed:
cam_a5_deinit_soc_resources(&a5_dev->soc_info);
init_soc_failure:
match_err:
kfree(a5_dev->core_info);
@@ -200,9 +201,21 @@ a5_dev_alloc_failure:
static void cam_a5_component_unbind(struct device *dev,
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);
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 = {
@@ -222,6 +235,12 @@ int cam_a5_probe(struct platform_device *pdev)
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[] = {
{
.compatible = "qcom,cam-a5",
@@ -233,6 +252,7 @@ MODULE_DEVICE_TABLE(of, cam_a5_dt_match);
struct platform_driver cam_a5_driver = {
.probe = cam_a5_probe,
.remove = cam_a5_remove,
.driver = {
.name = "cam-a5",
.owner = THIS_MODULE,

查看文件

@@ -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/io.h>
@@ -174,6 +174,15 @@ int cam_a5_init_soc_resources(struct cam_hw_soc_info *soc_info,
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 rc = 0;

查看文件

@@ -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.
*/
#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,
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_disable_soc_resources(struct cam_hw_soc_info *soc_info);

查看文件

@@ -177,9 +177,21 @@ static int cam_bps_component_bind(struct device *dev,
static void cam_bps_component_unbind(struct device *dev,
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);
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 = {
@@ -199,6 +211,12 @@ int cam_bps_probe(struct platform_device *pdev)
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[] = {
{
.compatible = "qcom,cam-bps",
@@ -210,6 +228,7 @@ MODULE_DEVICE_TABLE(of, cam_bps_dt_match);
struct platform_driver cam_bps_driver = {
.probe = cam_bps_probe,
.remove = cam_bps_remove,
.driver = {
.name = "cam-bps",
.owner = THIS_MODULE,

查看文件

@@ -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/io.h>
@@ -52,6 +52,15 @@ int cam_bps_init_soc_resources(struct cam_hw_soc_info *soc_info,
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 rc = 0;

查看文件

@@ -1,6 +1,6 @@
/* 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_
@@ -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,
uint32_t clk_rate);
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_*/

查看文件

@@ -1887,8 +1887,11 @@ static int cam_icp_hw_mgr_create_debugfs_entry(void)
int rc = 0;
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;
}
if (!debugfs_create_bool("icp_pc",
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);
if (!icp_hw_mgr.devices[CAM_ICP_DEV_A5]) {
rc = -ENOMEM;
CAM_ERR(CAM_ICP, "a5 allocation fail: rc = %d", rc);
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);
if (!icp_hw_mgr.devices[CAM_ICP_DEV_IPE]) {
rc = -ENOMEM;
CAM_ERR(CAM_ICP, "ipe device allocation fail : rc= %d", rc);
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);
if (!icp_hw_mgr.devices[CAM_ICP_DEV_BPS]) {
rc = -ENOMEM;
CAM_ERR(CAM_ICP, "bps device allocation fail : rc= %d", rc);
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;
rc = cam_icp_mgr_alloc_devs(of_node);
if (rc)
if (rc) {
CAM_ERR(CAM_ICP, "alloc_devs fail : rc = %d", rc);
return rc;
}
count = of_property_count_strings(of_node, "compat-hw-name");
if (!count) {
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 =
kzalloc(sizeof(struct hfi_cmd_work_data) * ICP_WORKQ_NUM_TASK,
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;
}
icp_hw_mgr.msg_work_data =
kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK,
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;
}
icp_hw_mgr.timer_work_data =
kzalloc(sizeof(struct hfi_msg_work_data) * ICP_WORKQ_NUM_TASK,
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;
}
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;
}
for (i = 0; i < ICP_WORKQ_NUM_TASK; i++)
icp_hw_mgr.msg_work->task.pool[i].payload =
&icp_hw_mgr.msg_work_data[i];
@@ -6020,6 +6033,13 @@ cmd_work_failed:
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)
{
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);
if (rc)
if (rc) {
CAM_ERR(CAM_ICP, "cam_icp_mgr_init_devs fail: rc: %d", rc);
goto dev_init_failed;
}
rc = cam_smmu_get_handle("icp", &icp_hw_mgr.iommu_hdl);
if (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();
if (rc)
if (rc) {
CAM_ERR(CAM_ICP, "cam_icp_mgr_create_wq fail: rc=%d", rc);
goto icp_wq_create_failed;
}
if (iommu_hdl)
*iommu_hdl = icp_hw_mgr.iommu_hdl;
@@ -6146,3 +6169,18 @@ dev_init_failed:
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);
}

查看文件

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

查看文件

@@ -169,9 +169,20 @@ static int cam_ipe_component_bind(struct device *dev,
static void cam_ipe_component_unbind(struct device *dev,
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);
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;
}
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[] = {
{
.compatible = "qcom,cam-ipe",
@@ -203,6 +220,7 @@ MODULE_DEVICE_TABLE(of, cam_ipe_dt_match);
struct platform_driver cam_ipe_driver = {
.probe = cam_ipe_probe,
.remove = cam_ipe_remove,
.driver = {
.name = "cam-ipe",
.owner = THIS_MODULE,

查看文件

@@ -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/io.h>
@@ -103,6 +103,15 @@ int cam_ipe_init_soc_resources(struct cam_hw_soc_info *soc_info,
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 rc = 0;

查看文件

@@ -1,6 +1,6 @@
/* 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
@@ -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,
uint32_t clk_rate);
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 */

查看文件

@@ -5302,7 +5302,7 @@ static int cam_isp_context_debug_register(void)
isp_ctx_debug.dentry = debugfs_create_dir("camera_isp_ctx",
NULL);
if (!isp_ctx_debug.dentry) {
if (IS_ERR_OR_NULL(isp_ctx_debug.dentry)) {
CAM_ERR(CAM_ISP, "failed to create dentry");
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++)
atomic64_set(&ctx->event_record_head[i], -1);
cam_isp_context_debug_register();
if (!isp_ctx_debug.dentry)
cam_isp_context_debug_register();
err:
return rc;
@@ -5391,8 +5392,6 @@ err:
int cam_isp_context_deinit(struct cam_isp_context *ctx)
{
int rc = 0;
if (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(
ctx->substate_activated));
debugfs_remove_recursive(isp_ctx_debug.dentry);
isp_ctx_debug.dentry = NULL;
memset(ctx, 0, sizeof(*ctx));
return rc;
return 0;
}

查看文件

@@ -175,7 +175,13 @@ static void cam_isp_dev_component_unbind(struct device *dev,
{
int rc = 0;
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 */
for (i = 0; i < CAM_CTX_MAX; i++) {
rc = cam_isp_context_deinit(&g_isp_dev.ctx_isp[i]);

查看文件

@@ -7867,3 +7867,27 @@ secure_fail:
g_ife_hw_mgr.mgr_common.img_iommu_hdl = -1;
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;
}

查看文件

@@ -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);
void cam_ife_hw_mgr_deinit(void);
#endif /* _CAM_IFE_HW_MGR_H_ */

查看文件

@@ -25,3 +25,13 @@ int cam_isp_hw_mgr_init(const char *device_name_str,
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);
}

查看文件

@@ -5523,3 +5523,27 @@ secure_fail:
g_tfe_hw_mgr.mgr_common.img_iommu_hdl = -1;
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;
}

查看文件

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

查看文件

@@ -371,4 +371,6 @@ struct cam_isp_start_args {
int cam_isp_hw_mgr_init(const char *device_name_str,
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__ */

查看文件

@@ -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>
#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);
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;
}

查看文件

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

查看文件

@@ -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_req_mgr_debug_unregister();
mutex_destroy(&g_crm_core_dev->crm_lock);
kfree(g_crm_core_dev);
g_crm_core_dev = NULL;

查看文件

@@ -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 "cam_req_mgr_debug.h"
@@ -8,6 +8,7 @@
#define MAX_SESS_INFO_LINE_BUFF_LEN 256
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)
{
@@ -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)
{
struct dentry *debugfs_root;
char dirname[32] = {0};
snprintf(dirname, sizeof(dirname), "cam_req_mgr");
debugfs_root = debugfs_create_dir(dirname, NULL);
if (!debugfs_root)
return -ENOMEM;
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)) {
if (IS_ERR_OR_NULL(debugfs_root)) {
CAM_ERR(CAM_CRM, "Failed to create cam_req_mgr debugfs dir");
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;
}
void cam_req_mgr_debug_unregister(void)
{
if (!debugfs_root)
debugfs_remove_recursive(debugfs_root);
}

查看文件

@@ -1,6 +1,6 @@
/* 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_
@@ -8,7 +8,9 @@
#include <linux/debugfs.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);
void cam_req_mgr_debug_unregister(void);
#endif

查看文件

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

查看文件

@@ -8,6 +8,57 @@
#include "cam_flash_soc.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(
struct device_node *of_node,
struct cam_flash_ctrl *fctrl,

查看文件

@@ -1,6 +1,6 @@
/* 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_
@@ -11,4 +11,5 @@
int cam_flash_get_dt_data(struct cam_flash_ctrl *fctrl,
struct cam_hw_soc_info *soc_info);
void cam_flash_put_source_node_data(struct cam_flash_ctrl *fctrl);
#endif /*_CAM_FLASH_SOC_H_*/

查看文件

@@ -1072,24 +1072,39 @@ int cam_synx_sync_signal(int32_t sync_obj, uint32_t synx_status)
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;
struct synx_register_params params;
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;
rc = synx_register_ops(&params);
rc = synx_register_ops(object);
if (rc)
CAM_ERR(CAM_SYNC, "synx registration fail with rc=%d", 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
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;
cam_sync_create_debugfs();
#if IS_REACHABLE(CONFIG_MSM_GLOBAL_SYNX)
CAM_INFO(CAM_SYNC, "Registering with synx driver");
rc = cam_sync_register_synx_bind_ops();
CAM_DBG(CAM_SYNC, "Registering with synx driver");
cam_sync_configure_synx_obj(&sync_dev->params);
rc = cam_sync_register_synx_bind_ops(&sync_dev->params);
if (rc)
goto v4l2_fail;
#endif
@@ -1195,6 +1211,9 @@ static void cam_sync_component_unbind(struct device *dev,
v4l2_device_unregister(sync_dev->vdev->v4l2_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_device_release(sync_dev->vdev);
debugfs_remove_recursive(sync_dev->dentry);

查看文件

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

查看文件

@@ -184,35 +184,35 @@ DEFINE_SIMPLE_ATTRIBUTE(cam_soc_util_clk_lvl_control,
static int cam_soc_util_create_clk_lvl_debugfs(
struct cam_hw_soc_info *soc_info)
{
struct dentry *dentry = NULL;
if (!soc_info) {
CAM_ERR(CAM_UTIL, "soc info is NULL");
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;
}
memset(debugfs_dir_name, 0, 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));
dentry = soc_info->dentry;
dentry = debugfs_create_dir(debugfs_dir_name, NULL);
if (!dentry) {
soc_info->dentry = debugfs_create_dir(debugfs_dir_name, NULL);
if (IS_ERR_OR_NULL(soc_info->dentry)) {
CAM_ERR(CAM_UTIL, "failed to create debug directory");
return -ENOMEM;
}
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");
goto err;
}
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");
goto err;
}
@@ -223,8 +223,10 @@ static int cam_soc_util_create_clk_lvl_debugfs(
return 0;
err:
debugfs_remove_recursive(dentry);
dentry = NULL;
CAM_ERR(CAM_UTIL, "Error in creating Debugfs Entry: %s",
soc_info->dev_name);
debugfs_remove_recursive(soc_info->dentry);
soc_info->dentry = NULL;
return -ENOMEM;
}