diff options
Diffstat (limited to 'drivers/i2c/i2c-core-base.c')
| -rw-r--r-- | drivers/i2c/i2c-core-base.c | 23 | 
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 688aa3b5f3ac..9732a81bb7dd 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1871,8 +1871,10 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  	if (WARN_ON(!msgs || num < 1))  		return -EINVAL; -	if (WARN_ON(test_bit(I2C_ALF_IS_SUSPENDED, &adap->locked_flags))) -		return -ESHUTDOWN; + +	ret = __i2c_check_suspended(adap); +	if (ret) +		return ret;  	if (adap->quirks && i2c_check_for_quirks(adap, msgs, num))  		return -EOPNOTSUPP; @@ -1894,7 +1896,11 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  	/* Retry automatically on arbitration loss */  	orig_jiffies = jiffies;  	for (ret = 0, try = 0; try <= adap->retries; try++) { -		ret = adap->algo->master_xfer(adap, msgs, num); +		if (i2c_in_atomic_xfer_mode() && adap->algo->master_xfer_atomic) +			ret = adap->algo->master_xfer_atomic(adap, msgs, num); +		else +			ret = adap->algo->master_xfer(adap, msgs, num); +  		if (ret != -EAGAIN)  			break;  		if (time_after(jiffies, orig_jiffies + adap->timeout)) @@ -1950,14 +1956,9 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  	 *    one (discarding status on the second message) or errno  	 *    (discarding status on the first one).  	 */ -	if (in_atomic() || irqs_disabled()) { -		ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT); -		if (!ret) -			/* I2C activity is ongoing. */ -			return -EAGAIN; -	} else { -		i2c_lock_bus(adap, I2C_LOCK_SEGMENT); -	} +	ret = __i2c_lock_bus_helper(adap); +	if (ret) +		return ret;  	ret = __i2c_transfer(adap, msgs, num);  	i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);  |