diff options
Diffstat (limited to 'arch/mips')
| -rw-r--r-- | arch/mips/alchemy/common/irq.c | 50 |
1 files changed, 22 insertions, 28 deletions
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index 422ecc632c23..ceb98b2f96c3 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c | |||
| @@ -39,11 +39,18 @@ | |||
| 39 | 39 | ||
| 40 | static int au1x_ic_settype(unsigned int irq, unsigned int flow_type); | 40 | static int au1x_ic_settype(unsigned int irq, unsigned int flow_type); |
| 41 | 41 | ||
| 42 | /* NOTE on interrupt priorities: The original writers of this code said: | ||
| 43 | * | ||
| 44 | * Because of the tight timing of SETUP token to reply transactions, | ||
| 45 | * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT) | ||
| 46 | * needs the highest priority. | ||
| 47 | */ | ||
| 48 | |||
| 42 | /* per-processor fixed function irqs */ | 49 | /* per-processor fixed function irqs */ |
| 43 | struct au1xxx_irqmap { | 50 | struct au1xxx_irqmap { |
| 44 | int im_irq; | 51 | int im_irq; |
| 45 | int im_type; | 52 | int im_type; |
| 46 | int im_request; | 53 | int im_request; /* set 1 to get higher priority */ |
| 47 | } au1xxx_ic0_map[] __initdata = { | 54 | } au1xxx_ic0_map[] __initdata = { |
| 48 | #if defined(CONFIG_SOC_AU1000) | 55 | #if defined(CONFIG_SOC_AU1000) |
| 49 | { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 56 | { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
| @@ -63,14 +70,14 @@ struct au1xxx_irqmap { | |||
| 63 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 70 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 64 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 71 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 65 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 72 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 66 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | 73 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 67 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 74 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 68 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 75 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 69 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 76 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 70 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 77 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 71 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 78 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
| 72 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 79 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
| 73 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 80 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, |
| 74 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 81 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 75 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | 82 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
| 76 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 83 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| @@ -97,12 +104,12 @@ struct au1xxx_irqmap { | |||
| 97 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 104 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 98 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 105 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 99 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 106 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 100 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | 107 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 101 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 108 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 102 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 109 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 103 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 110 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 104 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 111 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 105 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 112 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, |
| 106 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 113 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 107 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | 114 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
| 108 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 115 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| @@ -129,14 +136,14 @@ struct au1xxx_irqmap { | |||
| 129 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 136 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 130 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 137 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 131 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 138 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 132 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | 139 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 133 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 140 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 134 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 141 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 135 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 142 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 136 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 143 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 137 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 144 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
| 138 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 145 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
| 139 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 146 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, |
| 140 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 147 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 141 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | 148 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
| 142 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 149 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| @@ -163,13 +170,13 @@ struct au1xxx_irqmap { | |||
| 163 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 170 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 164 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 171 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 165 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 172 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 166 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | 173 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 167 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 174 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 168 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 175 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 169 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 176 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 170 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 177 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 171 | { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 178 | { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 172 | { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 179 | { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, |
| 173 | { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 180 | { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 174 | { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | 181 | { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
| 175 | { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 182 | { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
| @@ -191,7 +198,7 @@ struct au1xxx_irqmap { | |||
| 191 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 198 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 192 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 199 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 193 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 200 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 194 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | 201 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 195 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 202 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 196 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 203 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| 197 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 204 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
| @@ -507,7 +514,7 @@ static int au1x_ic_settype(unsigned int irq, unsigned int flow_type) | |||
| 507 | asmlinkage void plat_irq_dispatch(void) | 514 | asmlinkage void plat_irq_dispatch(void) |
| 508 | { | 515 | { |
| 509 | unsigned int pending = read_c0_status() & read_c0_cause(); | 516 | unsigned int pending = read_c0_status() & read_c0_cause(); |
| 510 | unsigned long s, off, bit; | 517 | unsigned long s, off; |
| 511 | 518 | ||
| 512 | if (pending & CAUSEF_IP7) { | 519 | if (pending & CAUSEF_IP7) { |
| 513 | do_IRQ(MIPS_CPU_IRQ_BASE + 7); | 520 | do_IRQ(MIPS_CPU_IRQ_BASE + 7); |
| @@ -527,25 +534,12 @@ asmlinkage void plat_irq_dispatch(void) | |||
| 527 | } else | 534 | } else |
| 528 | goto spurious; | 535 | goto spurious; |
| 529 | 536 | ||
| 530 | bit = 0; | ||
| 531 | s = au_readl(s); | 537 | s = au_readl(s); |
| 532 | if (unlikely(!s)) { | 538 | if (unlikely(!s)) { |
| 533 | spurious: | 539 | spurious: |
| 534 | spurious_interrupt(); | 540 | spurious_interrupt(); |
| 535 | return; | 541 | return; |
| 536 | } | 542 | } |
| 537 | #ifdef AU1000_USB_DEV_REQ_INT | ||
| 538 | /* | ||
| 539 | * Because of the tight timing of SETUP token to reply | ||
| 540 | * transactions, the USB devices-side packet complete | ||
| 541 | * interrupt needs the highest priority. | ||
| 542 | */ | ||
| 543 | bit = 1 << (AU1000_USB_DEV_REQ_INT - AU1000_INTC0_INT_BASE); | ||
| 544 | if ((pending & CAUSEF_IP2) && (s & bit)) { | ||
| 545 | do_IRQ(AU1000_USB_DEV_REQ_INT); | ||
| 546 | return; | ||
| 547 | } | ||
| 548 | #endif | ||
| 549 | do_IRQ(__ffs(s) + off); | 543 | do_IRQ(__ffs(s) + off); |
| 550 | } | 544 | } |
| 551 | 545 | ||
| @@ -566,11 +560,11 @@ static void __init setup_irqmap(struct au1xxx_irqmap *map, int count) | |||
| 566 | if (irq_nr >= AU1000_INTC1_INT_BASE) { | 560 | if (irq_nr >= AU1000_INTC1_INT_BASE) { |
| 567 | bit = irq_nr - AU1000_INTC1_INT_BASE; | 561 | bit = irq_nr - AU1000_INTC1_INT_BASE; |
| 568 | if (map[count].im_request) | 562 | if (map[count].im_request) |
| 569 | au_writel(1 << bit, IC1_ASSIGNCLR); | 563 | au_writel(1 << bit, IC1_ASSIGNSET); |
| 570 | } else { | 564 | } else { |
| 571 | bit = irq_nr - AU1000_INTC0_INT_BASE; | 565 | bit = irq_nr - AU1000_INTC0_INT_BASE; |
| 572 | if (map[count].im_request) | 566 | if (map[count].im_request) |
| 573 | au_writel(1 << bit, IC0_ASSIGNCLR); | 567 | au_writel(1 << bit, IC0_ASSIGNSET); |
| 574 | } | 568 | } |
| 575 | 569 | ||
| 576 | au1x_ic_settype(irq_nr, map[count].im_type); | 570 | au1x_ic_settype(irq_nr, map[count].im_type); |
| @@ -588,7 +582,7 @@ void __init arch_init_irq(void) | |||
| 588 | au_writel(0xffffffff, IC0_CFG1CLR); | 582 | au_writel(0xffffffff, IC0_CFG1CLR); |
| 589 | au_writel(0xffffffff, IC0_CFG2CLR); | 583 | au_writel(0xffffffff, IC0_CFG2CLR); |
| 590 | au_writel(0xffffffff, IC0_MASKCLR); | 584 | au_writel(0xffffffff, IC0_MASKCLR); |
| 591 | au_writel(0xffffffff, IC0_ASSIGNSET); | 585 | au_writel(0xffffffff, IC0_ASSIGNCLR); |
| 592 | au_writel(0xffffffff, IC0_WAKECLR); | 586 | au_writel(0xffffffff, IC0_WAKECLR); |
| 593 | au_writel(0xffffffff, IC0_SRCSET); | 587 | au_writel(0xffffffff, IC0_SRCSET); |
| 594 | au_writel(0xffffffff, IC0_FALLINGCLR); | 588 | au_writel(0xffffffff, IC0_FALLINGCLR); |
| @@ -599,7 +593,7 @@ void __init arch_init_irq(void) | |||
| 599 | au_writel(0xffffffff, IC1_CFG1CLR); | 593 | au_writel(0xffffffff, IC1_CFG1CLR); |
| 600 | au_writel(0xffffffff, IC1_CFG2CLR); | 594 | au_writel(0xffffffff, IC1_CFG2CLR); |
| 601 | au_writel(0xffffffff, IC1_MASKCLR); | 595 | au_writel(0xffffffff, IC1_MASKCLR); |
| 602 | au_writel(0xffffffff, IC1_ASSIGNSET); | 596 | au_writel(0xffffffff, IC1_ASSIGNCLR); |
| 603 | au_writel(0xffffffff, IC1_WAKECLR); | 597 | au_writel(0xffffffff, IC1_WAKECLR); |
| 604 | au_writel(0xffffffff, IC1_SRCSET); | 598 | au_writel(0xffffffff, IC1_SRCSET); |
| 605 | au_writel(0xffffffff, IC1_FALLINGCLR); | 599 | au_writel(0xffffffff, IC1_FALLINGCLR); |
