mirror of https://gitee.com/openkylin/linux.git
Blackfin: add support for the on-chip MAC status interrupts
This patch provides infrastructure for MAC Wake-On-Lan and PHYINT use in phylib. New Interrupts added: IRQ_MAC_PHYINT /* PHY_INT Interrupt */ IRQ_MAC_MMCINT /* MMC Counter Interrupt */ IRQ_MAC_RXFSINT /* RX Frame-Status Interrupt */ IRQ_MAC_TXFSINT /* TX Frame-Status Interrupt */ IRQ_MAC_WAKEDET /* Wake-Up Interrupt */ IRQ_MAC_RXDMAERR /* RX DMA Direction Error Interrupt */ IRQ_MAC_TXDMAERR /* TX DMA Direction Error Interrupt */ IRQ_MAC_STMDONE /* Station Mgt. Transfer Done Interrupt */ On BF537/6 the implementation is not straight forward since there are now two chained chained_handlers. A cleaner approach would have been to add latter IRQs to the demux of IRQ_GENERIC_ERROR. Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
This commit is contained in:
parent
b274080145
commit
aec59c9113
|
@ -151,7 +151,16 @@
|
|||
|
||||
#define GPIO_IRQ_BASE IRQ_PF0
|
||||
|
||||
#define NR_MACH_IRQS (IRQ_PH15 + 1)
|
||||
#define IRQ_MAC_PHYINT 119 /* PHY_INT Interrupt */
|
||||
#define IRQ_MAC_MMCINT 120 /* MMC Counter Interrupt */
|
||||
#define IRQ_MAC_RXFSINT 121 /* RX Frame-Status Interrupt */
|
||||
#define IRQ_MAC_TXFSINT 122 /* TX Frame-Status Interrupt */
|
||||
#define IRQ_MAC_WAKEDET 123 /* Wake-Up Interrupt */
|
||||
#define IRQ_MAC_RXDMAERR 124 /* RX DMA Direction Error Interrupt */
|
||||
#define IRQ_MAC_TXDMAERR 125 /* TX DMA Direction Error Interrupt */
|
||||
#define IRQ_MAC_STMDONE 126 /* Station Mgt. Transfer Done Interrupt */
|
||||
|
||||
#define NR_MACH_IRQS (IRQ_MAC_STMDONE + 1)
|
||||
#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS)
|
||||
|
||||
#define IVG7 7
|
||||
|
|
|
@ -151,7 +151,16 @@
|
|||
|
||||
#define GPIO_IRQ_BASE IRQ_PF0
|
||||
|
||||
#define NR_MACH_IRQS (IRQ_PH15 + 1)
|
||||
#define IRQ_MAC_PHYINT 119 /* PHY_INT Interrupt */
|
||||
#define IRQ_MAC_MMCINT 120 /* MMC Counter Interrupt */
|
||||
#define IRQ_MAC_RXFSINT 121 /* RX Frame-Status Interrupt */
|
||||
#define IRQ_MAC_TXFSINT 122 /* TX Frame-Status Interrupt */
|
||||
#define IRQ_MAC_WAKEDET 123 /* Wake-Up Interrupt */
|
||||
#define IRQ_MAC_RXDMAERR 124 /* RX DMA Direction Error Interrupt */
|
||||
#define IRQ_MAC_TXDMAERR 125 /* TX DMA Direction Error Interrupt */
|
||||
#define IRQ_MAC_STMDONE 126 /* Station Mgt. Transfer Done Interrupt */
|
||||
|
||||
#define NR_MACH_IRQS (IRQ_MAC_STMDONE + 1)
|
||||
#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS)
|
||||
|
||||
#define IVG7 7
|
||||
|
|
|
@ -134,7 +134,16 @@
|
|||
|
||||
#define GPIO_IRQ_BASE IRQ_PF0
|
||||
|
||||
#define NR_MACH_IRQS (IRQ_PH15 + 1)
|
||||
#define IRQ_MAC_PHYINT 98 /* PHY_INT Interrupt */
|
||||
#define IRQ_MAC_MMCINT 99 /* MMC Counter Interrupt */
|
||||
#define IRQ_MAC_RXFSINT 100 /* RX Frame-Status Interrupt */
|
||||
#define IRQ_MAC_TXFSINT 101 /* TX Frame-Status Interrupt */
|
||||
#define IRQ_MAC_WAKEDET 102 /* Wake-Up Interrupt */
|
||||
#define IRQ_MAC_RXDMAERR 103 /* RX DMA Direction Error Interrupt */
|
||||
#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 NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS)
|
||||
|
||||
#define IVG7 7
|
||||
|
|
|
@ -325,7 +325,6 @@ static int error_int_mask;
|
|||
static void bfin_generic_error_mask_irq(unsigned int irq)
|
||||
{
|
||||
error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
|
||||
|
||||
if (!error_int_mask)
|
||||
bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
|
||||
}
|
||||
|
@ -416,6 +415,127 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
|
|||
}
|
||||
#endif /* BF537_GENERIC_ERROR_INT_DEMUX */
|
||||
|
||||
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
|
||||
static int mac_stat_int_mask;
|
||||
|
||||
static void bfin_mac_status_ack_irq(unsigned int irq)
|
||||
{
|
||||
switch (irq) {
|
||||
case IRQ_MAC_MMCINT:
|
||||
bfin_write_EMAC_MMC_TIRQS(
|
||||
bfin_read_EMAC_MMC_TIRQE() &
|
||||
bfin_read_EMAC_MMC_TIRQS());
|
||||
bfin_write_EMAC_MMC_RIRQS(
|
||||
bfin_read_EMAC_MMC_RIRQE() &
|
||||
bfin_read_EMAC_MMC_RIRQS());
|
||||
break;
|
||||
case IRQ_MAC_RXFSINT:
|
||||
bfin_write_EMAC_RX_STKY(
|
||||
bfin_read_EMAC_RX_IRQE() &
|
||||
bfin_read_EMAC_RX_STKY());
|
||||
break;
|
||||
case IRQ_MAC_TXFSINT:
|
||||
bfin_write_EMAC_TX_STKY(
|
||||
bfin_read_EMAC_TX_IRQE() &
|
||||
bfin_read_EMAC_TX_STKY());
|
||||
break;
|
||||
case IRQ_MAC_WAKEDET:
|
||||
bfin_write_EMAC_WKUP_CTL(
|
||||
bfin_read_EMAC_WKUP_CTL() | MPKS | RWKS);
|
||||
break;
|
||||
default:
|
||||
/* These bits are W1C */
|
||||
bfin_write_EMAC_SYSTAT(1L << (irq - IRQ_MAC_PHYINT));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void bfin_mac_status_mask_irq(unsigned int irq)
|
||||
{
|
||||
mac_stat_int_mask &= ~(1L << (irq - IRQ_MAC_PHYINT));
|
||||
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
|
||||
switch (irq) {
|
||||
case IRQ_MAC_PHYINT:
|
||||
bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() & ~PHYIE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (!mac_stat_int_mask)
|
||||
bfin_internal_mask_irq(IRQ_MAC_ERROR);
|
||||
#endif
|
||||
bfin_mac_status_ack_irq(irq);
|
||||
}
|
||||
|
||||
static void bfin_mac_status_unmask_irq(unsigned int irq)
|
||||
{
|
||||
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
|
||||
switch (irq) {
|
||||
case IRQ_MAC_PHYINT:
|
||||
bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() | PHYIE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (!mac_stat_int_mask)
|
||||
bfin_internal_unmask_irq(IRQ_MAC_ERROR);
|
||||
#endif
|
||||
mac_stat_int_mask |= 1L << (irq - IRQ_MAC_PHYINT);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int bfin_mac_status_set_wake(unsigned int irq, unsigned int state)
|
||||
{
|
||||
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
|
||||
return bfin_internal_set_wake(IRQ_GENERIC_ERROR, state);
|
||||
#else
|
||||
return bfin_internal_set_wake(IRQ_MAC_ERROR, state);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct irq_chip bfin_mac_status_irqchip = {
|
||||
.name = "MACST",
|
||||
.ack = bfin_ack_noop,
|
||||
.mask_ack = bfin_mac_status_mask_irq,
|
||||
.mask = bfin_mac_status_mask_irq,
|
||||
.unmask = bfin_mac_status_unmask_irq,
|
||||
#ifdef CONFIG_PM
|
||||
.set_wake = bfin_mac_status_set_wake,
|
||||
#endif
|
||||
};
|
||||
|
||||
static 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();
|
||||
|
||||
for (i = 0; i < (IRQ_MAC_STMDONE - IRQ_MAC_PHYINT); i++)
|
||||
if (status & (1L << i)) {
|
||||
irq = IRQ_MAC_PHYINT + i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (irq) {
|
||||
if (mac_stat_int_mask & (1L << (irq - IRQ_MAC_PHYINT))) {
|
||||
bfin_handle_irq(irq);
|
||||
} else {
|
||||
bfin_mac_status_ack_irq(irq);
|
||||
pr_debug("IRQ %d:"
|
||||
" MASKED MAC ERROR INTERRUPT ASSERTED\n",
|
||||
irq);
|
||||
}
|
||||
} else
|
||||
printk(KERN_ERR
|
||||
"%s : %s : LINE %d :\nIRQ ?: MAC ERROR"
|
||||
" INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
|
||||
__func__, __FILE__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle)
|
||||
{
|
||||
#ifdef CONFIG_IPIPE
|
||||
|
@ -1070,7 +1190,11 @@ int __init init_arch_irq(void)
|
|||
set_irq_chained_handler(irq, bfin_demux_error_irq);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
|
||||
case IRQ_MAC_ERROR:
|
||||
set_irq_chained_handler(irq, bfin_demux_mac_status_irq);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_SMP
|
||||
case IRQ_SUPPLE_0:
|
||||
case IRQ_SUPPLE_1:
|
||||
|
@ -1111,14 +1235,22 @@ int __init init_arch_irq(void)
|
|||
for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
|
||||
set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip,
|
||||
handle_level_irq);
|
||||
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
|
||||
set_irq_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
|
||||
for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++)
|
||||
set_irq_chip_and_handler(irq, &bfin_mac_status_irqchip,
|
||||
handle_level_irq);
|
||||
#endif
|
||||
/* if configured as edge, then will be changed to do_edge_IRQ */
|
||||
for (irq = GPIO_IRQ_BASE; irq < NR_MACH_IRQS; irq++)
|
||||
for (irq = GPIO_IRQ_BASE;
|
||||
irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++)
|
||||
set_irq_chip_and_handler(irq, &bfin_gpio_irqchip,
|
||||
handle_level_irq);
|
||||
|
||||
|
||||
bfin_write_IMASK(0);
|
||||
CSYNC();
|
||||
ilat = bfin_read_ILAT();
|
||||
|
|
Loading…
Reference in New Issue