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:
committed by
Thierry Reding
parent
54eff2264d
commit
1752c9ee23
@ -1728,10 +1728,10 @@ EXPORT_SYMBOL(tegra_dfll_register);
|
|||||||
* @pdev: DFLL platform_device *
|
* @pdev: DFLL platform_device *
|
||||||
*
|
*
|
||||||
* Unbind this driver from the DFLL hardware device represented by
|
* Unbind this driver from the DFLL hardware device represented by
|
||||||
* @pdev. The DFLL must be disabled for this to succeed. Returns 0
|
* @pdev. The DFLL must be disabled for this to succeed. Returns a
|
||||||
* upon success or -EBUSY if the DFLL is still active.
|
* 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);
|
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) {
|
if (td->mode != DFLL_DISABLED) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"must disable DFLL before removing driver\n");
|
"must disable DFLL before removing driver\n");
|
||||||
return -EBUSY;
|
return ERR_PTR(-EBUSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
debugfs_remove_recursive(td->debugfs_dir);
|
debugfs_remove_recursive(td->debugfs_dir);
|
||||||
@ -1753,6 +1753,6 @@ int tegra_dfll_unregister(struct platform_device *pdev)
|
|||||||
|
|
||||||
reset_control_assert(td->dvco_rst);
|
reset_control_assert(td->dvco_rst);
|
||||||
|
|
||||||
return 0;
|
return td->soc;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tegra_dfll_unregister);
|
EXPORT_SYMBOL(tegra_dfll_unregister);
|
||||||
|
@ -43,7 +43,7 @@ struct tegra_dfll_soc_data {
|
|||||||
|
|
||||||
int tegra_dfll_register(struct platform_device *pdev,
|
int tegra_dfll_register(struct platform_device *pdev,
|
||||||
struct tegra_dfll_soc_data *soc);
|
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_suspend(struct device *dev);
|
||||||
int tegra_dfll_runtime_resume(struct device *dev);
|
int tegra_dfll_runtime_resume(struct device *dev);
|
||||||
|
|
||||||
|
@ -125,19 +125,17 @@ static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, soc);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra124_dfll_fcpu_remove(struct platform_device *pdev)
|
static int tegra124_dfll_fcpu_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct tegra_dfll_soc_data *soc = platform_get_drvdata(pdev);
|
struct tegra_dfll_soc_data *soc;
|
||||||
int err;
|
|
||||||
|
|
||||||
err = tegra_dfll_unregister(pdev);
|
soc = tegra_dfll_unregister(pdev);
|
||||||
if (err < 0)
|
if (IS_ERR(soc))
|
||||||
dev_err(&pdev->dev, "failed to unregister DFLL: %d\n", err);
|
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);
|
tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user