Commit f58c3276 authored by Mike Frysinger's avatar Mike Frysinger

Blackfin: move bf537-specific irq code out of common code

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: default avatarMike Frysinger <vapier@gentoo.org>
parent 6327a574
......@@ -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
......@@ -160,4 +160,6 @@
#define IRQ_MEM_DMA1_POS 24
#define IRQ_WATCH_POS 28
#define init_mach_irq init_mach_irq
#endif
......@@ -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
}
......@@ -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++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment