Wed Dec 13 00:27:53 2017 UTC ()
Add Watchdog timer implementation to wbsio(4). Implemeted by s-yamaguchi@IIJ, reviewed by msaitoh@n.o.

I just commit by proxy.


(knakahara)
diff -r1.17 -r1.18 src/sys/dev/isa/wbsio.c
diff -r1.6 -r1.7 src/sys/dev/isa/wbsioreg.h

cvs diff -r1.17 -r1.18 src/sys/dev/isa/wbsio.c (expand / switch to unified diff)

--- src/sys/dev/isa/wbsio.c 2017/12/13 00:27:01 1.17
+++ src/sys/dev/isa/wbsio.c 2017/12/13 00:27:53 1.18
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: wbsio.c,v 1.17 2017/12/13 00:27:01 knakahara Exp $ */ 1/* $NetBSD: wbsio.c,v 1.18 2017/12/13 00:27:53 knakahara Exp $ */
2/* $OpenBSD: wbsio.c,v 1.10 2015/03/14 03:38:47 jsg Exp $ */ 2/* $OpenBSD: wbsio.c,v 1.10 2015/03/14 03:38:47 jsg Exp $ */
3/* 3/*
4 * Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org> 4 * Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org>
5 * 5 *
6 * Permission to use, copy, modify, and distribute this software for any 6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies. 8 * copyright notice and this permission notice appear in all copies.
9 * 9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
@@ -24,55 +24,60 @@ @@ -24,55 +24,60 @@
24#include <sys/param.h> 24#include <sys/param.h>
25#include <sys/device.h> 25#include <sys/device.h>
26#include <sys/kernel.h> 26#include <sys/kernel.h>
27#include <sys/module.h> 27#include <sys/module.h>
28#include <sys/systm.h> 28#include <sys/systm.h>
29#include <sys/mutex.h> 29#include <sys/mutex.h>
30#include <sys/gpio.h> 30#include <sys/gpio.h>
31 31
32#include <sys/bus.h> 32#include <sys/bus.h>
33 33
34#include <dev/isa/isareg.h> 34#include <dev/isa/isareg.h>
35#include <dev/isa/isavar.h> 35#include <dev/isa/isavar.h>
36#include <dev/isa/wbsioreg.h> 36#include <dev/isa/wbsioreg.h>
 37#include <dev/sysmon/sysmonvar.h>
37 38
38/* Don't use gpio for now in the module */ 39/* Don't use gpio for now in the module */
39#ifndef _MODULE 40#ifndef _MODULE
40#include "gpio.h" 41#include "gpio.h"
41#endif 42#endif
42#if NGPIO > 0 43#if NGPIO > 0
43#include <dev/gpio/gpiovar.h> 44#include <dev/gpio/gpiovar.h>
44#endif 45#endif
45 46
46struct wbsio_softc { 47struct wbsio_softc {
47 device_t sc_dev; 48 device_t sc_dev;
48 device_t sc_lm_dev; 49 device_t sc_lm_dev;
49#if NGPIO > 0 50#if NGPIO > 0
50 device_t sc_gpio_dev; 51 device_t sc_gpio_dev;
51#endif 52#endif
52 53
53 bus_space_tag_t sc_iot; 54 bus_space_tag_t sc_iot;
54 bus_space_handle_t sc_ioh; 55 bus_space_handle_t sc_ioh;
 56 kmutex_t sc_conf_lock;
55 57
56 struct isa_attach_args sc_ia; 58 struct isa_attach_args sc_ia;
57 struct isa_io sc_io; 59 struct isa_io sc_io;
58 60
59#if NGPIO > 0 61#if NGPIO > 0
60 bus_space_handle_t sc_gpio_ioh; 62 bus_space_handle_t sc_gpio_ioh;
61 kmutex_t sc_gpio_lock; 63 kmutex_t sc_gpio_lock;
62 struct gpio_chipset_tag sc_gpio_gc; 64 struct gpio_chipset_tag sc_gpio_gc;
63 struct gpio_pin sc_gpio_pins[WBSIO_GPIO_NPINS]; 65 struct gpio_pin sc_gpio_pins[WBSIO_GPIO_NPINS];
64 bool sc_gpio_rt; 66 bool sc_gpio_rt;
65#endif 67#endif
 68
 69 struct sysmon_wdog sc_smw;
 70 bool sc_smw_valid;
66}; 71};
67 72
68static const struct wbsio_product { 73static const struct wbsio_product {
69 uint16_t id; 74 uint16_t id;
70 bool idis12bits; 75 bool idis12bits;
71 const char *str; 76 const char *str;
72} wbsio_products[] = { 77} wbsio_products[] = {
73 { WBSIO_ID_W83627HF, false, "W83627HF" }, 78 { WBSIO_ID_W83627HF, false, "W83627HF" },
74 { WBSIO_ID_W83697HF, false, "W83697HF" }, 79 { WBSIO_ID_W83697HF, false, "W83697HF" },
75 { WBSIO_ID_W83637HF, false, "W83637HF" }, 80 { WBSIO_ID_W83637HF, false, "W83637HF" },
76 { WBSIO_ID_W83627THF, false, "W83627THF" }, 81 { WBSIO_ID_W83627THF, false, "W83627THF" },
77 { WBSIO_ID_W83687THF, false, "W83687THF" }, 82 { WBSIO_ID_W83687THF, false, "W83687THF" },
78 { WBSIO_ID_W83627DHG, true, "W83627DHG" }, 83 { WBSIO_ID_W83627DHG, true, "W83627DHG" },
@@ -91,53 +96,67 @@ static const struct wbsio_product { @@ -91,53 +96,67 @@ static const struct wbsio_product {
91 { WBSIO_ID_NCT6792D, true, "NCT6792D" }, 96 { WBSIO_ID_NCT6792D, true, "NCT6792D" },
92 { WBSIO_ID_NCT6793D, true, "NCT6793D" }, 97 { WBSIO_ID_NCT6793D, true, "NCT6793D" },
93 { WBSIO_ID_NCT6795D, true, "NCT6795D" }, 98 { WBSIO_ID_NCT6795D, true, "NCT6795D" },
94}; 99};
95 100
96static const struct wbsio_product *wbsio_lookup(uint8_t id, uint8_t rev); 101static const struct wbsio_product *wbsio_lookup(uint8_t id, uint8_t rev);
97static int wbsio_match(device_t, cfdata_t, void *); 102static int wbsio_match(device_t, cfdata_t, void *);
98static void wbsio_attach(device_t, device_t, void *); 103static void wbsio_attach(device_t, device_t, void *);
99static int wbsio_detach(device_t, int); 104static int wbsio_detach(device_t, int);
100static int wbsio_rescan(device_t, const char *, const int *); 105static int wbsio_rescan(device_t, const char *, const int *);
101static void wbsio_childdet(device_t, device_t); 106static void wbsio_childdet(device_t, device_t);
102static int wbsio_print(void *, const char *); 107static int wbsio_print(void *, const char *);
103static int wbsio_search(device_t, cfdata_t, const int *, void *); 108static int wbsio_search(device_t, cfdata_t, const int *, void *);
 109static bool wbsio_suspend(device_t, const pmf_qual_t *);
104#if NGPIO > 0 110#if NGPIO > 0
105static int wbsio_gpio_search(device_t, cfdata_t, const int *, void *); 111static int wbsio_gpio_search(device_t, cfdata_t, const int *, void *);
106static int wbsio_gpio_rt_init(struct wbsio_softc *); 112static int wbsio_gpio_rt_init(struct wbsio_softc *);
107static int wbsio_gpio_rt_read(struct wbsio_softc *, int, int); 113static int wbsio_gpio_rt_read(struct wbsio_softc *, int, int);
108static void wbsio_gpio_rt_write(struct wbsio_softc *, int, int, int); 114static void wbsio_gpio_rt_write(struct wbsio_softc *, int, int, int);
109static int wbsio_gpio_rt_pin_read(void *, int); 115static int wbsio_gpio_rt_pin_read(void *, int);
110static void wbsio_gpio_rt_pin_write(void *, int, int); 116static void wbsio_gpio_rt_pin_write(void *, int, int);
111static void wbsio_gpio_rt_pin_ctl(void *, int, int); 117static void wbsio_gpio_rt_pin_ctl(void *, int, int);
112static void wbsio_gpio_enable_nct6779d(device_t); 118static void wbsio_gpio_enable_nct6779d(device_t);
113static void wbsio_gpio_pinconfig_nct6779d(device_t); 119static void wbsio_gpio_pinconfig_nct6779d(device_t);
114#endif 120#endif
 121static void wbsio_wdog_attach(device_t);
 122static int wbsio_wdog_detach(device_t);
 123static int wbsio_wdog_setmode(struct sysmon_wdog *);
 124static int wbsio_wdog_tickle(struct sysmon_wdog *);
 125static void wbsio_wdog_setcounter(struct wbsio_softc *, uint8_t);
 126static void wbsio_wdog_clear_timeout(struct wbsio_softc *);
115 127
116CFATTACH_DECL2_NEW(wbsio, sizeof(struct wbsio_softc), 128CFATTACH_DECL2_NEW(wbsio, sizeof(struct wbsio_softc),
117 wbsio_match, wbsio_attach, wbsio_detach, NULL, 129 wbsio_match, wbsio_attach, wbsio_detach, NULL,
118 wbsio_rescan, wbsio_childdet); 130 wbsio_rescan, wbsio_childdet);
119 131
120static __inline void 132static __inline void
121wbsio_conf_enable(bus_space_tag_t iot, bus_space_handle_t ioh) 133wbsio_conf_enable(kmutex_t *lock, bus_space_tag_t iot, bus_space_handle_t ioh)
122{ 134{
 135 if (lock)
 136 mutex_enter(lock);
 137
123 bus_space_write_1(iot, ioh, WBSIO_INDEX, WBSIO_CONF_EN_MAGIC); 138 bus_space_write_1(iot, ioh, WBSIO_INDEX, WBSIO_CONF_EN_MAGIC);
124 bus_space_write_1(iot, ioh, WBSIO_INDEX, WBSIO_CONF_EN_MAGIC); 139 bus_space_write_1(iot, ioh, WBSIO_INDEX, WBSIO_CONF_EN_MAGIC);
125} 140}
126 141
127static __inline void 142static __inline void
128wbsio_conf_disable(bus_space_tag_t iot, bus_space_handle_t ioh) 143wbsio_conf_disable(kmutex_t *lock, bus_space_tag_t iot, bus_space_handle_t ioh)
129{ 144{
 145
130 bus_space_write_1(iot, ioh, WBSIO_INDEX, WBSIO_CONF_DS_MAGIC); 146 bus_space_write_1(iot, ioh, WBSIO_INDEX, WBSIO_CONF_DS_MAGIC);
 147
 148 if (lock)
 149 mutex_exit(lock);
131} 150}
132 151
133static __inline uint8_t 152static __inline uint8_t
134wbsio_conf_read(bus_space_tag_t iot, bus_space_handle_t ioh, uint8_t index) 153wbsio_conf_read(bus_space_tag_t iot, bus_space_handle_t ioh, uint8_t index)
135{ 154{
136 bus_space_write_1(iot, ioh, WBSIO_INDEX, index); 155 bus_space_write_1(iot, ioh, WBSIO_INDEX, index);
137 return (bus_space_read_1(iot, ioh, WBSIO_DATA)); 156 return (bus_space_read_1(iot, ioh, WBSIO_DATA));
138} 157}
139 158
140static __inline void 159static __inline void
141wbsio_conf_write(bus_space_tag_t iot, bus_space_handle_t ioh, uint8_t index, 160wbsio_conf_write(bus_space_tag_t iot, bus_space_handle_t ioh, uint8_t index,
142 uint8_t data) 161 uint8_t data)
143{ 162{
@@ -178,31 +197,31 @@ wbsio_match(device_t parent, cfdata_t ma @@ -178,31 +197,31 @@ wbsio_match(device_t parent, cfdata_t ma
178 if (ia->ia_nio < 1) 197 if (ia->ia_nio < 1)
179 return 0; 198 return 0;
180 199
181 if (ISA_DIRECT_CONFIG(ia)) 200 if (ISA_DIRECT_CONFIG(ia))
182 return 0; 201 return 0;
183 202
184 if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) 203 if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
185 return 0; 204 return 0;
186 205
187 /* Match by device ID */ 206 /* Match by device ID */
188 iot = ia->ia_iot; 207 iot = ia->ia_iot;
189 if (bus_space_map(iot, ia->ia_io[0].ir_addr, WBSIO_IOSIZE, 0, &ioh)) 208 if (bus_space_map(iot, ia->ia_io[0].ir_addr, WBSIO_IOSIZE, 0, &ioh))
190 return 0; 209 return 0;
191 wbsio_conf_enable(iot, ioh); 210 wbsio_conf_enable(NULL, iot, ioh);
192 id = wbsio_conf_read(iot, ioh, WBSIO_ID); 211 id = wbsio_conf_read(iot, ioh, WBSIO_ID);
193 rev = wbsio_conf_read(iot, ioh, WBSIO_REV); 212 rev = wbsio_conf_read(iot, ioh, WBSIO_REV);
194 aprint_debug("wbsio_probe: id 0x%02x, rev 0x%02x\n", id, rev); 213 aprint_debug("wbsio_probe: id 0x%02x, rev 0x%02x\n", id, rev);
195 wbsio_conf_disable(iot, ioh); 214 wbsio_conf_disable(NULL, iot, ioh);
196 bus_space_unmap(iot, ioh, WBSIO_IOSIZE); 215 bus_space_unmap(iot, ioh, WBSIO_IOSIZE);
197 216
198 if ((product = wbsio_lookup(id, rev)) == NULL) 217 if ((product = wbsio_lookup(id, rev)) == NULL)
199 return 0; 218 return 0;
200 219
201 ia->ia_nio = 1; 220 ia->ia_nio = 1;
202 ia->ia_io[0].ir_size = WBSIO_IOSIZE; 221 ia->ia_io[0].ir_size = WBSIO_IOSIZE;
203 ia->ia_niomem = 0; 222 ia->ia_niomem = 0;
204 ia->ia_nirq = 0; 223 ia->ia_nirq = 0;
205 ia->ia_ndrq = 0; 224 ia->ia_ndrq = 0;
206 return 1; 225 return 1;
207} 226}
208 227
@@ -218,88 +237,98 @@ wbsio_attach(device_t parent, device_t s @@ -218,88 +237,98 @@ wbsio_attach(device_t parent, device_t s
218 237
219 sc->sc_dev = self; 238 sc->sc_dev = self;
220 239
221 sc->sc_ia = *ia; 240 sc->sc_ia = *ia;
222 241
223 /* Map ISA I/O space */ 242 /* Map ISA I/O space */
224 sc->sc_iot = ia->ia_iot; 243 sc->sc_iot = ia->ia_iot;
225 if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, 244 if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr,
226 WBSIO_IOSIZE, 0, &sc->sc_ioh)) { 245 WBSIO_IOSIZE, 0, &sc->sc_ioh)) {
227 aprint_error(": can't map i/o space\n"); 246 aprint_error(": can't map i/o space\n");
228 return; 247 return;
229 } 248 }
230 249
 250 mutex_init(&sc->sc_conf_lock, MUTEX_DEFAULT, IPL_NONE);
 251
231 /* Enter configuration mode */ 252 /* Enter configuration mode */
232 wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); 253 wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
233 254
234 /* Read device ID */ 255 /* Read device ID */
235 id = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID); 256 id = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID);
236 /* Read device revision */ 257 /* Read device revision */
237 rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV); 258 rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV);
238 259
239 /* Escape from configuration mode */ 260 /* Escape from configuration mode */
240 wbsio_conf_disable(sc->sc_iot, sc->sc_ioh); 261 wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
241 262
242 if ((product = wbsio_lookup(id, rev)) == NULL) { 263 if ((product = wbsio_lookup(id, rev)) == NULL) {
243 aprint_error_dev(self, "Unknown device. Failed to attach\n"); 264 aprint_error_dev(self, "Unknown device. Failed to attach\n");
244 return; 265 return;
245 } 266 }
246 if (product->idis12bits) 267 if (product->idis12bits)
247 rev &= 0x0f; /* Revision is low 4bits */ 268 rev &= 0x0f; /* Revision is low 4bits */
248 269
249 desc = product->str; 270 desc = product->str;
250 if (desc[0] == 'W') 271 if (desc[0] == 'W')
251 vendor = "Winbond"; 272 vendor = "Winbond";
252 else 273 else
253 vendor = "Nuvoton"; 274 vendor = "Nuvoton";
254 aprint_naive("\n"); 275 aprint_naive("\n");
255 aprint_normal(": %s LPC Super I/O %s rev ", vendor, desc); 276 aprint_normal(": %s LPC Super I/O %s rev ", vendor, desc);
256 if (product->idis12bits) { 277 if (product->idis12bits) {
257 /* Revision filed is 4bit only */ 278 /* Revision filed is 4bit only */
258 aprint_normal("%c\n", 'A' + rev); 279 aprint_normal("%c\n", 'A' + rev);
259 } else 280 } else
260 aprint_normal("0x%02x\n", rev); 281 aprint_normal("0x%02x\n", rev);
261 282
262 if (!pmf_device_register(self, NULL, NULL)) 283 if (!pmf_device_register(self, wbsio_suspend, NULL))
263 aprint_error_dev(self, "couldn't establish power handler\n"); 284 aprint_error_dev(self, "couldn't establish power handler\n");
 285
 286 wbsio_wdog_attach(self);
 287
264 wbsio_rescan(self, "wbsio", NULL); 288 wbsio_rescan(self, "wbsio", NULL);
265 289
266#if NGPIO > 0 290#if NGPIO > 0
267 291
268 wbsio_rescan(self, "gpiobus", NULL); 292 wbsio_rescan(self, "gpiobus", NULL);
269#endif 293#endif
270} 294}
271 295
272int 296int
273wbsio_detach(device_t self, int flags) 297wbsio_detach(device_t self, int flags)
274{ 298{
275 struct wbsio_softc *sc = device_private(self); 299 struct wbsio_softc *sc = device_private(self);
276 int rc; 300 int rc;
277 301
 302 if ((rc = wbsio_wdog_detach(self)) != 0)
 303 return rc;
 304
278 if ((rc = config_detach_children(self, flags)) != 0) 305 if ((rc = config_detach_children(self, flags)) != 0)
279 return rc; 306 return rc;
280 bus_space_unmap(sc->sc_iot, sc->sc_ioh, WBSIO_IOSIZE); 307 bus_space_unmap(sc->sc_iot, sc->sc_ioh, WBSIO_IOSIZE);
281 pmf_device_deregister(self); 308 pmf_device_deregister(self);
282 309
283#if NGPIO > 0 310#if NGPIO > 0
284 if (sc->sc_gpio_dev) { 311 if (sc->sc_gpio_dev) {
285 bus_space_unmap(sc->sc_iot, sc->sc_gpio_ioh, 312 bus_space_unmap(sc->sc_iot, sc->sc_gpio_ioh,
286 WBSIO_GPIO_IOSIZE); 313 WBSIO_GPIO_IOSIZE);
287 } 314 }
288 315
289 if (sc->sc_gpio_rt) { 316 if (sc->sc_gpio_rt) {
290 mutex_destroy(&sc->sc_gpio_lock); 317 mutex_destroy(&sc->sc_gpio_lock);
291 } 318 }
292#endif 319#endif
 320
 321 mutex_destroy(&sc->sc_conf_lock);
293 return 0; 322 return 0;
294} 323}
295 324
296int 325int
297wbsio_rescan(device_t self, const char *ifattr, const int *locators) 326wbsio_rescan(device_t self, const char *ifattr, const int *locators)
298{ 327{
299 328
300#if NGPIO > 0 329#if NGPIO > 0
301 if (ifattr_match(ifattr, "gpiobus")) { 330 if (ifattr_match(ifattr, "gpiobus")) {
302 config_search_loc(wbsio_gpio_search, self, 331 config_search_loc(wbsio_gpio_search, self,
303 ifattr, locators, NULL); 332 ifattr, locators, NULL);
304 return 0; 333 return 0;
305 } 334 }
@@ -318,55 +347,55 @@ wbsio_childdet(device_t self, device_t c @@ -318,55 +347,55 @@ wbsio_childdet(device_t self, device_t c
318 sc->sc_lm_dev = NULL; 347 sc->sc_lm_dev = NULL;
319} 348}
320 349
321static int 350static int
322wbsio_search(device_t parent, cfdata_t cf, const int *slocs, void *aux) 351wbsio_search(device_t parent, cfdata_t cf, const int *slocs, void *aux)
323{ 352{
324 struct wbsio_softc *sc = device_private(parent); 353 struct wbsio_softc *sc = device_private(parent);
325 const struct wbsio_product *product; 354 const struct wbsio_product *product;
326 uint16_t iobase; 355 uint16_t iobase;
327 uint16_t devid; 356 uint16_t devid;
328 uint8_t reg0, reg1, rev; 357 uint8_t reg0, reg1, rev;
329 358
330 /* Enter configuration mode */ 359 /* Enter configuration mode */
331 wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); 360 wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
332 361
333 /* Select HM logical device */ 362 /* Select HM logical device */
334 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_HM); 363 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_HM);
335 364
336 /* 365 /*
337 * The address should be 8-byte aligned, but it seems some 366 * The address should be 8-byte aligned, but it seems some
338 * BIOSes ignore this. They get away with it, because 367 * BIOSes ignore this. They get away with it, because
339 * Apparently the hardware simply ignores the lower three 368 * Apparently the hardware simply ignores the lower three
340 * bits. We do the same here. 369 * bits. We do the same here.
341 */ 370 */
342 reg0 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_HM_ADDR_LSB); 371 reg0 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_HM_ADDR_LSB);
343 reg1 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_HM_ADDR_MSB); 372 reg1 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_HM_ADDR_MSB);
344 373
345 /* Escape from configuration mode */ 374 /* Escape from configuration mode */
346 wbsio_conf_disable(sc->sc_iot, sc->sc_ioh); 375 wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
347 376
348 iobase = (reg1 << 8) | (reg0 & ~0x7); 377 iobase = (reg1 << 8) | (reg0 & ~0x7);
349 378
350 if (iobase == 0) 379 if (iobase == 0)
351 return -1; 380 return -1;
352 381
353 /* Enter configuration mode */ 382 /* Enter configuration mode */
354 wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); 383 wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
355 /* Read device ID and revision */ 384 /* Read device ID and revision */
356 devid = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID); 385 devid = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID);
357 rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV); 386 rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV);
358 /* Escape from configuration mode */ 387 /* Escape from configuration mode */
359 wbsio_conf_disable(sc->sc_iot, sc->sc_ioh); 388 wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
360 389
361 if ((product = wbsio_lookup(devid, rev)) == NULL) { 390 if ((product = wbsio_lookup(devid, rev)) == NULL) {
362 aprint_error_dev(parent, "%s: Unknown device.\n", __func__); 391 aprint_error_dev(parent, "%s: Unknown device.\n", __func__);
363 return -1; 392 return -1;
364 } 393 }
365 if (product->idis12bits) 394 if (product->idis12bits)
366 devid = (devid << 4) | (rev >> 4); 395 devid = (devid << 4) | (rev >> 4);
367 396
368 sc->sc_ia.ia_nio = 1; 397 sc->sc_ia.ia_nio = 1;
369 sc->sc_ia.ia_io = &sc->sc_io; 398 sc->sc_ia.ia_io = &sc->sc_io;
370 sc->sc_ia.ia_io[0].ir_addr = iobase; 399 sc->sc_ia.ia_io[0].ir_addr = iobase;
371 sc->sc_ia.ia_io[0].ir_size = 8; 400 sc->sc_ia.ia_io[0].ir_size = 8;
372 sc->sc_ia.ia_niomem = 0; 401 sc->sc_ia.ia_niomem = 0;
@@ -384,44 +413,58 @@ wbsio_print(void *aux, const char *pnp) @@ -384,44 +413,58 @@ wbsio_print(void *aux, const char *pnp)
384{ 413{
385 struct isa_attach_args *ia = aux; 414 struct isa_attach_args *ia = aux;
386 415
387 if (pnp) 416 if (pnp)
388 aprint_normal("%s", pnp); 417 aprint_normal("%s", pnp);
389 if (ia->ia_io[0].ir_size) 418 if (ia->ia_io[0].ir_size)
390 aprint_normal(" port 0x%x", ia->ia_io[0].ir_addr); 419 aprint_normal(" port 0x%x", ia->ia_io[0].ir_addr);
391 if (ia->ia_io[0].ir_size > 1) 420 if (ia->ia_io[0].ir_size > 1)
392 aprint_normal("-0x%x", ia->ia_io[0].ir_addr + 421 aprint_normal("-0x%x", ia->ia_io[0].ir_addr +
393 ia->ia_io[0].ir_size - 1); 422 ia->ia_io[0].ir_size - 1);
394 return (UNCONF); 423 return (UNCONF);
395} 424}
396 425
 426static bool
 427wbsio_suspend(device_t self, const pmf_qual_t *qual)
 428{
 429 struct wbsio_softc *sc = device_private(self);
 430
 431 if (sc->sc_smw_valid) {
 432 if ((sc->sc_smw.smw_mode & WDOG_MODE_MASK)
 433 != WDOG_MODE_DISARMED)
 434 return false;
 435 }
 436
 437 return true;
 438}
 439
397#if NGPIO > 0 440#if NGPIO > 0
398static int 441static int
399wbsio_gpio_search(device_t parent, cfdata_t cf, const int *slocs, void *aux) 442wbsio_gpio_search(device_t parent, cfdata_t cf, const int *slocs, void *aux)
400{ 443{
401 struct wbsio_softc *sc = device_private(parent); 444 struct wbsio_softc *sc = device_private(parent);
402 const struct wbsio_product *product; 445 const struct wbsio_product *product;
403 struct gpiobus_attach_args gba; 446 struct gpiobus_attach_args gba;
404 uint16_t devid; 447 uint16_t devid;
405 uint8_t rev; 448 uint8_t rev;
406 int i; 449 int i;
407 450
408 /* Enter configuration mode */ 451 /* Enter configuration mode */
409 wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); 452 wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
410 /* Read device ID and revision */ 453 /* Read device ID and revision */
411 devid = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID); 454 devid = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID);
412 rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV); 455 rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV);
413 /* Escape from configuration mode */ 456 /* Escape from configuration mode */
414 wbsio_conf_disable(sc->sc_iot, sc->sc_ioh); 457 wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
415 458
416 if ((product = wbsio_lookup(devid, rev)) == NULL) { 459 if ((product = wbsio_lookup(devid, rev)) == NULL) {
417 aprint_error_dev(parent, "%s: Unknown device.\n", __func__); 460 aprint_error_dev(parent, "%s: Unknown device.\n", __func__);
418 return -1; 461 return -1;
419 } 462 }
420 463
421 sc->sc_gpio_rt = false; 464 sc->sc_gpio_rt = false;
422 465
423 switch (product->id) { 466 switch (product->id) {
424 case WBSIO_ID_NCT6779D: 467 case WBSIO_ID_NCT6779D:
425 wbsio_gpio_enable_nct6779d(parent); 468 wbsio_gpio_enable_nct6779d(parent);
426 sc->sc_gpio_rt = true; 469 sc->sc_gpio_rt = true;
427 break; 470 break;
@@ -469,36 +512,36 @@ wbsio_gpio_search(device_t parent, cfdat @@ -469,36 +512,36 @@ wbsio_gpio_search(device_t parent, cfdat
469 512
470 sc->sc_gpio_dev = config_attach(parent, cf, &gba, gpiobus_print); 513 sc->sc_gpio_dev = config_attach(parent, cf, &gba, gpiobus_print);
471 514
472 return 0; 515 return 0;
473} 516}
474 517
475static int 518static int
476wbsio_gpio_rt_init(struct wbsio_softc *sc) 519wbsio_gpio_rt_init(struct wbsio_softc *sc)
477{ 520{
478 uint16_t iobase; 521 uint16_t iobase;
479 uint8_t reg0, reg1; 522 uint8_t reg0, reg1;
480 523
481 /* Enter configuration mode */ 524 /* Enter configuration mode */
482 wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); 525 wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
483 526
484 /* Get GPIO Register Table address */ 527 /* Get GPIO Register Table address */
485 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_GPIO0); 528 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_GPIO0);
486 reg0 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_GPIO_ADDR_LSB); 529 reg0 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_GPIO_ADDR_LSB);
487 reg1 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_GPIO_ADDR_MSB); 530 reg1 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_GPIO_ADDR_MSB);
488 iobase = (reg1 << 8) | (reg0 & ~0x7); 531 iobase = (reg1 << 8) | (reg0 & ~0x7);
489 532
490 /* Escape from configuration mode */ 533 /* Escape from configuration mode */
491 wbsio_conf_disable(sc->sc_iot, sc->sc_ioh); 534 wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
492 535
493 if (bus_space_map(sc->sc_iot, iobase, WBSIO_GPIO_IOSIZE, 536 if (bus_space_map(sc->sc_iot, iobase, WBSIO_GPIO_IOSIZE,
494 0, &sc->sc_gpio_ioh)) { 537 0, &sc->sc_gpio_ioh)) {
495 aprint_error_dev(sc->sc_dev, 538 aprint_error_dev(sc->sc_dev,
496 "can't map gpio to i/o space\n"); 539 "can't map gpio to i/o space\n");
497 return -1; 540 return -1;
498 } 541 }
499 542
500 aprint_normal_dev(sc->sc_dev, "GPIO: port 0x%x-0x%x\n", 543 aprint_normal_dev(sc->sc_dev, "GPIO: port 0x%x-0x%x\n",
501 iobase, iobase + WBSIO_GPIO_IOSIZE); 544 iobase, iobase + WBSIO_GPIO_IOSIZE);
502 545
503 mutex_init(&sc->sc_gpio_lock, MUTEX_DEFAULT, IPL_NONE); 546 mutex_init(&sc->sc_gpio_lock, MUTEX_DEFAULT, IPL_NONE);
504 547
@@ -596,62 +639,62 @@ wbsio_gpio_rt_pin_ctl(void *aux, int pin @@ -596,62 +639,62 @@ wbsio_gpio_rt_pin_ctl(void *aux, int pin
596 } 639 }
597 640
598 wbsio_gpio_rt_write(sc, port, WBSIO_GPIO_IOR, ior); 641 wbsio_gpio_rt_write(sc, port, WBSIO_GPIO_IOR, ior);
599 wbsio_gpio_rt_write(sc, port, WBSIO_GPIO_INV, inv); 642 wbsio_gpio_rt_write(sc, port, WBSIO_GPIO_INV, inv);
600} 643}
601 644
602static void 645static void
603wbsio_gpio_enable_nct6779d(device_t parent) 646wbsio_gpio_enable_nct6779d(device_t parent)
604{ 647{
605 struct wbsio_softc *sc = device_private(parent); 648 struct wbsio_softc *sc = device_private(parent);
606 uint8_t reg, conf; 649 uint8_t reg, conf;
607 650
608 /* Enter configuration mode */ 651 /* Enter configuration mode */
609 wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); 652 wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
610 653
611 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_GPIO0); 654 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_GPIO0);
612 reg = WBSIO_GPIO_CONF; 655 reg = WBSIO_GPIO_CONF;
613 conf = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, reg); 656 conf = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, reg);
614 /* Activate Register Table access */ 657 /* Activate Register Table access */
615 conf |= WBSIO_GPIO_BASEADDR; 658 conf |= WBSIO_GPIO_BASEADDR;
616 659
617 conf |= WBSIO_GPIO0_ENABLE; 660 conf |= WBSIO_GPIO0_ENABLE;
618 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, reg, conf); 661 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, reg, conf);
619 662
620 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_GPIO1); 663 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_GPIO1);
621 reg = WBSIO_GPIO_CONF; 664 reg = WBSIO_GPIO_CONF;
622 conf = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, reg); 665 conf = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, reg);
623 conf |= WBSIO_GPIO1_ENABLE; 666 conf |= WBSIO_GPIO1_ENABLE;
624 conf |= WBSIO_GPIO2_ENABLE; 667 conf |= WBSIO_GPIO2_ENABLE;
625 conf |= WBSIO_GPIO3_ENABLE; 668 conf |= WBSIO_GPIO3_ENABLE;
626 conf |= WBSIO_GPIO4_ENABLE; 669 conf |= WBSIO_GPIO4_ENABLE;
627 conf |= WBSIO_GPIO5_ENABLE; 670 conf |= WBSIO_GPIO5_ENABLE;
628 conf |= WBSIO_GPIO6_ENABLE; 671 conf |= WBSIO_GPIO6_ENABLE;
629 conf |= WBSIO_GPIO7_ENABLE; 672 conf |= WBSIO_GPIO7_ENABLE;
630 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, reg, conf); 673 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, reg, conf);
631 674
632 /* Escape from configuration mode */ 675 /* Escape from configuration mode */
633 wbsio_conf_disable(sc->sc_iot, sc->sc_ioh); 676 wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
634} 677}
635 678
636static void 679static void
637wbsio_gpio_pinconfig_nct6779d(device_t parent) 680wbsio_gpio_pinconfig_nct6779d(device_t parent)
638{ 681{
639 struct wbsio_softc *sc = device_private(parent); 682 struct wbsio_softc *sc = device_private(parent);
640 uint8_t sfr, mfs0, mfs1, mfs2, mfs3; 683 uint8_t sfr, mfs0, mfs1, mfs2, mfs3;
641 uint8_t mfs4, mfs5, mfs6, gopt2, hm_conf; 684 uint8_t mfs4, mfs5, mfs6, gopt2, hm_conf;
642 685
643 /* Enter configuration mode */ 686 /* Enter configuration mode */
644 wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); 687 wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
645 688
646 /* Strapping Function Result */ 689 /* Strapping Function Result */
647 sfr = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_SFR); 690 sfr = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_SFR);
648 sfr &= ~(WBSIO_SFR_LPT | WBSIO_SFR_DSW | WBSIO_SFR_AMDPWR); 691 sfr &= ~(WBSIO_SFR_LPT | WBSIO_SFR_DSW | WBSIO_SFR_AMDPWR);
649 692
650 /* Read current configuration */ 693 /* Read current configuration */
651 mfs0 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS0); 694 mfs0 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS0);
652 mfs1 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS1); 695 mfs1 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS1);
653 mfs2 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS2); 696 mfs2 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS2);
654 mfs3 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS3); 697 mfs3 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS3);
655 mfs4 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS4); 698 mfs4 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS4);
656 mfs5 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS5); 699 mfs5 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS5);
657 mfs6 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS6); 700 mfs6 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_MFS6);
@@ -730,30 +773,177 @@ wbsio_gpio_pinconfig_nct6779d(device_t p @@ -730,30 +773,177 @@ wbsio_gpio_pinconfig_nct6779d(device_t p
730 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS0, mfs0); 773 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS0, mfs0);
731 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS1, mfs1); 774 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS1, mfs1);
732 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS2, mfs2); 775 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS2, mfs2);
733 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS3, mfs3); 776 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS3, mfs3);
734 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS4, mfs4); 777 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS4, mfs4);
735 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS5, mfs5); 778 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS5, mfs5);
736 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS6, mfs6); 779 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_MFS6, mfs6);
737 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_GOPT2, gopt2); 780 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_GOPT2, gopt2);
738 781
739 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_HM); 782 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_HM);
740 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_HM_CONF, hm_conf); 783 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_HM_CONF, hm_conf);
741 784
742 /* Escape from configuration mode */ 785 /* Escape from configuration mode */
743 wbsio_conf_disable(sc->sc_iot, sc->sc_ioh); 786 wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
 787}
 788
 789#endif /* NGPIO > 0 */
 790
 791static void
 792wbsio_wdog_attach(device_t self)
 793{
 794 struct wbsio_softc *sc = device_private(self);
 795 const struct wbsio_product *product;
 796 uint8_t gpio, mode;
 797 uint16_t devid;
 798 uint8_t rev;
 799
 800 sc->sc_smw_valid = false;
 801
 802 wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
 803 devid = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID);
 804 rev = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV);
 805 wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
 806
 807 if ((product = wbsio_lookup(devid, rev)) == NULL) {
 808 return;
 809 }
 810
 811 switch (product->id) {
 812 case WBSIO_ID_NCT6779D:
 813 break;
 814 default:
 815 /* WDT is not supoorted */
 816 return;
 817 }
 818
 819 wbsio_wdog_setcounter(sc, WBSIO_WDT_CNTR_STOP);
 820
 821 wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
 822 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_GPIO0);
 823
 824 gpio = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_GPIO_CONF);
 825 mode = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_WDT_MODE);
 826
 827 gpio |= WBSIO_GPIO0_WDT1;
 828
 829 mode &= ~WBSIO_WDT_MODE_FASTER;
 830 mode &= ~WBSIO_WDT_MODE_MINUTES;
 831 mode &= ~WBSIO_WDT_MODE_KBCRST;
 832 mode &= ~WBSIO_WDT_MODE_LEVEL;
 833
 834 /* initialize WDT mode */
 835 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_WDT_MODE, mode);
 836 /* Activate WDT1 function */
 837 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_GPIO_CONF, gpio);
 838
 839 wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
 840
 841 sc->sc_smw.smw_name = device_xname(self);
 842 sc->sc_smw.smw_cookie = sc;
 843 sc->sc_smw.smw_setmode = wbsio_wdog_setmode;
 844 sc->sc_smw.smw_tickle = wbsio_wdog_tickle;
 845 sc->sc_smw.smw_period = WBSIO_WDT_CNTR_MAX;
 846
 847 if (sysmon_wdog_register(&sc->sc_smw))
 848 aprint_error_dev(self, "couldn't register with sysmon\n");
 849 else
 850 sc->sc_smw_valid = true;
 851}
 852
 853static int
 854wbsio_wdog_detach(device_t self)
 855{
 856 struct wbsio_softc *sc = device_private(self);
 857 int error;
 858
 859 error = 0;
 860
 861 if (sc->sc_smw_valid) {
 862 if ((sc->sc_smw.smw_mode & WDOG_MODE_MASK)
 863 != WDOG_MODE_DISARMED)
 864 return EBUSY;
 865
 866 error = sysmon_wdog_unregister(&sc->sc_smw);
 867 }
 868
 869 if (!error)
 870 sc->sc_smw_valid = false;
 871
 872 return error;
 873}
 874
 875static int
 876wbsio_wdog_setmode(struct sysmon_wdog *smw)
 877{
 878
 879 switch(smw->smw_mode & WDOG_MODE_MASK) {
 880 case WDOG_MODE_DISARMED:
 881 wbsio_wdog_setcounter(smw->smw_cookie, WBSIO_WDT_CNTR_STOP);
 882 wbsio_wdog_clear_timeout(smw->smw_cookie);
 883 break;
 884 default:
 885 if (smw->smw_period > WBSIO_WDT_CNTR_MAX
 886 || smw->smw_period == 0)
 887 return EINVAL;
 888
 889 wbsio_wdog_setcounter(smw->smw_cookie, smw->smw_period);
 890 }
 891
 892 return 0;
 893}
 894
 895static void
 896wbsio_wdog_setcounter(struct wbsio_softc *sc, uint8_t period)
 897{
 898
 899 KASSERT(!mutex_owned(&sc->sc_conf_lock));
 900
 901 wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
 902
 903 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_GPIO0);
 904 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_WDT_CNTR, period);
 905
 906 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_GPIO0);
 907
 908
 909 wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
 910}
 911
 912static void
 913wbsio_wdog_clear_timeout(struct wbsio_softc *sc)
 914{
 915 uint8_t st;
 916
 917 KASSERT(!mutex_owned(&sc->sc_conf_lock));
 918
 919 wbsio_conf_enable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
 920
 921 st = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_WDT_STAT);
 922 st &= ~WBSIO_WDT_STAT_TIMEOUT;
 923 wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_WDT_STAT, st);
 924
 925 wbsio_conf_disable(&sc->sc_conf_lock, sc->sc_iot, sc->sc_ioh);
 926}
 927
 928static int
 929wbsio_wdog_tickle(struct sysmon_wdog *smw)
 930{
 931
 932 wbsio_wdog_setcounter(smw->smw_cookie, smw->smw_period);
 933
 934 return 0;
744} 935}
745 936
746#endif 
747 937
748MODULE(MODULE_CLASS_DRIVER, wbsio, NULL); 938MODULE(MODULE_CLASS_DRIVER, wbsio, NULL);
749 939
750#ifdef _MODULE 940#ifdef _MODULE
751#include "ioconf.c" 941#include "ioconf.c"
752#endif 942#endif
753 943
754static int 944static int
755wbsio_modcmd(modcmd_t cmd, void *opaque) 945wbsio_modcmd(modcmd_t cmd, void *opaque)
756{ 946{
757 switch (cmd) { 947 switch (cmd) {
758 case MODULE_CMD_INIT: 948 case MODULE_CMD_INIT:
759#ifdef _MODULE 949#ifdef _MODULE

cvs diff -r1.6 -r1.7 src/sys/dev/isa/wbsioreg.h (expand / switch to unified diff)

--- src/sys/dev/isa/wbsioreg.h 2017/12/13 00:26:06 1.6
+++ src/sys/dev/isa/wbsioreg.h 2017/12/13 00:27:53 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: wbsioreg.h,v 1.6 2017/12/13 00:26:06 knakahara Exp $ */ 1/* $NetBSD: wbsioreg.h,v 1.7 2017/12/13 00:27:53 knakahara Exp $ */
2 2
3/* $OpenBSD: wbsioreg.h,v 1.4 2015/01/02 23:02:54 chris Exp $ */ 3/* $OpenBSD: wbsioreg.h,v 1.4 2015/01/02 23:02:54 chris Exp $ */
4/* 4/*
5 * Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org> 5 * Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
@@ -86,48 +86,67 @@ @@ -86,48 +86,67 @@
86 86
87/* Hardware Monitor Control Registers (LDN B) */ 87/* Hardware Monitor Control Registers (LDN B) */
88#define WBSIO_HM_ADDR_MSB 0x60 /* Address [15:8] */ 88#define WBSIO_HM_ADDR_MSB 0x60 /* Address [15:8] */
89#define WBSIO_HM_ADDR_LSB 0x61 /* Address [7:0] */ 89#define WBSIO_HM_ADDR_LSB 0x61 /* Address [7:0] */
90#define WBSIO_HM_CONF 0xE4 /* Configuration Register */ 90#define WBSIO_HM_CONF 0xE4 /* Configuration Register */
91#define WBSIO_HM_CONF_RSTOUT4 0x02 /* RSTOUT4# bit */ 91#define WBSIO_HM_CONF_RSTOUT4 0x02 /* RSTOUT4# bit */
92#define WBSIO_HM_CONF_RSTOUT3 0x04 /* RSTOUT3# bit */ 92#define WBSIO_HM_CONF_RSTOUT3 0x04 /* RSTOUT3# bit */
93#define WBSIO_HM_CONF_PWROK 0x08 /* Power OK Bit */ 93#define WBSIO_HM_CONF_PWROK 0x08 /* Power OK Bit */
94 94
95/* GPIO Registers */ 95/* GPIO Registers */
96#define WBSIO_GPIO_ADDR_MSB 0x60 /* Address [15:8] */ 96#define WBSIO_GPIO_ADDR_MSB 0x60 /* Address [15:8] */
97#define WBSIO_GPIO_ADDR_LSB 0x61 /* Address [7:0] */ 97#define WBSIO_GPIO_ADDR_LSB 0x61 /* Address [7:0] */
98#define WBSIO_GPIO_CONF 0x30 /* GPIO0, WDT1 config */ 98#define WBSIO_GPIO_CONF 0x30 /* GPIO0, WDT1 config */
 99#define WBSIO_WDT_MODE 0xF5 /* WDT1 Control Mode */
 100#define WBSIO_WDT_CNTR 0xF6 /* WDT1 Counter */
 101#define WBSIO_WDT_STAT 0xF7 /* WDT1 Control & Status */
 102#define WBSIO_GPIO4_MFS 0xEE /* GPIO4 Multi-Function Select */
99 103
 104#define WBSIO_GPIO0_WDT1 __BIT(0)
100#define WBSIO_GPIO0_ENABLE __BIT(1) 105#define WBSIO_GPIO0_ENABLE __BIT(1)
 106
 107 /* Reserved */
101#define WBSIO_GPIO_BASEADDR __BIT(3) /* Base address mode */ 108#define WBSIO_GPIO_BASEADDR __BIT(3) /* Base address mode */
102#define WBSIO_GPIO1_ENABLE __BIT(1) 109#define WBSIO_GPIO1_ENABLE __BIT(1)
103#define WBSIO_GPIO2_ENABLE __BIT(2) 110#define WBSIO_GPIO2_ENABLE __BIT(2)
104#define WBSIO_GPIO3_ENABLE __BIT(3) 111#define WBSIO_GPIO3_ENABLE __BIT(3)
105#define WBSIO_GPIO4_ENABLE __BIT(4) 112#define WBSIO_GPIO4_ENABLE __BIT(4)
106#define WBSIO_GPIO5_ENABLE __BIT(5) 113#define WBSIO_GPIO5_ENABLE __BIT(5)
107#define WBSIO_GPIO6_ENABLE __BIT(6) 114#define WBSIO_GPIO6_ENABLE __BIT(6)
108#define WBSIO_GPIO7_ENABLE __BIT(7) 115#define WBSIO_GPIO7_ENABLE __BIT(7)
109#define WBSIO_GPIO8_ENABLE __BIT(0) 116#define WBSIO_GPIO8_ENABLE __BIT(0)
110 117
111#define WBSIO_GPIO_NPINS 64 118#define WBSIO_GPIO_NPINS 64
112#define WBSIO_GPIO_IOSIZE 0x06 /* GPIO register table size */ 119#define WBSIO_GPIO_IOSIZE 0x06 /* GPIO register table size */
113 120
114#define WBSIO_GPIO_GSR 0x00 /* GPIO Select Register */ 121#define WBSIO_GPIO_GSR 0x00 /* GPIO Select Register */
115#define WBSIO_GPIO_IOR 0x01 /* I/O direction */ 122#define WBSIO_GPIO_IOR 0x01 /* I/O direction */
116#define WBSIO_GPIO_DAT 0x02 /* Data */ 123#define WBSIO_GPIO_DAT 0x02 /* Data */
117#define WBSIO_GPIO_INV 0x03 /* Inversion */ 124#define WBSIO_GPIO_INV 0x03 /* Inversion */
118#define WBSIO_GPIO_DST 0x04 /* Event Status */ 125#define WBSIO_GPIO_DST 0x04 /* Event Status */
119#define WBSIO_GPIO_WDTMOD 0x05 126 /* WDT1 Control Mode */
120#define WBSIO_GPIO_WDTTIM 0x06 127 /* WDT1 control */
 128#define WBSIO_WDT_MODE_LEVEL __BIT(0)
 129 /* enable/disable KBRST */
 130#define WBSIO_WDT_MODE_KBCRST __BIT(2)
 131#define WBSIO_WDT_MODE_MINUTES __BIT(3)
 132#define WBSIO_WDT_MODE_FASTER __BIT(4)
 133
 134#define WBSIO_WDT_CNTR_STOP 0
 135#define WBSIO_WDT_CNTR_MAX 255
 136
 137#define WBSIO_WDT_STAT_TIMEOUT __BIT(4)
 138#define WBSIO_WDT_STAT_EVENT __BIT(5)
 139
121 140
122/* NCT6779D */ 141/* NCT6779D */
123#define WBSIO_NCT6779D_MFS2_GP00 __BIT(0) 142#define WBSIO_NCT6779D_MFS2_GP00 __BIT(0)
124#define WBSIO_NCT6779D_MFS2_GP01 __BIT(1) 143#define WBSIO_NCT6779D_MFS2_GP01 __BIT(1)
125#define WBSIO_NCT6779D_MFS2_GP02 __BIT(2) 144#define WBSIO_NCT6779D_MFS2_GP02 __BIT(2)
126#define WBSIO_NCT6779D_MFS2_GP03_MASK (__BIT(3)|__BIT(4)) 145#define WBSIO_NCT6779D_MFS2_GP03_MASK (__BIT(3)|__BIT(4))
127#define WBSIO_NCT6779D_MFS2_GP04 __BIT(5) 146#define WBSIO_NCT6779D_MFS2_GP04 __BIT(5)
128#define WBSIO_NCT6779D_MFS2_GP05 __BIT(6) 147#define WBSIO_NCT6779D_MFS2_GP05 __BIT(6)
129#define WBSIO_NCT6779D_MFS2_GP06 __BIT(7) 148#define WBSIO_NCT6779D_MFS2_GP06 __BIT(7)
130#define WBSIO_NCT6779D_MFS3_GP07_MASK __BIT(0) 149#define WBSIO_NCT6779D_MFS3_GP07_MASK __BIT(0)
131#define WBSIO_NCT6779D_MFS4_GP10_GP17 __BIT(6) 150#define WBSIO_NCT6779D_MFS4_GP10_GP17 __BIT(6)
132#define WBSIO_NCT6779D_MFS4_GP20_GP21 __BIT(0) 151#define WBSIO_NCT6779D_MFS4_GP20_GP21 __BIT(0)
133#define WBSIO_NCT6779D_MFS4_GP22_GP23 __BIT(1) 152#define WBSIO_NCT6779D_MFS4_GP22_GP23 __BIT(1)
@@ -149,13 +168,14 @@ @@ -149,13 +168,14 @@
149#define WBSIO_NCT6779D_MFS0_GP41 __BIT(3) 168#define WBSIO_NCT6779D_MFS0_GP41 __BIT(3)
150#define WBSIO_NCT6779D_MFS0_GP41_MASK __BIT(2) 169#define WBSIO_NCT6779D_MFS0_GP41_MASK __BIT(2)
151#define WBSIO_NCT6779D_MFS1_GP42 (__BIT(1)|__BIT(2)) 170#define WBSIO_NCT6779D_MFS1_GP42 (__BIT(1)|__BIT(2))
152#define WBSIO_NCT6779D_GOPT2_GP43 __BIT(4) 171#define WBSIO_NCT6779D_GOPT2_GP43 __BIT(4)
153#define WBSIO_NCT6779D_MFS1_GP44_GP45_MASK __BIT(6) 172#define WBSIO_NCT6779D_MFS1_GP44_GP45_MASK __BIT(6)
154#define WBSIO_NCT6779D_GOPT2_GP46_MASK __BIT(5) 173#define WBSIO_NCT6779D_GOPT2_GP46_MASK __BIT(5)
155#define WBSIO_NCT6779D_MFS1_GP47 __BIT(7) 174#define WBSIO_NCT6779D_MFS1_GP47 __BIT(7)
156#define WBSIO_NCT6779D_HM_GP50_MASK __BIT(2) 175#define WBSIO_NCT6779D_HM_GP50_MASK __BIT(2)
157#define WBSIO_NCT6779D_HM_GP52_MASK __BIT(1) 176#define WBSIO_NCT6779D_HM_GP52_MASK __BIT(1)
158#define WBSIO_NCT6779D_HM_GP55_MASK __BIT(3) 177#define WBSIO_NCT6779D_HM_GP55_MASK __BIT(3)
159#define WBSIO_NCT6779D_MFS5_GP74 __BIT(5) 178#define WBSIO_NCT6779D_MFS5_GP74 __BIT(5)
160#define WBSIO_NCT6779D_MFS5_GP75 __BIT(6) 179#define WBSIO_NCT6779D_MFS5_GP75 __BIT(6)
161#define WBSIO_NCT6779D_MFS5_GP76 __BIT(7) 180#define WBSIO_NCT6779D_MFS5_GP76 __BIT(7)
 181#define WBSIO_NCT6779D_GPIO4_WDTO __BIT(4)