From 1c09e353073cc734f0c3a89c47e9119ee0ae410c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 12 Aug 2007 11:06:45 -0700 Subject: [PATCH] --- yaml --- r: 63978 b: refs/heads/master c: 738ddd30397c25adfa9729257623ada96ef8ce96 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/i386/kernel/io_apic.c | 7 +++++-- trunk/arch/x86_64/kernel/io_apic.c | 7 +++++-- trunk/kernel/irq/chip.c | 5 +---- trunk/kernel/irq/resend.c | 7 ++++++- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/[refs] b/[refs] index 3d6877479e04..7602c9997b1d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: de0cf899bbf06b6f64a5dce9c59d74c41b6b4232 +refs/heads/master: 738ddd30397c25adfa9729257623ada96ef8ce96 diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c index 893df8280756..4b8a8da4b2e0 100644 --- a/trunk/arch/i386/kernel/io_apic.c +++ b/trunk/arch/i386/kernel/io_apic.c @@ -1256,12 +1256,15 @@ static struct irq_chip ioapic_chip; static void ioapic_register_intr(int irq, int vector, unsigned long trigger) { if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) + trigger == IOAPIC_LEVEL) { + irq_desc[irq].status |= IRQ_LEVEL; set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_fasteoi_irq, "fasteoi"); - else + } else { + irq_desc[irq].status &= ~IRQ_LEVEL; set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_edge_irq, "edge"); + } set_intr_gate(vector, interrupt[irq]); } diff --git a/trunk/arch/x86_64/kernel/io_apic.c b/trunk/arch/x86_64/kernel/io_apic.c index 050141c0602b..f57f8b901912 100644 --- a/trunk/arch/x86_64/kernel/io_apic.c +++ b/trunk/arch/x86_64/kernel/io_apic.c @@ -800,12 +800,15 @@ static struct irq_chip ioapic_chip; static void ioapic_register_intr(int irq, unsigned long trigger) { - if (trigger) + if (trigger) { + irq_desc[irq].status |= IRQ_LEVEL; set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_fasteoi_irq, "fasteoi"); - else + } else { + irq_desc[irq].status &= ~IRQ_LEVEL; set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_edge_irq, "edge"); + } } static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq, diff --git a/trunk/kernel/irq/chip.c b/trunk/kernel/irq/chip.c index 615ce97c6cfd..f1a73f0b54e7 100644 --- a/trunk/kernel/irq/chip.c +++ b/trunk/kernel/irq/chip.c @@ -352,13 +352,10 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) * keep it masked and get out of here */ action = desc->action; - if (unlikely(!action || (desc->status & IRQ_DISABLED))) { - desc->status |= IRQ_PENDING; + if (unlikely(!action || (desc->status & IRQ_DISABLED))) goto out_unlock; - } desc->status |= IRQ_INPROGRESS; - desc->status &= ~IRQ_PENDING; spin_unlock(&desc->lock); action_ret = handle_IRQ_event(irq, action); diff --git a/trunk/kernel/irq/resend.c b/trunk/kernel/irq/resend.c index 5bfeaed7e487..a8046791ba2d 100644 --- a/trunk/kernel/irq/resend.c +++ b/trunk/kernel/irq/resend.c @@ -62,7 +62,12 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq) */ desc->chip->enable(irq); - if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { + /* + * We do not resend level type interrupts. Level type + * interrupts are resent by hardware when they are still + * active. + */ + if ((status & (IRQ_LEVEL | IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { desc->status = (status & ~IRQ_PENDING) | IRQ_REPLAY; if (!desc->chip || !desc->chip->retrigger ||