xref: /netbsd-src/sys/arch/x86/pci/ichlpcib.c (revision 3816d47b2c42fcd6e549e3407f842a5b1a1d23ad)
1 /*	$NetBSD: ichlpcib.c,v 1.23 2010/01/08 19:43:26 dyoung Exp $	*/
2 
3 /*-
4  * Copyright (c) 2004 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Minoura Makoto and Matthew R. Green.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Intel I/O Controller Hub (ICHn) LPC Interface Bridge driver
34  *
35  *  LPC Interface Bridge is basically a pcib (PCI-ISA Bridge), but has
36  *  some power management and monitoring functions.
37  *  Currently we support the watchdog timer, SpeedStep (on some systems)
38  *  and the power management timer.
39  */
40 
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: ichlpcib.c,v 1.23 2010/01/08 19:43:26 dyoung Exp $");
43 
44 #include <sys/types.h>
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/device.h>
48 #include <sys/sysctl.h>
49 #include <sys/timetc.h>
50 #include <sys/gpio.h>
51 #include <machine/bus.h>
52 
53 #include <dev/pci/pcivar.h>
54 #include <dev/pci/pcireg.h>
55 #include <dev/pci/pcidevs.h>
56 
57 #include <dev/gpio/gpiovar.h>
58 #include <dev/sysmon/sysmonvar.h>
59 
60 #include <dev/ic/acpipmtimer.h>
61 #include <dev/ic/i82801lpcreg.h>
62 #include <dev/ic/hpetreg.h>
63 #include <dev/ic/hpetvar.h>
64 
65 #include "hpet.h"
66 #include "pcibvar.h"
67 #include "gpio.h"
68 
69 #define LPCIB_GPIO_NPINS 64
70 
71 struct lpcib_softc {
72 	/* we call pcibattach() which assumes this starts like this: */
73 	struct pcib_softc	sc_pcib;
74 
75 	struct pci_attach_args	sc_pa;
76 	int			sc_has_rcba;
77 	int			sc_has_ich5_hpet;
78 
79 	/* RCBA */
80 	bus_space_tag_t		sc_rcbat;
81 	bus_space_handle_t	sc_rcbah;
82 	pcireg_t		sc_rcba_reg;
83 
84 	/* Watchdog variables. */
85 	struct sysmon_wdog	sc_smw;
86 	bus_space_tag_t		sc_iot;
87 	bus_space_handle_t	sc_ioh;
88 	bus_size_t		sc_iosize;
89 
90 #if NHPET > 0
91 	/* HPET variables. */
92 	uint32_t		sc_hpet_reg;
93 #endif
94 
95 #if NGPIO > 0
96 	device_t		sc_gpiobus;
97 	kmutex_t		sc_gpio_mtx;
98 	bus_space_tag_t		sc_gpio_iot;
99 	bus_space_handle_t	sc_gpio_ioh;
100 	bus_size_t		sc_gpio_ios;
101 	struct gpio_chipset_tag	sc_gpio_gc;
102 	gpio_pin_t		sc_gpio_pins[LPCIB_GPIO_NPINS];
103 #endif
104 
105 	/* Speedstep */
106 	pcireg_t		sc_pmcon_orig;
107 
108 	/* Power management */
109 	pcireg_t		sc_pirq[2];
110 	pcireg_t		sc_pmcon;
111 	pcireg_t		sc_fwhsel2;
112 
113 	/* Child devices */
114 	device_t		sc_hpetbus;
115 	acpipmtimer_t		sc_pmtimer;
116 	pcireg_t		sc_acpi_cntl;
117 
118 	struct sysctllog	*sc_log;
119 };
120 
121 static int lpcibmatch(device_t, cfdata_t, void *);
122 static void lpcibattach(device_t, device_t, void *);
123 static int lpcibdetach(device_t, int);
124 static void lpcibchilddet(device_t, device_t);
125 static int lpcibrescan(device_t, const char *, const int *);
126 static bool lpcib_suspend(device_t, pmf_qual_t);
127 static bool lpcib_resume(device_t, pmf_qual_t);
128 static bool lpcib_shutdown(device_t, int);
129 
130 static void pmtimer_configure(device_t);
131 static int pmtimer_unconfigure(device_t, int);
132 
133 static void tcotimer_configure(device_t);
134 static int tcotimer_unconfigure(device_t, int);
135 static int tcotimer_setmode(struct sysmon_wdog *);
136 static int tcotimer_tickle(struct sysmon_wdog *);
137 static void tcotimer_stop(struct lpcib_softc *);
138 static void tcotimer_start(struct lpcib_softc *);
139 static void tcotimer_status_reset(struct lpcib_softc *);
140 static int  tcotimer_disable_noreboot(device_t);
141 
142 static void speedstep_configure(device_t);
143 static void speedstep_unconfigure(device_t);
144 static int speedstep_sysctl_helper(SYSCTLFN_ARGS);
145 
146 #if NHPET > 0
147 static void lpcib_hpet_configure(device_t);
148 static int lpcib_hpet_unconfigure(device_t, int);
149 #endif
150 
151 #if NGPIO > 0
152 static void lpcib_gpio_configure(device_t);
153 static int lpcib_gpio_unconfigure(device_t, int);
154 static int lpcib_gpio_pin_read(void *, int);
155 static void lpcib_gpio_pin_write(void *, int, int);
156 static void lpcib_gpio_pin_ctl(void *, int, int);
157 #endif
158 
159 struct lpcib_softc *speedstep_cookie;	/* XXX */
160 
161 CFATTACH_DECL2_NEW(ichlpcib, sizeof(struct lpcib_softc),
162     lpcibmatch, lpcibattach, lpcibdetach, NULL, lpcibrescan, lpcibchilddet);
163 
164 static struct lpcib_device {
165 	pcireg_t vendor, product;
166 	int has_rcba;
167 	int has_ich5_hpet;
168 } lpcib_devices[] = {
169 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AA_LPC, 0, 0 },
170 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_LPC, 0, 0 },
171 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BAM_LPC, 0, 0 },
172 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_LPC, 0, 0 },
173 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CAM_LPC, 0, 0 },
174 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_LPC, 0, 0 },
175 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_ISA, 0, 0 },
176 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801EB_LPC, 0, 1 },
177 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FB_LPC, 1, 0 },
178 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FBM_LPC, 1, 0 },
179 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801G_LPC, 1, 0 },
180 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GBM_LPC, 1, 0 },
181 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GHM_LPC, 1, 0 },
182 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801H_LPC, 1, 0 },
183 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HEM_LPC, 1, 0 },
184 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HH_LPC, 1, 0 },
185 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HO_LPC, 1, 0 },
186 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HBM_LPC, 1, 0 },
187 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IH_LPC, 1, 0 },
188 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IO_LPC, 1, 0 },
189 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IR_LPC, 1, 0 },
190 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IEM_LPC, 1, 0 },
191 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IB_LPC, 1, 0 },
192 	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_63XXESB_LPC, 1, 0 },
193 
194 	{ 0, 0, 0, 0 },
195 };
196 
197 /*
198  * Autoconf callbacks.
199  */
200 static int
201 lpcibmatch(device_t parent, cfdata_t match, void *aux)
202 {
203 	struct pci_attach_args *pa = aux;
204 	struct lpcib_device *lpcib_dev;
205 
206 	/* We are ISA bridge, of course */
207 	if (PCI_CLASS(pa->pa_class) != PCI_CLASS_BRIDGE ||
208 	    PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_BRIDGE_ISA)
209 		return 0;
210 
211 	for (lpcib_dev = lpcib_devices; lpcib_dev->vendor; ++lpcib_dev) {
212 		if (PCI_VENDOR(pa->pa_id) == lpcib_dev->vendor &&
213 		    PCI_PRODUCT(pa->pa_id) == lpcib_dev->product)
214 			return 10;
215 	}
216 
217 	return 0;
218 }
219 
220 static void
221 lpcibattach(device_t parent, device_t self, void *aux)
222 {
223 	struct pci_attach_args *pa = aux;
224 	struct lpcib_softc *sc = device_private(self);
225 	struct lpcib_device *lpcib_dev;
226 
227 	sc->sc_pa = *pa;
228 
229 	for (lpcib_dev = lpcib_devices; lpcib_dev->vendor; ++lpcib_dev) {
230 		if (PCI_VENDOR(pa->pa_id) != lpcib_dev->vendor ||
231 		    PCI_PRODUCT(pa->pa_id) != lpcib_dev->product)
232 			continue;
233 		sc->sc_has_rcba = lpcib_dev->has_rcba;
234 		sc->sc_has_ich5_hpet = lpcib_dev->has_ich5_hpet;
235 		break;
236 	}
237 
238 	pcibattach(parent, self, aux);
239 
240 	/*
241 	 * Part of our I/O registers are used as ACPI PM regs.
242 	 * Since our ACPI subsystem accesses the I/O space directly so far,
243 	 * we do not have to bother bus_space I/O map confliction.
244 	 */
245 	if (pci_mapreg_map(pa, LPCIB_PCI_PMBASE, PCI_MAPREG_TYPE_IO, 0,
246 			   &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize)) {
247 		aprint_error_dev(self, "can't map power management i/o space");
248 		return;
249 	}
250 
251 	sc->sc_pmcon_orig = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
252 	    LPCIB_PCI_GEN_PMCON_1);
253 
254 	/* For ICH6 and later, always enable RCBA */
255 	if (sc->sc_has_rcba) {
256 		pcireg_t rcba;
257 
258 		sc->sc_rcbat = sc->sc_pa.pa_memt;
259 
260 		rcba = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
261 		     LPCIB_RCBA);
262 		if ((rcba & LPCIB_RCBA_EN) == 0) {
263 			aprint_error_dev(self, "RCBA is not enabled");
264 			return;
265 		}
266 		rcba &= ~LPCIB_RCBA_EN;
267 
268 		if (bus_space_map(sc->sc_rcbat, rcba, LPCIB_RCBA_SIZE, 0,
269 				  &sc->sc_rcbah)) {
270 			aprint_error_dev(self, "RCBA could not be mapped");
271 			return;
272 		}
273 	}
274 
275 	/* Set up the power management timer. */
276 	pmtimer_configure(self);
277 
278 	/* Set up the TCO (watchdog). */
279 	tcotimer_configure(self);
280 
281 	/* Set up SpeedStep. */
282 	speedstep_configure(self);
283 
284 #if NHPET > 0
285 	/* Set up HPET. */
286 	lpcib_hpet_configure(self);
287 #endif
288 
289 #if NGPIO > 0
290 	/* Set up GPIO */
291 	lpcib_gpio_configure(self);
292 #endif
293 
294 	/* Install power handler */
295 	if (!pmf_device_register1(self, lpcib_suspend, lpcib_resume,
296 	    lpcib_shutdown))
297 		aprint_error_dev(self, "couldn't establish power handler\n");
298 }
299 
300 static void
301 lpcibchilddet(device_t self, device_t child)
302 {
303 	struct lpcib_softc *sc = device_private(self);
304 	uint32_t val;
305 
306 #if NGPIO > 0
307 	if (sc->sc_gpiobus == child) {
308 		sc->sc_gpiobus = NULL;
309 		return;
310 	}
311 #endif
312 	if (sc->sc_hpetbus != child) {
313 		pcibchilddet(self, child);
314 		return;
315 	}
316 	sc->sc_hpetbus = NULL;
317 	if (sc->sc_has_ich5_hpet) {
318 		val = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
319 		    LPCIB_PCI_GEN_CNTL);
320 		switch (val & LPCIB_ICH5_HPTC_WIN_MASK) {
321 		case LPCIB_ICH5_HPTC_0000:
322 		case LPCIB_ICH5_HPTC_1000:
323 		case LPCIB_ICH5_HPTC_2000:
324 		case LPCIB_ICH5_HPTC_3000:
325 			break;
326 		default:
327 			return;
328 		}
329 		val &= ~LPCIB_ICH5_HPTC_EN;
330 		pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
331 		    LPCIB_PCI_GEN_CNTL, val);
332 	} else if (sc->sc_has_rcba) {
333 		val = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah,
334 		    LPCIB_RCBA_HPTC);
335 		switch (val & LPCIB_RCBA_HPTC_WIN_MASK) {
336 		case LPCIB_RCBA_HPTC_0000:
337 		case LPCIB_RCBA_HPTC_1000:
338 		case LPCIB_RCBA_HPTC_2000:
339 		case LPCIB_RCBA_HPTC_3000:
340 			break;
341 		default:
342 			return;
343 		}
344 		val &= ~LPCIB_RCBA_HPTC_EN;
345 		bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC,
346 		    val);
347 	}
348 }
349 
350 static int
351 lpcibrescan(device_t self, const char *ifattr, const int *locators)
352 {
353 #if NHPET > 0 || NGPIO > 0
354 	struct lpcib_softc *sc = device_private(self);
355 #endif
356 
357 #if NHPET > 0
358 	if (ifattr_match(ifattr, "hpetichbus") && sc->sc_hpetbus == NULL)
359 		lpcib_hpet_configure(self);
360 #endif
361 
362 #if NGPIO > 0
363 	if (ifattr_match(ifattr, "gpiobus") && sc->sc_gpiobus == NULL)
364 		lpcib_gpio_configure(self);
365 #endif
366 
367 	return pcibrescan(self, ifattr, locators);
368 }
369 
370 static int
371 lpcibdetach(device_t self, int flags)
372 {
373 	struct lpcib_softc *sc = device_private(self);
374 	int rc;
375 
376 	pmf_device_deregister(self);
377 
378 #if NHPET > 0
379 	if ((rc = lpcib_hpet_unconfigure(self, flags)) != 0)
380 		return rc;
381 #endif
382 
383 #if NGPIO > 0
384 	if ((rc = lpcib_gpio_unconfigure(self, flags)) != 0)
385 		return rc;
386 #endif
387 
388 	/* Set up SpeedStep. */
389 	speedstep_unconfigure(self);
390 
391 	if ((rc = tcotimer_unconfigure(self, flags)) != 0)
392 		return rc;
393 
394 	if ((rc = pmtimer_unconfigure(self, flags)) != 0)
395 		return rc;
396 
397 	if (sc->sc_has_rcba)
398 		bus_space_unmap(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_SIZE);
399 
400 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize);
401 
402 	return pcibdetach(self, flags);
403 }
404 
405 static bool
406 lpcib_shutdown(device_t dv, int howto)
407 {
408 	struct lpcib_softc *sc = device_private(dv);
409 
410 	pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
411 	    LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon_orig);
412 
413 	return true;
414 }
415 
416 static bool
417 lpcib_suspend(device_t dv, pmf_qual_t qual)
418 {
419 	struct lpcib_softc *sc = device_private(dv);
420 	pci_chipset_tag_t pc = sc->sc_pcib.sc_pc;
421 	pcitag_t tag = sc->sc_pcib.sc_tag;
422 
423 	/* capture PIRQ routing control registers */
424 	sc->sc_pirq[0] = pci_conf_read(pc, tag, LPCIB_PCI_PIRQA_ROUT);
425 	sc->sc_pirq[1] = pci_conf_read(pc, tag, LPCIB_PCI_PIRQE_ROUT);
426 
427 	sc->sc_pmcon = pci_conf_read(pc, tag, LPCIB_PCI_GEN_PMCON_1);
428 	sc->sc_fwhsel2 = pci_conf_read(pc, tag, LPCIB_PCI_GEN_STA);
429 
430 	if (sc->sc_has_rcba) {
431 		sc->sc_rcba_reg = pci_conf_read(pc, tag, LPCIB_RCBA);
432 #if NHPET > 0
433 		sc->sc_hpet_reg = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah,
434 		    LPCIB_RCBA_HPTC);
435 #endif
436 	} else if (sc->sc_has_ich5_hpet) {
437 #if NHPET > 0
438 		sc->sc_hpet_reg = pci_conf_read(pc, tag, LPCIB_PCI_GEN_CNTL);
439 #endif
440 	}
441 
442 	return true;
443 }
444 
445 static bool
446 lpcib_resume(device_t dv, pmf_qual_t qual)
447 {
448 	struct lpcib_softc *sc = device_private(dv);
449 	pci_chipset_tag_t pc = sc->sc_pcib.sc_pc;
450 	pcitag_t tag = sc->sc_pcib.sc_tag;
451 
452 	/* restore PIRQ routing control registers */
453 	pci_conf_write(pc, tag, LPCIB_PCI_PIRQA_ROUT, sc->sc_pirq[0]);
454 	pci_conf_write(pc, tag, LPCIB_PCI_PIRQE_ROUT, sc->sc_pirq[1]);
455 
456 	pci_conf_write(pc, tag, LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon);
457 	pci_conf_write(pc, tag, LPCIB_PCI_GEN_STA, sc->sc_fwhsel2);
458 
459 	if (sc->sc_has_rcba) {
460 		pci_conf_write(pc, tag, LPCIB_RCBA, sc->sc_rcba_reg);
461 #if NHPET > 0
462 		bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC,
463 		    sc->sc_hpet_reg);
464 #endif
465 	} else if (sc->sc_has_ich5_hpet) {
466 #if NHPET > 0
467 		pci_conf_write(pc, tag, LPCIB_PCI_GEN_CNTL, sc->sc_hpet_reg);
468 #endif
469 	}
470 
471 	return true;
472 }
473 
474 /*
475  * Initialize the power management timer.
476  */
477 static void
478 pmtimer_configure(device_t self)
479 {
480 	struct lpcib_softc *sc = device_private(self);
481 	pcireg_t control;
482 
483 	/*
484 	 * Check if power management I/O space is enabled and enable the ACPI_EN
485 	 * bit if it's disabled.
486 	 */
487 	control = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
488 	    LPCIB_PCI_ACPI_CNTL);
489 	sc->sc_acpi_cntl = control;
490 	if ((control & LPCIB_PCI_ACPI_CNTL_EN) == 0) {
491 		control |= LPCIB_PCI_ACPI_CNTL_EN;
492 		pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
493 		    LPCIB_PCI_ACPI_CNTL, control);
494 	}
495 
496 	/* Attach our PM timer with the generic acpipmtimer function */
497 	sc->sc_pmtimer = acpipmtimer_attach(self, sc->sc_iot, sc->sc_ioh,
498 	    LPCIB_PM1_TMR, 0);
499 }
500 
501 static int
502 pmtimer_unconfigure(device_t self, int flags)
503 {
504 	struct lpcib_softc *sc = device_private(self);
505 	int rc;
506 
507 	if (sc->sc_pmtimer != NULL &&
508 	    (rc = acpipmtimer_detach(sc->sc_pmtimer, flags)) != 0)
509 		return rc;
510 
511 	pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
512 	    LPCIB_PCI_ACPI_CNTL, sc->sc_acpi_cntl);
513 
514 	return 0;
515 }
516 
517 /*
518  * Initialize the watchdog timer.
519  */
520 static void
521 tcotimer_configure(device_t self)
522 {
523 	struct lpcib_softc *sc = device_private(self);
524 	uint32_t ioreg;
525 	unsigned int period;
526 
527 	/* Explicitly stop the TCO timer. */
528 	tcotimer_stop(sc);
529 
530 	/*
531 	 * Enable TCO timeout SMI only if the hardware reset does not
532 	 * work. We don't know what the SMBIOS does.
533 	 */
534 	ioreg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LPCIB_SMI_EN);
535 	ioreg &= ~LPCIB_SMI_EN_TCO_EN;
536 
537 	/*
538 	 * Clear the No Reboot (NR) bit. If this fails, enabling the TCO_EN bit
539 	 * in the SMI_EN register is the last chance.
540 	 */
541 	if (tcotimer_disable_noreboot(self)) {
542 		ioreg |= LPCIB_SMI_EN_TCO_EN;
543 	}
544 	if ((ioreg & LPCIB_SMI_EN_GBL_SMI_EN) != 0) {
545 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPCIB_SMI_EN, ioreg);
546 	}
547 
548 	/* Reset the watchdog status registers. */
549 	tcotimer_status_reset(sc);
550 
551 	/*
552 	 * Register the driver with the sysmon watchdog framework.
553 	 */
554 	sc->sc_smw.smw_name = device_xname(self);
555 	sc->sc_smw.smw_cookie = sc;
556 	sc->sc_smw.smw_setmode = tcotimer_setmode;
557 	sc->sc_smw.smw_tickle = tcotimer_tickle;
558 	if (sc->sc_has_rcba)
559 		period = LPCIB_TCOTIMER2_MAX_TICK;
560 	else
561 		period = LPCIB_TCOTIMER_MAX_TICK;
562 	sc->sc_smw.smw_period = lpcib_tcotimer_tick_to_second(period);
563 
564 	if (sysmon_wdog_register(&sc->sc_smw)) {
565 		aprint_error_dev(self, "unable to register TCO timer"
566 		       "as a sysmon watchdog device.\n");
567 		return;
568 	}
569 
570 	aprint_verbose_dev(self, "TCO (watchdog) timer configured.\n");
571 }
572 
573 static int
574 tcotimer_unconfigure(device_t self, int flags)
575 {
576 	struct lpcib_softc *sc = device_private(self);
577 	int rc;
578 
579 	if ((rc = sysmon_wdog_unregister(&sc->sc_smw)) != 0) {
580 		if (rc == ERESTART)
581 			rc = EINTR;
582 		return rc;
583 	}
584 
585 	/* Explicitly stop the TCO timer. */
586 	tcotimer_stop(sc);
587 
588 	/* XXX Set No Reboot? */
589 
590 	return 0;
591 }
592 
593 
594 /*
595  * Sysmon watchdog callbacks.
596  */
597 static int
598 tcotimer_setmode(struct sysmon_wdog *smw)
599 {
600 	struct lpcib_softc *sc = smw->smw_cookie;
601 	unsigned int period;
602 	uint16_t ich6period = 0;
603 	uint8_t ich5period = 0;
604 
605 	if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
606 		/* Stop the TCO timer. */
607 		tcotimer_stop(sc);
608 	} else {
609 		/*
610 		 * ICH6 or newer are limited to 2s min and 613s max.
611 		 * ICH5 or older are limited to 4s min and 39s max.
612 		 */
613 		period = lpcib_tcotimer_second_to_tick(smw->smw_period);
614 		if (sc->sc_has_rcba) {
615 			if (period < LPCIB_TCOTIMER2_MIN_TICK ||
616 			    period > LPCIB_TCOTIMER2_MAX_TICK)
617 				return EINVAL;
618 		} else {
619 			if (period < LPCIB_TCOTIMER_MIN_TICK ||
620 			    period > LPCIB_TCOTIMER_MAX_TICK)
621 				return EINVAL;
622 		}
623 
624 		/* Stop the TCO timer, */
625 		tcotimer_stop(sc);
626 
627 		/* set the timeout, */
628 		if (sc->sc_has_rcba) {
629 			/* ICH6 or newer */
630 			ich6period = bus_space_read_2(sc->sc_iot, sc->sc_ioh,
631 						      LPCIB_TCO_TMR2);
632 			ich6period &= 0xfc00;
633 			bus_space_write_2(sc->sc_iot, sc->sc_ioh,
634 					  LPCIB_TCO_TMR2, ich6period | period);
635 		} else {
636 			/* ICH5 or older */
637 			ich5period = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
638 						   LPCIB_TCO_TMR);
639 			ich5period &= 0xc0;
640 			bus_space_write_1(sc->sc_iot, sc->sc_ioh,
641 					  LPCIB_TCO_TMR, ich5period | period);
642 		}
643 
644 		/* and start/reload the timer. */
645 		tcotimer_start(sc);
646 		tcotimer_tickle(smw);
647 	}
648 
649 	return 0;
650 }
651 
652 static int
653 tcotimer_tickle(struct sysmon_wdog *smw)
654 {
655 	struct lpcib_softc *sc = smw->smw_cookie;
656 
657 	/* any value is allowed */
658 	if (sc->sc_has_rcba)
659 		bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO_RLD, 1);
660 	else
661 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, LPCIB_TCO_RLD, 1);
662 
663 	return 0;
664 }
665 
666 static void
667 tcotimer_stop(struct lpcib_softc *sc)
668 {
669 	uint16_t ioreg;
670 
671 	ioreg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT);
672 	ioreg |= LPCIB_TCO1_CNT_TCO_TMR_HLT;
673 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT, ioreg);
674 }
675 
676 static void
677 tcotimer_start(struct lpcib_softc *sc)
678 {
679 	uint16_t ioreg;
680 
681 	ioreg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT);
682 	ioreg &= ~LPCIB_TCO1_CNT_TCO_TMR_HLT;
683 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT, ioreg);
684 }
685 
686 static void
687 tcotimer_status_reset(struct lpcib_softc *sc)
688 {
689 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_STS,
690 			  LPCIB_TCO1_STS_TIMEOUT);
691 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO2_STS,
692 			  LPCIB_TCO2_STS_BOOT_STS);
693 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO2_STS,
694 			  LPCIB_TCO2_STS_SECONDS_TO_STS);
695 }
696 
697 /*
698  * Clear the No Reboot (NR) bit, this enables reboots when the timer
699  * reaches the timeout for the second time.
700  */
701 static int
702 tcotimer_disable_noreboot(device_t self)
703 {
704 	struct lpcib_softc *sc = device_private(self);
705 
706 	if (sc->sc_has_rcba) {
707 		uint32_t status;
708 
709 		status = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah,
710 		    LPCIB_GCS_OFFSET);
711 		status &= ~LPCIB_GCS_NO_REBOOT;
712 		bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah,
713 		    LPCIB_GCS_OFFSET, status);
714 		status = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah,
715 		    LPCIB_GCS_OFFSET);
716 		if (status & LPCIB_GCS_NO_REBOOT)
717 			goto error;
718 	} else {
719 		pcireg_t pcireg;
720 
721 		pcireg = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
722 				       LPCIB_PCI_GEN_STA);
723 		if (pcireg & LPCIB_PCI_GEN_STA_NO_REBOOT) {
724 			/* TCO timeout reset is disabled; try to enable it */
725 			pcireg &= ~LPCIB_PCI_GEN_STA_NO_REBOOT;
726 			pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
727 				       LPCIB_PCI_GEN_STA, pcireg);
728 			if (pcireg & LPCIB_PCI_GEN_STA_NO_REBOOT)
729 				goto error;
730 		}
731 	}
732 
733 	return 0;
734 error:
735 	aprint_error_dev(self, "TCO timer reboot disabled by hardware; "
736 	    "hope SMBIOS properly handles it.\n");
737 	return EINVAL;
738 }
739 
740 
741 /*
742  * Intel ICH SpeedStep support.
743  */
744 #define SS_READ(sc, reg) \
745 	bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (reg))
746 #define SS_WRITE(sc, reg, val) \
747 	bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
748 
749 /*
750  * Linux driver says that SpeedStep on older chipsets cause
751  * lockups on Dell Inspiron 8000 and 8100.
752  * It should also not be enabled on systems with the 82855GM
753  * Hub, which typically have an EST-enabled CPU.
754  */
755 static int
756 speedstep_bad_hb_check(struct pci_attach_args *pa)
757 {
758 
759 	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82815_FULL_HUB &&
760 	    PCI_REVISION(pa->pa_class) < 5)
761 		return 1;
762 
763 	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82855GM_MCH)
764 		return 1;
765 
766 	return 0;
767 }
768 
769 static void
770 speedstep_configure(device_t self)
771 {
772 	struct lpcib_softc *sc = device_private(self);
773 	const struct sysctlnode	*node, *ssnode;
774 	int rv;
775 
776 	/* Supported on ICH2-M, ICH3-M and ICH4-M.  */
777 	if (PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801DB_ISA ||
778 	    PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801CAM_LPC ||
779 	    (PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801BAM_LPC &&
780 	     pci_find_device(&sc->sc_pa, speedstep_bad_hb_check) == 0)) {
781 		pcireg_t pmcon;
782 
783 		/* Enable SpeedStep if it isn't already enabled. */
784 		pmcon = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
785 				      LPCIB_PCI_GEN_PMCON_1);
786 		if ((pmcon & LPCIB_PCI_GEN_PMCON_1_SS_EN) == 0)
787 			pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
788 				       LPCIB_PCI_GEN_PMCON_1,
789 				       pmcon | LPCIB_PCI_GEN_PMCON_1_SS_EN);
790 
791 		/* Put in machdep.speedstep_state (0 for low, 1 for high). */
792 		if ((rv = sysctl_createv(&sc->sc_log, 0, NULL, &node,
793 		    CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
794 		    NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL)) != 0)
795 			goto err;
796 
797 		/* CTLFLAG_ANYWRITE? kernel option like EST? */
798 		if ((rv = sysctl_createv(&sc->sc_log, 0, &node, &ssnode,
799 		    CTLFLAG_READWRITE, CTLTYPE_INT, "speedstep_state", NULL,
800 		    speedstep_sysctl_helper, 0, NULL, 0, CTL_CREATE,
801 		    CTL_EOL)) != 0)
802 			goto err;
803 
804 		/* XXX save the sc for IO tag/handle */
805 		speedstep_cookie = sc;
806 		aprint_verbose_dev(self, "SpeedStep enabled\n");
807 	}
808 
809 	return;
810 
811 err:
812 	aprint_normal("%s: sysctl_createv failed (rv = %d)\n", __func__, rv);
813 }
814 
815 static void
816 speedstep_unconfigure(device_t self)
817 {
818 	struct lpcib_softc *sc = device_private(self);
819 
820 	sysctl_teardown(&sc->sc_log);
821 	pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
822 	    LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon_orig);
823 
824 	speedstep_cookie = NULL;
825 }
826 
827 /*
828  * get/set the SpeedStep state: 0 == low power, 1 == high power.
829  */
830 static int
831 speedstep_sysctl_helper(SYSCTLFN_ARGS)
832 {
833 	struct sysctlnode	node;
834 	struct lpcib_softc 	*sc = speedstep_cookie;
835 	uint8_t			state, state2;
836 	int			ostate, nstate, s, error = 0;
837 
838 	/*
839 	 * We do the dance with spl's to avoid being at high ipl during
840 	 * sysctl_lookup() which can both copyin and copyout.
841 	 */
842 	s = splserial();
843 	state = SS_READ(sc, LPCIB_PM_SS_CNTL);
844 	splx(s);
845 	if ((state & LPCIB_PM_SS_STATE_LOW) == 0)
846 		ostate = 1;
847 	else
848 		ostate = 0;
849 	nstate = ostate;
850 
851 	node = *rnode;
852 	node.sysctl_data = &nstate;
853 
854 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
855 	if (error || newp == NULL)
856 		goto out;
857 
858 	/* Only two states are available */
859 	if (nstate != 0 && nstate != 1) {
860 		error = EINVAL;
861 		goto out;
862 	}
863 
864 	s = splserial();
865 	state2 = SS_READ(sc, LPCIB_PM_SS_CNTL);
866 	if ((state2 & LPCIB_PM_SS_STATE_LOW) == 0)
867 		ostate = 1;
868 	else
869 		ostate = 0;
870 
871 	if (ostate != nstate) {
872 		uint8_t cntl;
873 
874 		if (nstate == 0)
875 			state2 |= LPCIB_PM_SS_STATE_LOW;
876 		else
877 			state2 &= ~LPCIB_PM_SS_STATE_LOW;
878 
879 		/*
880 		 * Must disable bus master arbitration during the change.
881 		 */
882 		cntl = SS_READ(sc, LPCIB_PM_CTRL);
883 		SS_WRITE(sc, LPCIB_PM_CTRL, cntl | LPCIB_PM_SS_CNTL_ARB_DIS);
884 		SS_WRITE(sc, LPCIB_PM_SS_CNTL, state2);
885 		SS_WRITE(sc, LPCIB_PM_CTRL, cntl);
886 	}
887 	splx(s);
888 out:
889 	return error;
890 }
891 
892 #if NHPET > 0
893 struct lpcib_hpet_attach_arg {
894 	bus_space_tag_t hpet_mem_t;
895 	uint32_t hpet_reg;
896 };
897 
898 static int
899 lpcib_hpet_match(device_t parent, cfdata_t match, void *aux)
900 {
901 	struct lpcib_hpet_attach_arg *arg = aux;
902 	bus_space_tag_t tag;
903 	bus_space_handle_t handle;
904 
905 	tag = arg->hpet_mem_t;
906 
907 	if (bus_space_map(tag, arg->hpet_reg, HPET_WINDOW_SIZE, 0, &handle)) {
908 		aprint_verbose_dev(parent, "HPET window not mapped, skipping\n");
909 		return 0;
910 	}
911 	bus_space_unmap(tag, handle, HPET_WINDOW_SIZE);
912 
913 	return 1;
914 }
915 
916 static int
917 lpcib_hpet_detach(device_t self, int flags)
918 {
919 	struct hpet_softc *sc = device_private(self);
920 	int rc;
921 
922 	if ((rc = hpet_detach(self, flags)) != 0)
923 		return rc;
924 
925 	bus_space_unmap(sc->sc_memt, sc->sc_memh, HPET_WINDOW_SIZE);
926 
927 	return 0;
928 }
929 
930 static void
931 lpcib_hpet_attach(device_t parent, device_t self, void *aux)
932 {
933 	struct hpet_softc *sc = device_private(self);
934 	struct lpcib_hpet_attach_arg *arg = aux;
935 
936 	aprint_naive("\n");
937 	aprint_normal("\n");
938 
939 	sc->sc_memt = arg->hpet_mem_t;
940 
941 	if (bus_space_map(sc->sc_memt, arg->hpet_reg, HPET_WINDOW_SIZE, 0,
942 			  &sc->sc_memh)) {
943 		aprint_error_dev(self,
944 		    "HPET memory window could not be mapped");
945 		return;
946 	}
947 
948 	hpet_attach_subr(self);
949 }
950 
951 CFATTACH_DECL_NEW(ichlpcib_hpet, sizeof(struct hpet_softc), lpcib_hpet_match,
952     lpcib_hpet_attach, lpcib_hpet_detach, NULL);
953 
954 static void
955 lpcib_hpet_configure(device_t self)
956 {
957 	struct lpcib_softc *sc = device_private(self);
958 	struct lpcib_hpet_attach_arg arg;
959 	uint32_t hpet_reg, val;
960 
961 	if (sc->sc_has_ich5_hpet) {
962 		val = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
963 		    LPCIB_PCI_GEN_CNTL);
964 		switch (val & LPCIB_ICH5_HPTC_WIN_MASK) {
965 		case LPCIB_ICH5_HPTC_0000:
966 			hpet_reg = LPCIB_ICH5_HPTC_0000_BASE;
967 			break;
968 		case LPCIB_ICH5_HPTC_1000:
969 			hpet_reg = LPCIB_ICH5_HPTC_1000_BASE;
970 			break;
971 		case LPCIB_ICH5_HPTC_2000:
972 			hpet_reg = LPCIB_ICH5_HPTC_2000_BASE;
973 			break;
974 		case LPCIB_ICH5_HPTC_3000:
975 			hpet_reg = LPCIB_ICH5_HPTC_3000_BASE;
976 			break;
977 		default:
978 			return;
979 		}
980 		val |= sc->sc_hpet_reg | LPCIB_ICH5_HPTC_EN;
981 		pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
982 		    LPCIB_PCI_GEN_CNTL, val);
983 	} else if (sc->sc_has_rcba) {
984 		val = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah,
985 		    LPCIB_RCBA_HPTC);
986 		switch (val & LPCIB_RCBA_HPTC_WIN_MASK) {
987 		case LPCIB_RCBA_HPTC_0000:
988 			hpet_reg = LPCIB_RCBA_HPTC_0000_BASE;
989 			break;
990 		case LPCIB_RCBA_HPTC_1000:
991 			hpet_reg = LPCIB_RCBA_HPTC_1000_BASE;
992 			break;
993 		case LPCIB_RCBA_HPTC_2000:
994 			hpet_reg = LPCIB_RCBA_HPTC_2000_BASE;
995 			break;
996 		case LPCIB_RCBA_HPTC_3000:
997 			hpet_reg = LPCIB_RCBA_HPTC_3000_BASE;
998 			break;
999 		default:
1000 			return;
1001 		}
1002 		val |= LPCIB_RCBA_HPTC_EN;
1003 		bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC,
1004 		    val);
1005 	} else {
1006 		/* No HPET here */
1007 		return;
1008 	}
1009 
1010 	arg.hpet_mem_t = sc->sc_pa.pa_memt;
1011 	arg.hpet_reg = hpet_reg;
1012 
1013 	sc->sc_hpetbus = config_found_ia(self, "hpetichbus", &arg, NULL);
1014 }
1015 
1016 static int
1017 lpcib_hpet_unconfigure(device_t self, int flags)
1018 {
1019 	struct lpcib_softc *sc = device_private(self);
1020 	int rc;
1021 
1022 	if (sc->sc_hpetbus != NULL &&
1023 	    (rc = config_detach(sc->sc_hpetbus, flags)) != 0)
1024 		return rc;
1025 
1026 	return 0;
1027 }
1028 #endif
1029 
1030 #if NGPIO > 0
1031 static void
1032 lpcib_gpio_configure(device_t self)
1033 {
1034 	struct lpcib_softc *sc = device_private(self);
1035 	struct gpiobus_attach_args gba;
1036 	pcireg_t gpio_cntl;
1037 	uint32_t use, io, bit;
1038 	int pin, shift, base_reg, cntl_reg, reg;
1039 
1040 	/* this implies ICH >= 6, and thus different mapreg */
1041 	if (sc->sc_has_rcba) {
1042 		base_reg = LPCIB_PCI_GPIO_BASE_ICH6;
1043 		cntl_reg = LPCIB_PCI_GPIO_CNTL_ICH6;
1044 	} else {
1045 		base_reg = LPCIB_PCI_GPIO_BASE;
1046 		cntl_reg = LPCIB_PCI_GPIO_CNTL;
1047 	}
1048 
1049 	gpio_cntl = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
1050 				  cntl_reg);
1051 
1052 	/* Is GPIO enabled? */
1053 	if ((gpio_cntl & LPCIB_PCI_GPIO_CNTL_EN) == 0)
1054 		return;
1055 
1056 	if (pci_mapreg_map(&sc->sc_pa, base_reg, PCI_MAPREG_TYPE_IO, 0,
1057 			   &sc->sc_gpio_iot, &sc->sc_gpio_ioh,
1058 			   NULL, &sc->sc_gpio_ios)) {
1059 		aprint_error_dev(self, "can't map general purpose i/o space\n");
1060 		return;
1061 	}
1062 
1063 	mutex_init(&sc->sc_gpio_mtx, MUTEX_DEFAULT, IPL_NONE);
1064 
1065 	for (pin = 0; pin < LPCIB_GPIO_NPINS; pin++) {
1066 		sc->sc_gpio_pins[pin].pin_num = pin;
1067 
1068 		/* Read initial state */
1069 		reg = (pin < 32) ? LPCIB_GPIO_GPIO_USE_SEL : LPCIB_GPIO_GPIO_USE_SEL2;
1070 		use = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
1071 		reg = (pin < 32) ? LPCIB_GPIO_GP_IO_SEL : LPCIB_GPIO_GP_IO_SEL;
1072 		io = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, 4);
1073 		shift = pin % 32;
1074 		bit = __BIT(shift);
1075 
1076 		if ((use & bit) != 0) {
1077 			sc->sc_gpio_pins[pin].pin_caps =
1078 			    GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
1079 			if (pin < 32)
1080 				sc->sc_gpio_pins[pin].pin_caps |=
1081 				    GPIO_PIN_PULSATE;
1082 			if ((io & bit) != 0)
1083 				sc->sc_gpio_pins[pin].pin_flags =
1084 				    GPIO_PIN_INPUT;
1085 			else
1086 				sc->sc_gpio_pins[pin].pin_flags =
1087 				    GPIO_PIN_OUTPUT;
1088 		} else
1089 			sc->sc_gpio_pins[pin].pin_caps = 0;
1090 
1091 		if (lpcib_gpio_pin_read(sc, pin) == 0)
1092 			sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_LOW;
1093 		else
1094 			sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_HIGH;
1095 
1096 	}
1097 
1098 	/* Create controller tag */
1099 	sc->sc_gpio_gc.gp_cookie = sc;
1100 	sc->sc_gpio_gc.gp_pin_read = lpcib_gpio_pin_read;
1101 	sc->sc_gpio_gc.gp_pin_write = lpcib_gpio_pin_write;
1102 	sc->sc_gpio_gc.gp_pin_ctl = lpcib_gpio_pin_ctl;
1103 
1104 	memset(&gba, 0, sizeof(gba));
1105 
1106 	gba.gba_gc = &sc->sc_gpio_gc;
1107 	gba.gba_pins = sc->sc_gpio_pins;
1108 	gba.gba_npins = LPCIB_GPIO_NPINS;
1109 
1110 	sc->sc_gpiobus = config_found_ia(self, "gpiobus", &gba, gpiobus_print);
1111 }
1112 
1113 static int
1114 lpcib_gpio_unconfigure(device_t self, int flags)
1115 {
1116 	struct lpcib_softc *sc = device_private(self);
1117 	int rc;
1118 
1119 	if (sc->sc_gpiobus != NULL &&
1120 	    (rc = config_detach(sc->sc_gpiobus, flags)) != 0)
1121 		return rc;
1122 
1123 	mutex_destroy(&sc->sc_gpio_mtx);
1124 
1125 	bus_space_unmap(sc->sc_gpio_iot, sc->sc_gpio_ioh, sc->sc_gpio_ios);
1126 
1127 	return 0;
1128 }
1129 
1130 static int
1131 lpcib_gpio_pin_read(void *arg, int pin)
1132 {
1133 	struct lpcib_softc *sc = arg;
1134 	uint32_t data;
1135 	int reg, shift;
1136 
1137 	reg = (pin < 32) ? LPCIB_GPIO_GP_LVL : LPCIB_GPIO_GP_LVL2;
1138 	shift = pin % 32;
1139 
1140 	mutex_enter(&sc->sc_gpio_mtx);
1141 	data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
1142 	mutex_exit(&sc->sc_gpio_mtx);
1143 
1144 	return (__SHIFTOUT(data, __BIT(shift)) ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
1145 }
1146 
1147 static void
1148 lpcib_gpio_pin_write(void *arg, int pin, int value)
1149 {
1150 	struct lpcib_softc *sc = arg;
1151 	uint32_t data;
1152 	int reg, shift;
1153 
1154 	reg = (pin < 32) ? LPCIB_GPIO_GP_LVL : LPCIB_GPIO_GP_LVL2;
1155 	shift = pin % 32;
1156 
1157 	mutex_enter(&sc->sc_gpio_mtx);
1158 
1159 	data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
1160 
1161 	if(value)
1162 		data |= __BIT(shift);
1163 	else
1164 		data &= ~__BIT(shift);
1165 
1166 	bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data);
1167 
1168 	mutex_exit(&sc->sc_gpio_mtx);
1169 }
1170 
1171 static void
1172 lpcib_gpio_pin_ctl(void *arg, int pin, int flags)
1173 {
1174 	struct lpcib_softc *sc = arg;
1175 	uint32_t data;
1176 	int reg, shift;
1177 
1178 	shift = pin % 32;
1179 	reg = (pin < 32) ? LPCIB_GPIO_GP_IO_SEL : LPCIB_GPIO_GP_IO_SEL2;
1180 
1181 	mutex_enter(&sc->sc_gpio_mtx);
1182 
1183 	data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
1184 
1185 	if (flags & GPIO_PIN_OUTPUT)
1186 		data &= ~__BIT(shift);
1187 
1188 	if (flags & GPIO_PIN_INPUT)
1189 		data |= __BIT(shift);
1190 
1191 	bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data);
1192 
1193 
1194 	if (pin < 32) {
1195 		reg = LPCIB_GPIO_GPO_BLINK;
1196 		data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
1197 
1198 		if (flags & GPIO_PIN_PULSATE)
1199 			data |= __BIT(shift);
1200 		else
1201 			data &= ~__BIT(shift);
1202 
1203 		bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data);
1204 	}
1205 
1206 	mutex_exit(&sc->sc_gpio_mtx);
1207 }
1208 #endif
1209