diff options
author | Mike Frysinger <vapier@gentoo.org> | 2011-04-15 19:04:59 +0200 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2011-05-25 14:13:43 +0200 |
commit | 8c0541035007bd8bbacfc5d71c696cdf37696794 (patch) | |
tree | 3731d537dcb31b6decfc5493be6f4d5f3d055fb2 | |
parent | Blackfin: bf537: fix excessive gpio int demuxing (diff) | |
download | linux-8c0541035007bd8bbacfc5d71c696cdf37696794.tar.xz linux-8c0541035007bd8bbacfc5d71c696cdf37696794.zip |
Blackfin: bf537: demux port H mask A and emac rx ints
The BF537 SIC combines the gpio port H mask A interrupts with the
emac rx interrupt, so we need to demux this in software.
It also combines the gpio port H mask B and the emac tx interrupts,
and the watchdog and port F mask B interrupts, but since we don't
support mask B yet, just add the defines for now.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r-- | arch/blackfin/include/asm/irq_handler.h | 1 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 2 | ||||
-rw-r--r-- | arch/blackfin/mach-bf537/include/mach/irq.h | 33 | ||||
-rw-r--r-- | arch/blackfin/mach-bf537/ints-priority.c | 39 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 22 |
5 files changed, 77 insertions, 20 deletions
diff --git a/arch/blackfin/include/asm/irq_handler.h b/arch/blackfin/include/asm/irq_handler.h index 77341b3ad351..ee73f79aef10 100644 --- a/arch/blackfin/include/asm/irq_handler.h +++ b/arch/blackfin/include/asm/irq_handler.h @@ -60,5 +60,6 @@ extern void bfin_internal_unmask_irq(unsigned int irq); struct irq_desc; extern void bfin_demux_mac_status_irq(unsigned int, struct irq_desc *); +extern void bfin_demux_gpio_irq(unsigned int, struct irq_desc *); #endif diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 207bb6b11b5c..f9306bb5aede 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -535,7 +535,7 @@ static const unsigned int sic_iwr_irqs[] = { #if defined(BF533_FAMILY) IRQ_PROG_INTB #elif defined(BF537_FAMILY) - IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX + IRQ_PF_INTB_WATCH, IRQ_PORTG_INTB, IRQ_PH_INTB_MAC_TX #elif defined(BF538_FAMILY) IRQ_PORTF_INTB #elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x) diff --git a/arch/blackfin/mach-bf537/include/mach/irq.h b/arch/blackfin/mach-bf537/include/mach/irq.h index cc3132347414..b6ed8235bda4 100644 --- a/arch/blackfin/mach-bf537/include/mach/irq.h +++ b/arch/blackfin/mach-bf537/include/mach/irq.h @@ -28,8 +28,8 @@ #define IRQ_UART1_TX BFIN_IRQ(14) /* DMA11 Interrupt (UART1 TX) */ #define IRQ_CAN_RX BFIN_IRQ(15) /* CAN Receive Interrupt */ #define IRQ_CAN_TX BFIN_IRQ(16) /* CAN Transmit Interrupt */ -#define IRQ_MAC_RX BFIN_IRQ(17) /* DMA1 (Ethernet RX) Interrupt */ -#define IRQ_MAC_TX BFIN_IRQ(18) /* DMA2 (Ethernet TX) Interrupt */ +#define IRQ_PH_INTA_MAC_RX BFIN_IRQ(17) /* Port H Interrupt A & DMA1 Interrupt (Ethernet RX) */ +#define IRQ_PH_INTB_MAC_TX BFIN_IRQ(18) /* Port H Interrupt B & DMA2 Interrupt (Ethernet TX) */ #define IRQ_TIMER0 BFIN_IRQ(19) /* Timer 0 */ #define IRQ_TIMER1 BFIN_IRQ(20) /* Timer 1 */ #define IRQ_TIMER2 BFIN_IRQ(21) /* Timer 2 */ @@ -38,12 +38,11 @@ #define IRQ_TIMER5 BFIN_IRQ(24) /* Timer 5 */ #define IRQ_TIMER6 BFIN_IRQ(25) /* Timer 6 */ #define IRQ_TIMER7 BFIN_IRQ(26) /* Timer 7 */ -#define IRQ_PROG_INTA BFIN_IRQ(27) /* PF Ports F&G (PF15:0) Interrupt A */ -#define IRQ_PORTG_INTB BFIN_IRQ(28) /* PF Port G (PF15:0) Interrupt B */ +#define IRQ_PF_INTA_PG_INTA BFIN_IRQ(27) /* Ports F&G Interrupt A */ +#define IRQ_PORTG_INTB BFIN_IRQ(28) /* Port G Interrupt B */ #define IRQ_MEM_DMA0 BFIN_IRQ(29) /* (Memory DMA Stream 0) */ #define IRQ_MEM_DMA1 BFIN_IRQ(30) /* (Memory DMA Stream 1) */ -#define IRQ_PROG_INTB BFIN_IRQ(31) /* PF Ports F (PF15:0) Interrupt B */ -#define IRQ_WATCH BFIN_IRQ(32) /* Watch Dog Timer */ +#define IRQ_PF_INTB_WATCH BFIN_IRQ(31) /* Watchdog & Port F Interrupt B */ #define SYS_IRQS 39 @@ -118,7 +117,27 @@ #define IRQ_MAC_TXDMAERR 104 /* TX DMA Direction Error Interrupt */ #define IRQ_MAC_STMDONE 105 /* Station Mgt. Transfer Done Interrupt */ -#define NR_MACH_IRQS (IRQ_MAC_STMDONE + 1) +#define IRQ_MAC_RX 106 /* DMA1 Interrupt (Ethernet RX) */ +#define IRQ_PORTH_INTA 107 /* Port H Interrupt A */ + +#if 0 /* No Interrupt B support (yet) */ +#define IRQ_MAC_TX 108 /* DMA2 Interrupt (Ethernet TX) */ +#define IRQ_PORTH_INTB 109 /* Port H Interrupt B */ +#else +#define IRQ_MAC_TX IRQ_PH_INTB_MAC_TX +#endif + +#define IRQ_PORTF_INTA 110 /* Port F Interrupt A */ +#define IRQ_PORTG_INTA 111 /* Port G Interrupt A */ + +#if 0 /* No Interrupt B support (yet) */ +#define IRQ_WATCH 112 /* Watchdog Timer */ +#define IRQ_PORTF_INTB 113 /* Port F Interrupt B */ +#else +#define IRQ_WATCH IRQ_PF_INTB_WATCH +#endif + +#define NR_MACH_IRQS (113 + 1) /* IAR0 BIT FIELDS */ #define IRQ_PLL_WAKEUP_POS 0 diff --git a/arch/blackfin/mach-bf537/ints-priority.c b/arch/blackfin/mach-bf537/ints-priority.c index cbf19011667b..2137a209a22b 100644 --- a/arch/blackfin/mach-bf537/ints-priority.c +++ b/arch/blackfin/mach-bf537/ints-priority.c @@ -14,6 +14,7 @@ #include <asm/bfin5xx_spi.h> #include <asm/bfin_sport.h> #include <asm/bfin_can.h> +#include <asm/bfin_dma.h> #include <asm/dpmc.h> void __init program_IAR(void) @@ -157,6 +158,40 @@ static void bf537_demux_error_irq(unsigned int int_err_irq, } +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +static int mac_rx_int_mask; + +static void bf537_mac_rx_mask_irq(struct irq_data *d) +{ + mac_rx_int_mask &= ~(1L << (d->irq - IRQ_MAC_RX)); + if (!mac_rx_int_mask) + bfin_internal_mask_irq(IRQ_PH_INTA_MAC_RX); +} + +static void bf537_mac_rx_unmask_irq(struct irq_data *d) +{ + bfin_internal_unmask_irq(IRQ_PH_INTA_MAC_RX); + mac_rx_int_mask |= 1L << (d->irq - IRQ_MAC_RX); +} + +static struct irq_chip bf537_mac_rx_irqchip = { + .name = "ERROR", + .irq_ack = bfin_ack_noop, + .irq_mask_ack = bf537_mac_rx_mask_irq, + .irq_mask = bf537_mac_rx_mask_irq, + .irq_unmask = bf537_mac_rx_unmask_irq, +}; + +static void bf537_demux_mac_rx_irq(unsigned int int_irq, + struct irq_desc *desc) +{ + if (bfin_read_DMA1_IRQ_STATUS() & (DMA_DONE | DMA_ERR)) + bfin_handle_irq(IRQ_MAC_RX); + else + bfin_demux_gpio_irq(int_irq, desc); +} +#endif + void __init init_mach_irq(void) { int irq; @@ -172,6 +207,10 @@ void __init init_mach_irq(void) handle_level_irq); #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) + irq_set_chained_handler(IRQ_PH_INTA_MAC_RX, bf537_demux_mac_rx_irq); + irq_set_chip_and_handler(IRQ_MAC_RX, &bf537_mac_rx_irqchip, handle_level_irq); + irq_set_chip_and_handler(IRQ_PORTH_INTA, &bf537_mac_rx_irqchip, handle_level_irq); + irq_set_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq); #endif } diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index ad28eb12003a..1177369f9922 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -582,22 +582,20 @@ static void bfin_demux_gpio_block(unsigned int irq) } } -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) { unsigned int irq; switch (inta_irq) { #if defined(BF537_FAMILY) - case IRQ_PROG_INTA: + case IRQ_PF_INTA_PG_INTA: bfin_demux_gpio_block(IRQ_PF0); irq = IRQ_PG0; break; -# if !(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(BF533_FAMILY) case IRQ_PROG_INTA: irq = IRQ_PF0; @@ -881,8 +879,8 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) # 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; @@ -1001,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: |