diff options
author | Michael Albaugh <michael.albaugh@qlogic.com> | 2007-05-17 10:05:04 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-07-09 23:12:25 -0400 |
commit | 17b2eb9fe6bfadcb3ece308ed50193d10b71ba6e (patch) | |
tree | 567c1e7d11cc14990ecabd11fe23b1941a2ebcfd /drivers/infiniband/hw/ipath/ipath_iba6110.c | |
parent | 82466f00ec6ef0a5ca7ea8991c731af2ec561c7d (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.c | 3 |
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 | ||
1108 | static void ipath_init_ht_variables(struct ipath_devdata *dd) | 1111 | static void ipath_init_ht_variables(struct ipath_devdata *dd) |