]> git.sur5r.net Git - u-boot/blobdiff - drivers/watchdog/omap_wdt.c
SPDX: Convert all of our single license tags to Linux Kernel style
[u-boot] / drivers / watchdog / omap_wdt.c
index 7ea4b604cd6376d500944bd3ba81937df2a91cc1..343adb00c71bfe92c6cd4f27cca13d43a20c740b 100644 (file)
@@ -1,11 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * omap_wdt.c
  *
  * (C) Copyright 2013
  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  *
- * SPDX-License-Identifier:    GPL-2.0
- *
  * Based on:
  *
  * Watchdog driver for the TI OMAP 16xx & 24xx/34xx 32KHz (non-secure) watchdog
@@ -53,16 +52,25 @@ void hw_watchdog_reset(void)
 {
        struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
 
-       /* wait for posted write to complete */
-       while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WTGR)
-               ;
+       /*
+        * Somebody just triggered watchdog reset and write to WTGR register
+        * is in progress. It is resetting right now, no need to trigger it
+        * again
+        */
+       if ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WTGR)
+               return;
 
        wdt_trgr_pattern = ~wdt_trgr_pattern;
        writel(wdt_trgr_pattern, &wdt->wdtwtgr);
 
-       /* wait for posted write to complete */
-       while ((readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WTGR))
-               ;
+       /*
+        * Don't wait for posted write to complete, i.e. don't check
+        * WDT_WWPS_PEND_WTGR bit in WWPS register. There is no writes to
+        * WTGR register outside of this func, and if entering it
+        * we see WDT_WWPS_PEND_WTGR bit set, it means watchdog reset
+        * was just triggered. This prevents us from wasting time in busy
+        * polling of WDT_WWPS_PEND_WTGR bit.
+        */
 }
 
 static int omap_wdt_set_timeout(unsigned int timeout)
@@ -81,10 +89,32 @@ static int omap_wdt_set_timeout(unsigned int timeout)
        return 0;
 }
 
+void hw_watchdog_disable(void)
+{
+       struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+
+       /*
+        * Disable watchdog
+        */
+       writel(0xAAAA, &wdt->wdtwspr);
+       while (readl(&wdt->wdtwwps) != 0x0)
+               ;
+       writel(0x5555, &wdt->wdtwspr);
+       while (readl(&wdt->wdtwwps) != 0x0)
+               ;
+}
+
 void hw_watchdog_init(void)
 {
        struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
 
+       /*
+        * Make sure the watchdog is disabled. This is unfortunately required
+        * because writing to various registers with the watchdog running has no
+        * effect.
+        */
+       hw_watchdog_disable();
+
        /* initialize prescaler */
        while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
                ;
@@ -104,18 +134,3 @@ void hw_watchdog_init(void)
        while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
                ;
 }
-
-void hw_watchdog_disable(void)
-{
-       struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
-
-       /*
-        * Disable watchdog
-        */
-       writel(0xAAAA, &wdt->wdtwspr);
-       while (readl(&wdt->wdtwwps) != 0x0)
-               ;
-       writel(0x5555, &wdt->wdtwspr);
-       while (readl(&wdt->wdtwwps) != 0x0)
-               ;
-}