diff options
author | ian <ian@FreeBSD.org> | 2015-08-23 20:16:13 +0000 |
---|---|---|
committer | ian <ian@FreeBSD.org> | 2015-08-23 20:16:13 +0000 |
commit | d958a69ae31c2077009bd7d87b6d35829ac64f27 (patch) | |
tree | e79f361a8427f802be4070c71b25fa51fd4a8294 /sys/arm | |
parent | 8cf9fedbf651f151cb25af637e612be5b827d962 (diff) | |
download | FreeBSD-src-d958a69ae31c2077009bd7d87b6d35829ac64f27.zip FreeBSD-src-d958a69ae31c2077009bd7d87b6d35829ac64f27.tar.gz |
MFC r286942, r286943, r286944: imx watchdog fixes...
Add compatible strings for all the hardware this driver works with.
Also, move the READ/WRITE bus space access macros from the header into the
source file, and rename them to RD2/WR2 to make it clear they're 16-bit
accessors. (READ/WRITE just don't seem like good names to be in a public
header file.)
Make the imx watchdog actually work, by setting WDOG_CR_WDE (enable bit).
Also, follow the rules from watchdog(9) about what values to return in
various situations (especially, don't touch *error when asked to set a
non-zero timeout that isn't achievable on the hardware).
Enable the watchdog driver on imx6, now that it works.
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/conf/IMX6 | 2 | ||||
-rw-r--r-- | sys/arm/freescale/imx/imx_wdog.c | 67 | ||||
-rw-r--r-- | sys/arm/freescale/imx/imx_wdogreg.h | 4 |
3 files changed, 39 insertions, 34 deletions
diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6 index 394933d..2676a6d 100644 --- a/sys/arm/conf/IMX6 +++ b/sys/arm/conf/IMX6 @@ -160,5 +160,5 @@ device ffec # Freescale Fast Ethernet Controller device fsliic # Freescale i2c/iic device iic # iic protocol device iicbus # iic bus -#device imxwdt # Watchdog. WARNING: can't be disabled!!! +device imxwdt # Watchdog. WARNING: can't be disabled!!! diff --git a/sys/arm/freescale/imx/imx_wdog.c b/sys/arm/freescale/imx/imx_wdog.c index cadd1d7..a3bcef2 100644 --- a/sys/arm/freescale/imx/imx_wdog.c +++ b/sys/arm/freescale/imx/imx_wdog.c @@ -66,6 +66,20 @@ static struct resource_spec imx_wdog_spec[] = { { -1, 0 } }; +static struct ofw_compat_data compat_data[] = { + {"fsl,imx6sx-wdt", 1}, + {"fsl,imx6sl-wdt", 1}, + {"fsl,imx6q-wdt", 1}, + {"fsl,imx53-wdt", 1}, + {"fsl,imx51-wdt", 1}, + {"fsl,imx50-wdt", 1}, + {"fsl,imx35-wdt", 1}, + {"fsl,imx27-wdt", 1}, + {"fsl,imx25-wdt", 1}, + {"fsl,imx21-wdt", 1}, + {NULL, 0} +}; + static void imx_watchdog(void *, u_int, int *); static int imx_wdog_probe(device_t); static int imx_wdog_attach(device_t); @@ -84,46 +98,42 @@ static driver_t imx_wdog_driver = { static devclass_t imx_wdog_devclass; DRIVER_MODULE(imx_wdog, simplebus, imx_wdog_driver, imx_wdog_devclass, 0, 0); +#define RD2(_sc, _r) \ + bus_space_read_2((_sc)->sc_bst, (_sc)->sc_bsh, (_r)) +#define WR2(_sc, _r, _v) \ + bus_space_write_2((_sc)->sc_bst, (_sc)->sc_bsh, (_r), (_v)) static void imx_watchdog(void *arg, u_int cmd, int *error) { struct imx_wdog_softc *sc; uint16_t reg; - int timeout; + u_int timeout; sc = arg; mtx_lock(&sc->sc_mtx); - - /* Refresh counter, since we feels good */ - WRITE(sc, WDOG_SR_REG, WDOG_SR_STEP1); - WRITE(sc, WDOG_SR_REG, WDOG_SR_STEP2); - - /* We don't require precession, so "-10" (/1024) is ok */ - timeout = (1 << ((cmd & WD_INTERVAL) - 10)) / 1000000; - if (timeout > 1 && timeout < 128) { - if (timeout != sc->sc_timeout) { - device_printf(sc->sc_dev, - "WARNING: watchdog can't be disabled!!!"); - sc->sc_timeout = timeout; - reg = READ(sc, WDOG_CR_REG); - reg &= ~WDOG_CR_WT_MASK; - reg |= (timeout << (WDOG_CR_WT_SHIFT + 1)) & - WDOG_CR_WT_MASK; - WRITE(sc, WDOG_CR_REG, reg); + if (cmd == 0) { + if (bootverbose) + device_printf(sc->sc_dev, "Can not be disabled.\n"); + *error = EOPNOTSUPP; + } else { + timeout = (u_int)((1ULL << (cmd & WD_INTERVAL)) / 1000000000U); + if (timeout > 1 && timeout < 128) { + if (timeout != sc->sc_timeout) { + sc->sc_timeout = timeout; + reg = RD2(sc, WDOG_CR_REG); + reg &= ~WDOG_CR_WT_MASK; + reg |= (timeout << (WDOG_CR_WT_SHIFT + 1)) & + WDOG_CR_WT_MASK; + WR2(sc, WDOG_CR_REG, reg | WDOG_CR_WDE); + } /* Refresh counter */ - WRITE(sc, WDOG_SR_REG, WDOG_SR_STEP1); - WRITE(sc, WDOG_SR_REG, WDOG_SR_STEP2); + WR2(sc, WDOG_SR_REG, WDOG_SR_STEP1); + WR2(sc, WDOG_SR_REG, WDOG_SR_STEP2); *error = 0; - } else { - *error = EOPNOTSUPP; } - } else { - device_printf(sc->sc_dev, "Can not be disabled.\n"); - *error = EOPNOTSUPP; } mtx_unlock(&sc->sc_mtx); - } static int @@ -133,11 +143,10 @@ imx_wdog_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "fsl,imx51-wdt") && - !ofw_bus_is_compatible(dev, "fsl,imx53-wdt")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); - device_set_desc(dev, "Freescale i.MX5xx Watchdog Timer"); + device_set_desc(dev, "Freescale i.MX Watchdog"); return (0); } diff --git a/sys/arm/freescale/imx/imx_wdogreg.h b/sys/arm/freescale/imx/imx_wdogreg.h index 3728b98..1bff106 100644 --- a/sys/arm/freescale/imx/imx_wdogreg.h +++ b/sys/arm/freescale/imx/imx_wdogreg.h @@ -59,7 +59,3 @@ #define WDOG_MCR_REG 0x08 /* Miscellaneous Control Register */ #define WDOG_MCR_PDE (1 << 0) -#define READ(_sc, _r) \ - bus_space_read_2((_sc)->sc_bst, (_sc)->sc_bsh, (_r)) -#define WRITE(_sc, _r, _v) \ - bus_space_write_2((_sc)->sc_bst, (_sc)->sc_bsh, (_r), (_v)) |