Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/dwwdt/dwwdt.c
Show First 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | |||||
static struct ofw_compat_data compat_data[] = { | static struct ofw_compat_data compat_data[] = { | ||||
{ "snps,dw-wdt", 1 }, | { "snps,dw-wdt", 1 }, | ||||
{ NULL, 0 } | { NULL, 0 } | ||||
}; | }; | ||||
SYSCTL_NODE(_dev, OID_AUTO, dwwdt, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, | SYSCTL_NODE(_dev, OID_AUTO, dwwdt, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, | ||||
"Synopsys Designware watchdog timer"); | "Synopsys Designware watchdog timer"); | ||||
/* Setting this to 0 enables full restart mode. */ | |||||
static uint32_t dwwdt_prevent_restart = 1; | |||||
SYSCTL_UINT(_dev_dwwdt, OID_AUTO, prevent_restart, CTLFLAG_RW | CTLFLAG_MPSAFE, | |||||
&dwwdt_prevent_restart, 1, | |||||
"Prevent system restart (0 - Disabled; 1 - Enabled)"); | |||||
static uint32_t dwwdt_debug_enabled = 0; | /* Setting this to true disables full restart mode. */ | ||||
SYSCTL_UINT(_dev_dwwdt, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_MPSAFE, | static bool dwwdt_prevent_restart = false; | ||||
&dwwdt_debug_enabled, 1, "Debug mode (0 - Disabled; 1 - Enabled)"); | SYSCTL_BOOL(_dev_dwwdt, OID_AUTO, prevent_restart, CTLFLAG_RW | CTLFLAG_MPSAFE, | ||||
&dwwdt_prevent_restart, 0, "Disable system reset on timeout"); | |||||
static bool dwwdt_debug_enabled = false; | |||||
SYSCTL_BOOL(_dev_dwwdt, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_MPSAFE, | |||||
&dwwdt_debug_enabled, 0, "Enable debug mode"); | |||||
static bool dwwdt_panic_first = true; | |||||
SYSCTL_BOOL(_dev_dwwdt, OID_AUTO, panic_first, CTLFLAG_RW | CTLFLAG_MPSAFE, | |||||
&dwwdt_panic_first, 0, | |||||
"Try to panic on timeout, reset on another timeout"); | |||||
static int dwwdt_probe(device_t); | static int dwwdt_probe(device_t); | ||||
static int dwwdt_attach(device_t); | static int dwwdt_attach(device_t); | ||||
static int dwwdt_detach(device_t); | static int dwwdt_detach(device_t); | ||||
static int dwwdt_shutdown(device_t); | static int dwwdt_shutdown(device_t); | ||||
static void dwwdt_intr(void *); | static void dwwdt_intr(void *); | ||||
static void dwwdt_event(void *, unsigned int, int *); | static void dwwdt_event(void *, unsigned int, int *); | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
dwwdt_intr(void *arg) | dwwdt_intr(void *arg) | ||||
{ | { | ||||
struct dwwdt_softc *sc = arg; | struct dwwdt_softc *sc = arg; | ||||
KASSERT((DWWDT_READ4(sc, DWWDT_STAT) & DWWDT_STAT_STATUS) != 0, | KASSERT((DWWDT_READ4(sc, DWWDT_STAT) & DWWDT_STAT_STATUS) != 0, | ||||
("Missing interrupt status bit?")); | ("Missing interrupt status bit?")); | ||||
if (dwwdt_prevent_restart != 0 || sc->sc_status == DWWDT_STOPPED) { | if (dwwdt_prevent_restart || sc->sc_status == DWWDT_STOPPED) { | ||||
/* | /* | ||||
* Confirm interrupt reception. Restart counter. | * Confirm interrupt reception. Restart counter. | ||||
* This also emulates stopping watchdog. | * This also emulates stopping watchdog. | ||||
*/ | */ | ||||
(void)DWWDT_READ4(sc, DWWDT_EOI); | (void)DWWDT_READ4(sc, DWWDT_EOI); | ||||
return; | |||||
} | } | ||||
if (dwwdt_panic_first) | |||||
panic("dwwdt pre-timeout interrupt"); | |||||
} | } | ||||
static void | static void | ||||
dwwdt_event(void *arg, unsigned int cmd, int *error) | dwwdt_event(void *arg, unsigned int cmd, int *error) | ||||
{ | { | ||||
struct dwwdt_softc *sc = arg; | struct dwwdt_softc *sc = arg; | ||||
const int exponent = flsl(sc->sc_clk_freq); | const int exponent = flsl(sc->sc_clk_freq); | ||||
int timeout; | int timeout; | ||||
int val; | int val; | ||||
timeout = cmd & WD_INTERVAL; | timeout = cmd & WD_INTERVAL; | ||||
val = MAX(0, timeout + exponent - DWWDT_EXP_OFFSET); | val = MAX(0, timeout + exponent - DWWDT_EXP_OFFSET + 1); | ||||
dwwdt_stop(sc); | dwwdt_stop(sc); | ||||
if (cmd == 0 || val > 0x0f) { | if (cmd == 0 || val > 0x0f) { | ||||
/* | /* | ||||
* Set maximum time between interrupts and Leave watchdog | * Set maximum time between interrupts and Leave watchdog | ||||
* disabled. | * disabled. | ||||
*/ | */ | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
dwwdt_shutdown(device_t dev) | dwwdt_shutdown(device_t dev) | ||||
{ | { | ||||
struct dwwdt_softc *sc; | struct dwwdt_softc *sc; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
/* Prevent restarts during shutdown. */ | /* Prevent restarts during shutdown. */ | ||||
dwwdt_prevent_restart = 1; | dwwdt_prevent_restart = true; | ||||
dwwdt_stop(sc); | dwwdt_stop(sc); | ||||
return (bus_generic_shutdown(dev)); | return (bus_generic_shutdown(dev)); | ||||
} | } | ||||
static device_method_t dwwdt_methods[] = { | static device_method_t dwwdt_methods[] = { | ||||
DEVMETHOD(device_probe, dwwdt_probe), | DEVMETHOD(device_probe, dwwdt_probe), | ||||
DEVMETHOD(device_attach, dwwdt_attach), | DEVMETHOD(device_attach, dwwdt_attach), | ||||
DEVMETHOD(device_detach, dwwdt_detach), | DEVMETHOD(device_detach, dwwdt_detach), | ||||
Show All 14 Lines |