clk: tegra: dfll: Fix drvdata overwriting issue

Both tegra124-dfll and clk-dfll are using platform_set_drvdata
to set drvdata of the exact same pdev while they use different
pointers for the drvdata. Once the drvdata has been overwritten
by tegra124-dfll, clk-dfll will never get its td pointer as it
expects.

Since tegra124-dfll merely needs its soc pointer in its remove
function, this patch fixes the bug by removing the overwriting
in the tegra124-dfll file and letting the tegra_dfll_unregister
return an soc pointer for it.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Acked-By: Peter De Schrijver <pdeschrijver@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
Nicolin Chen 2017-10-12 16:09:59 -07:00 committed by Thierry Reding
parent 54eff2264d
commit 1752c9ee23
3 changed files with 11 additions and 13 deletions

View File

@ -1728,10 +1728,10 @@ EXPORT_SYMBOL(tegra_dfll_register);
* @pdev: DFLL platform_device *
*
* Unbind this driver from the DFLL hardware device represented by
* @pdev. The DFLL must be disabled for this to succeed. Returns 0
* upon success or -EBUSY if the DFLL is still active.
* @pdev. The DFLL must be disabled for this to succeed. Returns a
* soc pointer upon success or -EBUSY if the DFLL is still active.
*/
int tegra_dfll_unregister(struct platform_device *pdev)
struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev)
{
struct tegra_dfll *td = platform_get_drvdata(pdev);
@ -1739,7 +1739,7 @@ int tegra_dfll_unregister(struct platform_device *pdev)
if (td->mode != DFLL_DISABLED) {
dev_err(&pdev->dev,
"must disable DFLL before removing driver\n");
return -EBUSY;
return ERR_PTR(-EBUSY);
}
debugfs_remove_recursive(td->debugfs_dir);
@ -1753,6 +1753,6 @@ int tegra_dfll_unregister(struct platform_device *pdev)
reset_control_assert(td->dvco_rst);
return 0;
return td->soc;
}
EXPORT_SYMBOL(tegra_dfll_unregister);

View File

@ -43,7 +43,7 @@ struct tegra_dfll_soc_data {
int tegra_dfll_register(struct platform_device *pdev,
struct tegra_dfll_soc_data *soc);
int tegra_dfll_unregister(struct platform_device *pdev);
struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev);
int tegra_dfll_runtime_suspend(struct device *dev);
int tegra_dfll_runtime_resume(struct device *dev);

View File

@ -125,19 +125,17 @@ static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
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;
struct tegra_dfll_soc_data *soc;
err = tegra_dfll_unregister(pdev);
if (err < 0)
dev_err(&pdev->dev, "failed to unregister DFLL: %d\n", err);
soc = tegra_dfll_unregister(pdev);
if (IS_ERR(soc))
dev_err(&pdev->dev, "failed to unregister DFLL: %ld\n",
PTR_ERR(soc));
tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);