Skip to content

Commit

Permalink
Blackfin: move bf537-specific irq code out of common code
Browse files Browse the repository at this point in the history
The SIC interrupt line muxing that the bf537 does is specific to this
CPU (thankfully), so rip it out of the common code and move it to a
bf537-specific file.  This tidies up the common code significantly.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
  • Loading branch information
Mike Frysinger committed May 25, 2011
1 parent 6327a57 commit f58c327
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 138 deletions.
14 changes: 14 additions & 0 deletions arch/blackfin/include/asm/irq_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
2 changes: 2 additions & 0 deletions arch/blackfin/mach-bf537/include/mach/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,6 @@
#define IRQ_MEM_DMA1_POS 24
#define IRQ_WATCH_POS 28

#define init_mach_irq init_mach_irq

#endif
124 changes: 124 additions & 0 deletions arch/blackfin/mach-bf537/ints-priority.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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
}
Loading

0 comments on commit f58c327

Please sign in to comment.