mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
platform: tegra: bwmgr: Improve resource management to avoid leak
The previous implementation doesn't release the resource in a few cases, which can lead to leakage. Improving error handling and resource cleanup when the driver is removed. Bug 5483386 Change-Id: I316879075808ea945ebac997728aa51ff8b69488 Signed-off-by: robelin <robelin@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3474021 Reviewed-by: Johnny Liu <johnliu@nvidia.com> GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com> Reviewed-by: Rajkumar Kasirajan <rkasirajan@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
9831027796
commit
7f93fd77a5
@@ -189,8 +189,8 @@ static int tegra_bpmp_bwmgr_devfreq_register(struct tegra_bpmp_bwmgr *bwmgr)
|
|||||||
bwmgr->devfreq_profile,
|
bwmgr->devfreq_profile,
|
||||||
DEVFREQ_GOV_BWMGR, NULL);
|
DEVFREQ_GOV_BWMGR, NULL);
|
||||||
if (IS_ERR(bwmgr->devfreq)) {
|
if (IS_ERR(bwmgr->devfreq)) {
|
||||||
dev_pm_opp_remove_all_dynamic(bwmgr->dev);
|
ret = PTR_ERR(bwmgr->devfreq);
|
||||||
return PTR_ERR(bwmgr->devfreq);
|
goto devfreq_add_dev_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bwmgr->mrq_valid || !bwmgr->enabled) {
|
if (!bwmgr->mrq_valid || !bwmgr->enabled) {
|
||||||
@@ -209,12 +209,16 @@ static int tegra_bpmp_bwmgr_devfreq_register(struct tegra_bpmp_bwmgr *bwmgr)
|
|||||||
ret = dev_pm_qos_add_notifier(bwmgr->dev,
|
ret = dev_pm_qos_add_notifier(bwmgr->dev,
|
||||||
&bwmgr->max_freq_nb,
|
&bwmgr->max_freq_nb,
|
||||||
DEV_PM_QOS_MAX_FREQUENCY);
|
DEV_PM_QOS_MAX_FREQUENCY);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
devm_devfreq_remove_device(bwmgr->dev, bwmgr->devfreq);
|
goto devfreq_add_notifier_err;
|
||||||
dev_pm_opp_remove_all_dynamic(bwmgr->dev);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
devfreq_add_notifier_err:
|
||||||
|
devm_devfreq_remove_device(bwmgr->dev, bwmgr->devfreq);
|
||||||
|
devfreq_add_dev_err:
|
||||||
|
dev_pm_opp_remove_all_dynamic(bwmgr->dev);
|
||||||
|
kfree(bwmgr->devfreq_profile);
|
||||||
return ret;
|
return ret;
|
||||||
#else
|
#else
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
@@ -229,6 +233,7 @@ static void tegra_bpmp_bwmgr_devfreq_unregister(struct tegra_bpmp_bwmgr *bwmgr)
|
|||||||
DEV_PM_QOS_MAX_FREQUENCY);
|
DEV_PM_QOS_MAX_FREQUENCY);
|
||||||
devm_devfreq_remove_device(bwmgr->dev, bwmgr->devfreq);
|
devm_devfreq_remove_device(bwmgr->dev, bwmgr->devfreq);
|
||||||
dev_pm_opp_remove_all_dynamic(bwmgr->dev);
|
dev_pm_opp_remove_all_dynamic(bwmgr->dev);
|
||||||
|
kfree(bwmgr->devfreq_profile);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,12 +250,16 @@ static int tegra_bpmp_bwmgr_probe(struct platform_device *pdev)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
bwmgr->clk = devm_clk_get(&pdev->dev, "emc");
|
bwmgr->clk = devm_clk_get(&pdev->dev, "emc");
|
||||||
if (IS_ERR(bwmgr->clk))
|
if (IS_ERR(bwmgr->clk)) {
|
||||||
return PTR_ERR(bwmgr->clk);
|
err = PTR_ERR(bwmgr->clk);
|
||||||
|
goto devm_clk_get_err;
|
||||||
|
}
|
||||||
|
|
||||||
bwmgr->bpmp = tegra_bpmp_get(&pdev->dev);
|
bwmgr->bpmp = tegra_bpmp_get(&pdev->dev);
|
||||||
if (IS_ERR(bwmgr->bpmp))
|
if (IS_ERR(bwmgr->bpmp)) {
|
||||||
return PTR_ERR(bwmgr->bpmp);
|
err = PTR_ERR(bwmgr->bpmp);
|
||||||
|
goto bpmp_get_err;
|
||||||
|
}
|
||||||
|
|
||||||
bwmgr->mrq_valid = tegra_bpmp_mrq_is_supported(bwmgr->bpmp, MRQ_BWMGR_INT);
|
bwmgr->mrq_valid = tegra_bpmp_mrq_is_supported(bwmgr->bpmp, MRQ_BWMGR_INT);
|
||||||
if (bwmgr->mrq_valid) {
|
if (bwmgr->mrq_valid) {
|
||||||
@@ -285,16 +294,26 @@ static int tegra_bpmp_bwmgr_probe(struct platform_device *pdev)
|
|||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"fail to register devfreq governor %s: %d\n",
|
"fail to register devfreq governor %s: %d\n",
|
||||||
DEVFREQ_GOV_BWMGR, err);
|
DEVFREQ_GOV_BWMGR, err);
|
||||||
return err;
|
goto add_gov_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tegra_bpmp_bwmgr_devfreq_register(bwmgr);
|
err = tegra_bpmp_bwmgr_devfreq_register(bwmgr);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&pdev->dev, "fail to register devfreq device: %d\n", err);
|
dev_err(&pdev->dev, "fail to register devfreq device: %d\n", err);
|
||||||
return err;
|
goto devfreq_register_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
devfreq_register_err:
|
||||||
|
devfreq_remove_governor(&devfreq_gov_bwmgr);
|
||||||
|
add_gov_err:
|
||||||
|
tegra_bpmp_put(bwmgr->bpmp);
|
||||||
|
bpmp_get_err:
|
||||||
|
devm_clk_put(&pdev->dev, bwmgr->clk);
|
||||||
|
devm_clk_get_err:
|
||||||
|
kfree(bwmgr);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_bpmp_bwmgr_remove(struct platform_device *pdev)
|
static int tegra_bpmp_bwmgr_remove(struct platform_device *pdev)
|
||||||
@@ -303,6 +322,9 @@ static int tegra_bpmp_bwmgr_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
tegra_bpmp_bwmgr_devfreq_unregister(bwmgr);
|
tegra_bpmp_bwmgr_devfreq_unregister(bwmgr);
|
||||||
devfreq_remove_governor(&devfreq_gov_bwmgr);
|
devfreq_remove_governor(&devfreq_gov_bwmgr);
|
||||||
|
tegra_bpmp_put(bwmgr->bpmp);
|
||||||
|
devm_clk_put(&pdev->dev, bwmgr->clk);
|
||||||
|
kfree(bwmgr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user