Message ID | 20170726215439.9623-2-wsa+renesas@sang-engineering.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Geert Uytterhoeven |
Headers | show |
On Wed, Jul 26, 2017 at 11:54 PM, Wolfram Sang <wsa+renesas@sang-engineering.com> wrote: > On Renesas R-Car archs, RuntimePM does all the clock handling. So, use > it consistently to enable/disable the clocks. Also make sure that clocks > are really enabled around clk_get_rate(). clk_summary looks proper now: > > clock enable_cnt prepare_cnt rate ... > Before this commit: > > At boot: rwdt 1 1 32768 0 0 > WDT running: rwdt 2 2 32768 0 0 > > After this commit: > > At boot: rwdt 0 1 32768 0 0 > WDT running rwdt 1 1 32768 0 0 > > Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On Wed, Jul 26, 2017 at 11:54:37PM +0200, Wolfram Sang wrote: > On Renesas R-Car archs, RuntimePM does all the clock handling. So, use > it consistently to enable/disable the clocks. Also make sure that clocks > are really enabled around clk_get_rate(). clk_summary looks proper now: > > clock enable_cnt prepare_cnt rate ... > Before this commit: > > At boot: rwdt 1 1 32768 0 0 > WDT running: rwdt 2 2 32768 0 0 > > After this commit: > > At boot: rwdt 0 1 32768 0 0 > WDT running rwdt 1 1 32768 0 0 > > Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> > Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Guenter Roeck <linux@roeck-us.net> > --- > drivers/watchdog/renesas_wdt.c | 33 +++++++++++++++++++-------------- > 1 file changed, 19 insertions(+), 14 deletions(-) > > diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c > index e3f204bb8802aa..a03997b418ba9c 100644 > --- a/drivers/watchdog/renesas_wdt.c > +++ b/drivers/watchdog/renesas_wdt.c > @@ -76,7 +76,7 @@ static int rwdt_start(struct watchdog_device *wdev) > { > struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > > - clk_prepare_enable(priv->clk); > + pm_runtime_get_sync(wdev->parent); > > rwdt_write(priv, 0, RWTCSRB); > rwdt_write(priv, priv->cks, RWTCSRA); > @@ -95,7 +95,7 @@ static int rwdt_stop(struct watchdog_device *wdev) > struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > > rwdt_write(priv, priv->cks, RWTCSRA); > - clk_disable_unprepare(priv->clk); > + pm_runtime_put(wdev->parent); > > return 0; > } > @@ -141,9 +141,16 @@ static int rwdt_probe(struct platform_device *pdev) > if (IS_ERR(priv->clk)) > return PTR_ERR(priv->clk); > > + pm_runtime_enable(&pdev->dev); > + > + pm_runtime_get_sync(&pdev->dev); > priv->clk_rate = clk_get_rate(priv->clk); > - if (!priv->clk_rate) > - return -ENOENT; > + pm_runtime_put(&pdev->dev); > + > + if (!priv->clk_rate) { > + ret = -ENOENT; > + goto out_pm_disable; > + } > > for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { > clks_per_sec = priv->clk_rate / clk_divs[i]; > @@ -155,12 +162,10 @@ static int rwdt_probe(struct platform_device *pdev) > > if (i < 0) { > dev_err(&pdev->dev, "Can't find suitable clock divider\n"); > - return -ERANGE; > + ret = -ERANGE; > + goto out_pm_disable; > } > > - pm_runtime_enable(&pdev->dev); > - pm_runtime_get_sync(&pdev->dev); > - > priv->wdev.info = &rwdt_ident, > priv->wdev.ops = &rwdt_ops, > priv->wdev.parent = &pdev->dev; > @@ -178,13 +183,14 @@ static int rwdt_probe(struct platform_device *pdev) > dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n"); > > ret = watchdog_register_device(&priv->wdev); > - if (ret < 0) { > - pm_runtime_put(&pdev->dev); > - pm_runtime_disable(&pdev->dev); > - return ret; > - } > + if (ret < 0) > + goto out_pm_disable; > > return 0; > + > + out_pm_disable: > + pm_runtime_disable(&pdev->dev); > + return ret; > } > > static int rwdt_remove(struct platform_device *pdev) > @@ -192,7 +198,6 @@ static int rwdt_remove(struct platform_device *pdev) > struct rwdt_priv *priv = platform_get_drvdata(pdev); > > watchdog_unregister_device(&priv->wdev); > - pm_runtime_put(&pdev->dev); > pm_runtime_disable(&pdev->dev); > > return 0;
diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index e3f204bb8802aa..a03997b418ba9c 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c @@ -76,7 +76,7 @@ static int rwdt_start(struct watchdog_device *wdev) { struct rwdt_priv *priv = watchdog_get_drvdata(wdev); - clk_prepare_enable(priv->clk); + pm_runtime_get_sync(wdev->parent); rwdt_write(priv, 0, RWTCSRB); rwdt_write(priv, priv->cks, RWTCSRA); @@ -95,7 +95,7 @@ static int rwdt_stop(struct watchdog_device *wdev) struct rwdt_priv *priv = watchdog_get_drvdata(wdev); rwdt_write(priv, priv->cks, RWTCSRA); - clk_disable_unprepare(priv->clk); + pm_runtime_put(wdev->parent); return 0; } @@ -141,9 +141,16 @@ static int rwdt_probe(struct platform_device *pdev) if (IS_ERR(priv->clk)) return PTR_ERR(priv->clk); + pm_runtime_enable(&pdev->dev); + + pm_runtime_get_sync(&pdev->dev); priv->clk_rate = clk_get_rate(priv->clk); - if (!priv->clk_rate) - return -ENOENT; + pm_runtime_put(&pdev->dev); + + if (!priv->clk_rate) { + ret = -ENOENT; + goto out_pm_disable; + } for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { clks_per_sec = priv->clk_rate / clk_divs[i]; @@ -155,12 +162,10 @@ static int rwdt_probe(struct platform_device *pdev) if (i < 0) { dev_err(&pdev->dev, "Can't find suitable clock divider\n"); - return -ERANGE; + ret = -ERANGE; + goto out_pm_disable; } - pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); - priv->wdev.info = &rwdt_ident, priv->wdev.ops = &rwdt_ops, priv->wdev.parent = &pdev->dev; @@ -178,13 +183,14 @@ static int rwdt_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n"); ret = watchdog_register_device(&priv->wdev); - if (ret < 0) { - pm_runtime_put(&pdev->dev); - pm_runtime_disable(&pdev->dev); - return ret; - } + if (ret < 0) + goto out_pm_disable; return 0; + + out_pm_disable: + pm_runtime_disable(&pdev->dev); + return ret; } static int rwdt_remove(struct platform_device *pdev) @@ -192,7 +198,6 @@ static int rwdt_remove(struct platform_device *pdev) struct rwdt_priv *priv = platform_get_drvdata(pdev); watchdog_unregister_device(&priv->wdev); - pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0;
On Renesas R-Car archs, RuntimePM does all the clock handling. So, use it consistently to enable/disable the clocks. Also make sure that clocks are really enabled around clk_get_rate(). clk_summary looks proper now: clock enable_cnt prepare_cnt rate ... Before this commit: At boot: rwdt 1 1 32768 0 0 WDT running: rwdt 2 2 32768 0 0 After this commit: At boot: rwdt 0 1 32768 0 0 WDT running rwdt 1 1 32768 0 0 Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> --- drivers/watchdog/renesas_wdt.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-)