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 <jmcne...@invisible.ca>
@@ -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;

Reply via email to