svn commit: r309761 - stable/11/sys/arm/allwinner

Emmanuel Vadot manu at FreeBSD.org
Fri Dec 9 20:28:29 UTC 2016


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)
 		;
 


More information about the svn-src-all mailing list