diff options
author | jhb <jhb@FreeBSD.org> | 2006-10-10 23:23:12 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2006-10-10 23:23:12 +0000 |
commit | 920b219fcf73ff01950bf272923fd4b46e75fb62 (patch) | |
tree | eb9c93770a076684865872d673c762161b0390f7 /sys/amd64/isa/atpic.c | |
parent | 98af27d199c605e0cfa80eee1e631093cf1bf30a (diff) | |
download | FreeBSD-src-920b219fcf73ff01950bf272923fd4b46e75fb62.zip FreeBSD-src-920b219fcf73ff01950bf272923fd4b46e75fb62.tar.gz |
Change the x86 interrupt code to suspend/resume interrupt controllers
(PICs) rather than interrupt sources. This allows interrupt controllers
with no interrupt pics (such as the 8259As when APIC is in use) to
participate in suspend/resume.
- Always register the 8259A PICs even if we don't use any of their pins.
- Explicitly reset the 8259As on resume on amd64 if 'device atpic' isn't
included.
- Add a "dummy" PIC for the local APIC on the BSP to reset the local APIC
on resume. This gets suspend/resume working with APIC on UP systems.
SMP still needs more work to bring the APs back to life.
The MFC after is tentative.
Tested by: anholt (i386)
Submitted by: Andrea Bittau <a.bittau at cs.ucl.ac.uk> (3)
MFC after: 1 week
Diffstat (limited to 'sys/amd64/isa/atpic.c')
-rw-r--r-- | sys/amd64/isa/atpic.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/sys/amd64/isa/atpic.c b/sys/amd64/isa/atpic.c index 1398e47..1115c92 100644 --- a/sys/amd64/isa/atpic.c +++ b/sys/amd64/isa/atpic.c @@ -138,7 +138,7 @@ static void atpic_eoi_master(struct intsrc *isrc); static void atpic_eoi_slave(struct intsrc *isrc); static void atpic_enable_intr(struct intsrc *isrc); static int atpic_vector(struct intsrc *isrc); -static void atpic_resume(struct intsrc *isrc); +static void atpic_resume(struct pic *pic); static int atpic_source_pending(struct intsrc *isrc); static int atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig, enum intr_polarity pol); @@ -285,16 +285,13 @@ atpic_source_pending(struct intsrc *isrc) } static void -atpic_resume(struct intsrc *isrc) +atpic_resume(struct pic *pic) { - struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc; - struct atpic *ap = (struct atpic *)isrc->is_pic; + struct atpic *ap = (struct atpic *)pic; - if (ai->at_irq == 0) { - i8259_init(ap, ap == &atpics[SLAVE]); - if (ap == &atpics[SLAVE] && elcr_found) - elcr_resume(); - } + i8259_init(ap, ap == &atpics[SLAVE]); + if (ap == &atpics[SLAVE] && elcr_found) + elcr_resume(); } static int @@ -465,6 +462,14 @@ atpic_init(void *dummy __unused) int i; /* + * Register our PICs, even if we aren't going to use any of their + * pins so that they are suspended and resumed. + */ + if (intr_register_pic(&atpics[0].at_pic) != 0 || + intr_register_pic(&atpics[1].at_pic) != 0) + panic("Unable to register ATPICs"); + + /* * If any of the ISA IRQs have an interrupt source already, then * assume that the APICs are being used and don't register any * of our interrupt sources. This makes sure we don't accidentally |