[Note: I updated the subject to "PATCH v3"] On Wed, Jun 05, 2019 at 02:04:00PM +0900, Yoshihiro Shimoda wrote: > According to the hardware manual of R-Car Gen2 and Gen3, > software should wait a few RLCK cycles as following: > - Delay 2 cycles before setting watchdog counter. > - Delay 3 cycles before disabling module clock. > > So, this patch adds such delays. > > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda...@renesas.com> > Reviewed-by: Geert Uytterhoeven <geert+rene...@glider.be> > Reviewed-by: Wolfram Sang <wsa+rene...@sang-engineering.com> > Reviewed-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>
Reviewed-by: Guenter Roeck <li...@roeck-us.net> > --- > Changes from v2 (https://patchwork.kernel.org/patch/10972721/): > - Rename the wait function name. > - Rename the variable name in the wait function. > - Change variable type. > - Add Wolfram-san and Niklas-san's Reviewed-by. > > Changes from v1 (https://patchwork.kernel.org/patch/10972641/): > - Change formula to improve accuracy. > - Add Geert-san's Reviewed-by. > > drivers/watchdog/renesas_wdt.c | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > > diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c > index 565dbc1..0cfc0e9 100644 > --- a/drivers/watchdog/renesas_wdt.c > +++ b/drivers/watchdog/renesas_wdt.c > @@ -7,6 +7,7 @@ > */ > #include <linux/bitops.h> > #include <linux/clk.h> > +#include <linux/delay.h> > #include <linux/io.h> > #include <linux/kernel.h> > #include <linux/module.h> > @@ -70,6 +71,15 @@ static int rwdt_init_timeout(struct watchdog_device *wdev) > return 0; > } > > +static void rwdt_wait_cycles(struct rwdt_priv *priv, unsigned int cycles) > +{ > + unsigned int delay; > + > + delay = DIV_ROUND_UP(cycles * 1000000, priv->clk_rate); > + > + usleep_range(delay, 2 * delay); > +} > + > static int rwdt_start(struct watchdog_device *wdev) > { > struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > @@ -80,6 +90,8 @@ static int rwdt_start(struct watchdog_device *wdev) > /* Stop the timer before we modify any register */ > val = readb_relaxed(priv->base + RWTCSRA) & ~RWTCSRA_TME; > rwdt_write(priv, val, RWTCSRA); > + /* Delay 2 cycles before setting watchdog counter */ > + rwdt_wait_cycles(priv, 2); > > rwdt_init_timeout(wdev); > rwdt_write(priv, priv->cks, RWTCSRA); > @@ -98,6 +110,8 @@ static int rwdt_stop(struct watchdog_device *wdev) > struct rwdt_priv *priv = watchdog_get_drvdata(wdev); > > rwdt_write(priv, priv->cks, RWTCSRA); > + /* Delay 3 cycles before disabling module clock */ > + rwdt_wait_cycles(priv, 3); > pm_runtime_put(wdev->parent); > > return 0;