svn commit: r305058 - head/sys/arm/allwinner
Jared McNeill
jmcneill at FreeBSD.org
Tue Aug 30 10:21:33 UTC 2016
Author: jmcneill
Date: Tue Aug 30 10:21:32 2016
New Revision: 305058
URL: https://svnweb.freebsd.org/changeset/base/305058
Log:
Add support for Allwinner A64 watchdog timer.
Modified:
head/sys/arm/allwinner/aw_wdog.c
Modified: head/sys/arm/allwinner/aw_wdog.c
==============================================================================
--- head/sys/arm/allwinner/aw_wdog.c Tue Aug 30 08:34:49 2016 (r305057)
+++ head/sys/arm/allwinner/aw_wdog.c Tue Aug 30 10:21:32 2016 (r305058)
@@ -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>
@@ -54,6 +55,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
@@ -92,6 +94,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;
@@ -108,7 +111,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)
@@ -160,6 +164,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;
@@ -173,6 +178,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);
}
@@ -198,7 +206,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);
@@ -222,6 +231,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()
{
@@ -237,6 +253,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-head
mailing list