diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-19 17:48:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-19 17:48:12 -0700 |
commit | 78975f23cba0cd195db01cdbd6eb48138a655890 (patch) | |
tree | 0e808c0cfe220bd8fb00d66985d71655345904cb /include/linux/i2c.h | |
parent | feaa7cb5c59416143432829b15826be76605b8fe (diff) | |
parent | 73e8b0528346e88a0624f2d9821f382cd6256677 (diff) |
Merge branch 'i2c/for-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
- Peter Rosin did some major rework on the locking of i2c muxes by
seperating parent-locked muxes and mux-locked muxes.
This avoids deadlocks/workarounds when the mux itself needs i2c
commands for muxing. And as a side-effect, other workarounds in the
media layer could be eliminated. Also, Peter stepped up as the i2c
mux maintainer and will keep an eye on these changes.
- major updates to the octeon driver
- add a helper to the core to generate the address+rw_bit octal and
make drivers use it
- quite a bunch of driver updates
* 'i2c/for-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (84 commits)
i2c: rcar: add DMA support
i2c: st: Implement bus clear
i2c: only check scl functions when using generic recovery
i2c: algo-bit: declare i2c_bit_quirk_no_clk_stretch as static
i2c: tegra: disable clock before returning error
[media] rtl2832: regmap is aware of lockdep, drop local locking hack
[media] rtl2832_sdr: get rid of empty regmap wrappers
[media] rtl2832: change the i2c gate to be mux-locked
[media] si2168: change the i2c gate to be mux-locked
iio: imu: inv_mpu6050: change the i2c gate to be mux-locked
i2c: mux: document i2c muxes and elaborate on parent-/mux-locked muxes
i2c: mux: relax locking of the top i2c adapter during mux-locked muxing
i2c: muxes always lock the parent adapter
i2c: allow adapter drivers to override the adapter locking
i2c: uniphier: add "\n" at the end of error log
i2c: mv64xxx: remove CONFIG_HAVE_CLK conditionals
i2c: mv64xxx: use clk_{prepare_enable,disable_unprepare}
i2c: mv64xxx: handle probe deferral for the clock
i2c: mv64xxx: enable the driver on ARCH_MVEBU
i2c: octeon: Add workaround for broken irqs on CN3860
...
Diffstat (limited to 'include/linux/i2c.h')
-rw-r--r-- | include/linux/i2c.h | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 200cf13b00f6..96a25ae14494 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -524,6 +524,7 @@ struct i2c_adapter { /* data fields that are valid for all devices */ struct rt_mutex bus_lock; + struct rt_mutex mux_lock; int timeout; /* in jiffies */ int retries; @@ -538,6 +539,10 @@ struct i2c_adapter { struct i2c_bus_recovery_info *bus_recovery_info; const struct i2c_adapter_quirks *quirks; + + void (*lock_bus)(struct i2c_adapter *, unsigned int flags); + int (*trylock_bus)(struct i2c_adapter *, unsigned int flags); + void (*unlock_bus)(struct i2c_adapter *, unsigned int flags); }; #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) @@ -567,8 +572,44 @@ i2c_parent_is_i2c_adapter(const struct i2c_adapter *adapter) int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *)); /* Adapter locking functions, exported for shared pin cases */ -void i2c_lock_adapter(struct i2c_adapter *); -void i2c_unlock_adapter(struct i2c_adapter *); +#define I2C_LOCK_ROOT_ADAPTER BIT(0) +#define I2C_LOCK_SEGMENT BIT(1) + +/** + * i2c_lock_bus - Get exclusive access to an I2C bus segment + * @adapter: Target I2C bus segment + * @flags: I2C_LOCK_ROOT_ADAPTER locks the root i2c adapter, I2C_LOCK_SEGMENT + * locks only this branch in the adapter tree + */ +static inline void +i2c_lock_bus(struct i2c_adapter *adapter, unsigned int flags) +{ + adapter->lock_bus(adapter, flags); +} + +/** + * i2c_unlock_bus - Release exclusive access to an I2C bus segment + * @adapter: Target I2C bus segment + * @flags: I2C_LOCK_ROOT_ADAPTER unlocks the root i2c adapter, I2C_LOCK_SEGMENT + * unlocks only this branch in the adapter tree + */ +static inline void +i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags) +{ + adapter->unlock_bus(adapter, flags); +} + +static inline void +i2c_lock_adapter(struct i2c_adapter *adapter) +{ + i2c_lock_bus(adapter, I2C_LOCK_ROOT_ADAPTER); +} + +static inline void +i2c_unlock_adapter(struct i2c_adapter *adapter) +{ + i2c_unlock_bus(adapter, I2C_LOCK_ROOT_ADAPTER); +} /*flags for the client struct: */ #define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ @@ -654,6 +695,11 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap) return adap->nr; } +static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg) +{ + return (msg->addr << 1) | (msg->flags & I2C_M_RD ? 1 : 0); +} + /** * module_i2c_driver() - Helper macro for registering a modular I2C driver * @__i2c_driver: i2c_driver struct |