i2c: smbus: add unlocked __i2c_smbus_xfer variant
Removes all locking from i2c_smbus_xfer and renames it to __i2c_smbus_xfer, then adds a new i2c_smbus_xfer function that simply grabs the lock while calling the unlocked variant. This is not perfectly equivalent, since i2c_smbus_xfer was callable from atomic/irq context if you happened to end up emulating SMBus with an I2C transfer, and that is no longer the case with this patch. It is unknown (to me) if anything depends on that quirk, but it seems fragile enough to simply break those cases and require them to call i2c_transfer directly instead. While at it, for consistency rename the 2nd to last argument (size) of the i2c_smbus_xfer declaration to protocol and remove the surplus extern marker. Signed-off-by: Peter Rosin <peda@axentia.se> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
This commit is contained in:
parent
021c91791a
commit
eef5ba1aa1
|
@ -463,7 +463,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr,
|
||||||
msg[num-1].len++;
|
msg[num-1].len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = i2c_transfer(adapter, msg, num);
|
status = __i2c_transfer(adapter, msg, num);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (status != num) {
|
if (status != num) {
|
||||||
|
@ -524,9 +524,24 @@ cleanup:
|
||||||
* This executes an SMBus protocol operation, and returns a negative
|
* This executes an SMBus protocol operation, and returns a negative
|
||||||
* errno code else zero on success.
|
* errno code else zero on success.
|
||||||
*/
|
*/
|
||||||
s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
|
s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
|
||||||
char read_write, u8 command, int protocol,
|
unsigned short flags, char read_write,
|
||||||
union i2c_smbus_data *data)
|
u8 command, int protocol, union i2c_smbus_data *data)
|
||||||
|
{
|
||||||
|
s32 res;
|
||||||
|
|
||||||
|
i2c_lock_bus(adapter, I2C_LOCK_SEGMENT);
|
||||||
|
res = __i2c_smbus_xfer(adapter, addr, flags, read_write,
|
||||||
|
command, protocol, data);
|
||||||
|
i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(i2c_smbus_xfer);
|
||||||
|
|
||||||
|
s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
|
||||||
|
unsigned short flags, char read_write,
|
||||||
|
u8 command, int protocol, union i2c_smbus_data *data)
|
||||||
{
|
{
|
||||||
unsigned long orig_jiffies;
|
unsigned long orig_jiffies;
|
||||||
int try;
|
int try;
|
||||||
|
@ -543,8 +558,6 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
|
||||||
flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB;
|
flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB;
|
||||||
|
|
||||||
if (adapter->algo->smbus_xfer) {
|
if (adapter->algo->smbus_xfer) {
|
||||||
i2c_lock_bus(adapter, I2C_LOCK_SEGMENT);
|
|
||||||
|
|
||||||
/* Retry automatically on arbitration loss */
|
/* Retry automatically on arbitration loss */
|
||||||
orig_jiffies = jiffies;
|
orig_jiffies = jiffies;
|
||||||
for (res = 0, try = 0; try <= adapter->retries; try++) {
|
for (res = 0, try = 0; try <= adapter->retries; try++) {
|
||||||
|
@ -557,7 +570,6 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
|
||||||
orig_jiffies + adapter->timeout))
|
orig_jiffies + adapter->timeout))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i2c_unlock_bus(adapter, I2C_LOCK_SEGMENT);
|
|
||||||
|
|
||||||
if (res != -EOPNOTSUPP || !adapter->algo->master_xfer)
|
if (res != -EOPNOTSUPP || !adapter->algo->master_xfer)
|
||||||
goto trace;
|
goto trace;
|
||||||
|
@ -579,7 +591,7 @@ trace:
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(i2c_smbus_xfer);
|
EXPORT_SYMBOL(__i2c_smbus_xfer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate
|
* i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate
|
||||||
|
|
|
@ -140,9 +140,14 @@ extern int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
|
||||||
and probably just as fast.
|
and probably just as fast.
|
||||||
Note that we use i2c_adapter here, because you do not need a specific
|
Note that we use i2c_adapter here, because you do not need a specific
|
||||||
smbus adapter to call this function. */
|
smbus adapter to call this function. */
|
||||||
extern s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
|
s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
|
||||||
unsigned short flags, char read_write, u8 command,
|
unsigned short flags, char read_write, u8 command,
|
||||||
int size, union i2c_smbus_data *data);
|
int protocol, union i2c_smbus_data *data);
|
||||||
|
|
||||||
|
/* Unlocked flavor */
|
||||||
|
s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
|
||||||
|
unsigned short flags, char read_write, u8 command,
|
||||||
|
int protocol, union i2c_smbus_data *data);
|
||||||
|
|
||||||
/* Now follow the 'nice' access routines. These also document the calling
|
/* Now follow the 'nice' access routines. These also document the calling
|
||||||
conventions of i2c_smbus_xfer. */
|
conventions of i2c_smbus_xfer. */
|
||||||
|
|
Loading…
Reference in New Issue