summaryrefslogtreecommitdiff
path: root/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2016-04-08 16:16:28 +0300
committerThierry Reding <treding@nvidia.com>2016-04-28 13:41:54 +0300
commitf7c42d98621739d416cc4a739b721574fcbe910c (patch)
treecbd6f61c1a1b90780e63e7be5c3c4d3bd0988b5e /drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
parente8f6a68c508b5d1cc4612ada028d87c74ab279d5 (diff)
downloadlinux-f7c42d98621739d416cc4a739b721574fcbe910c.tar.xz
clk: tegra: dfll: Properly clean up on failure and removal
Upon failure to probe the DFLL, the OPP table will not be cleaned up properly. Fix this and while at it make sure the OPP table will also be cleared upon driver removal. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/clk/tegra/clk-tegra124-dfll-fcpu.c')
-rw-r--r--drivers/clk/tegra/clk-tegra124-dfll-fcpu.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
index c7ffd4fd2231..d052d9fa8230 100644
--- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
+++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
@@ -84,7 +84,7 @@ static const struct cvb_table tegra124_cpu_cvb_tables[] = {
static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
{
- int process_id, speedo_id, speedo_value;
+ int process_id, speedo_id, speedo_value, err;
struct tegra_dfll_soc_data *soc;
process_id = tegra_sku_info.cpu_process_id;
@@ -107,18 +107,41 @@ static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
return -ENODEV;
}
+ soc->max_freq = cpu_max_freq_table[speedo_id];
+
soc->cvb = tegra_cvb_add_opp_table(soc->dev, tegra124_cpu_cvb_tables,
ARRAY_SIZE(tegra124_cpu_cvb_tables),
process_id, speedo_id, speedo_value,
- cpu_max_freq_table[speedo_id]);
+ soc->max_freq);
if (IS_ERR(soc->cvb)) {
dev_err(&pdev->dev, "couldn't add OPP table: %ld\n",
PTR_ERR(soc->cvb));
return PTR_ERR(soc->cvb);
}
+ err = tegra_dfll_register(pdev, soc);
+ if (err < 0) {
+ tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
+ return err;
+ }
+
+ platform_set_drvdata(pdev, soc);
+
+ return 0;
+}
+
+static int tegra124_dfll_fcpu_remove(struct platform_device *pdev)
+{
+ struct tegra_dfll_soc_data *soc = platform_get_drvdata(pdev);
+ int err;
+
+ err = tegra_dfll_unregister(pdev);
+ if (err < 0)
+ dev_err(&pdev->dev, "failed to unregister DFLL: %d\n", err);
+
+ tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
- return tegra_dfll_register(pdev, soc);
+ return 0;
}
static const struct of_device_id tegra124_dfll_fcpu_of_match[] = {
@@ -134,7 +157,7 @@ static const struct dev_pm_ops tegra124_dfll_pm_ops = {
static struct platform_driver tegra124_dfll_fcpu_driver = {
.probe = tegra124_dfll_fcpu_probe,
- .remove = tegra_dfll_unregister,
+ .remove = tegra124_dfll_fcpu_remove,
.driver = {
.name = "tegra124-dfll",
.of_match_table = tegra124_dfll_fcpu_of_match,