aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath/ipath_iba6110.c
diff options
context:
space:
mode:
authorMichael Albaugh <michael.albaugh@qlogic.com>2007-05-17 10:05:04 -0400
committerRoland Dreier <rolandd@cisco.com>2007-07-09 23:12:25 -0400
commit17b2eb9fe6bfadcb3ece308ed50193d10b71ba6e (patch)
tree567c1e7d11cc14990ecabd11fe23b1941a2ebcfd /drivers/infiniband/hw/ipath/ipath_iba6110.c
parent82466f00ec6ef0a5ca7ea8991c731af2ec561c7d (diff)
IB/ipath: Lock and always use shadow copies of GPIO register
The new LED blinking interface adds more contention for the unprotected GPIO pins that were already shared, though not commonly at the same time. We add locks to the accesses to these pins so that Read-Modify-Write is now safe. Some of these locks are added at interrupt context, so we shadow the registers which drive and inspect these pins to avoid the mmio read/writes. This mitigates the effects of the locks and hastens us through the interrupt. Add locking and always use shadows for registers controlling GPIO pins (ExtCtrl and GPIOout). The use of shadows implies doing less I/O, which can make I2C operation too fast on some platforms. An explicit udelay(1) in SCL manipulation fixes that. Signed-off-by: Michael Albaugh <michael.albaugh@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_iba6110.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba6110.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c
index 4372c6c50ff6..8482ea366fb1 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba6110.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c
@@ -1059,6 +1059,7 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd,
1059 u64 lst, u64 ltst) 1059 u64 lst, u64 ltst)
1060{ 1060{
1061 u64 extctl; 1061 u64 extctl;
1062 unsigned long flags = 0;
1062 1063
1063 /* the diags use the LED to indicate diag info, so we leave 1064 /* the diags use the LED to indicate diag info, so we leave
1064 * the external LED alone when the diags are running */ 1065 * the external LED alone when the diags are running */
@@ -1075,6 +1076,7 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd,
1075 : INFINIPATH_IBCS_L_STATE_DOWN; 1076 : INFINIPATH_IBCS_L_STATE_DOWN;
1076 } 1077 }
1077 1078
1079 spin_lock_irqsave(&dd->ipath_gpio_lock, flags);
1078 /* 1080 /*
1079 * start by setting both LED control bits to off, then turn 1081 * start by setting both LED control bits to off, then turn
1080 * on the appropriate bit(s). 1082 * on the appropriate bit(s).
@@ -1103,6 +1105,7 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd,
1103 } 1105 }
1104 dd->ipath_extctrl = extctl; 1106 dd->ipath_extctrl = extctl;
1105 ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl); 1107 ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl);
1108 spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags);
1106} 1109}
1107 1110
1108static void ipath_init_ht_variables(struct ipath_devdata *dd) 1111static void ipath_init_ht_variables(struct ipath_devdata *dd)