diff options
author | Matthew Garrett <mjg59@srcf.ucam.org> | 2006-09-26 10:52:41 +0200 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-26 10:52:41 +0200 |
commit | 35d534a3ff4905c0a7bddbad0fc9df55967742c7 (patch) | |
tree | b926186d52d0b98f2931e7ad59ec6aefd2e5c641 | |
parent | f354b3a92af9b132b188b9c8ebbfb74de699926d (diff) | |
download | op-kernel-dev-35d534a3ff4905c0a7bddbad0fc9df55967742c7.zip op-kernel-dev-35d534a3ff4905c0a7bddbad0fc9df55967742c7.tar.gz |
[PATCH] x86: - restore i8259A eoi status on resume
Got it. i8259A_resume calls init_8259A(0) unconditionally, even if
auto_eoi has been set. Keep track of the current status and restore that
on resume. This fixes it for AMD64 and i386.
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
Signed-off-by: Andi Kleen <ak@suse.de>
-rw-r--r-- | arch/i386/kernel/i8259.c | 6 | ||||
-rw-r--r-- | arch/x86_64/kernel/i8259.c | 6 |
2 files changed, 10 insertions, 2 deletions
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index d4756d1..ea5f4e7 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -45,6 +45,8 @@ static void end_8259A_irq (unsigned int irq) #define shutdown_8259A_irq disable_8259A_irq +static int i8259A_auto_eoi; + static void mask_and_ack_8259A(unsigned int); unsigned int startup_8259A_irq(unsigned int irq) @@ -253,7 +255,7 @@ static void save_ELCR(char *trigger) static int i8259A_resume(struct sys_device *dev) { - init_8259A(0); + init_8259A(i8259A_auto_eoi); restore_ELCR(irq_trigger); return 0; } @@ -301,6 +303,8 @@ void init_8259A(int auto_eoi) { unsigned long flags; + i8259A_auto_eoi = auto_eoi; + spin_lock_irqsave(&i8259A_lock, flags); outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index d2f5acd..2dd51f3 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c @@ -123,6 +123,8 @@ void (*interrupt[NR_IRQS])(void) = { DEFINE_SPINLOCK(i8259A_lock); +static int i8259A_auto_eoi; + static void end_8259A_irq (unsigned int irq) { if (irq > 256) { @@ -336,6 +338,8 @@ void init_8259A(int auto_eoi) { unsigned long flags; + i8259A_auto_eoi = auto_eoi; + spin_lock_irqsave(&i8259A_lock, flags); outb(0xff, 0x21); /* mask all of 8259A-1 */ @@ -394,7 +398,7 @@ static void save_ELCR(char *trigger) static int i8259A_resume(struct sys_device *dev) { - init_8259A(0); + init_8259A(i8259A_auto_eoi); restore_ELCR(irq_trigger); return 0; } |