From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751803AbdJSHzG (ORCPT ); Thu, 19 Oct 2017 03:55:06 -0400 Received: from hqemgate15.nvidia.com ([216.228.121.64]:7750 "EHLO hqemgate15.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751681AbdJSHzE (ORCPT ); Thu, 19 Oct 2017 03:55:04 -0400 X-PGP-Universal: processed; by hqpgpgate102.nvidia.com on Thu, 19 Oct 2017 00:54:44 -0700 Date: Thu, 19 Oct 2017 10:51:29 +0300 From: Peter De Schrijver To: Nicolin Chen CC: , , , , , , , Subject: Re: [PATCH] clk: tegra: dfll: Fix drvdata overwriting issue Message-ID: <20171019075129.GO27164@tbergstrom-lnx.Nvidia.com> References: <1507849799-4256-1-git-send-email-nicoleotsuka@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <1507849799-4256-1-git-send-email-nicoleotsuka@gmail.com> X-NVConfidentiality: public User-Agent: Mutt/1.5.21 (2010-09-15) X-Originating-IP: [10.21.24.170] X-ClientProxiedBy: UKMAIL102.nvidia.com (10.26.138.15) To UKMAIL101.nvidia.com (10.26.138.13) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Oct 12, 2017 at 04:09:59PM -0700, Nicolin Chen wrote: > 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 Acked-By: Peter De Schrijver > --- > > As I don't have a T124 platform, I can't verify it on a board. > If someone could provide a Tested-by, it would be very helpful. > The test could be a simple system suspend/resume that activates > runtime_suspend/resume() where a platform_get_drvdata() would > be called. -- Nicolin > > drivers/clk/tegra/clk-dfll.c | 10 +++++----- > drivers/clk/tegra/clk-dfll.h | 2 +- > drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | 12 +++++------- > 3 files changed, 11 insertions(+), 13 deletions(-) > > diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c > index 2c44aeb..0a7deee 100644 > --- a/drivers/clk/tegra/clk-dfll.c > +++ b/drivers/clk/tegra/clk-dfll.c > @@ -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); > diff --git a/drivers/clk/tegra/clk-dfll.h b/drivers/clk/tegra/clk-dfll.h > index ed2ad88..83352c8 100644 > --- a/drivers/clk/tegra/clk-dfll.h > +++ b/drivers/clk/tegra/clk-dfll.h > @@ -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); > > diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c > index ad1c1cc..269d359 100644 > --- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c > +++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c > @@ -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); > > -- > 2.1.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-clk" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html