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

i2c: designware: Add i2c bus locking support

Adds support for acquiring and releasing a hardware bus lock in the i2c
designware core transfer function. This is needed for i2c bus controllers
that are shared with but not controlled by the kernel.

Signed-off-by: David E. Box <david.e.box@linux.intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

authored by

David Box and committed by
Wolfram Sang
c0601d28 72f02715

+32
+26
drivers/i2c/busses/i2c-designware-core.c
··· 285 285 u32 hcnt, lcnt; 286 286 u32 reg; 287 287 u32 sda_falling_time, scl_falling_time; 288 + int ret; 289 + 290 + if (dev->acquire_lock) { 291 + ret = dev->acquire_lock(dev); 292 + if (ret) { 293 + dev_err(dev->dev, "couldn't acquire bus ownership\n"); 294 + return ret; 295 + } 296 + } 288 297 289 298 input_clock_khz = dev->get_clk_rate_khz(dev); 290 299 ··· 307 298 } else if (reg != DW_IC_COMP_TYPE_VALUE) { 308 299 dev_err(dev->dev, "Unknown Synopsys component type: " 309 300 "0x%08x\n", reg); 301 + if (dev->release_lock) 302 + dev->release_lock(dev); 310 303 return -ENODEV; 311 304 } 312 305 ··· 375 364 376 365 /* configure the i2c master */ 377 366 dw_writel(dev, dev->master_cfg , DW_IC_CON); 367 + 368 + if (dev->release_lock) 369 + dev->release_lock(dev); 378 370 return 0; 379 371 } 380 372 EXPORT_SYMBOL_GPL(i2c_dw_init); ··· 641 627 dev->abort_source = 0; 642 628 dev->rx_outstanding = 0; 643 629 630 + if (dev->acquire_lock) { 631 + ret = dev->acquire_lock(dev); 632 + if (ret) { 633 + dev_err(dev->dev, "couldn't acquire bus ownership\n"); 634 + goto done_nolock; 635 + } 636 + } 637 + 644 638 ret = i2c_dw_wait_bus_not_busy(dev); 645 639 if (ret < 0) 646 640 goto done; ··· 694 672 ret = -EIO; 695 673 696 674 done: 675 + if (dev->release_lock) 676 + dev->release_lock(dev); 677 + 678 + done_nolock: 697 679 pm_runtime_mark_last_busy(dev->dev); 698 680 pm_runtime_put_autosuspend(dev->dev); 699 681 mutex_unlock(&dev->lock);
+6
drivers/i2c/busses/i2c-designware-core.h
··· 61 61 * @ss_lcnt: standard speed LCNT value 62 62 * @fs_hcnt: fast speed HCNT value 63 63 * @fs_lcnt: fast speed LCNT value 64 + * @acquire_lock: function to acquire a hardware lock on the bus 65 + * @release_lock: function to release a hardware lock on the bus 66 + * @pm_runtime_disabled: true if pm runtime is disabled 64 67 * 65 68 * HCNT and LCNT parameters can be used if the platform knows more accurate 66 69 * values than the one computed based only on the input clock frequency. ··· 104 101 u16 ss_lcnt; 105 102 u16 fs_hcnt; 106 103 u16 fs_lcnt; 104 + int (*acquire_lock)(struct dw_i2c_dev *dev); 105 + void (*release_lock)(struct dw_i2c_dev *dev); 106 + bool pm_runtime_disabled; 107 107 }; 108 108 109 109 #define ACCESS_SWAP 0x00000001