Messages in this thread Patch in this message | | | Date | Mon, 24 Apr 2006 14:22:43 -0700 | From | Stephen Hemminger <> | Subject | [RFC 1/2] irq: record edge-level setting |
| |
Record the level vs edge-triggered status of IRQ to allow for error checks later.
Note: this is only done fir i386/x86_64.
--- irq.orig/arch/i386/kernel/i8259.c +++ irq/arch/i386/kernel/i8259.c @@ -128,11 +128,22 @@ int i8259A_irq_pending(unsigned int irq) return ret; } +static int i8259A_trigger(unsigned int irq) +{ + if (irq & 8) + return inb(0x4d1) & (1<< (irq-8)); + else + return inb(0x4d0) & (1<<irq); +} + + void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<<irq); irq_desc[irq].handler = &i8259A_irq_type; + if (i8259A_trigger(irq)) + irq_desc[irq].status |= IRQ_LEVEL; enable_irq(irq); } --- irq.orig/arch/i386/kernel/io_apic.c +++ irq/arch/i386/kernel/io_apic.c @@ -1186,17 +1186,23 @@ static inline void ioapic_register_intr( { if (use_pci_vector() && !platform_legacy_irq(irq)) { if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) + trigger == IOAPIC_LEVEL) { irq_desc[vector].handler = &ioapic_level_type; - else + irq_desc[vector].status |= IRQ_LEVEL; + } else { irq_desc[vector].handler = &ioapic_edge_type; + irq_desc[vector].status &= ~IRQ_LEVEL; + } set_intr_gate(vector, interrupt[vector]); } else { if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) + trigger == IOAPIC_LEVEL) { irq_desc[irq].handler = &ioapic_level_type; - else + irq_desc[irq].status |= IRQ_LEVEL; + } else { irq_desc[irq].handler = &ioapic_edge_type; + irq_desc[irq].status &= ~IRQ_LEVEL; + } set_intr_gate(vector, interrupt[irq]); } } --- irq.orig/arch/x86_64/kernel/i8259.c +++ irq/arch/x86_64/kernel/i8259.c @@ -231,11 +231,22 @@ int i8259A_irq_pending(unsigned int irq) return ret; } +static int i8259A_trigger(unsigned int irq) +{ + if (irq & 8) + return inb(0x4d1) & (1<< (irq-8)); + else + return inb(0x4d0) & (1<<irq); +} + + void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<<irq); irq_desc[irq].handler = &i8259A_irq_type; + if (i8259A_trigger(irq)) + irq_desc[irq].status |= IRQ_LEVEL; enable_irq(irq); } --- irq.orig/arch/x86_64/kernel/io_apic.c +++ irq/arch/x86_64/kernel/io_apic.c @@ -848,17 +848,23 @@ static inline void ioapic_register_intr( { if (use_pci_vector() && !platform_legacy_irq(irq)) { if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) + trigger == IOAPIC_LEVEL) { irq_desc[vector].handler = &ioapic_level_type; - else + irq_desc[vector].status |= IRQ_LEVEL; + } else { irq_desc[vector].handler = &ioapic_edge_type; + irq_desc[vector].status &= ~IRQ_LEVEL; + } set_intr_gate(vector, interrupt[vector]); } else { if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) + trigger == IOAPIC_LEVEL) { irq_desc[irq].handler = &ioapic_level_type; - else + irq_desc[irq].status |= IRQ_LEVEL; + } else { irq_desc[irq].handler = &ioapic_edge_type; + irq_desc[irq].status &= ~IRQ_LEVEL; + } set_intr_gate(vector, interrupt[irq]); } } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |