Merge branch 'docs-move' of git://git.kernel.org/pub/scm/linux/kernel/git/rdunlap...
[pandora-kernel.git] / arch / blackfin / mach-common / ints-priority.c
index 43d9fb1..1177369 100644 (file)
 #ifdef CONFIG_IPIPE
 #include <linux/ipipe.h>
 #endif
-#ifdef CONFIG_KGDB
-#include <linux/kgdb.h>
-#endif
 #include <asm/traps.h>
 #include <asm/blackfin.h>
 #include <asm/gpio.h>
 #include <asm/irq_handler.h>
 #include <asm/dpmc.h>
-#include <asm/bfin5xx_spi.h>
-#include <asm/bfin_sport.h>
-#include <asm/bfin_can.h>
 
 #define SIC_SYSIRQ(irq)        (irq - (IRQ_CORETMR + 1))
 
-#ifdef BF537_FAMILY
-# define BF537_GENERIC_ERROR_INT_DEMUX
-# define SPI_ERR_MASK   (BIT_STAT_TXCOL | BIT_STAT_RBSY | BIT_STAT_MODF | BIT_STAT_TXE)        /* SPI_STAT */
-# define SPORT_ERR_MASK (ROVF | RUVF | TOVF | TUVF)    /* SPORT_STAT */
-# define PPI_ERR_MASK   (0xFFFF & ~FLD)        /* PPI_STATUS */
-# define EMAC_ERR_MASK  (PHYINT | MMCINT | RXFSINT | TXFSINT | WAKEDET | RXDMAERR | TXDMAERR | STMDONE)        /* EMAC_SYSTAT */
-# define UART_ERR_MASK  (0x6)  /* UART_IIR */
-# define CAN_ERR_MASK   (EWTIF | EWRIF | EPIF | BOIF | WUIF | UIAIF | AAIF | RMLIF | UCEIF | EXTIF | ADIF)     /* CAN_GIF */
-#else
-# undef BF537_GENERIC_ERROR_INT_DEMUX
-#endif
-
 /*
  * NOTES:
  * - we have separated the physical Hardware interrupt from the
@@ -63,22 +45,19 @@ unsigned long bfin_irq_flags = 0x1f;
 EXPORT_SYMBOL(bfin_irq_flags);
 #endif
 
-/* The number of spurious interrupts */
-atomic_t num_spurious;
-
 #ifdef CONFIG_PM
 unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */
 unsigned vr_wakeup;
 #endif
 
-struct ivgx {
+static struct ivgx {
        /* irq number for request_irq, available in mach-bf5xx/irq.h */
        unsigned int irqno;
        /* corresponding bit in the SIC_ISR register */
        unsigned int isrflag;
 } ivg_table[NR_PERI_INTS];
 
-struct ivg_slice {
+static struct ivg_slice {
        /* position of first irq in ivg_table for given ivg */
        struct ivgx *ifirst;
        struct ivgx *istop;
@@ -125,7 +104,7 @@ static void __init search_IAR(void)
  * This is for core internal IRQs
  */
 
-static void bfin_ack_noop(struct irq_data *d)
+void bfin_ack_noop(struct irq_data *d)
 {
        /* Dummy function.  */
 }
@@ -154,26 +133,24 @@ static void bfin_core_unmask_irq(struct irq_data *d)
        return;
 }
 
-static void bfin_internal_mask_irq(unsigned int irq)
+void bfin_internal_mask_irq(unsigned int irq)
 {
-       unsigned long flags;
+       unsigned long flags = hard_local_irq_save();
 
-#ifdef CONFIG_BF53x
-       flags = hard_local_irq_save();
-       bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
-                            ~(1 << SIC_SYSIRQ(irq)));
-#else
-       unsigned mask_bank, mask_bit;
-       flags = hard_local_irq_save();
-       mask_bank = SIC_SYSIRQ(irq) / 32;
-       mask_bit = SIC_SYSIRQ(irq) % 32;
+#ifdef SIC_IMASK0
+       unsigned mask_bank = SIC_SYSIRQ(irq) / 32;
+       unsigned mask_bit = SIC_SYSIRQ(irq) % 32;
        bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
                             ~(1 << mask_bit));
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
        bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) &
                             ~(1 << mask_bit));
+# endif
+#else
+       bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
+                            ~(1 << SIC_SYSIRQ(irq)));
 #endif
-#endif
+
        hard_local_irq_restore(flags);
 }
 
@@ -186,33 +163,31 @@ static void bfin_internal_mask_irq_chip(struct irq_data *d)
 static void bfin_internal_unmask_irq_affinity(unsigned int irq,
                const struct cpumask *affinity)
 #else
-static void bfin_internal_unmask_irq(unsigned int irq)
+void bfin_internal_unmask_irq(unsigned int irq)
 #endif
 {
-       unsigned long flags;
+       unsigned long flags = hard_local_irq_save();
 
-#ifdef CONFIG_BF53x
-       flags = hard_local_irq_save();
-       bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
-                            (1 << SIC_SYSIRQ(irq)));
-#else
-       unsigned mask_bank, mask_bit;
-       flags = hard_local_irq_save();
-       mask_bank = SIC_SYSIRQ(irq) / 32;
-       mask_bit = SIC_SYSIRQ(irq) % 32;
-#ifdef CONFIG_SMP
+#ifdef SIC_IMASK0
+       unsigned mask_bank = SIC_SYSIRQ(irq) / 32;
+       unsigned mask_bit = SIC_SYSIRQ(irq) % 32;
+# ifdef CONFIG_SMP
        if (cpumask_test_cpu(0, affinity))
-#endif
+# endif
                bfin_write_SIC_IMASK(mask_bank,
                        bfin_read_SIC_IMASK(mask_bank) |
                        (1 << mask_bit));
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
        if (cpumask_test_cpu(1, affinity))
                bfin_write_SICB_IMASK(mask_bank,
                        bfin_read_SICB_IMASK(mask_bank) |
                        (1 << mask_bit));
+# endif
+#else
+       bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
+                            (1 << SIC_SYSIRQ(irq)));
 #endif
-#endif
+
        hard_local_irq_restore(flags);
 }
 
@@ -295,6 +270,8 @@ static int bfin_internal_set_wake_chip(struct irq_data *d, unsigned int state)
 {
        return bfin_internal_set_wake(d->irq, state);
 }
+#else
+# define bfin_internal_set_wake_chip NULL
 #endif
 
 static struct irq_chip bfin_core_irqchip = {
@@ -315,12 +292,10 @@ static struct irq_chip bfin_internal_irqchip = {
 #ifdef CONFIG_SMP
        .irq_set_affinity = bfin_internal_set_affinity,
 #endif
-#ifdef CONFIG_PM
        .irq_set_wake = bfin_internal_set_wake_chip,
-#endif
 };
 
-static void bfin_handle_irq(unsigned irq)
+void bfin_handle_irq(unsigned irq)
 {
 #ifdef CONFIG_IPIPE
        struct pt_regs regs;    /* Contents not used. */
@@ -332,102 +307,6 @@ static void bfin_handle_irq(unsigned irq)
 #endif  /* !CONFIG_IPIPE */
 }
 
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
-static int error_int_mask;
-
-static void bfin_generic_error_mask_irq(struct irq_data *d)
-{
-       error_int_mask &= ~(1L << (d->irq - IRQ_PPI_ERROR));
-       if (!error_int_mask)
-               bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
-}
-
-static void bfin_generic_error_unmask_irq(struct irq_data *d)
-{
-       bfin_internal_unmask_irq(IRQ_GENERIC_ERROR);
-       error_int_mask |= 1L << (d->irq - IRQ_PPI_ERROR);
-}
-
-static struct irq_chip bfin_generic_error_irqchip = {
-       .name = "ERROR",
-       .irq_ack = bfin_ack_noop,
-       .irq_mask_ack = bfin_generic_error_mask_irq,
-       .irq_mask = bfin_generic_error_mask_irq,
-       .irq_unmask = bfin_generic_error_unmask_irq,
-};
-
-static void bfin_demux_error_irq(unsigned int int_err_irq,
-                                struct irq_desc *inta_desc)
-{
-       int irq = 0;
-
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
-       if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK)
-               irq = IRQ_MAC_ERROR;
-       else
-#endif
-       if (bfin_read_SPORT0_STAT() & SPORT_ERR_MASK)
-               irq = IRQ_SPORT0_ERROR;
-       else if (bfin_read_SPORT1_STAT() & SPORT_ERR_MASK)
-               irq = IRQ_SPORT1_ERROR;
-       else if (bfin_read_PPI_STATUS() & PPI_ERR_MASK)
-               irq = IRQ_PPI_ERROR;
-       else if (bfin_read_CAN_GIF() & CAN_ERR_MASK)
-               irq = IRQ_CAN_ERROR;
-       else if (bfin_read_SPI_STAT() & SPI_ERR_MASK)
-               irq = IRQ_SPI_ERROR;
-       else if ((bfin_read_UART0_IIR() & UART_ERR_MASK) == UART_ERR_MASK)
-               irq = IRQ_UART0_ERROR;
-       else if ((bfin_read_UART1_IIR() & UART_ERR_MASK) == UART_ERR_MASK)
-               irq = IRQ_UART1_ERROR;
-
-       if (irq) {
-               if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR)))
-                       bfin_handle_irq(irq);
-               else {
-
-                       switch (irq) {
-                       case IRQ_PPI_ERROR:
-                               bfin_write_PPI_STATUS(PPI_ERR_MASK);
-                               break;
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
-                       case IRQ_MAC_ERROR:
-                               bfin_write_EMAC_SYSTAT(EMAC_ERR_MASK);
-                               break;
-#endif
-                       case IRQ_SPORT0_ERROR:
-                               bfin_write_SPORT0_STAT(SPORT_ERR_MASK);
-                               break;
-
-                       case IRQ_SPORT1_ERROR:
-                               bfin_write_SPORT1_STAT(SPORT_ERR_MASK);
-                               break;
-
-                       case IRQ_CAN_ERROR:
-                               bfin_write_CAN_GIS(CAN_ERR_MASK);
-                               break;
-
-                       case IRQ_SPI_ERROR:
-                               bfin_write_SPI_STAT(SPI_ERR_MASK);
-                               break;
-
-                       default:
-                               break;
-                       }
-
-                       pr_debug("IRQ %d:"
-                                " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
-                                irq);
-               }
-       } else
-               printk(KERN_ERR
-                      "%s : %s : LINE %d :\nIRQ ?: PERIPHERAL ERROR"
-                      " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
-                      __func__, __FILE__, __LINE__);
-
-}
-#endif                         /* BF537_GENERIC_ERROR_INT_DEMUX */
-
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static int mac_stat_int_mask;
 
@@ -468,7 +347,7 @@ static void bfin_mac_status_mask_irq(struct irq_data *d)
        unsigned int irq = d->irq;
 
        mac_stat_int_mask &= ~(1L << (irq - IRQ_MAC_PHYINT));
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+#ifdef BF537_FAMILY
        switch (irq) {
        case IRQ_MAC_PHYINT:
                bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() & ~PHYIE);
@@ -487,7 +366,7 @@ static void bfin_mac_status_unmask_irq(struct irq_data *d)
 {
        unsigned int irq = d->irq;
 
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+#ifdef BF537_FAMILY
        switch (irq) {
        case IRQ_MAC_PHYINT:
                bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() | PHYIE);
@@ -505,12 +384,14 @@ static void bfin_mac_status_unmask_irq(struct irq_data *d)
 #ifdef CONFIG_PM
 int bfin_mac_status_set_wake(struct irq_data *d, unsigned int state)
 {
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+#ifdef BF537_FAMILY
        return bfin_internal_set_wake(IRQ_GENERIC_ERROR, state);
 #else
        return bfin_internal_set_wake(IRQ_MAC_ERROR, state);
 #endif
 }
+#else
+# define bfin_mac_status_set_wake NULL
 #endif
 
 static struct irq_chip bfin_mac_status_irqchip = {
@@ -519,13 +400,11 @@ static struct irq_chip bfin_mac_status_irqchip = {
        .irq_mask_ack = bfin_mac_status_mask_irq,
        .irq_mask = bfin_mac_status_mask_irq,
        .irq_unmask = bfin_mac_status_unmask_irq,
-#ifdef CONFIG_PM
        .irq_set_wake = bfin_mac_status_set_wake,
-#endif
 };
 
-static void bfin_demux_mac_status_irq(unsigned int int_err_irq,
-                                struct irq_desc *inta_desc)
+void bfin_demux_mac_status_irq(unsigned int int_err_irq,
+                              struct irq_desc *inta_desc)
 {
        int i, irq = 0;
        u32 status = bfin_read_EMAC_SYSTAT();
@@ -680,29 +559,48 @@ static int bfin_gpio_irq_type(struct irq_data *d, unsigned int type)
 }
 
 #ifdef CONFIG_PM
-int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
+static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
 {
        return gpio_pm_wakeup_ctrl(irq_to_gpio(d->irq), state);
 }
+#else
+# define bfin_gpio_set_wake NULL
 #endif
 
-static void bfin_demux_gpio_irq(unsigned int inta_irq,
-                               struct irq_desc *desc)
+static void bfin_demux_gpio_block(unsigned int irq)
 {
-       unsigned int i, gpio, mask, irq, search = 0;
+       unsigned int gpio, mask;
+
+       gpio = irq_to_gpio(irq);
+       mask = get_gpiop_data(gpio) & get_gpiop_maska(gpio);
+
+       while (mask) {
+               if (mask & 1)
+                       bfin_handle_irq(irq);
+               irq++;
+               mask >>= 1;
+       }
+}
+
+void bfin_demux_gpio_irq(unsigned int inta_irq,
+                        struct irq_desc *desc)
+{
+       unsigned int irq;
 
        switch (inta_irq) {
-#if defined(CONFIG_BF53x)
-       case IRQ_PROG_INTA:
-               irq = IRQ_PF0;
-               search = 1;
+#if defined(BF537_FAMILY)
+       case IRQ_PF_INTA_PG_INTA:
+               bfin_demux_gpio_block(IRQ_PF0);
+               irq = IRQ_PG0;
                break;
-# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
-       case IRQ_MAC_RX:
+       case IRQ_PH_INTA_MAC_RX:
                irq = IRQ_PH0;
                break;
-# endif
-#elif defined(CONFIG_BF538) || defined(CONFIG_BF539)
+#elif defined(BF533_FAMILY)
+       case IRQ_PROG_INTA:
+               irq = IRQ_PF0;
+               break;
+#elif defined(BF538_FAMILY)
        case IRQ_PORTF_INTA:
                irq = IRQ_PF0;
                break;
@@ -732,31 +630,7 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq,
                return;
        }
 
-       if (search) {
-               for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
-                       irq += i;
-
-                       mask = get_gpiop_data(i) & get_gpiop_maska(i);
-
-                       while (mask) {
-                               if (mask & 1)
-                                       bfin_handle_irq(irq);
-                               irq++;
-                               mask >>= 1;
-                       }
-               }
-       } else {
-                       gpio = irq_to_gpio(irq);
-                       mask = get_gpiop_data(gpio) & get_gpiop_maska(gpio);
-
-                       do {
-                               if (mask & 1)
-                                       bfin_handle_irq(irq);
-                               irq++;
-                               mask >>= 1;
-                       } while (mask);
-       }
-
+       bfin_demux_gpio_block(irq);
 }
 
 #else                          /* CONFIG_BF54x */
@@ -974,15 +848,11 @@ static int bfin_gpio_irq_type(struct irq_data *d, unsigned int type)
 }
 
 #ifdef CONFIG_PM
-u32 pint_saved_masks[NR_PINT_SYS_IRQS];
-u32 pint_wakeup_masks[NR_PINT_SYS_IRQS];
-
-int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
+static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
 {
        u32 pint_irq;
        u32 pint_val = irq2pint_lut[d->irq - SYS_IRQS];
        u32 bank = PINT_2_BANK(pint_val);
-       u32 pintbit = PINT_BIT(pint_val);
 
        switch (bank) {
        case 0:
@@ -1003,46 +873,14 @@ int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
 
        bfin_internal_set_wake(pint_irq, state);
 
-       if (state)
-               pint_wakeup_masks[bank] |= pintbit;
-       else
-               pint_wakeup_masks[bank] &= ~pintbit;
-
        return 0;
 }
-
-u32 bfin_pm_setup(void)
-{
-       u32 val, i;
-
-       for (i = 0; i < NR_PINT_SYS_IRQS; i++) {
-               val = pint[i]->mask_clear;
-               pint_saved_masks[i] = val;
-               if (val ^ pint_wakeup_masks[i]) {
-                       pint[i]->mask_clear = val;
-                       pint[i]->mask_set = pint_wakeup_masks[i];
-               }
-       }
-
-       return 0;
-}
-
-void bfin_pm_restore(void)
-{
-       u32 i, val;
-
-       for (i = 0; i < NR_PINT_SYS_IRQS; i++) {
-               val = pint_saved_masks[i];
-               if (val ^ pint_wakeup_masks[i]) {
-                       pint[i]->mask_clear = pint[i]->mask_clear;
-                       pint[i]->mask_set = val;
-               }
-       }
-}
+#else
+# define bfin_gpio_set_wake NULL
 #endif
 
-static void bfin_demux_gpio_irq(unsigned int inta_irq,
-                               struct irq_desc *desc)
+void bfin_demux_gpio_irq(unsigned int inta_irq,
+                        struct irq_desc *desc)
 {
        u32 bank, pint_val;
        u32 request, irq;
@@ -1091,9 +929,7 @@ static struct irq_chip bfin_gpio_irqchip = {
        .irq_set_type = bfin_gpio_irq_type,
        .irq_startup = bfin_gpio_irq_startup,
        .irq_shutdown = bfin_gpio_irq_shutdown,
-#ifdef CONFIG_PM
        .irq_set_wake = bfin_gpio_set_wake,
-#endif
 };
 
 void __cpuinit init_exception_vectors(void)
@@ -1127,12 +963,12 @@ int __init init_arch_irq(void)
 {
        int irq;
        unsigned long ilat = 0;
+
        /*  Disable all the peripheral intrs  - page 4-29 HW Ref manual */
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) \
-       || defined(BF538_FAMILY) || defined(CONFIG_BF51x)
+#ifdef SIC_IMASK0
        bfin_write_SIC_IMASK0(SIC_UNMASK_ALL);
        bfin_write_SIC_IMASK1(SIC_UNMASK_ALL);
-# ifdef CONFIG_BF54x
+# ifdef SIC_IMASK2
        bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
 # endif
 # ifdef CONFIG_SMP
@@ -1145,11 +981,6 @@ int __init init_arch_irq(void)
 
        local_irq_disable();
 
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
-       /* Clear EMAC Interrupt Status bits so we can demux it later */
-       bfin_write_EMAC_SYSTAT(-1);
-#endif
-
 #ifdef CONFIG_BF54x
 # ifdef CONFIG_PINTx_REASSIGN
        pint[0]->assign = CONFIG_PINT0_ASSIGN;
@@ -1168,11 +999,11 @@ int __init init_arch_irq(void)
                        irq_set_chip(irq, &bfin_internal_irqchip);
 
                switch (irq) {
-#if defined(CONFIG_BF53x)
+#if defined(BF537_FAMILY)
+               case IRQ_PH_INTA_MAC_RX:
+               case IRQ_PF_INTA_PG_INTA:
+#elif defined(BF533_FAMILY)
                case IRQ_PROG_INTA:
-# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
-               case IRQ_MAC_RX:
-# endif
 #elif defined(CONFIG_BF54x)
                case IRQ_PINT0:
                case IRQ_PINT1:
@@ -1186,16 +1017,11 @@ int __init init_arch_irq(void)
                case IRQ_PROG0_INTA:
                case IRQ_PROG1_INTA:
                case IRQ_PROG2_INTA:
-#elif defined(CONFIG_BF538) || defined(CONFIG_BF539)
+#elif defined(BF538_FAMILY)
                case IRQ_PORTF_INTA:
 #endif
                        irq_set_chained_handler(irq, bfin_demux_gpio_irq);
                        break;
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
-               case IRQ_GENERIC_ERROR:
-                       irq_set_chained_handler(irq, bfin_demux_error_irq);
-                       break;
-#endif
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
                case IRQ_MAC_ERROR:
                        irq_set_chained_handler(irq,
@@ -1213,11 +1039,10 @@ int __init init_arch_irq(void)
                case IRQ_CORETMR:
 # ifdef CONFIG_SMP
                        irq_set_handler(irq, handle_percpu_irq);
-                       break;
 # else
                        irq_set_handler(irq, handle_simple_irq);
-                       break;
 # endif
+                       break;
 #endif
 
 #ifdef CONFIG_TICKSOURCE_GPTMR0
@@ -1226,26 +1051,17 @@ int __init init_arch_irq(void)
                        break;
 #endif
 
-#ifdef CONFIG_IPIPE
                default:
+#ifdef CONFIG_IPIPE
                        irq_set_handler(irq, handle_level_irq);
-                       break;
-#else /* !CONFIG_IPIPE */
-               default:
+#else
                        irq_set_handler(irq, handle_simple_irq);
+#endif
                        break;
-#endif /* !CONFIG_IPIPE */
                }
        }
 
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
-       for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
-               irq_set_chip_and_handler(irq, &bfin_generic_error_irqchip,
-                                        handle_level_irq);
-#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
-       irq_set_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq);
-#endif
-#endif
+       init_mach_irq();
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
        for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++)
@@ -1307,53 +1123,54 @@ int __init init_arch_irq(void)
 #ifdef CONFIG_DO_IRQ_L1
 __attribute__((l1_text))
 #endif
-void do_irq(int vec, struct pt_regs *fp)
+static int vec_to_irq(int vec)
 {
-       if (vec == EVT_IVTMR_P) {
-               vec = IRQ_CORETMR;
-       } else {
-               struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
-               struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
-#if defined(SIC_ISR0)
-               unsigned long sic_status[3];
+       struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
+       struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
+       unsigned long sic_status[3];
+
+       if (likely(vec == EVT_IVTMR_P))
+               return IRQ_CORETMR;
 
-               if (smp_processor_id()) {
+#ifdef SIC_ISR
+       sic_status[0] = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
+#else
+       if (smp_processor_id()) {
 # ifdef SICB_ISR0
-                       /* This will be optimized out in UP mode. */
-                       sic_status[0] = bfin_read_SICB_ISR0() & bfin_read_SICB_IMASK0();
-                       sic_status[1] = bfin_read_SICB_ISR1() & bfin_read_SICB_IMASK1();
-# endif
-               } else {
-                       sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
-                       sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
-               }
-# ifdef SIC_ISR2
-               sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2();
+               /* This will be optimized out in UP mode. */
+               sic_status[0] = bfin_read_SICB_ISR0() & bfin_read_SICB_IMASK0();
+               sic_status[1] = bfin_read_SICB_ISR1() & bfin_read_SICB_IMASK1();
 # endif
-               for (;; ivg++) {
-                       if (ivg >= ivg_stop) {
-                               atomic_inc(&num_spurious);
-                               return;
-                       }
-                       if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
-                               break;
-               }
-#else
-               unsigned long sic_status;
-
-               sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
+       } else {
+               sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
+               sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
+       }
+#endif
+#ifdef SIC_ISR2
+       sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2();
+#endif
 
-               for (;; ivg++) {
-                       if (ivg >= ivg_stop) {
-                               atomic_inc(&num_spurious);
-                               return;
-                       } else if (sic_status & ivg->isrflag)
-                               break;
-               }
+       for (;; ivg++) {
+               if (ivg >= ivg_stop)
+                       return -1;
+#ifdef SIC_ISR
+               if (sic_status[0] & ivg->isrflag)
+#else
+               if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
 #endif
-               vec = ivg->irqno;
+                       return ivg->irqno;
        }
-       asm_do_IRQ(vec, fp);
+}
+
+#ifdef CONFIG_DO_IRQ_L1
+__attribute__((l1_text))
+#endif
+void do_irq(int vec, struct pt_regs *fp)
+{
+       int irq = vec_to_irq(vec);
+       if (irq == -1)
+               return;
+       asm_do_IRQ(irq, fp);
 }
 
 #ifdef CONFIG_IPIPE
@@ -1391,40 +1208,9 @@ asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs)
        struct ivgx *ivg = ivg7_13[vec-IVG7].ifirst;
        int irq, s = 0;
 
-       if (likely(vec == EVT_IVTMR_P))
-               irq = IRQ_CORETMR;
-       else {
-#if defined(SIC_ISR0)
-               unsigned long sic_status[3];
-
-               sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
-               sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
-# ifdef SIC_ISR2
-               sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2();
-# endif
-               for (;; ivg++) {
-                       if (ivg >= ivg_stop) {
-                               atomic_inc(&num_spurious);
-                               return 0;
-                       }
-                       if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
-                               break;
-               }
-#else
-               unsigned long sic_status;
-
-               sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
-
-               for (;; ivg++) {
-                       if (ivg >= ivg_stop) {
-                               atomic_inc(&num_spurious);
-                               return 0;
-                       } else if (sic_status & ivg->isrflag)
-                               break;
-               }
-#endif
-               irq = ivg->irqno;
-       }
+       irq = vec_to_irq(vec);
+       if (irq == -1)
+               return 0;
 
        if (irq == IRQ_SYSTMR) {
 #if !defined(CONFIG_GENERIC_CLOCKEVENTS) || defined(CONFIG_TICKSOURCE_GPTMR0)