Hi, Here is a patch for the SGI O2 that fixes a typo in the edge interrupt range checking and protects the irq handler from reentrancy. Vivien. ================================================================================ --- linux/arch/mips64/sgi-ip32/ip32-irq.c Thu Jan 3 21:24:55 2002 +++ linux.build/arch/mips64/sgi-ip32/ip32-irq.c Tue Jan 22 13:01:30 2002 @@ -199,9 +201,9 @@ unsigned long flags; /* Edge triggered interrupts must be cleared. */ - if ((irq <= CRIME_GBE0_IRQ && irq >= CRIME_GBE3_IRQ) - || (irq <= CRIME_RE_EMPTY_E_IRQ && irq >= CRIME_RE_IDLE_E_IRQ) - || (irq <= CRIME_SOFT0_IRQ && irq >= CRIME_SOFT2_IRQ)) { + if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ) + || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) + || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { save_and_cli(flags); crime_mask = crime_read_64(CRIME_HARD_INT); crime_mask &= ~(1 << (irq - 1)); @@ -473,9 +475,18 @@ /* CRIME 1.1 appears to deliver all interrupts to this one pin. */ void ip32_irq0(struct pt_regs *regs) { - u64 crime_int = crime_read_64 (CRIME_INT_STAT); + u64 crime_int; + u64 crime_mask; int irq = 0; - + unsigned long flags; + + save_and_cli (flags); + /* disable crime interrupts */ + crime_mask = crime_read_64(CRIME_INT_MASK); + crime_write_64(CRIME_INT_MASK, 0); + + crime_int = crime_read_64(CRIME_INT_STAT); + if (crime_int & CRIME_MACE_INT_MASK) { crime_int &= CRIME_MACE_INT_MASK; irq = ffs (crime_int); @@ -498,6 +510,10 @@ ip32_unknown_interrupt(regs); DBG("*irq %u*\n", irq); do_IRQ(irq, regs); + + /* enable crime interrupts */ + crime_write_64(CRIME_INT_MASK, crime_mask); + restore_flags (flags); } void ip32_irq1(struct pt_regs *regs)