Messages in this thread Patch in this message | | | From | Jeff Garzik <> | Subject | [PATCH 7/17] drivers/char/{rio,specialix,sx}: irq handler cleanups | Date | Sun, 21 Oct 2007 03:52:28 -0400 (EDT) |
| |
commit ac608e65f5c2a99affced5f02eefe24125f9c5bd Author: Jeff Garzik <jeff@garzik.org> Date: Fri Oct 19 16:43:21 2007 -0400
drivers/char/{rio,specialix,sx}: irq handler cleanups * explicitly separate polled and irq-driven modes of operation * no need to reference 'irq' function arg * mark a free_irq() -in-irq-handler use with a FIXME (ugh!) Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
drivers/char/rio/rio_linux.c | 23 +++++++++++++---------- drivers/char/specialix.c | 10 ++++------ drivers/char/sx.c | 22 ++++++++++++++-------- 3 files changed, 31 insertions(+), 24 deletions(-)
ac608e65f5c2a99affced5f02eefe24125f9c5bd diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index 0ce9667..fb06665 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c @@ -362,14 +362,11 @@ static void rio_reset_interrupt(struct Host *HostP) func_exit(); } - -static irqreturn_t rio_interrupt(int irq, void *ptr) +static irqreturn_t __rio_interrupt(struct Host *HostP, bool polled) { - struct Host *HostP; func_enter(); - HostP = ptr; /* &p->RIOHosts[(long)ptr]; */ - rio_dprintk(RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", irq, HostP->Ivec); + rio_dprintk(RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d)\n", HostP->Ivec); /* AAargh! The order in which to do these things is essential and not trivial. @@ -389,7 +386,7 @@ static irqreturn_t rio_interrupt(int irq, void *ptr) */ rio_dprintk(RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n"); - if (HostP->Ivec == irq) { + if (!polled) { /* Tell the card we've noticed the interrupt. */ rio_reset_interrupt(HostP); } @@ -398,26 +395,32 @@ static irqreturn_t rio_interrupt(int irq, void *ptr) return IRQ_HANDLED; if (test_and_set_bit(RIO_BOARD_INTR_LOCK, &HostP->locks)) { - printk(KERN_ERR "Recursive interrupt! (host %p/irq%d)\n", ptr, HostP->Ivec); + printk(KERN_ERR "Recursive interrupt! (host %p/irq%d)\n", + HostP, HostP->Ivec); return IRQ_HANDLED; } RIOServiceHost(p, HostP); - rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n", ptr, HostP->Type); + rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n", + HostP, HostP->Type); clear_bit(RIO_BOARD_INTR_LOCK, &HostP->locks); - rio_dprintk(RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", irq, HostP->Ivec); + rio_dprintk(RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d)\n", HostP->Ivec); func_exit(); return IRQ_HANDLED; } +static irqreturn_t rio_interrupt(int dummy, void *ptr) +{ + return __rio_interrupt(ptr, false); +} static void rio_pollfunc(unsigned long data) { func_enter(); - rio_interrupt(0, &p->RIOHosts[data]); + __rio_interrupt(&p->RIOHosts[data], true); mod_timer(&p->RIOHosts[data].timer, jiffies + rio_poll); func_exit(); diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 4558556..706e74f 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -446,8 +446,7 @@ void missed_irq (unsigned long data) spin_unlock_irqrestore(&bp->lock, flags); if (irq) { printk (KERN_INFO "Missed interrupt... Calling int from timer. \n"); - sx_interrupt (((struct specialix_board *)data)->irq, - (void*)data); + sx_interrupt (-1, bp); } mod_timer(&missed_irq_timer, jiffies + sx_poll); } @@ -876,23 +875,22 @@ static inline void sx_check_modem(struct specialix_board * bp) /* The main interrupt processing routine */ -static irqreturn_t sx_interrupt(int irq, void *dev_id) +static irqreturn_t sx_interrupt(int dummy, void *dev_id) { unsigned char status; unsigned char ack; - struct specialix_board *bp; + struct specialix_board *bp = dev_id; unsigned long loop = 0; int saved_reg; unsigned long flags; func_enter(); - bp = dev_id; spin_lock_irqsave(&bp->lock, flags); dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1); if (!(bp->flags & SX_BOARD_ACTIVE)) { - dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq); + dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", bp->irq); spin_unlock_irqrestore(&bp->lock, flags); func_exit(); return IRQ_NONE; diff --git a/drivers/char/sx.c b/drivers/char/sx.c index a6e1c9b..ae9e973 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -1241,15 +1241,13 @@ static inline void sx_check_modem_signals(struct sx_port *port) * Small, elegant, clear. */ -static irqreturn_t sx_interrupt(int irq, void *ptr) +static irqreturn_t __sx_interrupt(struct sx_board *board, bool polled) { - struct sx_board *board = ptr; struct sx_port *port; int i; func_enter(); - sx_dprintk(SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq, - board->irq); + sx_dprintk(SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d)\n", board->irq); /* AAargh! The order in which to do these things is essential and not trivial. @@ -1281,6 +1279,10 @@ static irqreturn_t sx_interrupt(int irq, void *ptr) if (lastjif == jiffies) { if (++nintr > IRQ_RATE_LIMIT) { + /* + * FIXME: free_irq() inside irq handler + * is unwise + */ free_irq(board->irq, board); printk(KERN_ERR "sx: Too many interrupts. " "Turning off interrupt %d.\n", @@ -1293,7 +1295,7 @@ static irqreturn_t sx_interrupt(int irq, void *ptr) } #endif - if (board->irq == irq) { + if (!polled) { /* Tell the card we've noticed the interrupt. */ sx_write_board_word(board, cc_int_pending, 0); @@ -1339,19 +1341,23 @@ static irqreturn_t sx_interrupt(int irq, void *ptr) clear_bit(SX_BOARD_INTR_LOCK, &board->locks); - sx_dprintk(SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq, - board->irq); + sx_dprintk(SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d)\n", board->irq); func_exit(); return IRQ_HANDLED; } +static irqreturn_t sx_interrupt(int dummy, void *data) +{ + return __sx_interrupt(data, false); +} + static void sx_pollfunc(unsigned long data) { struct sx_board *board = (struct sx_board *)data; func_enter(); - sx_interrupt(0, board); + __sx_interrupt(board, true); mod_timer(&board->timer, jiffies + sx_poll); func_exit(); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |