dwcwdt: make this work correctly
- sysmon_wdog.smw_period is seconds, not milliseconds - tickle the watchdog before enabling it
This commit is contained in:
parent
560ec699fa
commit
849f0a348f
@ -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 <jmcneill@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 *sc, u_int period,
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -120,6 +120,18 @@ dwcwdt_map_period(struct dwcwdt_softc *sc, u_int period,
|
||||
return -1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -127,8 +139,10 @@ dwcwdt_setmode(struct sysmon_wdog *smw)
|
||||
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;
|
||||
@ -149,18 +163,6 @@ dwcwdt_setmode(struct sysmon_wdog *smw)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user