Commit 6960331d authored by Jan Dabros's avatar Jan Dabros Committed by Wolfram Sang

i2c: designware: Add missing locks

All accesses to controller's registers should be protected on
probe, disable and xfer paths. This is needed for i2c bus controllers
that are shared with but not controller by kernel.
Signed-off-by: default avatarJan Dabros <jsd@semihalf.com>
Reviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Acked-by: default avatarJarkko Nikula <jarkko.nikula@linux.intel.com>
Tested-by: default avatarJarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarWolfram Sang <wsa@kernel.org>
parent 6cf72f41
...@@ -578,7 +578,12 @@ int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev) ...@@ -578,7 +578,12 @@ int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev)
* Try to detect the FIFO depth if not set by interface driver, * Try to detect the FIFO depth if not set by interface driver,
* the depth could be from 2 to 256 from HW spec. * the depth could be from 2 to 256 from HW spec.
*/ */
ret = i2c_dw_acquire_lock(dev);
if (ret)
return ret;
ret = regmap_read(dev->map, DW_IC_COMP_PARAM_1, &param); ret = regmap_read(dev->map, DW_IC_COMP_PARAM_1, &param);
i2c_dw_release_lock(dev);
if (ret) if (ret)
return ret; return ret;
...@@ -607,6 +612,11 @@ u32 i2c_dw_func(struct i2c_adapter *adap) ...@@ -607,6 +612,11 @@ u32 i2c_dw_func(struct i2c_adapter *adap)
void i2c_dw_disable(struct dw_i2c_dev *dev) void i2c_dw_disable(struct dw_i2c_dev *dev)
{ {
u32 dummy; u32 dummy;
int ret;
ret = i2c_dw_acquire_lock(dev);
if (ret)
return;
/* Disable controller */ /* Disable controller */
__i2c_dw_disable(dev); __i2c_dw_disable(dev);
...@@ -614,6 +624,8 @@ void i2c_dw_disable(struct dw_i2c_dev *dev) ...@@ -614,6 +624,8 @@ void i2c_dw_disable(struct dw_i2c_dev *dev)
/* Disable all interrupts */ /* Disable all interrupts */
regmap_write(dev->map, DW_IC_INTR_MASK, 0); regmap_write(dev->map, DW_IC_INTR_MASK, 0);
regmap_read(dev->map, DW_IC_CLR_INTR, &dummy); regmap_read(dev->map, DW_IC_CLR_INTR, &dummy);
i2c_dw_release_lock(dev);
} }
void i2c_dw_disable_int(struct dw_i2c_dev *dev) void i2c_dw_disable_int(struct dw_i2c_dev *dev)
......
...@@ -905,7 +905,13 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) ...@@ -905,7 +905,13 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev)
irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND; irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND;
} }
ret = i2c_dw_acquire_lock(dev);
if (ret)
return ret;
i2c_dw_disable_int(dev); i2c_dw_disable_int(dev);
i2c_dw_release_lock(dev);
ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, irq_flags, ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, irq_flags,
dev_name(dev->dev), dev); dev_name(dev->dev), dev);
if (ret) { if (ret) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment