diff options
| -rw-r--r-- | drivers/i2c/i2c-core.c | 39 | ||||
| -rw-r--r-- | include/linux/i2c.h | 20 |
2 files changed, 37 insertions, 22 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 6e1c2f54d9cf..e09e143379b1 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -430,6 +430,35 @@ static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr) | |||
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | /** | 432 | /** |
| 433 | * i2c_lock_adapter - Get exclusive access to an I2C bus segment | ||
| 434 | * @adapter: Target I2C bus segment | ||
| 435 | */ | ||
| 436 | void i2c_lock_adapter(struct i2c_adapter *adapter) | ||
| 437 | { | ||
| 438 | rt_mutex_lock(&adapter->bus_lock); | ||
| 439 | } | ||
| 440 | EXPORT_SYMBOL_GPL(i2c_lock_adapter); | ||
| 441 | |||
| 442 | /** | ||
| 443 | * i2c_trylock_adapter - Try to get exclusive access to an I2C bus segment | ||
| 444 | * @adapter: Target I2C bus segment | ||
| 445 | */ | ||
| 446 | static int i2c_trylock_adapter(struct i2c_adapter *adapter) | ||
| 447 | { | ||
| 448 | return rt_mutex_trylock(&adapter->bus_lock); | ||
| 449 | } | ||
| 450 | |||
| 451 | /** | ||
| 452 | * i2c_unlock_adapter - Release exclusive access to an I2C bus segment | ||
| 453 | * @adapter: Target I2C bus segment | ||
| 454 | */ | ||
| 455 | void i2c_unlock_adapter(struct i2c_adapter *adapter) | ||
| 456 | { | ||
| 457 | rt_mutex_unlock(&adapter->bus_lock); | ||
| 458 | } | ||
| 459 | EXPORT_SYMBOL_GPL(i2c_unlock_adapter); | ||
| 460 | |||
| 461 | /** | ||
| 433 | * i2c_new_device - instantiate an i2c device | 462 | * i2c_new_device - instantiate an i2c device |
| 434 | * @adap: the adapter managing the device | 463 | * @adap: the adapter managing the device |
| 435 | * @info: describes one I2C device; bus_num is ignored | 464 | * @info: describes one I2C device; bus_num is ignored |
| @@ -1238,12 +1267,12 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
| 1238 | #endif | 1267 | #endif |
| 1239 | 1268 | ||
| 1240 | if (in_atomic() || irqs_disabled()) { | 1269 | if (in_atomic() || irqs_disabled()) { |
| 1241 | ret = rt_mutex_trylock(&adap->bus_lock); | 1270 | ret = i2c_trylock_adapter(adap); |
| 1242 | if (!ret) | 1271 | if (!ret) |
| 1243 | /* I2C activity is ongoing. */ | 1272 | /* I2C activity is ongoing. */ |
| 1244 | return -EAGAIN; | 1273 | return -EAGAIN; |
| 1245 | } else { | 1274 | } else { |
| 1246 | rt_mutex_lock(&adap->bus_lock); | 1275 | i2c_lock_adapter(adap); |
| 1247 | } | 1276 | } |
| 1248 | 1277 | ||
| 1249 | /* Retry automatically on arbitration loss */ | 1278 | /* Retry automatically on arbitration loss */ |
| @@ -1255,7 +1284,7 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
| 1255 | if (time_after(jiffies, orig_jiffies + adap->timeout)) | 1284 | if (time_after(jiffies, orig_jiffies + adap->timeout)) |
| 1256 | break; | 1285 | break; |
| 1257 | } | 1286 | } |
| 1258 | rt_mutex_unlock(&adap->bus_lock); | 1287 | i2c_unlock_adapter(adap); |
| 1259 | 1288 | ||
| 1260 | return ret; | 1289 | return ret; |
| 1261 | } else { | 1290 | } else { |
| @@ -2013,7 +2042,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, | |||
| 2013 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; | 2042 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; |
| 2014 | 2043 | ||
| 2015 | if (adapter->algo->smbus_xfer) { | 2044 | if (adapter->algo->smbus_xfer) { |
| 2016 | rt_mutex_lock(&adapter->bus_lock); | 2045 | i2c_lock_adapter(adapter); |
| 2017 | 2046 | ||
| 2018 | /* Retry automatically on arbitration loss */ | 2047 | /* Retry automatically on arbitration loss */ |
| 2019 | orig_jiffies = jiffies; | 2048 | orig_jiffies = jiffies; |
| @@ -2027,7 +2056,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, | |||
| 2027 | orig_jiffies + adapter->timeout)) | 2056 | orig_jiffies + adapter->timeout)) |
| 2028 | break; | 2057 | break; |
| 2029 | } | 2058 | } |
| 2030 | rt_mutex_unlock(&adapter->bus_lock); | 2059 | i2c_unlock_adapter(adapter); |
| 2031 | } else | 2060 | } else |
| 2032 | res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, | 2061 | res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, |
| 2033 | command, protocol, data); | 2062 | command, protocol, data); |
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index c8627e453e97..5bf0f4beea31 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
| @@ -382,23 +382,9 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data) | |||
| 382 | dev_set_drvdata(&dev->dev, data); | 382 | dev_set_drvdata(&dev->dev, data); |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | /** | 385 | /* Adapter locking functions, exported for shared pin cases */ |
| 386 | * i2c_lock_adapter - Prevent access to an I2C bus segment | 386 | void i2c_lock_adapter(struct i2c_adapter *); |
| 387 | * @adapter: Target I2C bus segment | 387 | void i2c_unlock_adapter(struct i2c_adapter *); |
| 388 | */ | ||
| 389 | static inline void i2c_lock_adapter(struct i2c_adapter *adapter) | ||
| 390 | { | ||
| 391 | rt_mutex_lock(&adapter->bus_lock); | ||
| 392 | } | ||
| 393 | |||
| 394 | /** | ||
| 395 | * i2c_unlock_adapter - Reauthorize access to an I2C bus segment | ||
| 396 | * @adapter: Target I2C bus segment | ||
| 397 | */ | ||
| 398 | static inline void i2c_unlock_adapter(struct i2c_adapter *adapter) | ||
| 399 | { | ||
| 400 | rt_mutex_unlock(&adapter->bus_lock); | ||
| 401 | } | ||
| 402 | 388 | ||
| 403 | /*flags for the client struct: */ | 389 | /*flags for the client struct: */ |
| 404 | #define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ | 390 | #define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ |
