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