diff --git a/drivers/cam_cdm/cam_cdm_hw_core.c b/drivers/cam_cdm/cam_cdm_hw_core.c index ed3498308b..e8a4b6b7ac 100644 --- a/drivers/cam_cdm/cam_cdm_hw_core.c +++ b/drivers/cam_cdm/cam_cdm_hw_core.c @@ -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); diff --git a/drivers/cam_icp/cam_icp_subdev.c b/drivers/cam_icp/cam_icp_subdev.c index d4c7e025af..ee7fe5132d 100644 --- a/drivers/cam_icp/cam_icp_subdev.c +++ b/drivers/cam_icp/cam_icp_subdev.c @@ -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); diff --git a/drivers/cam_icp/icp_hw/a5_hw/a5_dev.c b/drivers/cam_icp/icp_hw/a5_hw/a5_dev.c index ef5ec1119d..64d02a7d5b 100644 --- a/drivers/cam_icp/icp_hw/a5_hw/a5_dev.c +++ b/drivers/cam_icp/icp_hw/a5_hw/a5_dev.c @@ -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, diff --git a/drivers/cam_icp/icp_hw/a5_hw/a5_soc.c b/drivers/cam_icp/icp_hw/a5_hw/a5_soc.c index d062961219..6e9bace10c 100644 --- a/drivers/cam_icp/icp_hw/a5_hw/a5_soc.c +++ b/drivers/cam_icp/icp_hw/a5_hw/a5_soc.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 @@ -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; diff --git a/drivers/cam_icp/icp_hw/a5_hw/a5_soc.h b/drivers/cam_icp/icp_hw/a5_hw/a5_soc.h index 480364df1f..8b5bc1c23c 100644 --- a/drivers/cam_icp/icp_hw/a5_hw/a5_soc.h +++ b/drivers/cam_icp/icp_hw/a5_hw/a5_soc.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. */ #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); diff --git a/drivers/cam_icp/icp_hw/bps_hw/bps_dev.c b/drivers/cam_icp/icp_hw/bps_hw/bps_dev.c index b70b2f187d..7dab07468d 100644 --- a/drivers/cam_icp/icp_hw/bps_hw/bps_dev.c +++ b/drivers/cam_icp/icp_hw/bps_hw/bps_dev.c @@ -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, diff --git a/drivers/cam_icp/icp_hw/bps_hw/bps_soc.c b/drivers/cam_icp/icp_hw/bps_hw/bps_soc.c index 481eeafdb0..d1a97de5c0 100644 --- a/drivers/cam_icp/icp_hw/bps_hw/bps_soc.c +++ b/drivers/cam_icp/icp_hw/bps_hw/bps_soc.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 @@ -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; diff --git a/drivers/cam_icp/icp_hw/bps_hw/bps_soc.h b/drivers/cam_icp/icp_hw/bps_hw/bps_soc.h index da4feac909..b7657bf671 100644 --- a/drivers/cam_icp/icp_hw/bps_hw/bps_soc.h +++ b/drivers/cam_icp/icp_hw/bps_hw/bps_soc.h @@ -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_*/ diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 1c804d5df6..268256d8a4 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -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); +} diff --git a/drivers/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h b/drivers/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h index 84129cba7e..c18e4053bc 100644 --- a/drivers/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h +++ b/drivers/cam_icp/icp_hw/include/cam_icp_hw_mgr_intf.h @@ -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 diff --git a/drivers/cam_icp/icp_hw/ipe_hw/ipe_dev.c b/drivers/cam_icp/icp_hw/ipe_hw/ipe_dev.c index c4b75711ce..70957a4068 100644 --- a/drivers/cam_icp/icp_hw/ipe_hw/ipe_dev.c +++ b/drivers/cam_icp/icp_hw/ipe_hw/ipe_dev.c @@ -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, diff --git a/drivers/cam_icp/icp_hw/ipe_hw/ipe_soc.c b/drivers/cam_icp/icp_hw/ipe_hw/ipe_soc.c index 11cc7f7a33..92d3390a9a 100644 --- a/drivers/cam_icp/icp_hw/ipe_hw/ipe_soc.c +++ b/drivers/cam_icp/icp_hw/ipe_hw/ipe_soc.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 @@ -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; diff --git a/drivers/cam_icp/icp_hw/ipe_hw/ipe_soc.h b/drivers/cam_icp/icp_hw/ipe_hw/ipe_soc.h index 8981b18823..c7e1150625 100644 --- a/drivers/cam_icp/icp_hw/ipe_hw/ipe_soc.h +++ b/drivers/cam_icp/icp_hw/ipe_hw/ipe_soc.h @@ -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 */ diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 0e95661bc6..71bac56daa 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -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; } diff --git a/drivers/cam_isp/cam_isp_dev.c b/drivers/cam_isp/cam_isp_dev.c index a8c56ae192..778621bcdb 100644 --- a/drivers/cam_isp/cam_isp_dev.c +++ b/drivers/cam_isp/cam_isp_dev.c @@ -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]); diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 17aa1ff4f2..0772711710 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -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; +} diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h index 9ff4c05d0e..ca1648d616 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h @@ -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_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.c index 4c83fa6b94..e68fd557a3 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.c @@ -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); +} diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c index 9d7ec3e038..6425088a46 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c @@ -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; +} diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h index 5b9ca51365..971863d5b5 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h @@ -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_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h index 32f38d81b5..2ed1f8b211 100644 --- a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.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__ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c index 7abcc64068..2065a3aeb4 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.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 #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; } diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c index 6f4152671f..3179362f7c 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c @@ -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; diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.c b/drivers/cam_req_mgr/cam_req_mgr_core.c index bd403c93b2..aaa10827fb 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/cam_req_mgr/cam_req_mgr_core.c @@ -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; diff --git a/drivers/cam_req_mgr/cam_req_mgr_debug.c b/drivers/cam_req_mgr/cam_req_mgr_debug.c index db6bec7043..6b6a91b630 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_debug.c +++ b/drivers/cam_req_mgr/cam_req_mgr_debug.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 "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); +} diff --git a/drivers/cam_req_mgr/cam_req_mgr_debug.h b/drivers/cam_req_mgr/cam_req_mgr_debug.h index dc72c522d1..defe55a731 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_debug.h +++ b/drivers/cam_req_mgr/cam_req_mgr_debug.h @@ -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 #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 diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c index 3d2ef84a2a..ae6620017d 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -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); diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c b/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c index abd2355403..17b7c7e0ae 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c @@ -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, diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_soc.h b/drivers/cam_sensor_module/cam_flash/cam_flash_soc.h index cfe7c3464f..466fbeef19 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_soc.h +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_soc.h @@ -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_*/ diff --git a/drivers/cam_sync/cam_sync.c b/drivers/cam_sync/cam_sync.c index a984a7be8f..37461c27d8 100644 --- a/drivers/cam_sync/cam_sync.c +++ b/drivers/cam_sync/cam_sync.c @@ -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(¶ms); + 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); diff --git a/drivers/cam_sync/cam_sync_private.h b/drivers/cam_sync/cam_sync_private.h index 2cd8917758..8d95efe2cf 100644 --- a/drivers/cam_sync/cam_sync_private.h +++ b/drivers/cam_sync/cam_sync_private.h @@ -17,6 +17,10 @@ #include #include +#if IS_REACHABLE(CONFIG_MSM_GLOBAL_SYNX) +#include +#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 }; diff --git a/drivers/cam_utils/cam_soc_util.c b/drivers/cam_utils/cam_soc_util.c index 39da1d20e3..5ea6375752 100644 --- a/drivers/cam_utils/cam_soc_util.c +++ b/drivers/cam_utils/cam_soc_util.c @@ -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; }