aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Jones <arthur.jones@qlogic.com>2007-05-10 15:10:49 -0400
committerRoland Dreier <rolandd@cisco.com>2007-05-14 16:22:42 -0400
commit8f140b407f3be04e7202be9aa0cfef3006d14c9f (patch)
tree34f308cacd261f03cc3e490a187df369f0bac7f3
parent26c6bc7b812b4157ba929035e467c0f4dd165916 (diff)
IB/ipath: Shadow the gpio_mask register
Once upon a time, GPIO interrupts were rare. But then a chip bug in the waldo series forced the use of a GPIO interrupt to signal packet reception. This greatly increased the frequency of GPIO interrupts which have the gpio_mask bits set on the waldo chips. Other bits in the gpio_status register are used for I2C clock and data lines, these bits are usually on. An "unlikely" annotation leftover from the old days was improperly applied to these bits, and an unnecessary chip mmio read was being accessed in the interrupt fast path on waldo. Remove the stagnant unlikely annotation in the interrupt handler and keep a shadow copy of the gpio_mask register to avoid the slow mmio read when testing for interruptable GPIO bits. Signed-off-by: Arthur Jones <arthur.jones@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6120.c7
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c7
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c12
4 files changed, 14 insertions, 14 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c
index 1b9c308577..4e2e3dfeb2 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6120.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c
@@ -747,7 +747,6 @@ static void ipath_pe_quiet_serdes(struct ipath_devdata *dd)
747 747
748static int ipath_pe_intconfig(struct ipath_devdata *dd) 748static int ipath_pe_intconfig(struct ipath_devdata *dd)
749{ 749{
750 u64 val;
751 u32 chiprev; 750 u32 chiprev;
752 751
753 /* 752 /*
@@ -760,9 +759,9 @@ static int ipath_pe_intconfig(struct ipath_devdata *dd)
760 if ((chiprev & INFINIPATH_R_CHIPREVMINOR_MASK) > 1) { 759 if ((chiprev & INFINIPATH_R_CHIPREVMINOR_MASK) > 1) {
761 /* Rev2+ reports extra errors via internal GPIO pins */ 760 /* Rev2+ reports extra errors via internal GPIO pins */
762 dd->ipath_flags |= IPATH_GPIO_ERRINTRS; 761 dd->ipath_flags |= IPATH_GPIO_ERRINTRS;
763 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask); 762 dd->ipath_gpio_mask |= IPATH_GPIO_ERRINTR_MASK;
764 val |= IPATH_GPIO_ERRINTR_MASK; 763 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask,
765 ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val); 764 dd->ipath_gpio_mask);
766 } 765 }
767 return 0; 766 return 0;
768} 767}
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 45d033169c..a90d3b5699 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -1056,7 +1056,7 @@ irqreturn_t ipath_intr(int irq, void *data)
1056 gpiostatus &= ~(1 << IPATH_GPIO_PORT0_BIT); 1056 gpiostatus &= ~(1 << IPATH_GPIO_PORT0_BIT);
1057 chk0rcv = 1; 1057 chk0rcv = 1;
1058 } 1058 }
1059 if (unlikely(gpiostatus)) { 1059 if (gpiostatus) {
1060 /* 1060 /*
1061 * Some unexpected bits remain. If they could have 1061 * Some unexpected bits remain. If they could have
1062 * caused the interrupt, complain and clear. 1062 * caused the interrupt, complain and clear.
@@ -1065,9 +1065,8 @@ irqreturn_t ipath_intr(int irq, void *data)
1065 * GPIO interrupts, possibly on a "three strikes" 1065 * GPIO interrupts, possibly on a "three strikes"
1066 * basis. 1066 * basis.
1067 */ 1067 */
1068 u32 mask; 1068 const u32 mask = (u32) dd->ipath_gpio_mask;
1069 mask = ipath_read_kreg32( 1069
1070 dd, dd->ipath_kregs->kr_gpio_mask);
1071 if (mask & gpiostatus) { 1070 if (mask & gpiostatus) {
1072 ipath_dbg("Unexpected GPIO IRQ bits %x\n", 1071 ipath_dbg("Unexpected GPIO IRQ bits %x\n",
1073 gpiostatus & mask); 1072 gpiostatus & mask);
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index e900c2593f..12194f3dd8 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -397,6 +397,8 @@ struct ipath_devdata {
397 unsigned long ipath_pioavailshadow[8]; 397 unsigned long ipath_pioavailshadow[8];
398 /* shadow of kr_gpio_out, for rmw ops */ 398 /* shadow of kr_gpio_out, for rmw ops */
399 u64 ipath_gpio_out; 399 u64 ipath_gpio_out;
400 /* shadow the gpio mask register */
401 u64 ipath_gpio_mask;
400 /* kr_revision shadow */ 402 /* kr_revision shadow */
401 u64 ipath_revision; 403 u64 ipath_revision;
402 /* 404 /*
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index 12933e77c7..bb70845279 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -1387,13 +1387,12 @@ static int enable_timer(struct ipath_devdata *dd)
1387 * processing. 1387 * processing.
1388 */ 1388 */
1389 if (dd->ipath_flags & IPATH_GPIO_INTR) { 1389 if (dd->ipath_flags & IPATH_GPIO_INTR) {
1390 u64 val;
1391 ipath_write_kreg(dd, dd->ipath_kregs->kr_debugportselect, 1390 ipath_write_kreg(dd, dd->ipath_kregs->kr_debugportselect,
1392 0x2074076542310ULL); 1391 0x2074076542310ULL);
1393 /* Enable GPIO bit 2 interrupt */ 1392 /* Enable GPIO bit 2 interrupt */
1394 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask); 1393 dd->ipath_gpio_mask |= (u64) (1 << IPATH_GPIO_PORT0_BIT);
1395 val |= (u64) (1 << IPATH_GPIO_PORT0_BIT); 1394 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask,
1396 ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val); 1395 dd->ipath_gpio_mask);
1397 } 1396 }
1398 1397
1399 init_timer(&dd->verbs_timer); 1398 init_timer(&dd->verbs_timer);
@@ -1412,8 +1411,9 @@ static int disable_timer(struct ipath_devdata *dd)
1412 u64 val; 1411 u64 val;
1413 /* Disable GPIO bit 2 interrupt */ 1412 /* Disable GPIO bit 2 interrupt */
1414 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask); 1413 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask);
1415 val &= ~((u64) (1 << IPATH_GPIO_PORT0_BIT)); 1414 dd->ipath_gpio_mask &= ~((u64) (1 << IPATH_GPIO_PORT0_BIT));
1416 ipath_write_kreg( dd, dd->ipath_kregs->kr_gpio_mask, val); 1415 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask,
1416 dd->ipath_gpio_mask);
1417 /* 1417 /*
1418 * We might want to undo changes to debugportselect, 1418 * We might want to undo changes to debugportselect,
1419 * but how? 1419 * but how?