Message ID | 1559711040-29779-1-git-send-email-yoshihiro.shimoda.uh@renesas.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | watchdog: renesas_wdt: Add a few cycles delay | expand |
> From: Yoshihiro Shimoda, Sent: Wednesday, June 5, 2019 2:04 PM > Subject: [PATCH] watchdog: renesas_wdt: Add a few cycles delay Oops, I should have submitted as "PATCH v3" on the subject... Best regards, Yoshihiro Shimoda
[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.uh@renesas.com> > Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> > Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> Reviewed-by: Guenter Roeck <linux@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;
On Fri, Jun 07, 2019 at 10:44:11AM -0700, Guenter Roeck wrote: > [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.uh@renesas.com> > > Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> > > Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> > > Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> > > Reviewed-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
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;