patch-2.2.12 linux/arch/ppc/kernel/i8259.c
Next file: linux/arch/ppc/kernel/irq.c
Previous file: linux/arch/ppc/kernel/head.S
Back to the patch index
Back to the overall index
- Lines: 79
- Date:
Wed Aug 25 17:29:46 1999
- Orig file:
v2.2.11/linux/arch/ppc/kernel/i8259.c
- Orig date:
Tue May 11 08:24:32 1999
diff -u --recursive --new-file v2.2.11/linux/arch/ppc/kernel/i8259.c linux/arch/ppc/kernel/i8259.c
@@ -13,33 +13,32 @@
int i8259_irq(int cpu)
{
int irq;
+ unsigned char irr;
/*
* Perform an interrupt acknowledge cycle on controller 1
- */
- outb(0x0C, 0x20);
- irq = inb(0x20) & 7;
- if (irq == 2)
- {
- /*
+ */
+ irr = inb(0x20) & ~cached_21;
+ if (!irr) return -1;
+ irq = 0;
+ while ((irq < 7) && !(irr&0x01))
+ {
+ irq++;
+ irr >>= 1;
+ }
+ if (irq == 2)
+ {
+ /*
* Interrupt is cascaded so perform interrupt
* acknowledge on controller 2
*/
- outb(0x0C, 0xA0);
- irq = (inb(0xA0) & 7) + 8;
- }
- else if (irq==7)
- {
- /*
- * This may be a spurious interrupt
- *
- * Read the interrupt status register. If the most
- * significant bit is not set then there is no valid
- * interrupt
- */
- outb(0x0b, 0x20);
- if(~inb(0x20)&0x80)
- return -1;
+ irr = inb(0xA0) & ~cached_A1;
+ irq = 8;
+ while ((irq < 15) && !(irr&0x01))
+ {
+ irq++;
+ irr >>= 1;
+ }
}
return irq;
}
@@ -53,13 +52,13 @@
cached_A1 |= 1 << (irq_nr-8);
inb(0xA1); /* DUMMY */
outb(cached_A1,0xA1);
- outb(0x20,0xA0); /* Non-specific EOI */
- outb(0x20,0x20); /* Non-specific EOI to cascade */
+ outb(0x62,0x20); /* Specific EOI to cascade */
+ outb(0x60|(irq_nr-8),0xA0); /* Specific EOI */
} else {
cached_21 |= 1 << irq_nr;
inb(0x21); /* DUMMY */
outb(cached_21,0x21);
- outb(0x20,0x20); /* Non-specific EOI */
+ outb(0x60|irq_nr,0x20); /* Specific EOI */
}
}
@@ -82,7 +81,6 @@
static void i8259_unmask_irq(unsigned int irq_nr)
{
-
if ( irq_nr >= i8259_pic.irq_offset )
irq_nr -= i8259_pic.irq_offset;
if ( irq_nr < 8 )
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)