atpic.c revision 177253
1/*-
2 * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of any co-contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30/*
31 * PIC driver for the 8259A Master and Slave PICs in PC/AT machines.
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD: head/sys/i386/isa/atpic.c 177253 2008-03-16 10:58:09Z rwatson $");
36
37#include "opt_auto_eoi.h"
38#include "opt_isa.h"
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/bus.h>
43#include <sys/interrupt.h>
44#include <sys/kernel.h>
45#include <sys/lock.h>
46#include <sys/module.h>
47#include <sys/mutex.h>
48
49#include <machine/cpufunc.h>
50#include <machine/frame.h>
51#include <machine/intr_machdep.h>
52#include <machine/md_var.h>
53#include <machine/resource.h>
54#include <machine/segments.h>
55
56#include <dev/ic/i8259.h>
57#include <i386/isa/icu.h>
58#ifdef PC98
59#include <pc98/cbus/cbus.h>
60#else
61#include <i386/isa/isa.h>
62#endif
63#include <isa/isavar.h>
64
65#define	MASTER	0
66#define	SLAVE	1
67
68/*
69 * PC-98 machines wire the slave 8259A to pin 7 on the master PIC, and
70 * PC-AT machines wire the slave PIC to pin 2 on the master PIC.
71 */
72#ifdef PC98
73#define	ICU_SLAVEID	7
74#else
75#define	ICU_SLAVEID	2
76#endif
77
78/*
79 * Determine the base master and slave modes not including auto EOI support.
80 * All machines that FreeBSD supports use 8086 mode.
81 */
82#ifdef PC98
83/*
84 * PC-98 machines do not support auto EOI on the second PIC.  Also, it
85 * seems that PC-98 machine PICs use buffered mode, and the master PIC
86 * uses special fully nested mode.
87 */
88#define	BASE_MASTER_MODE	(ICW4_SFNM | ICW4_BUF | ICW4_MS | ICW4_8086)
89#define	BASE_SLAVE_MODE		(ICW4_BUF | ICW4_8086)
90#else
91#define	BASE_MASTER_MODE	ICW4_8086
92#define	BASE_SLAVE_MODE		ICW4_8086
93#endif
94
95/* Enable automatic EOI if requested. */
96#ifdef AUTO_EOI_1
97#define	MASTER_MODE		(BASE_MASTER_MODE | ICW4_AEOI)
98#else
99#define	MASTER_MODE		BASE_MASTER_MODE
100#endif
101#ifdef AUTO_EOI_2
102#define	SLAVE_MODE		(BASE_SLAVE_MODE | ICW4_AEOI)
103#else
104#define	SLAVE_MODE		BASE_SLAVE_MODE
105#endif
106
107#define	IRQ_MASK(irq)		(1 << (irq))
108#define	IMEN_MASK(ai)		(IRQ_MASK((ai)->at_irq))
109
110#define	NUM_ISA_IRQS		16
111
112static void	atpic_init(void *dummy);
113
114unsigned int imen;	/* XXX */
115
116inthand_t
117	IDTVEC(atpic_intr0), IDTVEC(atpic_intr1), IDTVEC(atpic_intr2),
118	IDTVEC(atpic_intr3), IDTVEC(atpic_intr4), IDTVEC(atpic_intr5),
119	IDTVEC(atpic_intr6), IDTVEC(atpic_intr7), IDTVEC(atpic_intr8),
120	IDTVEC(atpic_intr9), IDTVEC(atpic_intr10), IDTVEC(atpic_intr11),
121	IDTVEC(atpic_intr12), IDTVEC(atpic_intr13), IDTVEC(atpic_intr14),
122	IDTVEC(atpic_intr15);
123
124#define	IRQ(ap, ai)	((ap)->at_irqbase + (ai)->at_irq)
125
126#define	ATPIC(io, base, eoi, imenptr)					\
127     	{ { atpic_enable_source, atpic_disable_source, (eoi),		\
128	    atpic_enable_intr, atpic_disable_intr, atpic_vector,	\
129	    atpic_source_pending, NULL,	atpic_resume, atpic_config_intr,\
130	    atpic_assign_cpu }, (io), (base), IDT_IO_INTS + (base),	\
131	    (imenptr) }
132
133#define	INTSRC(irq)							\
134	{ { &atpics[(irq) / 8].at_pic }, IDTVEC(atpic_intr ## irq ),	\
135	    (irq) % 8 }
136
137struct atpic {
138	struct pic at_pic;
139	int	at_ioaddr;
140	int	at_irqbase;
141	uint8_t	at_intbase;
142	uint8_t	*at_imen;
143};
144
145struct atpic_intsrc {
146	struct intsrc at_intsrc;
147	inthand_t *at_intr;
148	int	at_irq;			/* Relative to PIC base. */
149	enum intr_trigger at_trigger;
150	u_long	at_count;
151	u_long	at_straycount;
152};
153
154static void atpic_enable_source(struct intsrc *isrc);
155static void atpic_disable_source(struct intsrc *isrc, int eoi);
156static void atpic_eoi_master(struct intsrc *isrc);
157static void atpic_eoi_slave(struct intsrc *isrc);
158static void atpic_enable_intr(struct intsrc *isrc);
159static void atpic_disable_intr(struct intsrc *isrc);
160static int atpic_vector(struct intsrc *isrc);
161static void atpic_resume(struct pic *pic);
162static int atpic_source_pending(struct intsrc *isrc);
163static int atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
164    enum intr_polarity pol);
165static void atpic_assign_cpu(struct intsrc *isrc, u_int apic_id);
166static void i8259_init(struct atpic *pic, int slave);
167
168static struct atpic atpics[] = {
169	ATPIC(IO_ICU1, 0, atpic_eoi_master, (uint8_t *)&imen),
170	ATPIC(IO_ICU2, 8, atpic_eoi_slave, ((uint8_t *)&imen) + 1)
171};
172
173static struct atpic_intsrc atintrs[] = {
174	INTSRC(0),
175	INTSRC(1),
176	INTSRC(2),
177	INTSRC(3),
178	INTSRC(4),
179	INTSRC(5),
180	INTSRC(6),
181	INTSRC(7),
182	INTSRC(8),
183	INTSRC(9),
184	INTSRC(10),
185	INTSRC(11),
186	INTSRC(12),
187	INTSRC(13),
188	INTSRC(14),
189	INTSRC(15),
190};
191
192CTASSERT(sizeof(atintrs) / sizeof(atintrs[0]) == NUM_ISA_IRQS);
193
194static __inline void
195_atpic_eoi_master(struct intsrc *isrc)
196{
197
198	KASSERT(isrc->is_pic == &atpics[MASTER].at_pic,
199	    ("%s: mismatched pic", __func__));
200#ifndef AUTO_EOI_1
201	outb(atpics[MASTER].at_ioaddr, OCW2_EOI);
202#endif
203}
204
205/*
206 * The data sheet says no auto-EOI on slave, but it sometimes works.
207 * So, if AUTO_EOI_2 is enabled, we use it.
208 */
209static __inline void
210_atpic_eoi_slave(struct intsrc *isrc)
211{
212
213	KASSERT(isrc->is_pic == &atpics[SLAVE].at_pic,
214	    ("%s: mismatched pic", __func__));
215#ifndef AUTO_EOI_2
216	outb(atpics[SLAVE].at_ioaddr, OCW2_EOI);
217#ifndef AUTO_EOI_1
218	outb(atpics[MASTER].at_ioaddr, OCW2_EOI);
219#endif
220#endif
221}
222
223static void
224atpic_enable_source(struct intsrc *isrc)
225{
226	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
227	struct atpic *ap = (struct atpic *)isrc->is_pic;
228
229	mtx_lock_spin(&icu_lock);
230	if (*ap->at_imen & IMEN_MASK(ai)) {
231		*ap->at_imen &= ~IMEN_MASK(ai);
232		outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen);
233	}
234	mtx_unlock_spin(&icu_lock);
235}
236
237static void
238atpic_disable_source(struct intsrc *isrc, int eoi)
239{
240	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
241	struct atpic *ap = (struct atpic *)isrc->is_pic;
242
243	mtx_lock_spin(&icu_lock);
244	if (ai->at_trigger != INTR_TRIGGER_EDGE) {
245		*ap->at_imen |= IMEN_MASK(ai);
246		outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen);
247	}
248
249	/*
250	 * Take care to call these functions directly instead of through
251	 * a function pointer.  All of the referenced variables should
252	 * still be hot in the cache.
253	 */
254	if (eoi == PIC_EOI) {
255		if (isrc->is_pic == &atpics[MASTER].at_pic)
256			_atpic_eoi_master(isrc);
257		else
258			_atpic_eoi_slave(isrc);
259	}
260
261	mtx_unlock_spin(&icu_lock);
262}
263
264static void
265atpic_eoi_master(struct intsrc *isrc)
266{
267#ifndef AUTO_EOI_1
268	mtx_lock_spin(&icu_lock);
269	_atpic_eoi_master(isrc);
270	mtx_unlock_spin(&icu_lock);
271#endif
272}
273
274static void
275atpic_eoi_slave(struct intsrc *isrc)
276{
277#ifndef AUTO_EOI_2
278	mtx_lock_spin(&icu_lock);
279	_atpic_eoi_slave(isrc);
280	mtx_unlock_spin(&icu_lock);
281#endif
282}
283
284static void
285atpic_enable_intr(struct intsrc *isrc)
286{
287}
288
289static void
290atpic_disable_intr(struct intsrc *isrc)
291{
292}
293
294
295static int
296atpic_vector(struct intsrc *isrc)
297{
298	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
299	struct atpic *ap = (struct atpic *)isrc->is_pic;
300
301	return (IRQ(ap, ai));
302}
303
304static int
305atpic_source_pending(struct intsrc *isrc)
306{
307	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
308	struct atpic *ap = (struct atpic *)isrc->is_pic;
309
310	return (inb(ap->at_ioaddr) & IMEN_MASK(ai));
311}
312
313static void
314atpic_resume(struct pic *pic)
315{
316	struct atpic *ap = (struct atpic *)pic;
317
318	i8259_init(ap, ap == &atpics[SLAVE]);
319#ifndef PC98
320	if (ap == &atpics[SLAVE] && elcr_found)
321		elcr_resume();
322#endif
323}
324
325static int
326atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
327    enum intr_polarity pol)
328{
329	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
330	u_int vector;
331
332	/* Map conforming values to edge/hi and sanity check the values. */
333	if (trig == INTR_TRIGGER_CONFORM)
334		trig = INTR_TRIGGER_EDGE;
335	if (pol == INTR_POLARITY_CONFORM)
336		pol = INTR_POLARITY_HIGH;
337	vector = atpic_vector(isrc);
338	if ((trig == INTR_TRIGGER_EDGE && pol == INTR_POLARITY_LOW) ||
339	    (trig == INTR_TRIGGER_LEVEL && pol == INTR_POLARITY_HIGH)) {
340		printf(
341		"atpic: Mismatched config for IRQ%u: trigger %s, polarity %s\n",
342		    vector, trig == INTR_TRIGGER_EDGE ? "edge" : "level",
343		    pol == INTR_POLARITY_HIGH ? "high" : "low");
344		return (EINVAL);
345	}
346
347	/* If there is no change, just return. */
348	if (ai->at_trigger == trig)
349		return (0);
350
351#ifdef PC98
352	if ((vector == 0 || vector == 1 || vector == 7 || vector == 8) &&
353	    trig == INTR_TRIGGER_LEVEL) {
354		if (bootverbose)
355			printf(
356		"atpic: Ignoring invalid level/low configuration for IRQ%u\n",
357			    vector);
358		return (EINVAL);
359	}
360	return (ENXIO);
361#else
362	/*
363	 * Certain IRQs can never be level/lo, so don't try to set them
364	 * that way if asked.  At least some ELCR registers ignore setting
365	 * these bits as well.
366	 */
367	if ((vector == 0 || vector == 1 || vector == 2 || vector == 13) &&
368	    trig == INTR_TRIGGER_LEVEL) {
369		if (bootverbose)
370			printf(
371		"atpic: Ignoring invalid level/low configuration for IRQ%u\n",
372			    vector);
373		return (EINVAL);
374	}
375	if (!elcr_found) {
376		if (bootverbose)
377			printf("atpic: No ELCR to configure IRQ%u as %s\n",
378			    vector, trig == INTR_TRIGGER_EDGE ? "edge/high" :
379			    "level/low");
380		return (ENXIO);
381	}
382	if (bootverbose)
383		printf("atpic: Programming IRQ%u as %s\n", vector,
384		    trig == INTR_TRIGGER_EDGE ? "edge/high" : "level/low");
385	mtx_lock_spin(&icu_lock);
386	elcr_write_trigger(atpic_vector(isrc), trig);
387	ai->at_trigger = trig;
388	mtx_unlock_spin(&icu_lock);
389	return (0);
390#endif /* PC98 */
391}
392
393static void
394atpic_assign_cpu(struct intsrc *isrc, u_int apic_id)
395{
396
397	/*
398	 * 8259A's are only used in UP in which case all interrupts always
399	 * go to the sole CPU and this function shouldn't even be called.
400	 */
401	panic("%s: bad cookie", __func__);
402}
403
404static void
405i8259_init(struct atpic *pic, int slave)
406{
407	int imr_addr;
408
409	/* Reset the PIC and program with next four bytes. */
410	mtx_lock_spin(&icu_lock);
411#ifdef DEV_MCA
412	/* MCA uses level triggered interrupts. */
413	if (MCA_system)
414		outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4 | ICW1_LTIM);
415	else
416#endif
417		outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4);
418	imr_addr = pic->at_ioaddr + ICU_IMR_OFFSET;
419
420	/* Start vector. */
421	outb(imr_addr, pic->at_intbase);
422
423	/*
424	 * Setup slave links.  For the master pic, indicate what line
425	 * the slave is configured on.  For the slave indicate
426	 * which line on the master we are connected to.
427	 */
428	if (slave)
429		outb(imr_addr, ICU_SLAVEID);
430	else
431		outb(imr_addr, IRQ_MASK(ICU_SLAVEID));
432
433	/* Set mode. */
434	if (slave)
435		outb(imr_addr, SLAVE_MODE);
436	else
437		outb(imr_addr, MASTER_MODE);
438
439	/* Set interrupt enable mask. */
440	outb(imr_addr, *pic->at_imen);
441
442	/* Reset is finished, default to IRR on read. */
443	outb(pic->at_ioaddr, OCW3_SEL | OCW3_RR);
444
445#ifndef PC98
446	/* OCW2_L1 sets priority order to 3-7, 0-2 (com2 first). */
447	if (!slave)
448		outb(pic->at_ioaddr, OCW2_R | OCW2_SL | OCW2_L1);
449#endif
450	mtx_unlock_spin(&icu_lock);
451}
452
453void
454atpic_startup(void)
455{
456	struct atpic_intsrc *ai;
457	int i;
458
459	/* Start off with all interrupts disabled. */
460	imen = 0xffff;
461	i8259_init(&atpics[MASTER], 0);
462	i8259_init(&atpics[SLAVE], 1);
463	atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]);
464
465	/* Install low-level interrupt handlers for all of our IRQs. */
466	for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) {
467		if (i == ICU_SLAVEID)
468			continue;
469		ai->at_intsrc.is_count = &ai->at_count;
470		ai->at_intsrc.is_straycount = &ai->at_straycount;
471		setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase +
472		    ai->at_irq, ai->at_intr, SDT_SYS386IGT, SEL_KPL,
473		    GSEL(GCODE_SEL, SEL_KPL));
474	}
475
476#ifdef DEV_MCA
477	/* For MCA systems, all interrupts are level triggered. */
478	if (MCA_system)
479		for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
480			ai->at_trigger = INTR_TRIGGER_LEVEL;
481	else
482#endif
483
484#ifdef PC98
485	for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
486		switch (i) {
487		case 0:
488		case 1:
489		case 7:
490		case 8:
491			ai->at_trigger = INTR_TRIGGER_EDGE;
492			break;
493		default:
494			ai->at_trigger = INTR_TRIGGER_LEVEL;
495			break;
496		}
497#else
498	/*
499	 * Look for an ELCR.  If we find one, update the trigger modes.
500	 * If we don't find one, assume that IRQs 0, 1, 2, and 13 are
501	 * edge triggered and that everything else is level triggered.
502	 * We only use the trigger information to reprogram the ELCR if
503	 * we have one and as an optimization to avoid masking edge
504	 * triggered interrupts.  For the case that we don't have an ELCR,
505	 * it doesn't hurt to mask an edge triggered interrupt, so we
506	 * assume level trigger for any interrupt that we aren't sure is
507	 * edge triggered.
508	 */
509	if (elcr_found) {
510		for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
511			ai->at_trigger = elcr_read_trigger(i);
512	} else {
513		for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
514			switch (i) {
515			case 0:
516			case 1:
517			case 2:
518			case 8:
519			case 13:
520				ai->at_trigger = INTR_TRIGGER_EDGE;
521				break;
522			default:
523				ai->at_trigger = INTR_TRIGGER_LEVEL;
524				break;
525			}
526	}
527#endif /* PC98 */
528}
529
530static void
531atpic_init(void *dummy __unused)
532{
533	struct atpic_intsrc *ai;
534	int i;
535
536	/*
537	 * Register our PICs, even if we aren't going to use any of their
538	 * pins so that they are suspended and resumed.
539	 */
540	if (intr_register_pic(&atpics[0].at_pic) != 0 ||
541	    intr_register_pic(&atpics[1].at_pic) != 0)
542		panic("Unable to register ATPICs");
543
544	/*
545	 * If any of the ISA IRQs have an interrupt source already, then
546	 * assume that the APICs are being used and don't register any
547	 * of our interrupt sources.  This makes sure we don't accidentally
548	 * use mixed mode.  The "accidental" use could otherwise occur on
549	 * machines that route the ACPI SCI interrupt to a different ISA
550	 * IRQ (at least one machines routes it to IRQ 13) thus disabling
551	 * that APIC ISA routing and allowing the ATPIC source for that IRQ
552	 * to leak through.  We used to depend on this feature for routing
553	 * IRQ0 via mixed mode, but now we don't use mixed mode at all.
554	 */
555	for (i = 0; i < NUM_ISA_IRQS; i++)
556		if (intr_lookup_source(i) != NULL)
557			return;
558
559	/* Loop through all interrupt sources and add them. */
560	for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) {
561		if (i == ICU_SLAVEID)
562			continue;
563		intr_register_source(&ai->at_intsrc);
564	}
565}
566SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL);
567
568void
569atpic_handle_intr(u_int vector, struct trapframe *frame)
570{
571	struct intsrc *isrc;
572
573	KASSERT(vector < NUM_ISA_IRQS, ("unknown int %u\n", vector));
574	isrc = &atintrs[vector].at_intsrc;
575
576	/*
577	 * If we don't have an event, see if this is a spurious
578	 * interrupt.
579	 */
580	if (isrc->is_event == NULL && (vector == 7 || vector == 15)) {
581		int port, isr;
582
583		/*
584		 * Read the ISR register to see if IRQ 7/15 is really
585		 * pending.  Reset read register back to IRR when done.
586		 */
587		port = ((struct atpic *)isrc->is_pic)->at_ioaddr;
588		mtx_lock_spin(&icu_lock);
589		outb(port, OCW3_SEL | OCW3_RR | OCW3_RIS);
590		isr = inb(port);
591		outb(port, OCW3_SEL | OCW3_RR);
592		mtx_unlock_spin(&icu_lock);
593		if ((isr & IRQ_MASK(7)) == 0)
594			return;
595	}
596	intr_execute_handlers(isrc, frame);
597}
598
599#ifdef DEV_ISA
600/*
601 * Bus attachment for the ISA PIC.
602 */
603static struct isa_pnp_id atpic_ids[] = {
604	{ 0x0000d041 /* PNP0000 */, "AT interrupt controller" },
605	{ 0 }
606};
607
608static int
609atpic_probe(device_t dev)
610{
611	int result;
612
613	result = ISA_PNP_PROBE(device_get_parent(dev), dev, atpic_ids);
614	if (result <= 0)
615		device_quiet(dev);
616	return (result);
617}
618
619/*
620 * We might be granted IRQ 2, as this is typically consumed by chaining
621 * between the two PIC components.  If we're using the APIC, however,
622 * this may not be the case, and as such we should free the resource.
623 * (XXX untested)
624 *
625 * The generic ISA attachment code will handle allocating any other resources
626 * that we don't explicitly claim here.
627 */
628static int
629atpic_attach(device_t dev)
630{
631	struct resource *res;
632	int rid;
633
634	/* Try to allocate our IRQ and then free it. */
635	rid = 0;
636	res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 0);
637	if (res != NULL)
638		bus_release_resource(dev, SYS_RES_IRQ, rid, res);
639	return (0);
640}
641
642static device_method_t atpic_methods[] = {
643	/* Device interface */
644	DEVMETHOD(device_probe,		atpic_probe),
645	DEVMETHOD(device_attach,	atpic_attach),
646	DEVMETHOD(device_detach,	bus_generic_detach),
647	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
648	DEVMETHOD(device_suspend,	bus_generic_suspend),
649	DEVMETHOD(device_resume,	bus_generic_resume),
650	{ 0, 0 }
651};
652
653static driver_t atpic_driver = {
654	"atpic",
655	atpic_methods,
656	1,		/* no softc */
657};
658
659static devclass_t atpic_devclass;
660
661DRIVER_MODULE(atpic, isa, atpic_driver, atpic_devclass, 0, 0);
662#ifndef PC98
663DRIVER_MODULE(atpic, acpi, atpic_driver, atpic_devclass, 0, 0);
664#endif
665
666/*
667 * Return a bitmap of the current interrupt requests.  This is 8259-specific
668 * and is only suitable for use at probe time.
669 */
670intrmask_t
671isa_irq_pending(void)
672{
673	u_char irr1;
674	u_char irr2;
675
676	irr1 = inb(IO_ICU1);
677	irr2 = inb(IO_ICU2);
678	return ((irr2 << 8) | irr1);
679}
680#endif /* DEV_ISA */
681