Author: manu
Date: Fri Dec  9 20:28:28 2016
New Revision: 309761
URL: https://svnweb.freebsd.org/changeset/base/309761

Log:
  MFC r305058 (jmcneill):
  
  Add support for Allwinner A64 watchdog timer.

Modified:
  stable/11/sys/arm/allwinner/aw_wdog.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/arm/allwinner/aw_wdog.c
==============================================================================
--- stable/11/sys/arm/allwinner/aw_wdog.c       Fri Dec  9 20:25:59 2016        
(r309760)
+++ stable/11/sys/arm/allwinner/aw_wdog.c       Fri Dec  9 20:28:28 2016        
(r309761)
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/watchdog.h>
+#include <sys/reboot.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
@@ -53,6 +54,7 @@ __FBSDID("$FreeBSD$");
 #define        A10_WDOG_CTRL           0x00
 #define        A31_WDOG_CTRL           0x10
 #define         WDOG_CTRL_RESTART      (1 << 0)
+#define         A31_WDOG_CTRL_KEY      (0xa57 << 1)
 #define        A10_WDOG_MODE           0x04
 #define        A31_WDOG_MODE           0x18
 #define         A10_WDOG_MODE_INTVL_SHIFT      3
@@ -91,6 +93,7 @@ struct aw_wdog_softc {
        struct resource *       res;
        struct mtx              mtx;
        uint8_t                 wdog_ctrl;
+       uint32_t                wdog_ctrl_key;
        uint8_t                 wdog_mode;
        uint8_t                 wdog_mode_intvl_shift;
        uint8_t                 wdog_mode_en;
@@ -107,7 +110,8 @@ static struct ofw_compat_data compat_dat
        {NULL,             0}
 };
 
-static void aw_wdog_watchdog_fn(void *private, u_int cmd, int *error);
+static void aw_wdog_watchdog_fn(void *, u_int, int *);
+static void aw_wdog_shutdown_fn(void *, int);
 
 static int
 aw_wdog_probe(device_t dev)
@@ -159,6 +163,7 @@ aw_wdog_attach(device_t dev)
                break;
        case A31_WATCHDOG:
                sc->wdog_ctrl = A31_WDOG_CTRL;
+               sc->wdog_ctrl_key = A31_WDOG_CTRL_KEY;
                sc->wdog_mode = A31_WDOG_MODE;
                sc->wdog_mode_intvl_shift = A31_WDOG_MODE_INTVL_SHIFT;
                sc->wdog_mode_en = WDOG_MODE_EN;
@@ -172,6 +177,9 @@ aw_wdog_attach(device_t dev)
 
        mtx_init(&sc->mtx, "AW Watchdog", "aw_wdog", MTX_DEF);
        EVENTHANDLER_REGISTER(watchdog_list, aw_wdog_watchdog_fn, sc, 0);
+       EVENTHANDLER_REGISTER(shutdown_final, aw_wdog_shutdown_fn, sc,
+           SHUTDOWN_PRI_LAST - 1);
+       
        return (0);
 }
 
@@ -197,7 +205,8 @@ aw_wdog_watchdog_fn(void *private, u_int
                        WRITE(sc, sc->wdog_mode,
                          (wd_intervals[i].value << sc->wdog_mode_intvl_shift) |
                            sc->wdog_mode_en);
-                       WRITE(sc, sc->wdog_ctrl, WDOG_CTRL_RESTART);
+                       WRITE(sc, sc->wdog_ctrl,
+                           WDOG_CTRL_RESTART | sc->wdog_ctrl_key);
                        if (sc->wdog_config)
                                WRITE(sc, sc->wdog_config,
                                    sc->wdog_config_value);
@@ -221,6 +230,13 @@ aw_wdog_watchdog_fn(void *private, u_int
        mtx_unlock(&sc->mtx);
 }
 
+static void
+aw_wdog_shutdown_fn(void *private, int howto)
+{
+       if ((howto & (RB_POWEROFF|RB_HALT)) == 0)
+               aw_wdog_watchdog_reset();
+}
+
 void
 aw_wdog_watchdog_reset()
 {
@@ -236,6 +252,8 @@ aw_wdog_watchdog_reset()
        if (aw_wdog_sc->wdog_config)
                WRITE(aw_wdog_sc, aw_wdog_sc->wdog_config,
                      aw_wdog_sc->wdog_config_value);
+       WRITE(aw_wdog_sc, aw_wdog_sc->wdog_ctrl,
+           WDOG_CTRL_RESTART | aw_wdog_sc->wdog_ctrl_key);
        while(1)
                ;
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to