diff options
-rw-r--r-- | arch/blackfin/include/asm/irq_handler.h | 14 | ||||
-rw-r--r-- | arch/blackfin/mach-bf537/include/mach/irq.h | 2 | ||||
-rw-r--r-- | arch/blackfin/mach-bf537/ints-priority.c | 124 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 148 |
4 files changed, 150 insertions, 138 deletions
diff --git a/arch/blackfin/include/asm/irq_handler.h b/arch/blackfin/include/asm/irq_handler.h index 88c35e4ea4bf..77341b3ad351 100644 --- a/arch/blackfin/include/asm/irq_handler.h +++ b/arch/blackfin/include/asm/irq_handler.h @@ -14,6 +14,11 @@ extern int __init init_arch_irq(void); extern void init_exception_vectors(void); extern void __init program_IAR(void); +#ifdef init_mach_irq +extern void __init init_mach_irq(void); +#else +# define init_mach_irq() +#endif /* BASE LEVEL interrupt handler routines */ asmlinkage void evt_exception(void); @@ -47,4 +52,13 @@ extern asmlinkage void bfin_return_from_exception(void); extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs); extern int bfin_internal_set_wake(unsigned int irq, unsigned int state); +struct irq_data; +extern void bfin_handle_irq(unsigned irq); +extern void bfin_ack_noop(struct irq_data *); +extern void bfin_internal_mask_irq(unsigned int irq); +extern void bfin_internal_unmask_irq(unsigned int irq); + +struct irq_desc; +extern void bfin_demux_mac_status_irq(unsigned int, struct irq_desc *); + #endif diff --git a/arch/blackfin/mach-bf537/include/mach/irq.h b/arch/blackfin/mach-bf537/include/mach/irq.h index fe2223b5dd52..cc3132347414 100644 --- a/arch/blackfin/mach-bf537/include/mach/irq.h +++ b/arch/blackfin/mach-bf537/include/mach/irq.h @@ -160,4 +160,6 @@ #define IRQ_MEM_DMA1_POS 24 #define IRQ_WATCH_POS 28 +#define init_mach_irq init_mach_irq + #endif diff --git a/arch/blackfin/mach-bf537/ints-priority.c b/arch/blackfin/mach-bf537/ints-priority.c index f6500622b35d..cbf19011667b 100644 --- a/arch/blackfin/mach-bf537/ints-priority.c +++ b/arch/blackfin/mach-bf537/ints-priority.c @@ -10,6 +10,12 @@ #include <linux/irq.h> #include <asm/blackfin.h> +#include <asm/irq_handler.h> +#include <asm/bfin5xx_spi.h> +#include <asm/bfin_sport.h> +#include <asm/bfin_can.h> +#include <asm/dpmc.h> + void __init program_IAR(void) { /* Program the IAR0 Register with the configured priority */ @@ -51,3 +57,121 @@ void __init program_IAR(void) SSYNC(); } + +#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 */ + +static int error_int_mask; + +static void bf537_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 bf537_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 bf537_generic_error_irqchip = { + .name = "ERROR", + .irq_ack = bfin_ack_noop, + .irq_mask_ack = bf537_generic_error_mask_irq, + .irq_mask = bf537_generic_error_mask_irq, + .irq_unmask = bf537_generic_error_unmask_irq, +}; + +static void bf537_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 + pr_err("%s: IRQ ?: PERIPHERAL ERROR INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", + __func__); + +} + +void __init init_mach_irq(void) +{ + int irq; + +#if defined(CONFIG_BF537) || defined(CONFIG_BF536) + /* Clear EMAC Interrupt Status bits so we can demux it later */ + bfin_write_EMAC_SYSTAT(-1); +#endif + + irq_set_chained_handler(IRQ_GENERIC_ERROR, bf537_demux_error_irq); + for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) + irq_set_chip_and_handler(irq, &bf537_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 +} diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 766e9f6d0627..e32cd6f11010 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -24,24 +24,9 @@ #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 @@ -119,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. */ } @@ -148,7 +133,7 @@ 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 = hard_local_irq_save(); @@ -178,7 +163,7 @@ 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 = hard_local_irq_save(); @@ -310,7 +295,7 @@ static struct irq_chip bfin_internal_irqchip = { .irq_set_wake = bfin_internal_set_wake_chip, }; -static void bfin_handle_irq(unsigned irq) +void bfin_handle_irq(unsigned irq) { #ifdef CONFIG_IPIPE struct pt_regs regs; /* Contents not used. */ @@ -322,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; @@ -458,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); @@ -477,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); @@ -495,7 +384,7 @@ 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); @@ -514,8 +403,8 @@ static struct irq_chip bfin_mac_status_irqchip = { .irq_set_wake = bfin_mac_status_set_wake, }; -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(); @@ -1137,11 +1026,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; @@ -1183,11 +1067,6 @@ int __init init_arch_irq(void) #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, @@ -1227,14 +1106,7 @@ int __init init_arch_irq(void) } } -#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++) |