From: Yoshihiro Shimoda Date: Wed, 5 Jun 2019 05:04:00 +0000 (+0900) Subject: watchdog: renesas_wdt: Add a few cycles delay X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=b836005b4f95cccdc1f53849a31cac2dc375f4b7;p=openwrt%2Fstaging%2Fblogic.git watchdog: renesas_wdt: Add a few cycles delay 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 Reviewed-by: Geert Uytterhoeven Reviewed-by: Wolfram Sang Reviewed-by: Niklas Söderlund Reviewed-by: Simon Horman Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index d8ac2299400b..00662a8e039c 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c @@ -7,6 +7,7 @@ */ #include #include +#include #include #include #include @@ -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;