Skip to content

Commit

Permalink
[PATCH] smc91x: fix one source of spurious interrupts
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nicolas Pitre authored and Jeff Garzik committed Nov 18, 2005
1 parent fc71fe4 commit 5d0571d
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions drivers/net/smc91x.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 5d0571d

Please sign in to comment.