summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2015-08-23 20:16:13 +0000
committerian <ian@FreeBSD.org>2015-08-23 20:16:13 +0000
commitd958a69ae31c2077009bd7d87b6d35829ac64f27 (patch)
treee79f361a8427f802be4070c71b25fa51fd4a8294 /sys/arm
parent8cf9fedbf651f151cb25af637e612be5b827d962 (diff)
downloadFreeBSD-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/IMX62
-rw-r--r--sys/arm/freescale/imx/imx_wdog.c67
-rw-r--r--sys/arm/freescale/imx/imx_wdogreg.h4
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))
OpenPOWER on IntegriCloud