linux-mips
[Top] [All Lists]

[2.5 PATCH] O2 irq handling

To: Ralf Baechle <ralf@oss.sgi.com>
Subject: [2.5 PATCH] O2 irq handling
From: Vivien Chappelier <vivien.chappelier@enst-bretagne.fr>
Date: Sun, 14 Jul 2002 21:55:15 +0200 (CEST)
Cc: linux-mips@oss.sgi.com
Sender: owner-linux-mips@oss.sgi.com
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)


<Prev in Thread] Current Thread [Next in Thread>
  • [2.5 PATCH] O2 irq handling, Vivien Chappelier <=