diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-14 11:25:37 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-14 11:25:37 -0800 |
commit | 32250e4a5fa0b618044afa59fba01093a4bcb14a (patch) | |
tree | 678461393befc77b25e8d68cb637529927d3c284 /drivers/i2c/busses/i2c-designware-core.c | |
parent | 5339f9d4c2ceccab00b28d65bd5c2b2cd6a3de05 (diff) | |
parent | c698d639f72b55686ec3518d2bc8dc5f2eca9354 (diff) |
Merge branch 'i2c/for-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
"Quite some driver updates:
- piix4 can now handle multiplexed adapters
- brcmstb, xlr, eg20t, designware drivers support more SoCs
- emev2 gained i2c slave support
- img-scb and rcar got bigger refactoring to remove issues
- lots of common driver updates
i2c core changes:
- new quirk flag when an adapter does not support clock stretching,
so clients can be configured to avoid that if possible
- added a helper function to retrieve timing parameters from firmware
(with rcar being the first user)
- "multi-master" DT binding added so drivers can adapt to this
setting (like disabling PM to keep arbitration working)
- RuntimePM for the logical adapter device is now always enabled by
the core to ensure propagation from childs to the parent (the HW
device)
- new macro builtin_i2c_driver to reduce boilerplate"
* 'i2c/for-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (70 commits)
i2c: create builtin_i2c_driver to avoid registration boilerplate
i2c: imx: fix i2c resource leak with dma transfer
dt-bindings: i2c: eeprom: add another EEPROM device
dt-bindings: move I2C eeprom descriptions to the proper file
i2c: designware: Do not require clock when SSCN and FFCN are provided
DT: i2c: trivial-devices: Add Epson RX8010 and MPL3115
i2c: s3c2410: remove superfluous runtime PM calls
i2c: always enable RuntimePM for the adapter device
i2c: designware: retry transfer on transient failure
i2c: ibm_iic: rename i2c_timings struct due to clash with generic version
i2c: designware: Add support for AMD Seattle I2C
i2c: imx: Remove unneeded comments
i2c: st: use to_platform_device()
i2c: designware: use to_pci_dev()
i2c: brcmstb: Adding support for CM and DSL SoCs
i2c: mediatek: fix i2c multi transfer issue in high speed mode
i2c: imx: improve code readability
i2c: imx: Improve message log when DMA is not used
i2c: imx: add runtime pm support to improve the performance
i2c: imx: init bus recovery info before adding i2c adapter
...
Diffstat (limited to 'drivers/i2c/busses/i2c-designware-core.c')
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index de7fbbb374cd..ba9732c236c5 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -271,6 +271,17 @@ static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) enable ? "en" : "dis"); } +static unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev) +{ + /* + * Clock is not necessary if we got LCNT/HCNT values directly from + * the platform code. + */ + if (WARN_ON_ONCE(!dev->get_clk_rate_khz)) + return 0; + return dev->get_clk_rate_khz(dev); +} + /** * i2c_dw_init() - initialize the designware i2c master hardware * @dev: device private data @@ -281,7 +292,6 @@ static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) */ int i2c_dw_init(struct dw_i2c_dev *dev) { - u32 input_clock_khz; u32 hcnt, lcnt; u32 reg; u32 sda_falling_time, scl_falling_time; @@ -295,8 +305,6 @@ int i2c_dw_init(struct dw_i2c_dev *dev) } } - input_clock_khz = dev->get_clk_rate_khz(dev); - reg = dw_readl(dev, DW_IC_COMP_TYPE); if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) { /* Configure register endianess access */ @@ -325,12 +333,12 @@ int i2c_dw_init(struct dw_i2c_dev *dev) hcnt = dev->ss_hcnt; lcnt = dev->ss_lcnt; } else { - hcnt = i2c_dw_scl_hcnt(input_clock_khz, + hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev), 4000, /* tHD;STA = tHIGH = 4.0 us */ sda_falling_time, 0, /* 0: DW default, 1: Ideal */ 0); /* No offset */ - lcnt = i2c_dw_scl_lcnt(input_clock_khz, + lcnt = i2c_dw_scl_lcnt(i2c_dw_clk_rate(dev), 4700, /* tLOW = 4.7 us */ scl_falling_time, 0); /* No offset */ @@ -344,12 +352,12 @@ int i2c_dw_init(struct dw_i2c_dev *dev) hcnt = dev->fs_hcnt; lcnt = dev->fs_lcnt; } else { - hcnt = i2c_dw_scl_hcnt(input_clock_khz, + hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev), 600, /* tHD;STA = tHIGH = 0.6 us */ sda_falling_time, 0, /* 0: DW default, 1: Ideal */ 0); /* No offset */ - lcnt = i2c_dw_scl_lcnt(input_clock_khz, + lcnt = i2c_dw_scl_lcnt(i2c_dw_clk_rate(dev), 1300, /* tLOW = 1.3 us */ scl_falling_time, 0); /* No offset */ @@ -860,6 +868,7 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) snprintf(adap->name, sizeof(adap->name), "Synopsys DesignWare I2C adapter"); + adap->retries = 3; adap->algo = &i2c_dw_algo; adap->dev.parent = dev->dev; i2c_set_adapdata(adap, dev); |