aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/i2c-core.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 7161f913de14..ddd1b83f44d4 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -33,6 +33,8 @@
33#include <linux/platform_device.h> 33#include <linux/platform_device.h>
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35#include <linux/completion.h> 35#include <linux/completion.h>
36#include <linux/hardirq.h>
37#include <linux/irqflags.h>
36#include <asm/uaccess.h> 38#include <asm/uaccess.h>
37#include <asm/semaphore.h> 39#include <asm/semaphore.h>
38 40
@@ -861,7 +863,15 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
861 } 863 }
862#endif 864#endif
863 865
864 mutex_lock_nested(&adap->bus_lock, adap->level); 866 if (in_atomic() || irqs_disabled()) {
867 ret = mutex_trylock(&adap->bus_lock);
868 if (!ret)
869 /* I2C activity is ongoing. */
870 return -EAGAIN;
871 } else {
872 mutex_lock_nested(&adap->bus_lock, adap->level);
873 }
874
865 ret = adap->algo->master_xfer(adap,msgs,num); 875 ret = adap->algo->master_xfer(adap,msgs,num);
866 mutex_unlock(&adap->bus_lock); 876 mutex_unlock(&adap->bus_lock);
867 877