diff options
author | Jeff Garzik <jeff@garzik.org> | 2007-10-19 15:38:40 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-23 19:53:16 -0400 |
commit | 6bd3bd6794d4139aa1b5193a82e3adfcb488c392 (patch) | |
tree | 4d89ce8c3b2b57662be431489a93f9705e8dcb68 | |
parent | f3518e4ee70916e6bd43c8082e02f0dd1e19d7af (diff) |
drivers/char/ip2: separate polling and irq-driven work entry points
Polling currently calls the irq handler, which loops through all the
boards, calling the work function for all polling boards with work.
irq handling loops through all the boards, finding the specific board
that applies to us, and calling the work just for that one board.
The two logics are sufficiently different to warrant different
functions, rather than being slack and calling the same function in two
different ways.
This serves to make the interrupt handler a -lot- more efficient.
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r-- | drivers/char/ip2/ip2main.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 150e1e364ca7..e04e66cf2c68 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -752,7 +752,7 @@ retry: | |||
752 | continue; | 752 | continue; |
753 | rc = request_irq( ip2config.irq[i], ip2_interrupt, | 753 | rc = request_irq( ip2config.irq[i], ip2_interrupt, |
754 | IP2_SA_FLAGS | (ip2config.type[i] == PCI ? IRQF_SHARED : 0), | 754 | IP2_SA_FLAGS | (ip2config.type[i] == PCI ? IRQF_SHARED : 0), |
755 | pcName, (void *)&pcName); | 755 | pcName, i2BoardPtrTable[i]); |
756 | if (rc) { | 756 | if (rc) { |
757 | printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc); | 757 | printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc); |
758 | ip2config.irq[i] = CIR_POLL; | 758 | ip2config.irq[i] = CIR_POLL; |
@@ -1191,12 +1191,12 @@ ip2_irq_work(i2eBordStrPtr pB) | |||
1191 | #endif /* USE_IQI */ | 1191 | #endif /* USE_IQI */ |
1192 | } | 1192 | } |
1193 | 1193 | ||
1194 | static irqreturn_t | 1194 | static void |
1195 | ip2_interrupt(int irq, void *dev_id) | 1195 | ip2_polled_interrupt(void) |
1196 | { | 1196 | { |
1197 | int i; | 1197 | int i; |
1198 | i2eBordStrPtr pB; | 1198 | i2eBordStrPtr pB; |
1199 | int handled = 0; | 1199 | const int irq = 0; |
1200 | 1200 | ||
1201 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq ); | 1201 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq ); |
1202 | 1202 | ||
@@ -1208,7 +1208,6 @@ ip2_interrupt(int irq, void *dev_id) | |||
1208 | // IRQ = 0 for polled boards, we won't poll "IRQ" boards | 1208 | // IRQ = 0 for polled boards, we won't poll "IRQ" boards |
1209 | 1209 | ||
1210 | if ( pB && (pB->i2eUsingIrq == irq) ) { | 1210 | if ( pB && (pB->i2eUsingIrq == irq) ) { |
1211 | handled = 1; | ||
1212 | ip2_irq_work(pB); | 1211 | ip2_irq_work(pB); |
1213 | } | 1212 | } |
1214 | } | 1213 | } |
@@ -1216,7 +1215,21 @@ ip2_interrupt(int irq, void *dev_id) | |||
1216 | ++irq_counter; | 1215 | ++irq_counter; |
1217 | 1216 | ||
1218 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); | 1217 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); |
1219 | return IRQ_RETVAL(handled); | 1218 | } |
1219 | |||
1220 | static irqreturn_t | ||
1221 | ip2_interrupt(int irq, void *dev_id) | ||
1222 | { | ||
1223 | i2eBordStrPtr pB = dev_id; | ||
1224 | |||
1225 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, pB->i2eUsingIrq ); | ||
1226 | |||
1227 | ip2_irq_work(pB); | ||
1228 | |||
1229 | ++irq_counter; | ||
1230 | |||
1231 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); | ||
1232 | return IRQ_HANDLED; | ||
1220 | } | 1233 | } |
1221 | 1234 | ||
1222 | /******************************************************************************/ | 1235 | /******************************************************************************/ |
@@ -1239,7 +1252,7 @@ ip2_poll(unsigned long arg) | |||
1239 | // Just polled boards, IRQ = 0 will hit all non-interrupt boards. | 1252 | // Just polled boards, IRQ = 0 will hit all non-interrupt boards. |
1240 | // It will NOT poll boards handled by hard interrupts. | 1253 | // It will NOT poll boards handled by hard interrupts. |
1241 | // The issue of queued BH interrups is handled in ip2_interrupt(). | 1254 | // The issue of queued BH interrups is handled in ip2_interrupt(). |
1242 | ip2_interrupt(0, NULL); | 1255 | ip2_polled_interrupt(); |
1243 | 1256 | ||
1244 | PollTimer.expires = POLL_TIMEOUT; | 1257 | PollTimer.expires = POLL_TIMEOUT; |
1245 | add_timer( &PollTimer ); | 1258 | add_timer( &PollTimer ); |