Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Jan Dabros <jsd@semihalf.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>

authored by

Jan Dabros and committed by
Wolfram Sang
6960331d 6cf72f41

+18
+12
drivers/i2c/busses/i2c-designware-common.c
··· 578 578 * Try to detect the FIFO depth if not set by interface driver, 579 579 * the depth could be from 2 to 256 from HW spec. 580 580 */ 581 + ret = i2c_dw_acquire_lock(dev); 582 + if (ret) 583 + return ret; 584 + 581 585 ret = regmap_read(dev->map, DW_IC_COMP_PARAM_1, &param); 586 + i2c_dw_release_lock(dev); 582 587 if (ret) 583 588 return ret; 584 589 ··· 612 607 void i2c_dw_disable(struct dw_i2c_dev *dev) 613 608 { 614 609 u32 dummy; 610 + int ret; 611 + 612 + ret = i2c_dw_acquire_lock(dev); 613 + if (ret) 614 + return; 615 615 616 616 /* Disable controller */ 617 617 __i2c_dw_disable(dev); ··· 624 614 /* Disable all interrupts */ 625 615 regmap_write(dev->map, DW_IC_INTR_MASK, 0); 626 616 regmap_read(dev->map, DW_IC_CLR_INTR, &dummy); 617 + 618 + i2c_dw_release_lock(dev); 627 619 } 628 620 629 621 void i2c_dw_disable_int(struct dw_i2c_dev *dev)
+6
drivers/i2c/busses/i2c-designware-master.c
··· 905 905 irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND; 906 906 } 907 907 908 + ret = i2c_dw_acquire_lock(dev); 909 + if (ret) 910 + return ret; 911 + 908 912 i2c_dw_disable_int(dev); 913 + i2c_dw_release_lock(dev); 914 + 909 915 ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, irq_flags, 910 916 dev_name(dev->dev), dev); 911 917 if (ret) {