Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/isa Add Watchdog timer implementation to wbsio(4). I...
details: https://anonhg.NetBSD.org/src/rev/863615e83698
branches: trunk
changeset: 828417:863615e83698
user: knakahara <knakahara%NetBSD.org@localhost>
date: Wed Dec 13 00:27:53 2017 +0000
description:
Add Watchdog timer implementation to wbsio(4). Implemeted by s-yamaguchi@IIJ, reviewed by msaitoh@n.o.
I just commit by proxy.
diffstat:
sys/dev/isa/wbsio.c | 232 ++++++++++++++++++++++++++++++++++++++++++++----
sys/dev/isa/wbsioreg.h | 26 ++++-
2 files changed, 234 insertions(+), 24 deletions(-)
diffs (truncated from 475 to 300 lines):
diff -r a7d49f3d7825 -r 863615e83698 sys/dev/isa/wbsio.c
--- a/sys/dev/isa/wbsio.c Wed Dec 13 00:27:01 2017 +0000
+++ b/sys/dev/isa/wbsio.c Wed Dec 13 00:27:53 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wbsio.c,v 1.17 2017/12/13 00:27:01 knakahara Exp $ */
+/* $NetBSD: wbsio.c,v 1.18 2017/12/13 00:27:53 knakahara Exp $ */
/* $OpenBSD: wbsio.c,v 1.10 2015/03/14 03:38:47 jsg Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis <kettenis%openbsd.org@localhost>
@@ -34,6 +34,7 @@
#include <dev/isa/isareg.h>
#include <dev/isa/isavar.h>
#include <dev/isa/wbsioreg.h>
+#include <dev/sysmon/sysmonvar.h>
/* Don't use gpio for now in the module */
#ifndef _MODULE
@@ -52,6 +53,7 @@
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
+ kmutex_t sc_conf_lock;
struct isa_attach_args sc_ia;
struct isa_io sc_io;
@@ -63,6 +65,9 @@
struct gpio_pin sc_gpio_pins[WBSIO_GPIO_NPINS];
bool sc_gpio_rt;
#endif
+
+ struct sysmon_wdog sc_smw;
+ bool sc_smw_valid;
};
static const struct wbsio_product {
@@ -101,6 +106,7 @@
static void wbsio_childdet(device_t, device_t);
static int wbsio_print(void *, const char *);
static int wbsio_search(device_t, cfdata_t, const int *, void *);
+static bool wbsio_suspend(device_t, const pmf_qual_t *);
#if NGPIO > 0
static int wbsio_gpio_search(device_t, cfdata_t, const int *, void *);
static int wbsio_gpio_rt_init(struct wbsio_softc *);
@@ -112,22 +118,35 @@
static void wbsio_gpio_enable_nct6779d(device_t);
static void wbsio_gpio_pinconfig_nct6779d(device_t);
#endif
+static void wbsio_wdog_attach(device_t);
+static int wbsio_wdog_detach(device_t);
+static int wbsio_wdog_setmode(struct sysmon_wdog *);
+static int wbsio_wdog_tickle(struct sysmon_wdog *);
+static void wbsio_wdog_setcounter(struct wbsio_softc *, uint8_t);
+static void wbsio_wdog_clear_timeout(struct wbsio_softc *);
CFATTACH_DECL2_NEW(wbsio, sizeof(struct wbsio_softc),
wbsio_match, wbsio_attach, wbsio_detach, NULL,
wbsio_rescan, wbsio_childdet);
static __inline void
-wbsio_conf_enable(bus_space_tag_t iot, bus_space_handle_t ioh)
+wbsio_conf_enable(kmutex_t *lock, bus_space_tag_t iot, bus_space_handle_t ioh)
{
+ if (lock)
+ mutex_enter(lock);
+
bus_space_write_1(iot, ioh, WBSIO_INDEX, WBSIO_CONF_EN_MAGIC);
bus_space_write_1(iot, ioh, WBSIO_INDEX, WBSIO_CONF_EN_MAGIC);
}
static __inline void
-wbsio_conf_disable(bus_space_tag_t iot, bus_space_handle_t ioh)
+wbsio_conf_disable(kmutex_t *lock, bus_space_tag_t iot, bus_space_handle_t ioh)
{
+
bus_space_write_1(iot, ioh, WBSIO_INDEX, WBSIO_CONF_DS_MAGIC);
+
+ if (lock)
+ mutex_exit(lock);
}
static __inline uint8_t
@@ -188,11 +207,11 @@
iot = ia->ia_iot;
if (bus_space_map(iot, ia->ia_io[0].ir_addr, WBSIO_IOSIZE, 0, &ioh))
return 0;
- wbsio_conf_enable(iot, ioh);
+ wbsio_conf_enable(NULL, iot, ioh);
id = wbsio_conf_read(iot, ioh, WBSIO_ID);
rev = wbsio_conf_read(iot, ioh, WBSIO_REV);
aprint_debug("wbsio_probe: id 0x%02x, rev 0x%02x\n", id, rev);
- wbsio_conf_disable(iot, ioh);
+ wbsio_conf_disable(NULL, iot, ioh);
bus_space_unmap(iot, ioh, WBSIO_IOSIZE);
if ((product = wbsio_lookup(id, rev)) == NULL)
@@ -228,8 +247,10 @@
return;
}
+ mutex_init(&sc->sc_conf_lock, MUTEX_DEFAULT, IPL_NONE);
+
/* Enter configuration mode */
- wbsio_conf_enable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
/* Read device ID */
id = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID);
@@ -237,7 +258,7 @@
rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV);
/* Escape from configuration mode */
- wbsio_conf_disable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
if ((product = wbsio_lookup(id, rev)) == NULL) {
aprint_error_dev(self, "Unknown device. Failed to attach\n");
@@ -259,8 +280,11 @@
} else
aprint_normal("0x%02x\n", rev);
- if (!pmf_device_register(self, NULL, NULL))
+ if (!pmf_device_register(self, wbsio_suspend, NULL))
aprint_error_dev(self, "couldn't establish power handler\n");
+
+ wbsio_wdog_attach(self);
+
wbsio_rescan(self, "wbsio", NULL);
#if NGPIO > 0
@@ -275,6 +299,9 @@
struct wbsio_softc *sc = device_private(self);
int rc;
+ if ((rc = wbsio_wdog_detach(self)) != 0)
+ return rc;
+
if ((rc = config_detach_children(self, flags)) != 0)
return rc;
bus_space_unmap(sc->sc_iot, sc->sc_ioh, WBSIO_IOSIZE);
@@ -290,6 +317,8 @@
mutex_destroy(&sc->sc_gpio_lock);
}
#endif
+
+ mutex_destroy(&sc->sc_conf_lock);
return 0;
}
@@ -328,7 +357,7 @@
uint8_t reg0, reg1, rev;
/* Enter configuration mode */
- wbsio_conf_enable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
/* Select HM logical device */
wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_HM);
@@ -343,7 +372,7 @@
reg1 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_HM_ADDR_MSB);
/* Escape from configuration mode */
- wbsio_conf_disable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
iobase = (reg1 << 8) | (reg0 & ~0x7);
@@ -351,12 +380,12 @@
return -1;
/* Enter configuration mode */
- wbsio_conf_enable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
/* Read device ID and revision */
devid = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID);
rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV);
/* Escape from configuration mode */
- wbsio_conf_disable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
if ((product = wbsio_lookup(devid, rev)) == NULL) {
aprint_error_dev(parent, "%s: Unknown device.\n", __func__);
@@ -394,6 +423,20 @@
return (UNCONF);
}
+static bool
+wbsio_suspend(device_t self, const pmf_qual_t *qual)
+{
+ struct wbsio_softc *sc = device_private(self);
+
+ if (sc->sc_smw_valid) {
+ if ((sc->sc_smw.smw_mode & WDOG_MODE_MASK)
+ != WDOG_MODE_DISARMED)
+ return false;
+ }
+
+ return true;
+}
+
#if NGPIO > 0
static int
wbsio_gpio_search(device_t parent, cfdata_t cf, const int *slocs, void *aux)
@@ -406,12 +449,12 @@
int i;
/* Enter configuration mode */
- wbsio_conf_enable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
/* Read device ID and revision */
devid = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID);
rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV);
/* Escape from configuration mode */
- wbsio_conf_disable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
if ((product = wbsio_lookup(devid, rev)) == NULL) {
aprint_error_dev(parent, "%s: Unknown device.\n", __func__);
@@ -479,7 +522,7 @@
uint8_t reg0, reg1;
/* Enter configuration mode */
- wbsio_conf_enable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
/* Get GPIO Register Table address */
wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_GPIO0);
@@ -488,7 +531,7 @@
iobase = (reg1 << 8) | (reg0 & ~0x7);
/* Escape from configuration mode */
- wbsio_conf_disable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
if (bus_space_map(sc->sc_iot, iobase, WBSIO_GPIO_IOSIZE,
0, &sc->sc_gpio_ioh)) {
@@ -606,7 +649,7 @@
uint8_t reg, conf;
/* Enter configuration mode */
- wbsio_conf_enable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_GPIO0);
reg = WBSIO_GPIO_CONF;
@@ -630,7 +673,7 @@
wbsio_conf_write(sc->sc_iot, sc->sc_ioh, reg, conf);
/* Escape from configuration mode */
- wbsio_conf_disable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
}
static void
@@ -641,7 +684,7 @@
uint8_t mfs4, mfs5, mfs6, gopt2, hm_conf;
/* Enter configuration mode */
- wbsio_conf_enable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
/* Strapping Function Result */
sfr = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_SFR);
@@ -740,10 +783,157 @@
wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_HM_CONF, hm_conf);
/* Escape from configuration mode */
- wbsio_conf_disable(sc->sc_iot, sc->sc_ioh);
+ wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
+}
+
+#endif /* NGPIO > 0 */
+
+static void
+wbsio_wdog_attach(device_t self)
+{
+ struct wbsio_softc *sc = device_private(self);
+ const struct wbsio_product *product;
+ uint8_t gpio, mode;
+ uint16_t devid;
+ uint8_t rev;
+
+ sc->sc_smw_valid = false;
+
+ wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
+ devid = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID);
+ rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV);
+ wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
+
+ if ((product = wbsio_lookup(devid, rev)) == NULL) {
+ return;
+ }
+
+ switch (product->id) {
+ case WBSIO_ID_NCT6779D:
+ break;
+ default:
+ /* WDT is not supoorted */
+ return;
+ }
+
Home |
Main Index |
Thread Index |
Old Index