Message ID | 20240410134044.2138310-6-claudiu.beznea.uj@bp.renesas.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | watchdog: rzg2l_wdt: Add support for RZ/G3S | expand |
On Wed, Apr 10, 2024 at 04:40:39PM +0300, Claudiu wrote: > From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> > > There is no need to de-assert the reset signal on probe as the watchdog > is not used prior executing start. Also, the clocks are not enabled in > probe (pm_runtime_enable() doesn't do that), thus this is another indicator > that the watchdog wasn't used previously like this. Instead, keep the > watchdog hardware in its previous state at probe (by default it is in > reset state), enable it when it is started and move it to reset state > when it is stopped. This saves some extra power when the watchdog is > unused. > > Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> > --- > > Changes in v8: > - none > > Changes in v7: > - none > > Changes in v6: > - none > > Changes in v5: > - update patch title > > Changes in v4: > - none > > Changes in v3: > - none > > Changes in v2: > - none > > drivers/watchdog/rzg2l_wdt.c | 26 +++++++++++++++----------- > 1 file changed, 15 insertions(+), 11 deletions(-) > > diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c > index 7bce093316c4..93a49fd0c7aa 100644 > --- a/drivers/watchdog/rzg2l_wdt.c > +++ b/drivers/watchdog/rzg2l_wdt.c > @@ -129,6 +129,10 @@ static int rzg2l_wdt_start(struct watchdog_device *wdev) > if (ret) > return ret; > > + ret = reset_control_deassert(priv->rstc); > + if (ret) > + return ret; > + > /* Initialize time out */ > rzg2l_wdt_init_timeout(wdev); > > @@ -146,7 +150,9 @@ static int rzg2l_wdt_stop(struct watchdog_device *wdev) > struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); > int ret; > > - rzg2l_wdt_reset(priv); > + ret = reset_control_assert(priv->rstc); > + if (ret) > + return ret; > > ret = pm_runtime_put(wdev->parent); > if (ret < 0) > @@ -186,6 +192,12 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev, > clk_prepare_enable(priv->osc_clk); > > if (priv->devtype == WDT_RZG2L) { > + int ret; > + > + ret = reset_control_deassert(priv->rstc); > + if (ret) > + return ret; > + > /* Generate Reset (WDTRSTB) Signal on parity error */ > rzg2l_wdt_write(priv, 0, PECR); > > @@ -236,13 +248,11 @@ static const struct watchdog_ops rzg2l_wdt_ops = { > .restart = rzg2l_wdt_restart, > }; > > -static void rzg2l_wdt_reset_assert_pm_disable(void *data) > +static void rzg2l_wdt_pm_disable(void *data) > { > struct watchdog_device *wdev = data; > - struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); > > pm_runtime_disable(wdev->parent); > - reset_control_assert(priv->rstc); > } > > static int rzg2l_wdt_probe(struct platform_device *pdev) > @@ -285,10 +295,6 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) > return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc), > "failed to get cpg reset"); > > - ret = reset_control_deassert(priv->rstc); > - if (ret) > - return dev_err_probe(dev, ret, "failed to deassert"); > - > priv->devtype = (uintptr_t)of_device_get_match_data(dev); > > if (priv->devtype == WDT_RZV2M) { > @@ -309,9 +315,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) > priv->wdev.timeout = WDT_DEFAULT_TIMEOUT; > > watchdog_set_drvdata(&priv->wdev, priv); > - ret = devm_add_action_or_reset(&pdev->dev, > - rzg2l_wdt_reset_assert_pm_disable, > - &priv->wdev); > + ret = devm_add_action_or_reset(&pdev->dev, rzg2l_wdt_pm_disable, &priv->wdev); > if (ret < 0) > return ret; > > -- > 2.39.2 >
diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c index 7bce093316c4..93a49fd0c7aa 100644 --- a/drivers/watchdog/rzg2l_wdt.c +++ b/drivers/watchdog/rzg2l_wdt.c @@ -129,6 +129,10 @@ static int rzg2l_wdt_start(struct watchdog_device *wdev) if (ret) return ret; + ret = reset_control_deassert(priv->rstc); + if (ret) + return ret; + /* Initialize time out */ rzg2l_wdt_init_timeout(wdev); @@ -146,7 +150,9 @@ static int rzg2l_wdt_stop(struct watchdog_device *wdev) struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); int ret; - rzg2l_wdt_reset(priv); + ret = reset_control_assert(priv->rstc); + if (ret) + return ret; ret = pm_runtime_put(wdev->parent); if (ret < 0) @@ -186,6 +192,12 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev, clk_prepare_enable(priv->osc_clk); if (priv->devtype == WDT_RZG2L) { + int ret; + + ret = reset_control_deassert(priv->rstc); + if (ret) + return ret; + /* Generate Reset (WDTRSTB) Signal on parity error */ rzg2l_wdt_write(priv, 0, PECR); @@ -236,13 +248,11 @@ static const struct watchdog_ops rzg2l_wdt_ops = { .restart = rzg2l_wdt_restart, }; -static void rzg2l_wdt_reset_assert_pm_disable(void *data) +static void rzg2l_wdt_pm_disable(void *data) { struct watchdog_device *wdev = data; - struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); pm_runtime_disable(wdev->parent); - reset_control_assert(priv->rstc); } static int rzg2l_wdt_probe(struct platform_device *pdev) @@ -285,10 +295,6 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc), "failed to get cpg reset"); - ret = reset_control_deassert(priv->rstc); - if (ret) - return dev_err_probe(dev, ret, "failed to deassert"); - priv->devtype = (uintptr_t)of_device_get_match_data(dev); if (priv->devtype == WDT_RZV2M) { @@ -309,9 +315,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) priv->wdev.timeout = WDT_DEFAULT_TIMEOUT; watchdog_set_drvdata(&priv->wdev, priv); - ret = devm_add_action_or_reset(&pdev->dev, - rzg2l_wdt_reset_assert_pm_disable, - &priv->wdev); + ret = devm_add_action_or_reset(&pdev->dev, rzg2l_wdt_pm_disable, &priv->wdev); if (ret < 0) return ret;