diff options
author | 2009-03-25 20:41:31 +0000 | |
---|---|---|
committer | 2009-03-25 20:41:31 +0000 | |
commit | dfabaf41803447f23ee2e7065fdac2ca970279de (patch) | |
tree | 9a148c510db11b94f03105f3ad50fdb16952c239 | |
parent | convert lockmgr over to rwlock in ntfs, mostly trivial. (diff) | |
download | wireguard-openbsd-dfabaf41803447f23ee2e7065fdac2ca970279de.tar.xz wireguard-openbsd-dfabaf41803447f23ee2e7065fdac2ca970279de.zip |
Add support for the watchdog timer.
``just have the balls and commit it'' deraadt
-rw-r--r-- | share/man/man4/schsio.4 | 42 | ||||
-rw-r--r-- | sys/dev/isa/sch311x.c | 182 |
2 files changed, 169 insertions, 55 deletions
diff --git a/share/man/man4/schsio.4 b/share/man/man4/schsio.4 index 2154da93d28..e117bc700fd 100644 --- a/share/man/man4/schsio.4 +++ b/share/man/man4/schsio.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: schsio.4,v 1.2 2009/02/08 15:34:06 mk Exp $ +.\" $OpenBSD: schsio.4,v 1.3 2009/03/25 20:41:31 mk Exp $ .\" .\" Copyright (c) 2009 Michael Knudsen <mk@openbsd.org> .\" @@ -13,17 +13,17 @@ .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -.Dd $Mdocdate: February 8 2009 $ +.Dd $Mdocdate: March 25 2009 $ .Dt SCHSIO 4 .Os .Sh NAME .Nm schsio .Nd SMSC SCH311x LPC Super I/O .Sh SYNOPSIS -.Cd "schsio* at isa? port 0x2e -.Cd "schsio* at isa? port 0x4e -.Cd "schsio* at isa? port 0x162e -.Cd "schsio* at isa? port 0x164e +.Cd "schsio* at isa? port 0x2e flags 0x0000" +.Cd "schsio* at isa? port 0x4e flags 0x0000" +.Cd "schsio* at isa? port 0x162e flags 0x0000" +.Cd "schsio* at isa? port 0x164e flags 0x0000" .Sh DESCRIPTION The .Nm @@ -33,7 +33,8 @@ Among other things, the devices contain environment sensors, a watchdog timer, and fan control. The .Nm -driver currently only supports the environment sensors. +driver supports the environment sensors and the watchdog timer. +.Pp The hardware provides the following sensors: .Bl -column "Internal diode" "Units" "Typical" -offset indent .It Sy "Sensor" Ta Sy "Units" Ta Sy "Typical use" @@ -51,12 +52,37 @@ The hardware provides the following sensors: .It Li "+3.3V (VTR)" Ta "uV" Ta "Voltage" .It Li "+3V (Vbat)" Ta "uV" Ta "Voltage" .El +.Pp +.Nm +provides the standard +.Xr watchdog 4 +interface and may be used with +.Xr watchdogd 8 . +The watchdog timer may be configured to a value from 1 second to 255 +minutes. +The watchdog timer has a resolution of 1 second in the timeout interval +1 to 255 seconds. +Outside this interval, the resolution is 1 minute. +.Pp +Note that the pin used for signalling the timer expiration is +configurable and may on some boards be intended for other uses than this. +Because of this, the chip may not by default be configured to use the +pin for watchdog operation. +To force the +.Nm +device to use the pin for watchdog operation, the driver may be +configured with an +.Xr autoconf 9 +.Ar flags +setting of 0x0001. .Sh SEE ALSO .Xr intro 4 , .Xr isa 4 , .Xr watchdog 4 , .Xr sensorsd 8 , -.Xr sysctl 8 +.Xr sysctl 8 , +.Xr watchdogd 8 , +.Xr autoconf 9 .Sh HISTORY The .Nm diff --git a/sys/dev/isa/sch311x.c b/sys/dev/isa/sch311x.c index 733d0e62a03..c2ab4c4029a 100644 --- a/sys/dev/isa/sch311x.c +++ b/sys/dev/isa/sch311x.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sch311x.c,v 1.4 2009/01/26 15:07:49 kettenis Exp $ */ +/* $OpenBSD: sch311x.c,v 1.5 2009/03/25 20:41:31 mk Exp $ */ /* * Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org> * Copyright (c) 2009 Michael Knudsen <mk@openbsd.org> @@ -42,7 +42,7 @@ /* These are used in configuration mode */ #define SCHSIO_PORT_INDEX 0x00 -#define SCHSIO_PORT_DATA 0x01 +#define SCHSIO_PORT_DATA 0x01 #define SCHSIO_CONFIG_ENTER 0x55 #define SCHSIO_CONFIG_LEAVE 0xaa @@ -57,16 +57,16 @@ /* Logical devices */ #define SCHSIO_LDEV_RUNTIME 0x0a /* holds wdog and sensors */ - +#define SCHSIO_LDEV_RUNTIME_SZ 0x100 /* Hardware monitor */ #define SCHSIO_HWM_INTERVAL 5 /* seconds */ /* Register access */ -#define SCHSIO_HWM_IOSIZE 0x02 +#define SCHSIO_HWM_IOSIZE 0x100 #define SCHSIO_HWM_OFFSET 0x70 -#define SCHSIO_HWM_INDEX 0x00 -#define SCHSIO_HWM_DATA 0x01 +#define SCHSIO_HWM_INDEX 0x70 +#define SCHSIO_HWM_DATA 0x71 /* Sensor definitions */ /* Voltage */ @@ -124,11 +124,27 @@ #define SCHSIO_SENSOR_TEMP3 12 -#ifdef SCHSIO_DEBUG -#define DPRINTF(x) printf x -#else -#define DPRINTF(x) -#endif +/* Watchdog */ + +/* Register access */ +#define SCHSIO_WDT_GPIO 0x47 +#define SCHSIO_WDT_TIMEOUT 0x65 +#define SCHSIO_WDT_VAL 0x66 +#define SCHSIO_WDT_CFG 0x67 +#define SCHSIO_WDT_CTRL 0x68 + +/* Bits */ +#define SCHSIO_WDT_GPIO_MASK 0x0f +#define SCHSIO_WDT_GPIO_OUT 0x0e + +#define SCHSIO_WDT_TO_SECONDS (1 << 7) + +#define SCHSIO_WDT_CTRL_TRIGGERED (1 << 0) +#define SCHSIO_WDT_CFG_KBDEN (1 << 1) +#define SCHSIO_WDT_CFG_MSEN (1 << 2) + +/* autoconf(9) flags etc. */ +#define SCHSIO_CFFLAGS_WDTEN (1 << 0) #define DEVNAME(x) ((x)->sc_dev.dv_xname) @@ -138,7 +154,7 @@ struct schsio_softc { bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; - bus_space_handle_t sc_hwm_ioh; + bus_space_handle_t sc_ioh_rr; struct ksensordev sc_sensordev; struct ksensor sc_sensor[SCHSIO_SENSORS]; @@ -161,9 +177,12 @@ void schsio_config_write(bus_space_tag_t iot, /* HWM prototypes */ void schsio_hwm_init(struct schsio_softc *sc); void schsio_hwm_update(void *arg); - u_int8_t schsio_hwm_read(struct schsio_softc *sc, int reg); +/* Watchdog prototypes */ + +void schsio_wdt_init(struct schsio_softc *sc); +int schsio_wdt_cb(void *arg, int period); struct cfattach schsio_ca = { sizeof(struct schsio_softc), @@ -243,7 +262,8 @@ schsio_attach(struct device *parent, struct device *self, void *aux) { struct schsio_softc *sc = (void *)self; struct isa_attach_args *ia = aux; - u_int8_t reg; + u_int16_t iobase; + u_int8_t reg0, reg1; /* Map ISA I/O space */ sc->sc_iot = ia->ia_iot; @@ -257,8 +277,8 @@ schsio_attach(struct device *parent, struct device *self, void *aux) schsio_config_enable(sc->sc_iot, sc->sc_ioh); /* Read device ID */ - reg = schsio_config_read(sc->sc_iot, sc->sc_ioh, SCHSIO_IDX_DEVICE); - switch (reg) { + reg0 = schsio_config_read(sc->sc_iot, sc->sc_ioh, SCHSIO_IDX_DEVICE); + switch (reg0) { case SCHSIO_ID_SCH3112: printf(": SCH3112"); break; @@ -271,9 +291,27 @@ schsio_attach(struct device *parent, struct device *self, void *aux) } /* Read device revision */ - reg = schsio_config_read(sc->sc_iot, sc->sc_ioh, SCHSIO_IDX_REV); - printf(" rev 0x%02x", reg); + reg0 = schsio_config_read(sc->sc_iot, sc->sc_ioh, SCHSIO_IDX_REV); + printf(" rev 0x%02x", reg0); + + /* Select runtime registers logical device */ + schsio_config_write(sc->sc_iot, sc->sc_ioh, SCHSIO_IDX_LDEVSEL, + SCHSIO_LDEV_RUNTIME); + + reg0 = schsio_config_read(sc->sc_iot, sc->sc_ioh, + SCHSIO_IDX_BASE_HI); + reg1 = schsio_config_read(sc->sc_iot, sc->sc_ioh, + SCHSIO_IDX_BASE_LO); + iobase = (reg0 << 8) | reg1; + if (bus_space_map(sc->sc_iot, iobase, SCHSIO_LDEV_RUNTIME_SZ, + 0, &sc->sc_ioh_rr)) { + printf(": can't map I/O space\n"); + return; + } + + + schsio_wdt_init(sc); schsio_hwm_init(sc); printf("\n"); @@ -287,25 +325,6 @@ void schsio_hwm_init(struct schsio_softc *sc) { int i; - u_int16_t iobase; - u_int8_t reg0, reg1; - - /* Select runtime registers logical device */ - schsio_config_write(sc->sc_iot, sc->sc_ioh, SCHSIO_IDX_LDEVSEL, - SCHSIO_LDEV_RUNTIME); - - reg0 = schsio_config_read(sc->sc_iot, sc->sc_ioh, - SCHSIO_IDX_BASE_HI); - reg1 = schsio_config_read(sc->sc_iot, sc->sc_ioh, - SCHSIO_IDX_BASE_LO); - iobase = ((reg0 << 8) | reg1) + SCHSIO_HWM_OFFSET; - - - if (bus_space_map(sc->sc_iot, iobase, - SCHSIO_HWM_IOSIZE, 0, &sc->sc_hwm_ioh)) { - printf(": can't map I/O space\n"); - return; - } /* Set up sensors */ for (i = SCHSIO_SENSOR_FAN1; i < SCHSIO_SENSOR_FAN3 + 1; i++) @@ -362,12 +381,6 @@ schsio_hwm_update(void *arg) sc = (struct schsio_softc *)arg; - schsio_config_enable(sc->sc_iot, sc->sc_ioh); - - /* Select logical device a */ - schsio_config_write(sc->sc_iot, sc->sc_ioh, SCHSIO_IDX_LDEVSEL, - SCHSIO_LDEV_RUNTIME); - reg0 = schsio_hwm_read(sc, SCHSIO_HWM_TACH1_L); reg1 = schsio_hwm_read(sc, SCHSIO_HWM_TACH1_U); tach = (reg1 << 8) | reg0; @@ -432,13 +445,88 @@ schsio_hwm_update(void *arg) sc->sc_sensor[SCHSIO_SENSOR_TEMP3].flags = ((uint8_t)temp == 0x80) ? SENSOR_FINVALID : 0; - schsio_config_disable(sc->sc_iot, sc->sc_ioh); - } u_int8_t schsio_hwm_read(struct schsio_softc *sc, int reg) { - bus_space_write_1(sc->sc_iot, sc->sc_hwm_ioh, SCHSIO_HWM_INDEX, reg); - return (bus_space_read_1(sc->sc_iot, sc->sc_hwm_ioh, SCHSIO_HWM_DATA)); + bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_HWM_INDEX, reg); + return (bus_space_read_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_HWM_DATA)); } + +void +schsio_wdt_init(struct schsio_softc *sc) +{ + u_int8_t reg; + + reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_GPIO); + if ((reg & SCHSIO_WDT_GPIO_MASK) != SCHSIO_WDT_GPIO_OUT) { + if (sc->sc_dev.dv_cfdata->cf_flags & SCHSIO_CFFLAGS_WDTEN) { + reg &= ~0x0f; + reg |= SCHSIO_WDT_GPIO_OUT; + bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, + SCHSIO_WDT_GPIO, reg); + } + else { + printf(", watchdog disabled"); + return; + } + } + + /* First of all, make sure the wdt is disabled */ + bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_VAL, 0); + + /* Clear triggered status */ + reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh_rr, + SCHSIO_WDT_CTRL); + if (reg & SCHSIO_WDT_CTRL_TRIGGERED) { + printf(", warning: watchdog triggered"); + reg &= ~SCHSIO_WDT_CTRL_TRIGGERED; + bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, + SCHSIO_WDT_CTRL, reg); + } + + /* Disable wdt reset by mouse and kbd */ + reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_CFG); + reg &= ~(SCHSIO_WDT_CFG_MSEN | SCHSIO_WDT_CFG_MSEN); + bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_CFG, reg); + + wdog_register(sc, schsio_wdt_cb); +} + +int +schsio_wdt_cb(void *arg, int period) +{ + struct schsio_softc *sc; + uint8_t val, minute, reg; + + sc = (struct schsio_softc *)arg; + + if (period > 255) { + val = period / 60; + minute = 1; + } else { + val = period; + minute = 0; + } + + /* Set unit */ + reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh_rr, + SCHSIO_WDT_TIMEOUT); + if (!minute) + reg |= SCHSIO_WDT_TO_SECONDS; + else + reg &= ~SCHSIO_WDT_TO_SECONDS; + + bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_TIMEOUT, + reg); + + /* Set value */ + bus_space_write_1(sc->sc_iot, sc->sc_ioh_rr, SCHSIO_WDT_VAL, val); + + if (!minute) + return val; + else + return val * 60; +} + |