Skip to content

Commit cea443a

Browse files
Mike RapoportJean Delvare
authored andcommitted
i2c: Support i2c_transfer in atomic contexts
Allow i2c_transfer to be called in contexts where sleeping is not allowed. It is the reponsability of the caller to ensure that the underlying i2c bus driver will not sleep either. Signed-off-by: Mike Rapoport <mike@compulab.co.il> Signed-off-by: Jean Delvare <khali@linux-fr.org>
1 parent 5271071 commit cea443a

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

drivers/i2c/i2c-core.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include <linux/platform_device.h>
3434
#include <linux/mutex.h>
3535
#include <linux/completion.h>
36+
#include <linux/hardirq.h>
37+
#include <linux/irqflags.h>
3638
#include <asm/uaccess.h>
3739
#include <asm/semaphore.h>
3840

@@ -861,7 +863,15 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
861863
}
862864
#endif
863865

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+
865875
ret = adap->algo->master_xfer(adap,msgs,num);
866876
mutex_unlock(&adap->bus_lock);
867877

0 commit comments

Comments
 (0)