aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core-base.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-09 14:41:55 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-09 14:41:55 -0700
commit45182e4e1f8ac04708ca7508c51d9103f07d81ab (patch)
treeec8e7131c686bfec6cdd8a7ba6757d5b8fef22bb /drivers/i2c/i2c-core-base.c
parentMerge tag 'nfs-for-5.2-1' of git://git.linux-nfs.org/projects/anna/linux-nfs (diff)
parentdt-bindings: i2c: riic: document r7s9210 support (diff)
downloadlinux-dev-45182e4e1f8ac04708ca7508c51d9103f07d81ab.tar.xz
linux-dev-45182e4e1f8ac04708ca7508c51d9103f07d81ab.zip
Merge branch 'i2c/for-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang: - API for late atomic transfers (e.g. to shut down via PMIC). We have a seperate callback now which is called under clearly defined conditions. In-kernel users are converted, too. - new driver for the AMD PCIe MP2 I2C controller - large refactoring for at91 and bcm-iproc (both gain slave support due to this) - and a good share of various driver improvements anf fixes * 'i2c/for-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (57 commits) dt-bindings: i2c: riic: document r7s9210 support i2c: imx-lpi2c: Use __maybe_unused instead of #if CONFIG_PM_SLEEP i2c-piix4: Add Hygon Dhyana SMBus support i2c: core: apply 'is_suspended' check for SMBus, too i2c: core: ratelimit 'transfer when suspended' errors i2c: iproc: Change driver to use 'BIT' macro i2c: riic: Add Runtime PM support i2c: mux: demux-pinctrl: use struct_size() in devm_kzalloc() i2c: mux: pca954x: allow management of device idle state via sysfs i2c: mux: pca9541: remove support for unused platform data i2c: mux: pca954x: remove support for unused platform data dt-bindings: i2c: i2c-mtk: add support for MT8516 i2c: axxia: use auto cmd for last message i2c: gpio: flag atomic capability if possible i2c: algo: bit: add flag to whitelist atomic transfers i2c: stu300: use xfer_atomic callback to bail out early i2c: ocores: enable atomic xfers i2c: ocores: refactor setup for polling i2c: tegra-bpmp: convert to use new atomic callbacks i2c: omap: Add the master_xfer_atomic hook ...
Diffstat (limited to 'drivers/i2c/i2c-core-base.c')
-rw-r--r--drivers/i2c/i2c-core-base.c23
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);