Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1752c9ee authored by Nicolin Chen's avatar Nicolin Chen Committed by Thierry Reding
Browse files

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: default avatarNicolin Chen <nicoleotsuka@gmail.com>
Acked-By: default avatarPeter De Schrijver <pdeschrijver@nvidia.com>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 54eff226
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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);

+5 −7
Original line number Diff line number Diff line
@@ -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);