From cea443a81c9c6257bf2d00f1392f7d1d4ce03b75 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Sun, 27 Jan 2008 18:14:50 +0100 Subject: [PATCH] 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 Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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 @@ #include #include #include +#include +#include #include #include @@ -861,7 +863,15 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) } #endif - mutex_lock_nested(&adap->bus_lock, adap->level); + if (in_atomic() || irqs_disabled()) { + ret = mutex_trylock(&adap->bus_lock); + if (!ret) + /* I2C activity is ongoing. */ + return -EAGAIN; + } else { + mutex_lock_nested(&adap->bus_lock, adap->level); + } + ret = adap->algo->master_xfer(adap,msgs,num); mutex_unlock(&adap->bus_lock);