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