diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-22 12:47:40 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-22 12:47:40 -0700 |
commit | b852495908cd1b02ad47672a83f622ad4264801b (patch) | |
tree | 71d5c3b46098bd5bca165837f06c9f65db7d4678 | |
parent | 5266e5b12c8b73587130325f7074d2f49ef9e427 (diff) | |
parent | 886f6f8337dd506e9ae0e45ee13eef3a0ceebd03 (diff) |
Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
"Mostly usual driver updates and improvements. The changelog should
give an idea. Standing out is the i2c-qup driver with lots of new
capabilities and we also have now an i2c-demuxer.
I'd especially like to welcome Peter Rosin as the i2c-mux maintainer.
He has an interesting series for muxes in the queue and agreed to look
after this part of the subsystem. Thank you, Peter, and welcome
again!
The octeon changes were applied pretty recently before the merge
window. I am aware. They are the first (and relatively simple)
patches of a larger overhaul to this driver. In case something goes
wrong with them, they are easy to fix (or revert). The advantage I
see is that they are out of the way, and I can concentrate on the next
block of patches. I really would like to apply the overhaul in
smaller batches to avoid regressions. And waiting a cycle for the
introductory patches seemed too much of a delay for me"
* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (39 commits)
i2c: octeon: Support I2C_M_RECV_LEN
i2c: octeon: Cleanup resource allocation code
i2c: octeon: Cleanup i2c-octeon driver
MAINTAINERS: add Peter Rosin as i2c mux maintainer
dt-bindings: i2c: Spelling s/propoerty/property/
i2c: immediately mark ourselves as registered
i2c: i801: sort IDs alphabetically
MAINTAINERS: Mika and me are designated reviewers for I2C DESIGNWARE
i2c: octeon: Cleanup kerneldoc comments
i2c: do not use internal data from driver core
i2c: cadence: Fix the kernel-doc warnings
i2c: imx: remove extra spaces.
i2c: rcar: don't open code of_device_get_match_data()
i2c: qup: Fix fifo handling after adding V2 support
i2c: xiic: Implement power management
i2c: piix4: Pre-shift the port number
i2c: piix4: Always use the same type for port
i2c: piix4: Support alternative port selection register
i2c: tegra: don't open code of_device_get_match_data()
i2c: riic, sh_mobile, rcar: Use ARCH_RENESAS
...
31 files changed, 1893 insertions, 372 deletions
diff --git a/Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl b/Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl new file mode 100644 index 000000000000..7ac7d7262bb7 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl @@ -0,0 +1,23 @@ +What: /sys/devices/platform/<i2c-demux-name>/cur_master +Date: January 2016 +KernelVersion: 4.6 +Contact: Wolfram Sang <wsa@the-dreams.de> +Description: + +This file selects the active I2C master for a demultiplexed bus. + +Write 0 there for the first master, 1 for the second etc. Reading the file will +give you a list with the active master marked. Example from a Renesas Lager +board: + +root@Lager:~# cat /sys/devices/platform/i2c@8/cur_master +* 0 - /i2c@9 + 1 - /i2c@e6520000 + 2 - /i2c@e6530000 + +root@Lager:~# echo 2 > /sys/devices/platform/i2c@8/cur_master + +root@Lager:~# cat /sys/devices/platform/i2c@8/cur_master + 0 - /i2c@9 + 1 - /i2c@e6520000 +* 2 - /i2c@e6530000 diff --git a/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt new file mode 100644 index 000000000000..6078aefe7ed4 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt @@ -0,0 +1,135 @@ +Pinctrl-based I2C Bus DeMux + +This binding describes an I2C bus demultiplexer that uses pin multiplexing to +route the I2C signals, and represents the pin multiplexing configuration using +the pinctrl device tree bindings. This may be used to select one I2C IP core at +runtime which may have a better feature set for a given task than another I2C +IP core on the SoC. The most simple example is to fall back to GPIO bitbanging +if your current runtime configuration hits an errata of the internal IP core. + + +-------------------------------+ + | SoC | + | | +-----+ +-----+ + | +------------+ | | dev | | dev | + | |I2C IP Core1|--\ | +-----+ +-----+ + | +------------+ \-------+ | | | + | |Pinctrl|--|------+--------+ + | +------------+ +-------+ | + | |I2C IP Core2|--/ | + | +------------+ | + | | + +-------------------------------+ + +Required properties: +- compatible: "i2c-demux-pinctrl" +- i2c-parent: List of phandles of I2C masters available for selection. The first + one will be used as default. +- i2c-bus-name: The name of this bus. Also needed as pinctrl-name for the I2C + parents. + +Furthermore, I2C mux properties and child nodes. See mux.txt in this directory. + +Example: + +Here is a snipplet for a bus to be demuxed. It contains various i2c clients for +HDMI, so the bus is named "i2c-hdmi": + + i2chdmi: i2c@8 { + + compatible = "i2c-demux-pinctrl"; + i2c-parent = <&gpioi2c>, <&iic2>, <&i2c2>; + i2c-bus-name = "i2c-hdmi"; + #address-cells = <1>; + #size-cells = <0>; + + ak4643: sound-codec@12 { + compatible = "asahi-kasei,ak4643"; + + #sound-dai-cells = <0>; + reg = <0x12>; + }; + + composite-in@20 { + compatible = "adi,adv7180"; + reg = <0x20>; + remote = <&vin1>; + + port { + adv7180: endpoint { + bus-width = <8>; + remote-endpoint = <&vin1ep0>; + }; + }; + }; + + hdmi@39 { + compatible = "adi,adv7511w"; + reg = <0x39>; + interrupt-parent = <&gpio1>; + interrupts = <15 IRQ_TYPE_LEVEL_LOW>; + + adi,input-depth = <8>; + adi,input-colorspace = "rgb"; + adi,input-clock = "1x"; + adi,input-style = <1>; + adi,input-justification = "evenly"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7511_in: endpoint { + remote-endpoint = <&du_out_lvds0>; + }; + }; + + port@1 { + reg = <1>; + adv7511_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; + }; + +And for clarification, here are the snipplets for the i2c-parents: + + gpioi2c: i2c@9 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "i2c-gpio"; + status = "disabled"; + gpios = <&gpio5 6 GPIO_ACTIVE_HIGH /* sda */ + &gpio5 5 GPIO_ACTIVE_HIGH /* scl */ + >; + i2c-gpio,delay-us = <5>; + }; + +... + +&i2c2 { + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "i2c-hdmi"; + + clock-frequency = <100000>; +}; + +... + +&iic2 { + pinctrl-0 = <&iic2_pins>; + pinctrl-names = "i2c-hdmi"; + + clock-frequency = <100000>; +}; + +Please note: + +- pinctrl properties for the parent I2C controllers need a pinctrl state + with the same name as i2c-bus-name, not "default"! + +- the i2c masters must have their status "disabled". This driver will + enable them at runtime when needed. diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.txt b/Documentation/devicetree/bindings/i2c/i2c-imx.txt index eab5836ba7f9..b967544590e8 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-imx.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-imx.txt @@ -11,7 +11,7 @@ Required properties: Optional properties: - clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz. - The absence of the propoerty indicates the default frequency 100 kHz. + The absence of the property indicates the default frequency 100 kHz. - dmas: A list of two dma specifiers, one for each entry in dma-names. - dma-names: should contain "tx" and "rx". - scl-gpios: specify the gpio related to SCL pin diff --git a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt index 95e97223a71c..cf8bfc956cdc 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt @@ -17,7 +17,7 @@ Required properties: Optional properties: - clock-frequency: desired I2C bus clock frequency in Hz. The absence of this - propoerty indicates the default frequency 100 kHz. + property indicates the default frequency 100 kHz. - clocks: clock specifier. - i2c-scl-falling-time-ns: see i2c.txt diff --git a/Documentation/devicetree/bindings/i2c/i2c-sirf.txt b/Documentation/devicetree/bindings/i2c/i2c-sirf.txt index 7baf9e133fa8..2701eefb00f7 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-sirf.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-sirf.txt @@ -8,7 +8,7 @@ Required properties : Optional properties: - clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz. - The absence of the propoerty indicates the default frequency 100 kHz. + The absence of the property indicates the default frequency 100 kHz. Examples : diff --git a/Documentation/devicetree/bindings/i2c/i2c-xiic.txt b/Documentation/devicetree/bindings/i2c/i2c-xiic.txt index ceabbe91ae44..caf42e989462 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-xiic.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-xiic.txt @@ -6,14 +6,17 @@ Required properties: - interrupts : IIC controller unterrupt - #address-cells = <1> - #size-cells = <0> +- clocks: Input clock specifier. Refer to common clock bindings. Optional properties: - Child nodes conforming to i2c bus binding +- clock-names: Input clock name, should be 'pclk'. Example: axi_iic_0: i2c@40800000 { compatible = "xlnx,xps-iic-2.00.a"; + clocks = <&clkc 15>; interrupts = < 1 2 >; reg = < 0x40800000 0x10000 >; diff --git a/MAINTAINERS b/MAINTAINERS index cc637cd31f3b..0f3063cce44c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5270,6 +5270,16 @@ F: include/linux/hyperv.h F: tools/hv/ F: Documentation/ABI/stable/sysfs-bus-vmbus +I2C MUXES +M: Peter Rosin <peda@axentia.se> +L: linux-i2c@vger.kernel.org +S: Maintained +F: Documentation/i2c/muxes/ +F: Documentation/devicetree/bindings/i2c/i2c-mux* +F: drivers/i2c/i2c-mux.c +F: drivers/i2c/muxes/ +F: include/linux/i2c-mux.h + I2C OVER PARALLEL PORT M: Jean Delvare <jdelvare@suse.com> L: linux-i2c@vger.kernel.org @@ -9676,9 +9686,9 @@ F: Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt F: drivers/net/ethernet/synopsys/dwc_eth_qos.c SYNOPSYS DESIGNWARE I2C DRIVER -M: Andy Shevchenko <andriy.shevchenko@linux.intel.com> M: Jarkko Nikula <jarkko.nikula@linux.intel.com> -M: Mika Westerberg <mika.westerberg@linux.intel.com> +R: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +R: Mika Westerberg <mika.westerberg@linux.intel.com> L: linux-i2c@vger.kernel.org S: Maintained F: drivers/i2c/busses/i2c-designware-* diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 0299dfa746a3..faa8e6821fea 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -789,7 +789,7 @@ config I2C_QUP config I2C_RIIC tristate "Renesas RIIC adapter" - depends on ARCH_SHMOBILE || COMPILE_TEST + depends on ARCH_RENESAS || COMPILE_TEST help If you say yes to this option, support will be included for the Renesas RIIC I2C interface. @@ -833,7 +833,7 @@ config I2C_SH7760 config I2C_SH_MOBILE tristate "SuperH Mobile I2C Controller" depends on HAS_DMA - depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST + depends on SUPERH || ARCH_RENESAS || COMPILE_TEST help If you say yes to this option, support will be included for the built-in I2C interface on the Renesas SH-Mobile processor. @@ -908,7 +908,7 @@ config I2C_TEGRA config I2C_UNIPHIER tristate "UniPhier FIFO-less I2C controller" - depends on ARCH_UNIPHIER + depends on ARCH_UNIPHIER || COMPILE_TEST help If you say yes to this option, support will be included for the UniPhier FIFO-less I2C interface embedded in PH1-LD4, PH1-sLD8, @@ -916,7 +916,7 @@ config I2C_UNIPHIER config I2C_UNIPHIER_F tristate "UniPhier FIFO-builtin I2C controller" - depends on ARCH_UNIPHIER + depends on ARCH_UNIPHIER || COMPILE_TEST help If you say yes to this option, support will be included for the UniPhier FIFO-builtin I2C interface embedded in PH1-Pro4, @@ -985,7 +985,7 @@ config I2C_XLP9XX config I2C_RCAR tristate "Renesas R-Car I2C Controller" - depends on ARCH_SHMOBILE || COMPILE_TEST + depends on ARCH_RENESAS || COMPILE_TEST select I2C_SLAVE help If you say yes to this option, support will be included for the diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c index 0419f5284609..b9f0fff4e723 100644 --- a/drivers/i2c/busses/i2c-bcm-iproc.c +++ b/drivers/i2c/busses/i2c-bcm-iproc.c @@ -58,11 +58,13 @@ #define IE_M_RX_FIFO_FULL_SHIFT 31 #define IE_M_RX_THLD_SHIFT 30 #define IE_M_START_BUSY_SHIFT 28 +#define IE_M_TX_UNDERRUN_SHIFT 27 #define IS_OFFSET 0x3c #define IS_M_RX_FIFO_FULL_SHIFT 31 #define IS_M_RX_THLD_SHIFT 30 #define IS_M_START_BUSY_SHIFT 28 +#define IS_M_TX_UNDERRUN_SHIFT 27 #define M_TX_OFFSET 0x40 #define M_TX_WR_STATUS_SHIFT 31 @@ -76,7 +78,7 @@ #define M_RX_DATA_SHIFT 0 #define M_RX_DATA_MASK 0xff -#define I2C_TIMEOUT_MESC 100 +#define I2C_TIMEOUT_MSEC 50000 #define M_TX_RX_FIFO_SIZE 64 enum bus_speed_index { @@ -95,12 +97,17 @@ struct bcm_iproc_i2c_dev { struct completion done; int xfer_is_done; + + struct i2c_msg *msg; + + /* bytes that have been transferred */ + unsigned int tx_bytes; }; /* * Can be expanded in the future if more interrupt status bits are utilized */ -#define ISR_MASK (1 << IS_M_START_BUSY_SHIFT) +#define ISR_MASK (BIT(IS_M_START_BUSY_SHIFT) | BIT(IS_M_TX_UNDERRUN_SHIFT)) static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data) { @@ -112,13 +119,95 @@ static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data) if (!status) return IRQ_NONE; + /* TX FIFO is empty and we have more data to send */ + if (status & BIT(IS_M_TX_UNDERRUN_SHIFT)) { + struct i2c_msg *msg = iproc_i2c->msg; + unsigned int tx_bytes = msg->len - iproc_i2c->tx_bytes; + unsigned int i; + u32 val; + + /* can only fill up to the FIFO size */ + tx_bytes = min_t(unsigned int, tx_bytes, M_TX_RX_FIFO_SIZE); + for (i = 0; i < tx_bytes; i++) { + /* start from where we left over */ + unsigned int idx = iproc_i2c->tx_bytes + i; + + val = msg->buf[idx]; + + /* mark the last byte */ + if (idx == msg->len - 1) { + u32 tmp; + + val |= BIT(M_TX_WR_STATUS_SHIFT); + + /* + * Since this is the last byte, we should + * now disable TX FIFO underrun interrupt + */ + tmp = readl(iproc_i2c->base + IE_OFFSET); + tmp &= ~BIT(IE_M_TX_UNDERRUN_SHIFT); + writel(tmp, iproc_i2c->base + IE_OFFSET); + } + + /* load data into TX FIFO */ + writel(val, iproc_i2c->base + M_TX_OFFSET); + } + /* update number of transferred bytes */ + iproc_i2c->tx_bytes += tx_bytes; + } + + if (status & BIT(IS_M_START_BUSY_SHIFT)) { + iproc_i2c->xfer_is_done = 1; + complete_all(&iproc_i2c->done); + } + writel(status, iproc_i2c->base + IS_OFFSET); - iproc_i2c->xfer_is_done = 1; - complete_all(&iproc_i2c->done); return IRQ_HANDLED; } +static int bcm_iproc_i2c_init(struct bcm_iproc_i2c_dev *iproc_i2c) +{ + u32 val; + + /* put controller in reset */ + val = readl(iproc_i2c->base + CFG_OFFSET); + val |= 1 << CFG_RESET_SHIFT; + val &= ~(1 << CFG_EN_SHIFT); + writel(val, iproc_i2c->base + CFG_OFFSET); + + /* wait 100 usec per spec */ + udelay(100); + + /* bring controller out of reset */ + val &= ~(1 << CFG_RESET_SHIFT); + writel(val, iproc_i2c->base + CFG_OFFSET); + + /* flush TX/RX FIFOs and set RX FIFO threshold to zero */ + val = (1 << M_FIFO_RX_FLUSH_SHIFT) | (1 << M_FIFO_TX_FLUSH_SHIFT); + writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); + /* disable all interrupts */ + writel(0, iproc_i2c->base + IE_OFFSET); + + /* clear all pending interrupts */ + writel(0xffffffff, iproc_i2c->base + IS_OFFSET); + + return 0; +} + +static void bcm_iproc_i2c_enable_disable(struct bcm_iproc_i2c_dev *iproc_i2c, + bool enable) +{ + u32 val; + + val = readl(iproc_i2c->base + CFG_OFFSET); + if (enable) + val |= BIT(CFG_EN_SHIFT); + else + val &= ~BIT(CFG_EN_SHIFT); + writel(val, iproc_i2c->base + CFG_OFFSET); +} + static int bcm_iproc_i2c_check_status(struct bcm_iproc_i2c_dev *iproc_i2c, struct i2c_msg *msg) { @@ -149,6 +238,12 @@ static int bcm_iproc_i2c_check_status(struct bcm_iproc_i2c_dev *iproc_i2c, default: dev_dbg(iproc_i2c->device, "unknown error code=%d\n", val); + + /* re-initialize i2c for recovery */ + bcm_iproc_i2c_enable_disable(iproc_i2c, false); + bcm_iproc_i2c_init(iproc_i2c); + bcm_iproc_i2c_enable_disable(iproc_i2c, true); + return -EIO; } } @@ -159,7 +254,8 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, int ret, i; u8 addr; u32 val; - unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT_MESC); + unsigned int tx_bytes; + unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT_MSEC); /* check if bus is busy */ if (!!(readl(iproc_i2c->base + M_CMD_OFFSET) & @@ -168,13 +264,20 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, return -EBUSY; } + iproc_i2c->msg = msg; + /* format and load slave address into the TX FIFO */ addr = msg->addr << 1 | (msg->flags & I2C_M_RD ? 1 : 0); writel(addr, iproc_i2c->base + M_TX_OFFSET); - /* for a write transaction, load data into the TX FIFO */ + /* + * For a write transaction, load data into the TX FIFO. Only allow + * loading up to TX FIFO size - 1 bytes of data since the first byte + * has been used up by the slave address + */ + tx_bytes = min_t(unsigned int, msg->len, M_TX_RX_FIFO_SIZE - 1); if (!(msg->flags & I2C_M_RD)) { - for (i = 0; i < msg->len; i++) { + for (i = 0; i < tx_bytes; i++) { val = msg->buf[i]; /* mark the last byte */ @@ -183,6 +286,7 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, writel(val, iproc_i2c->base + M_TX_OFFSET); } + iproc_i2c->tx_bytes = tx_bytes; } /* mark as incomplete before starting the transaction */ @@ -194,13 +298,24 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, * transaction is done, i.e., the internal start_busy bit, transitions * from 1 to 0. */ - writel(1 << IE_M_START_BUSY_SHIFT, iproc_i2c->base + IE_OFFSET); + val = BIT(IE_M_START_BUSY_SHIFT); + + /* + * If TX data size is larger than the TX FIFO, need to enable TX + * underrun interrupt, which will be triggerred when the TX FIFO is + * empty. When that happens we can then pump more data into the FIFO + */ + if (!(msg->flags & I2C_M_RD) && + msg->len > iproc_i2c->tx_bytes) + val |= BIT(IE_M_TX_UNDERRUN_SHIFT); + + writel(val, iproc_i2c->base + IE_OFFSET); /* * Now we can activate the transfer. For a read operation, specify the * number of bytes to read */ - val = 1 << M_CMD_START_BUSY_SHIFT; + val = BIT(M_CMD_START_BUSY_SHIFT); if (msg->flags & I2C_M_RD) { val |= (M_CMD_PROTOCOL_BLK_RD << M_CMD_PROTOCOL_SHIFT) | (msg->len << M_CMD_RD_CNT_SHIFT); @@ -283,7 +398,6 @@ static const struct i2c_algorithm bcm_iproc_algo = { static struct i2c_adapter_quirks bcm_iproc_i2c_quirks = { /* need to reserve one byte in the FIFO for the slave address */ .max_read_len = M_TX_RX_FIFO_SIZE - 1, - .max_write_len = M_TX_RX_FIFO_SIZE - 1, }; static int bcm_iproc_i2c_cfg_speed(struct bcm_iproc_i2c_dev *iproc_i2c) @@ -321,49 +435,6 @@ static int bcm_iproc_i2c_cfg_speed(struct bcm_iproc_i2c_dev *iproc_i2c) return 0; } -static int bcm_iproc_i2c_init(struct bcm_iproc_i2c_dev *iproc_i2c) -{ - u32 val; - - /* put controller in reset */ - val = readl(iproc_i2c->base + CFG_OFFSET); - val |= 1 << CFG_RESET_SHIFT; - val &= ~(1 << CFG_EN_SHIFT); - writel(val, iproc_i2c->base + CFG_OFFSET); - - /* wait 100 usec per spec */ - udelay(100); - - /* bring controller out of reset */ - val &= ~(1 << CFG_RESET_SHIFT); - writel(val, iproc_i2c->base + CFG_OFFSET); - - /* flush TX/RX FIFOs and set RX FIFO threshold to zero */ - val = (1 << M_FIFO_RX_FLUSH_SHIFT) | (1 << M_FIFO_TX_FLUSH_SHIFT); - writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); - - /* disable all interrupts */ - writel(0, iproc_i2c->base + IE_OFFSET); - - /* clear all pending interrupts */ - writel(0xffffffff, iproc_i2c->base + IS_OFFSET); - - return 0; -} - -static void bcm_iproc_i2c_enable_disable(struct bcm_iproc_i2c_dev *iproc_i2c, - bool enable) -{ - u32 val; - - val = readl(iproc_i2c->base + CFG_OFFSET); - if (enable) - val |= BIT(CFG_EN_SHIFT); - else - val &= ~BIT(CFG_EN_SHIFT); - writel(val, iproc_i2c->base + CFG_OFFSET); -} - static int bcm_iproc_i2c_probe(struct platform_device *pdev) { int irq, ret = 0; diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 6b08d1607b7a..90bbd9f9dd8f 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -124,6 +124,8 @@ /** * struct cdns_i2c - I2C device private data structure + * + * @dev: Pointer to device structure * @membase: Base address of the I2C device * @adap: I2C adapter instance * @p_msg: Message pointer @@ -171,7 +173,7 @@ struct cdns_platform_data { clk_rate_change_nb) /** - * cdns_i2c_clear_bus_hold() - Clear bus hold bit + * cdns_i2c_clear_bus_hold - Clear bus hold bit * @id: Pointer to driver data struct * * Helper to clear the controller's bus hold bit. @@ -815,8 +817,8 @@ static int cdns_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long } /** - * cdns_i2c_suspend - Suspend method for the driver - * @_dev: Address of the platform_device structure + * cdns_i2c_runtime_suspend - Runtime suspend method for the driver + * @dev: Address of the platform_device structure * * Put the driver into low power mode. * @@ -833,10 +835,10 @@ static int __maybe_unused cdns_i2c_runtime_suspend(struct device *dev) } /** - * cdns_i2c_resume - Resume from suspend - * @_dev: Address of the platform_device structure + * cdns_i2c_runtime_resume - Runtime resume + * @dev: Address of the platform_device structure * - * Resume operation after suspend. + * Runtime resume callback. * * Return: 0 on success and error value on error */ diff --git a/drivers/i2c/busses/i2c-designware-baytrail.c b/drivers/i2c/busses/i2c-designware-baytrail.c index e38c2bbba940..1590ad0a8081 100644 --- a/drivers/i2c/busses/i2c-designware-baytrail.c +++ b/drivers/i2c/busses/i2c-designware-baytrail.c @@ -11,7 +11,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. */ -#include <linux/module.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/acpi.h> @@ -151,7 +150,3 @@ int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev) return 0; } - -MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>"); -MODULE_DESCRIPTION("Baytrail I2C Semaphore driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 10fbd6d841e0..99b54be6ba73 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -634,7 +634,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); - mutex_lock(&dev->lock); pm_runtime_get_sync(dev->dev); reinit_completion(&dev->cmd_complete); @@ -673,11 +672,12 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) } /* - * We must disable the adapter before unlocking the &dev->lock mutex - * below. Otherwise the hardware might continue generating interrupts - * which in turn causes a race condition with the following transfer. - * Needs some more investigation if the additional interrupts are - * a hardware bug or this driver doesn't handle them correctly yet. + * We must disable the adapter before returning and signaling the end + * of the current transfer. Otherwise the hardware might continue + * generating interrupts which in turn causes a race condition with + * the following transfer. Needs some more investigation if the + * additional interrupts are a hardware bug or this driver doesn't + * handle them correctly yet. */ __i2c_dw_enable(dev, false); @@ -706,7 +706,6 @@ done: done_nolock: pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); - mutex_unlock(&dev->lock); return ret; } @@ -860,7 +859,6 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) int r; init_completion(&dev->cmd_complete); - mutex_init(&dev->lock); r = i2c_dw_init(dev); if (r) @@ -883,9 +881,17 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) return r; } + /* + * Increment PM usage count during adapter registration in order to + * avoid possible spurious runtime suspend when adapter device is + * registered to the device core and immediate resume in case bus has + * registered I2C slaves that do I2C transfers in their probe. + */ + pm_runtime_get_noresume(dev->dev); r = i2c_add_numbered_adapter(adap); if (r) dev_err(dev->dev, "failure adding adapter: %d\n", r); + pm_runtime_put_noidle(dev->dev); return r; } diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 9ffb63a60f95..cd409e7fbc71 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -36,7 +36,6 @@ * @dev: driver model device node * @base: IO registers pointer * @cmd_complete: tx completion indicator - * @lock: protect this struct and IO registers * @clk: input reference clock * @cmd_err: run time hadware error code * @msgs: points to an array of messages currently being transfered @@ -73,7 +72,6 @@ struct dw_i2c_dev { struct device *dev; void __iomem *base; struct completion cmd_complete; - struct mutex lock; struct clk *clk; u32 (*get_clk_rate_khz) (struct dw_i2c_dev *dev); struct dw_pci_controller *controller; diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 27fa0cb09538..585a3b7915bd 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -184,7 +184,7 @@ /* Older devices have their ID defined in <linux/pci_ids.h> */ #define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 -#define PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS 0x2292 +#define PCI_DEVICE_ID_INTEL_DNV_SMBUS 0x19df #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ @@ -193,9 +193,11 @@ #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72 #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22 #define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS 0x1f3c +#define PCI_DEVICE_ID_INTEL_BRASWELL_SMBUS 0x2292 #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 |