[PATCH 7/17] drivers/char/{rio,specialix,sx}: irq handler cleanups

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



commit ac608e65f5c2a99affced5f02eefe24125f9c5bd
Author: Jeff Garzik <[email protected]>
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 <[email protected]>

 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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux