Skip to content

Commit 5359b93

Browse files
Maciej W. Rozyckiralfbaechle
authored andcommitted
MIPS: DECstation I/O ASIC DMA interrupt handling fix
This change complements commit d0da7c0 and brings clear_ioasic_irq back, renaming it to clear_ioasic_dma_irq at the same time, to make I/O ASIC DMA interrupts functional. Unlike ordinary I/O ASIC interrupts DMA interrupts need to be deasserted by software by writing 0 to the respective bit in I/O ASIC's System Interrupt Register (SIR), similarly to how CP0.Cause.IP0 and CP0.Cause.IP1 bits are handled in the CPU (the difference is SIR DMA interrupt bits are R/W0C so there's no need for an RMW cycle). Otherwise the handler is reentered over and over again. The only current user is the DEC LANCE Ethernet driver and its extremely uncommon DMA memory error handler that does not care when exactly the interrupt is cleared. Anticipating the use of DMA interrupts by the Zilog SCC driver this change however exports clear_ioasic_dma_irq for device drivers to choose the right application-specific sequence to clear the request explicitly rather than calling it implicitly in the .irq_eoi handler of `struct irq_chip'. Previously these interrupts were cleared in the .end handler of the said structure, before it was removed. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/5826/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
1 parent daed128 commit 5359b93

File tree

3 files changed

+11
-0
lines changed

3 files changed

+11
-0
lines changed

arch/mips/dec/ioasic-irq.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ static struct irq_chip ioasic_irq_type = {
5151
.irq_unmask = unmask_ioasic_irq,
5252
};
5353

54+
void clear_ioasic_dma_irq(unsigned int irq)
55+
{
56+
u32 sir;
57+
58+
sir = ~(1 << (irq - ioasic_irq_base));
59+
ioasic_write(IO_REG_SIR, sir);
60+
}
61+
5462
static struct irq_chip ioasic_dma_irq_type = {
5563
.name = "IO-ASIC-DMA",
5664
.irq_ack = ack_ioasic_irq,

arch/mips/include/asm/dec/ioasic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ static inline u32 ioasic_read(unsigned int reg)
3131
return ioasic_base[reg / 4];
3232
}
3333

34+
extern void clear_ioasic_dma_irq(unsigned int irq);
35+
3436
extern void init_ioasic_irqs(int base);
3537

3638
extern int dec_ioasic_clocksource_init(void);

drivers/net/ethernet/amd/declance.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,7 @@ static irqreturn_t lance_dma_merr_int(int irq, void *dev_id)
725725
{
726726
struct net_device *dev = dev_id;
727727

728+
clear_ioasic_dma_irq(irq);
728729
printk(KERN_ERR "%s: DMA error\n", dev->name);
729730
return IRQ_HANDLED;
730731
}

0 commit comments

Comments
 (0)