Module Name: src
Committed By: tnn
Date: Sat Oct 19 13:08:52 UTC 2019
Modified Files:
src/sys/dev/fdt: dwcwdt_fdt.c
Log Message:
dwcwdt: make this work correctly
- sysmon_wdog.smw_period is seconds, not milliseconds
- tickle the watchdog before enabling it
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/fdt/dwcwdt_fdt.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/fdt/dwcwdt_fdt.c
diff -u src/sys/dev/fdt/dwcwdt_fdt.c:1.3 src/sys/dev/fdt/dwcwdt_fdt.c:1.4
--- src/sys/dev/fdt/dwcwdt_fdt.c:1.3 Sun Oct 28 15:06:10 2018
+++ src/sys/dev/fdt/dwcwdt_fdt.c Sat Oct 19 13:08:52 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: dwcwdt_fdt.c,v 1.3 2018/10/28 15:06:10 aymeric Exp $ */
+/* $NetBSD: dwcwdt_fdt.c,v 1.4 2019/10/19 13:08:52 tnn Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dwcwdt_fdt.c,v 1.3 2018/10/28 15:06:10 aymeric Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dwcwdt_fdt.c,v 1.4 2019/10/19 13:08:52 tnn Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -111,8 +111,8 @@ dwcwdt_map_period(struct dwcwdt_softc *s
for (i = 0; i < __arraycount(wdt_torr); i++) {
const u_int ms = (u_int)((((uint64_t)wdt_torr[i] + 1) * 1000) / sc->sc_clkrate);
- if (ms >= period) {
- *aperiod = ms;
+ if (ms >= period * 1000) {
+ *aperiod = ms / 1000;
return i;
}
}
@@ -121,14 +121,28 @@ dwcwdt_map_period(struct dwcwdt_softc *s
}
static int
+dwcwdt_tickle(struct sysmon_wdog *smw)
+{
+ struct dwcwdt_softc * const sc = smw->smw_cookie;
+ const uint32_t crr =
+ __SHIFTIN(WDT_CRR_CNT_RESTART_MAGIC, WDT_CRR_CNT_RESTART);
+
+ WR4(sc, WDT_CRR, crr);
+
+ return 0;
+}
+
+static int
dwcwdt_setmode(struct sysmon_wdog *smw)
{
struct dwcwdt_softc * const sc = smw->smw_cookie;
uint32_t cr, torr;
int intv;
- if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED)
+ if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
+ /* Watchdog can only be disarmed by a reset */
return EIO;
+ }
if (smw->smw_period == WDOG_PERIOD_DEFAULT)
smw->smw_period = DWCWDT_PERIOD_DEFAULT;
@@ -140,7 +154,7 @@ dwcwdt_setmode(struct sysmon_wdog *smw)
torr = __SHIFTIN(intv, WDT_TORR_TIMEOUT_PERIOD);
WR4(sc, WDT_TORR, torr);
-
+ dwcwdt_tickle(smw);
cr = RD4(sc, WDT_CR);
cr &= ~WDT_CR_RESP_MODE;
cr |= WDT_CR_WDT_EN;
@@ -150,18 +164,6 @@ dwcwdt_setmode(struct sysmon_wdog *smw)
}
static int
-dwcwdt_tickle(struct sysmon_wdog *smw)
-{
- struct dwcwdt_softc * const sc = smw->smw_cookie;
- const uint32_t crr =
- __SHIFTIN(WDT_CRR_CNT_RESTART_MAGIC, WDT_CRR_CNT_RESTART);
-
- WR4(sc, WDT_CRR, crr);
-
- return 0;
-}
-
-static int
dwcwdt_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;