diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-10 00:41:55 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-10 00:41:55 +0300 |
commit | 45182e4e1f8ac04708ca7508c51d9103f07d81ab (patch) | |
tree | ec8e7131c686bfec6cdd8a7ba6757d5b8fef22bb /drivers/i2c/i2c-core-base.c | |
parent | 06cbd26d312edfe4a83ff541c23f8f866265eb24 (diff) | |
parent | e6ae3ca27477226eae77cc00d5fad89d7ce64aea (diff) | |
download | linux-45182e4e1f8ac04708ca7508c51d9103f07d81ab.tar.xz |
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.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); |