summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2005-11-17 14:02:48 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-18 13:10:30 -0500
commit5d0571d915f3e281f151df9a18a6a0be5a57c4b0 (patch)
tree731e8546c3a663208b8d8ad429dd86a9b49a2a1c
parentfc71fe40d2bedcc57d3406bf2050481f8b3441b6 (diff)
downloadlinux-3.10-5d0571d915f3e281f151df9a18a6a0be5a57c4b0.tar.gz
linux-3.10-5d0571d915f3e281f151df9a18a6a0be5a57c4b0.tar.bz2
linux-3.10-5d0571d915f3e281f151df9a18a6a0be5a57c4b0.zip
[PATCH] smc91x: fix one source of spurious interrupts
Not only SMC_ACK_INT(IM_TX_EMPTY_INT) in in smc_hardware_send_pkt) appears to be unnecessary (tested with an SMC91C94 and SMC91C111), but it seems to trigger spurious interrupts on some machines as well. Removed. While at it, let's log any remaining spurious interrupts if any (and clean usage of the max IRQ loop count value). Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r--drivers/net/smc91x.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index c91e2e81f13..1021108e9a2 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -155,6 +155,12 @@ MODULE_LICENSE("GPL");
#define MEMORY_WAIT_TIME 16
/*
+ * The maximum number of processing loops allowed for each call to the
+ * IRQ handler.
+ */
+#define MAX_IRQ_LOOPS 8
+
+/*
* This selects whether TX packets are sent one by one to the SMC91x internal
* memory and throttled until transmission completes. This may prevent
* RX overruns a litle by keeping much of the memory free for RX packets
@@ -684,7 +690,6 @@ static void smc_hardware_send_pkt(unsigned long data)
/* queue the packet for TX */
SMC_SET_MMU_CMD(MC_ENQUEUE);
- SMC_ACK_INT(IM_TX_EMPTY_INT);
smc_special_unlock(&lp->lock);
dev->trans_start = jiffies;
@@ -1305,7 +1310,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
SMC_SET_INT_MASK(0);
/* set a timeout value, so I don't stay here forever */
- timeout = 8;
+ timeout = MAX_IRQ_LOOPS;
do {
status = SMC_GET_INT();
@@ -1372,10 +1377,13 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* restore register states */
SMC_SET_PTR(saved_pointer);
SMC_SET_INT_MASK(mask);
-
spin_unlock(&lp->lock);
- DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout);
+ if (timeout == MAX_IRQ_LOOPS)
+ PRINTK("%s: spurious interrupt (mask = 0x%02x)\n",
+ dev->name, mask);
+ DBG(3, "%s: Interrupt done (%d loops)\n",
+ dev->name, MAX_IRQ_LOOPS - timeout);
/*
* We return IRQ_HANDLED unconditionally here even if there was