Merge tag 'i2c-for-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 20 May 2024 15:55:18 +0000 (08:55 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 20 May 2024 15:55:18 +0000 (08:55 -0700)
Pull i2c updates from Wolfram Sang:
 "i2c core removes an argument from the i2c_mux_add_adapter() call to
  further deprecate class based I2C device instantiation. All users are
  converted, too.

  Other that that, Andi collected a number if I2C host driver patches.
  Those merges have their own description"

* tag 'i2c-for-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (72 commits)
  power: supply: sbs-manager: Remove class argument from i2c_mux_add_adapter()
  i2c: mux: Remove class argument from i2c_mux_add_adapter()
  i2c: synquacer: Fix an error handling path in synquacer_i2c_probe()
  i2c: acpi: Unbind mux adapters before delete
  i2c: designware: Replace MODULE_ALIAS() with MODULE_DEVICE_TABLE()
  i2c: pxa: use 'time_left' variable with wait_event_timeout()
  i2c: s3c2410: use 'time_left' variable with wait_event_timeout()
  i2c: rk3x: use 'time_left' variable with wait_event_timeout()
  i2c: qcom-geni: use 'time_left' variable with wait_for_completion_timeout()
  i2c: jz4780: use 'time_left' variable with wait_for_completion_timeout()
  i2c: synquacer: use 'time_left' variable with wait_for_completion_timeout()
  i2c: stm32f7: use 'time_left' variable with wait_for_completion_timeout()
  i2c: stm32f4: use 'time_left' variable with wait_for_completion_timeout()
  i2c: st: use 'time_left' variable with wait_for_completion_timeout()
  i2c: omap: use 'time_left' variable with wait_for_completion_timeout()
  i2c: imx-lpi2c: use 'time_left' variable with wait_for_completion_timeout()
  i2c: hix5hd2: use 'time_left' variable with wait_for_completion_timeout()
  i2c: exynos5: use 'time_left' variable with wait_for_completion_timeout()
  i2c: digicolor: use 'time_left' variable with wait_for_completion_timeout()
  i2c: amd-mp2-plat: use 'time_left' variable with wait_for_completion_timeout()
  ...

79 files changed:
Documentation/devicetree/bindings/i2c/i2c-pnx.txt [deleted file]
Documentation/devicetree/bindings/i2c/nxp,pnx-i2c.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml
Documentation/devicetree/bindings/i2c/renesas,riic.yaml
MAINTAINERS
drivers/gpu/drm/bridge/sii902x.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-ali1535.c
drivers/i2c/busses/i2c-ali1563.c
drivers/i2c/busses/i2c-ali15x3.c
drivers/i2c/busses/i2c-amd-mp2-plat.c
drivers/i2c/busses/i2c-at91-master.c
drivers/i2c/busses/i2c-bcm-iproc.c
drivers/i2c/busses/i2c-bcm2835.c
drivers/i2c/busses/i2c-cadence.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-designware-pcidrv.c
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-digicolor.c
drivers/i2c/busses/i2c-exynos5.c
drivers/i2c/busses/i2c-hix5hd2.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-img-scb.c
drivers/i2c/busses/i2c-imx-lpi2c.c
drivers/i2c/busses/i2c-ismt.c
drivers/i2c/busses/i2c-jz4780.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-nomadik.c
drivers/i2c/busses/i2c-ocores.c
drivers/i2c/busses/i2c-octeon-core.c
drivers/i2c/busses/i2c-octeon-core.h
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/busses/i2c-qcom-geni.c
drivers/i2c/busses/i2c-qup.c
drivers/i2c/busses/i2c-riic.c
drivers/i2c/busses/i2c-rk3x.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-sh_mobile.c
drivers/i2c/busses/i2c-st.c
drivers/i2c/busses/i2c-stm32f4.c
drivers/i2c/busses/i2c-stm32f7.c
drivers/i2c/busses/i2c-synquacer.c
drivers/i2c/busses/i2c-tegra.c
drivers/i2c/busses/i2c-thunderx-pcidrv.c
drivers/i2c/busses/i2c-uniphier-f.c
drivers/i2c/busses/i2c-uniphier.c
drivers/i2c/busses/i2c-viai2c-common.c [new file with mode: 0644]
drivers/i2c/busses/i2c-viai2c-common.h [new file with mode: 0644]
drivers/i2c/busses/i2c-viai2c-wmt.c [new file with mode: 0644]
drivers/i2c/busses/i2c-viai2c-zhaoxin.c [new file with mode: 0644]
drivers/i2c/busses/i2c-viperboard.c
drivers/i2c/busses/i2c-wmt.c [deleted file]
drivers/i2c/i2c-core-acpi.c
drivers/i2c/i2c-mux.c
drivers/i2c/muxes/i2c-arb-gpio-challenge.c
drivers/i2c/muxes/i2c-mux-gpio.c
drivers/i2c/muxes/i2c-mux-gpmux.c
drivers/i2c/muxes/i2c-mux-ltc4306.c
drivers/i2c/muxes/i2c-mux-mlxcpld.c
drivers/i2c/muxes/i2c-mux-pca9541.c
drivers/i2c/muxes/i2c-mux-pca954x.c
drivers/i2c/muxes/i2c-mux-pinctrl.c
drivers/i2c/muxes/i2c-mux-reg.c
drivers/iio/gyro/mpu3050-i2c.c
drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
drivers/media/dvb-frontends/af9013.c
drivers/media/dvb-frontends/lgdt3306a.c
drivers/media/dvb-frontends/m88ds3103.c
drivers/media/dvb-frontends/rtl2830.c
drivers/media/dvb-frontends/rtl2832.c
drivers/media/dvb-frontends/si2168.c
drivers/media/i2c/max9286.c
drivers/media/usb/cx231xx/cx231xx-i2c.c
drivers/of/unittest.c
drivers/power/supply/sbs-manager.c
include/linux/i2c-mux.h
include/linux/platform_data/i2c-mux-gpio.h

diff --git a/Documentation/devicetree/bindings/i2c/i2c-pnx.txt b/Documentation/devicetree/bindings/i2c/i2c-pnx.txt
deleted file mode 100644 (file)
index 2a59006..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-* NXP PNX I2C Controller
-
-Required properties:
-
- - reg: Offset and length of the register set for the device
- - compatible: should be "nxp,pnx-i2c"
- - interrupts: configure one interrupt line
- - #address-cells: always 1 (for i2c addresses)
- - #size-cells: always 0
-
-Optional properties:
-
- - clock-frequency: desired I2C bus clock frequency in Hz, Default: 100000 Hz
-
-Examples:
-
-       i2c1: i2c@400a0000 {
-               compatible = "nxp,pnx-i2c";
-               reg = <0x400a0000 0x100>;
-               interrupt-parent = <&mic>;
-               interrupts = <51 0>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-       };
-
-       i2c2: i2c@400a8000 {
-               compatible = "nxp,pnx-i2c";
-               reg = <0x400a8000 0x100>;
-               interrupt-parent = <&mic>;
-               interrupts = <50 0>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-               clock-frequency = <100000>;
-       };
diff --git a/Documentation/devicetree/bindings/i2c/nxp,pnx-i2c.yaml b/Documentation/devicetree/bindings/i2c/nxp,pnx-i2c.yaml
new file mode 100644 (file)
index 0000000..798a693
--- /dev/null
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/nxp,pnx-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP PNX I2C Controller
+
+maintainers:
+  - Animesh Agarwal <animeshagarwal28@gmail.com>
+
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#
+
+properties:
+  compatible:
+    const: nxp,pnx-i2c
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clock-frequency:
+    default: 100000
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - "#address-cells"
+  - "#size-cells"
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c@400a0000 {
+        compatible = "nxp,pnx-i2c";
+        reg = <0x400a0000 0x100>;
+        interrupt-parent = <&mic>;
+        interrupts = <51 0>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+    };
index f0eabff863106afdaf8547fceb0126ae1147dc88..daf4e71b8e7f9326fff477e36e0d56672a9e8cdb 100644 (file)
@@ -26,6 +26,7 @@ properties:
       - items:
           - enum:
               - qcom,sc7280-cci
+              - qcom,sc8280xp-cci
               - qcom,sdm845-cci
               - qcom,sm6350-cci
               - qcom,sm8250-cci
@@ -176,6 +177,24 @@ allOf:
             - const: cci
             - const: cci_src
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,sc8280xp-cci
+    then:
+      properties:
+        clocks:
+          minItems: 4
+          maxItems: 4
+        clock-names:
+          items:
+            - const: camnoc_axi
+            - const: slow_ahb_src
+            - const: cpas_ahb
+            - const: cci
+
 additionalProperties: false
 
 examples:
index 2291a7cd619be4eedef4be803663fadc60f946a8..91ecf17b7a81a1447ef8adbcd1a8224228681a5c 100644 (file)
@@ -15,14 +15,17 @@ allOf:
 
 properties:
   compatible:
-    items:
-      - enum:
-          - renesas,riic-r7s72100   # RZ/A1H
-          - renesas,riic-r7s9210    # RZ/A2M
-          - renesas,riic-r9a07g043  # RZ/G2UL and RZ/Five
-          - renesas,riic-r9a07g044  # RZ/G2{L,LC}
-          - renesas,riic-r9a07g054  # RZ/V2L
-      - const: renesas,riic-rz      # RZ/A or RZ/G2L
+    oneOf:
+      - items:
+          - enum:
+              - renesas,riic-r7s72100   # RZ/A1H
+              - renesas,riic-r7s9210    # RZ/A2M
+              - renesas,riic-r9a07g043  # RZ/G2UL and RZ/Five
+              - renesas,riic-r9a07g044  # RZ/G2{L,LC}
+              - renesas,riic-r9a07g054  # RZ/V2L
+          - const: renesas,riic-rz      # RZ/A or RZ/G2L
+
+      - const: renesas,riic-r9a09g057   # RZ/V2H(P)
 
   reg:
     maxItems: 1
index bce6826991569e34783e32215f10df1efd6b4799..47bf2f680dfe3649a5c8dd6f7120a12ffd74c705 100644 (file)
@@ -2362,7 +2362,7 @@ M:        Vladimir Zapolskiy <vz@mleia.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 T:     git git://github.com/vzapolskiy/linux-lpc32xx.git
-F:     Documentation/devicetree/bindings/i2c/i2c-pnx.txt
+F:     Documentation/devicetree/bindings/i2c/nxp,pnx-i2c.yaml
 F:     arch/arm/boot/dts/nxp/lpc/lpc32*
 F:     arch/arm/mach-lpc32xx/
 F:     drivers/i2c/busses/i2c-pnx.c
@@ -3082,7 +3082,7 @@ S:        Orphan
 F:     Documentation/devicetree/bindings/i2c/i2c-wmt.txt
 F:     arch/arm/mach-vt8500/
 F:     drivers/clocksource/timer-vt8500.c
-F:     drivers/i2c/busses/i2c-wmt.c
+F:     drivers/i2c/busses/i2c-viai2c-wmt.c
 F:     drivers/mmc/host/wmt-sdmmc.c
 F:     drivers/pwm/pwm-vt8500.c
 F:     drivers/rtc/rtc-vt8500.c
@@ -10400,6 +10400,14 @@ L:     linux-i2c@vger.kernel.org
 F:     Documentation/i2c/busses/i2c-ismt.rst
 F:     drivers/i2c/busses/i2c-ismt.c
 
+I2C/SMBUS ZHAOXIN DRIVER
+M:     Hans Hu <hanshu@zhaoxin.com>
+L:     linux-i2c@vger.kernel.org
+S:     Maintained
+W:     https://www.zhaoxin.com
+F:     drivers/i2c/busses/i2c-viai2c-common.c
+F:     drivers/i2c/busses/i2c-viai2c-zhaoxin.c
+
 I2C/SMBUS STUB DRIVER
 M:     Jean Delvare <jdelvare@suse.com>
 L:     linux-i2c@vger.kernel.org
index 8f84e98249c74e9402b4ee6ca1459ee8e5f07be1..2fbeda9025bfc93008c02a0b5c23fc5a8a7cbe96 100644 (file)
@@ -1092,7 +1092,7 @@ static int sii902x_init(struct sii902x *sii902x)
        }
 
        sii902x->i2cmux->priv = sii902x;
-       ret = i2c_mux_add_adapter(sii902x->i2cmux, 0, 0, 0);
+       ret = i2c_mux_add_adapter(sii902x->i2cmux, 0, 0);
        if (ret)
                goto err_unreg_audio;
 
index 97989c914260f2893ee12ba2dca5ac202a1ed475..fe6e8a1bb6072115991e808e0d5327b55933d23f 100644 (file)
@@ -18,7 +18,7 @@ config I2C_CCGX_UCSI
 
 config I2C_ALI1535
        tristate "ALI 1535"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        help
          If you say yes to this option, support will be included for the SMB
          Host controller on Acer Labs Inc. (ALI) M1535 South Bridges.  The SMB
@@ -30,7 +30,7 @@ config I2C_ALI1535
 
 config I2C_ALI1563
        tristate "ALI 1563"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        help
          If you say yes to this option, support will be included for the SMB
          Host controller on Acer Labs Inc. (ALI) M1563 South Bridges.  The SMB
@@ -42,7 +42,7 @@ config I2C_ALI1563
 
 config I2C_ALI15X3
        tristate "ALI 15x3"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        help
          If you say yes to this option, support will be included for the
          Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces.
@@ -52,7 +52,7 @@ config I2C_ALI15X3
 
 config I2C_AMD756
        tristate "AMD 756/766/768/8111 and nVidia nForce"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        help
          If you say yes to this option, support will be included for the AMD
          756/766/768 mainboard I2C interfaces.  The driver also includes
@@ -77,7 +77,7 @@ config I2C_AMD756_S4882
 
 config I2C_AMD8111
        tristate "AMD 8111"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        help
          If you say yes to this option, support will be included for the
          second (SMBus 2.0) AMD 8111 mainboard I2C interface.
@@ -107,7 +107,7 @@ config I2C_HIX5HD2
 
 config I2C_I801
        tristate "Intel 82801 (ICH/PCH)"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        select P2SB if X86
        select CHECK_SIGNATURE if X86 && DMI
        select I2C_SMBUS
@@ -163,9 +163,17 @@ config I2C_I801
          This driver can also be built as a module.  If so, the module
          will be called i2c-i801.
 
+config I2C_I801_MUX
+       def_bool I2C_I801
+       depends on DMI && I2C_MUX_GPIO
+       depends on !(I2C_I801=y && I2C_MUX=m)
+       help
+         Optional support for multiplexed SMBUS on certain systems with
+         more than 8 memory slots.
+
 config I2C_ISCH
        tristate "Intel SCH SMBus 1.0"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        select LPC_SCH
        help
          Say Y here if you want to use SMBus controller on the Intel SCH
@@ -186,7 +194,7 @@ config I2C_ISMT
 
 config I2C_PIIX4
        tristate "Intel PIIX4 and compatible (ATI/AMD/Serverworks/Broadcom/SMSC)"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        help
          If you say yes to this option, support will be included for the Intel
          PIIX4 family of mainboard I2C interfaces.  Specifically, the following
@@ -232,7 +240,7 @@ config I2C_CHT_WC
 
 config I2C_NFORCE2
        tristate "Nvidia nForce2, nForce3 and nForce4"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        help
          If you say yes to this option, support will be included for the Nvidia
          nForce2, nForce3 and nForce4 families of mainboard I2C interfaces.
@@ -265,7 +273,7 @@ config I2C_NVIDIA_GPU
 
 config I2C_SIS5595
        tristate "SiS 5595"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        help
          If you say yes to this option, support will be included for the
          SiS5595 SMBus (a subset of I2C) interface.
@@ -275,7 +283,7 @@ config I2C_SIS5595
 
 config I2C_SIS630
        tristate "SiS 630/730/964"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        help
          If you say yes to this option, support will be included for the
          SiS630, SiS730 and SiS964 SMBus (a subset of I2C) interface.
@@ -285,7 +293,7 @@ config I2C_SIS630
 
 config I2C_SIS96X
        tristate "SiS 96x"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        help
          If you say yes to this option, support will be included for the SiS
          96x SMBus (a subset of I2C) interfaces.  Specifically, the following
@@ -303,7 +311,7 @@ config I2C_SIS96X
 
 config I2C_VIA
        tristate "VIA VT82C586B"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        select I2C_ALGOBIT
        help
          If you say yes to this option, support will be included for the VIA
@@ -314,7 +322,7 @@ config I2C_VIA
 
 config I2C_VIAPRO
        tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx/VX900"
-       depends on PCI
+       depends on PCI && HAS_IOPORT
        help
          If you say yes to this option, support will be included for the VIA
          VT82C596 and later SMBus interface.  Specifically, the following
@@ -336,6 +344,16 @@ config I2C_VIAPRO
 
 if ACPI
 
+config I2C_ZHAOXIN
+       tristate "Zhaoxin I2C Interface"
+       depends on PCI || COMPILE_TEST
+       help
+         If you say yes to this option, support will be included for the
+         ZHAOXIN I2C interface
+
+         This driver can also be built as a module. If so, the module
+         will be called i2c-zhaoxin.
+
 comment "ACPI drivers"
 
 config I2C_SCMI
@@ -500,7 +518,7 @@ config I2C_BRCMSTB
 
 config I2C_CADENCE
        tristate "Cadence I2C Controller"
-       depends on ARCH_ZYNQ || ARM64 || XTENSA || COMPILE_TEST
+       depends on ARCH_ZYNQ || ARM64 || XTENSA || RISCV || COMPILE_TEST
        help
          Say yes here to select Cadence I2C Host Controller. This controller is
          e.g. used by Xilinx Zynq.
@@ -1397,6 +1415,7 @@ config I2C_ICY
 config I2C_MLXCPLD
        tristate "Mellanox I2C driver"
        depends on X86_64 || (ARM64 && ACPI) || COMPILE_TEST
+       depends on HAS_IOPORT
        help
          This exposes the Mellanox platform I2C busses to the linux I2C layer
          for X86 and ARM64/ACPI based systems.
index aa0ee8ecd6f2f53ea109cfeacffe5e2682ae228e..3d65934f5eb4863f59ef2979850c5554395cc955 100644 (file)
@@ -29,6 +29,8 @@ obj-$(CONFIG_I2C_SIS630)      += i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)       += i2c-sis96x.o
 obj-$(CONFIG_I2C_VIA)          += i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)       += i2c-viapro.o
+i2c-zhaoxin-objs := i2c-viai2c-zhaoxin.o i2c-viai2c-common.o
+obj-$(CONFIG_I2C_ZHAOXIN)      += i2c-zhaoxin.o
 
 # Mac SMBus host controller drivers
 obj-$(CONFIG_I2C_HYDRA)                += i2c-hydra.o
@@ -118,6 +120,7 @@ obj-$(CONFIG_I2C_TEGRA_BPMP)        += i2c-tegra-bpmp.o
 obj-$(CONFIG_I2C_UNIPHIER)     += i2c-uniphier.o
 obj-$(CONFIG_I2C_UNIPHIER_F)   += i2c-uniphier-f.o
 obj-$(CONFIG_I2C_VERSATILE)    += i2c-versatile.o
+i2c-wmt-objs := i2c-viai2c-wmt.o i2c-viai2c-common.o
 obj-$(CONFIG_I2C_WMT)          += i2c-wmt.o
 i2c-octeon-objs := i2c-octeon-core.o i2c-octeon-platdrv.o
 obj-$(CONFIG_I2C_OCTEON)       += i2c-octeon.o
index 461eb23f9d476786bebadbbb79c888f6aa0a057f..9d7b4efe26ad01b8edfcbc3bd4e8aa30d0670a38 100644 (file)
@@ -285,10 +285,8 @@ static int ali1535_transaction(struct i2c_adapter *adap)
                 && (timeout++ < MAX_TIMEOUT));
 
        /* If the SMBus is still busy, we give up */
-       if (timeout > MAX_TIMEOUT) {
+       if (timeout > MAX_TIMEOUT)
                result = -ETIMEDOUT;
-               dev_err(&adap->dev, "SMBus Timeout!\n");
-       }
 
        if (temp & ALI1535_STS_FAIL) {
                result = -EIO;
@@ -313,10 +311,8 @@ static int ali1535_transaction(struct i2c_adapter *adap)
        }
 
        /* check to see if the "command complete" indication is set */
-       if (!(temp & ALI1535_STS_DONE)) {
+       if (!(temp & ALI1535_STS_DONE))
                result = -ETIMEDOUT;
-               dev_err(&adap->dev, "Error: command never completed\n");
-       }
 
        dev_dbg(&adap->dev, "Transaction (post): STS=%02x, TYP=%02x, "
                "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
index 307fb0666ecb2f296af23926fe3d5728d78fb74b..63897a89bb35f7f7e2602eb786b1d8b37222a8c3 100644 (file)
@@ -99,7 +99,6 @@ static int ali1563_transaction(struct i2c_adapter *a, int size)
                return 0;
 
        if (!timeout) {
-               dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n");
                /* Issue 'kill' to host controller */
                outb_p(HST_CNTL2_KILL, SMB_HST_CNTL2);
                data = inb_p(SMB_HST_STS);
index d2fa30deb054c7fafe0d2e1749ca53e684a1fa32..956e5020d71e2f9dd35f5c678bbbf0e5bdf650d6 100644 (file)
@@ -294,10 +294,8 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
                 && (timeout++ < MAX_TIMEOUT));
 
        /* If the SMBus is still busy, we give up */
-       if (timeout > MAX_TIMEOUT) {
+       if (timeout > MAX_TIMEOUT)
                result = -ETIMEDOUT;
-               dev_err(&adap->dev, "SMBus Timeout!\n");
-       }
 
        if (temp & ALI15X3_STS_TERM) {
                result = -EIO;
index 112fe2bc5662b29052fbed9727bafaa597cdaf11..d3ac1c77a5098d730e3397a8ce5a0518f9adb050 100644 (file)
@@ -97,17 +97,17 @@ static void i2c_amd_cmd_completion(struct amd_i2c_common *i2c_common)
 static int i2c_amd_check_cmd_completion(struct amd_i2c_dev *i2c_dev)
 {
        struct amd_i2c_common *i2c_common = &i2c_dev->common;
-       unsigned long timeout;
+       unsigned long time_left;
 
-       timeout = wait_for_completion_timeout(&i2c_dev->cmd_complete,
-                                             i2c_dev->adap.timeout);
+       time_left = wait_for_completion_timeout(&i2c_dev->cmd_complete,
+                                               i2c_dev->adap.timeout);
 
        if ((i2c_common->reqcmd == i2c_read ||
             i2c_common->reqcmd == i2c_write) &&
            i2c_common->msg->len > 32)
                i2c_amd_dma_unmap(i2c_common);
 
-       if (timeout == 0) {
+       if (time_left == 0) {
                amd_mp2_rw_timeout(i2c_common);
                return -ETIMEDOUT;
        }
index d311981d3e6088a0af09bc1465617503dcc71530..ee3b469ddfb98d64d2f40b30885b2836663f3262 100644 (file)
@@ -591,7 +591,6 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
                                              dev->adapter.timeout);
        if (time_left == 0) {
                dev->transfer_status |= at91_twi_read(dev, AT91_TWI_SR);
-               dev_err(dev->dev, "controller timed out\n");
                at91_init_twi_bus(dev);
                ret = -ETIMEDOUT;
                goto error;
index e905734c26a049c890b9e50a5270a8c9ee028502..133d02899c6bd77bd04a648cbf20c60abd43044d 100644 (file)
@@ -811,8 +811,6 @@ static int bcm_iproc_i2c_xfer_wait(struct bcm_iproc_i2c_dev *iproc_i2c,
        }
 
        if (!time_left && !iproc_i2c->xfer_is_done) {
-               dev_err(iproc_i2c->device, "transaction timed out\n");
-
                /* flush both TX/RX FIFOs */
                val = BIT(M_FIFO_RX_FLUSH_SHIFT) | BIT(M_FIFO_TX_FLUSH_SHIFT);
                iproc_i2c_wr_reg(iproc_i2c, M_FIFO_CTRL_OFFSET, val);
index b92de1944221691e91412f9c33ad3d4274917e48..3045ba82380dbdd73f16a33d74e3090ee4a2bff3 100644 (file)
@@ -370,7 +370,6 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
        if (!time_left) {
                bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C,
                                   BCM2835_I2C_C_CLEAR);
-               dev_err(i2c_dev->dev, "i2c transfer timed out\n");
                return -ETIMEDOUT;
        }
 
index 4bb7d6756947cd16a9ab64295dfaa650bd58677f..87b9ba95b2e134c4760c0ff26627e1e61027d6f0 100644 (file)
@@ -633,6 +633,7 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
 
        if (hold_clear) {
                ctrl_reg &= ~CDNS_I2C_CR_HOLD;
+               ctrl_reg &= ~CDNS_I2C_CR_CLR_FIFO;
                /*
                 * In case of Xilinx Zynq SOC, clear the HOLD bit before transfer size
                 * register reaches '0'. This is an IP bug which causes transfer size
@@ -789,8 +790,6 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg,
        time_left = wait_for_completion_timeout(&id->xfer_done, msg_timeout);
        if (time_left == 0) {
                cdns_i2c_master_reset(adap);
-               dev_err(id->adap.dev.parent,
-                               "timeout waiting on completion\n");
                return -ETIMEDOUT;
        }
 
index 02b3b1160fb062a9f64b2af166cdce225702a523..7ae611120cfa82eaec8477200dc2bdd6f788d61c 100644 (file)
@@ -489,7 +489,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
        time_left = wait_for_completion_timeout(&dev->cmd_complete,
                                                dev->adapter.timeout);
        if (!time_left) {
-               dev_err(dev->dev, "controller timed out\n");
                i2c_recover_bus(adap);
                dev->buf_len = 0;
                return -ETIMEDOUT;
index 9be9a2658e1f6ede697906827b26da319b098902..a1b379a1e9040127af7743e927baf49969cd88d9 100644 (file)
@@ -424,8 +424,6 @@ static struct pci_driver dw_i2c_driver = {
 };
 module_pci_driver(dw_i2c_driver);
 
-/* Work with hotplug and coldplug */
-MODULE_ALIAS("i2c_designware-pci");
 MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
 MODULE_DESCRIPTION("Synopsys DesignWare PCI I2C bus adapter");
 MODULE_LICENSE("GPL");
index 4ab41ba39d55fb6312c6ecc8068d894d7e37e936..29aac9c873684a8ab3d254ff4060cef6e610af62 100644 (file)
@@ -46,6 +46,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
        { "INT33C3", 0 },
        { "INT3432", 0 },
        { "INT3433", 0 },
+       { "INTC10EF", 0 },
        { "80860F41", ACCESS_NO_IRQ_SUSPEND },
        { "808622C1", ACCESS_NO_IRQ_SUSPEND },
        { "AMD0010", ACCESS_INTR_MASK },
@@ -479,8 +480,11 @@ static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
        RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend, dw_i2c_plat_runtime_resume, NULL)
 };
 
-/* Work with hotplug and coldplug */
-MODULE_ALIAS("platform:i2c_designware");
+static const struct platform_device_id dw_i2c_platform_ids[] = {
+       { "i2c_designware" },
+       {}
+};
+MODULE_DEVICE_TABLE(platform, dw_i2c_platform_ids);
 
 static struct platform_driver dw_i2c_driver = {
        .probe = dw_i2c_plat_probe,
@@ -491,6 +495,7 @@ static struct platform_driver dw_i2c_driver = {
                .acpi_match_table = ACPI_PTR(dw_i2c_acpi_match),
                .pm     = pm_ptr(&dw_i2c_dev_pm_ops),
        },
+       .id_table = dw_i2c_platform_ids,
 };
 
 static int __init dw_i2c_init_driver(void)
index 3462f2bc0fa87042a3a4f6f0790ad14b9dbfbab5..737604ae11fc6af045e3ee5cf660926ae025c1a8 100644 (file)
@@ -213,7 +213,7 @@ out:
 static int dc_i2c_xfer_msg(struct dc_i2c *i2c, struct i2c_msg *msg, int first,
                           int last)
 {
-       unsigned long timeout = msecs_to_jiffies(TIMEOUT_MS);
+       unsigned long time_left = msecs_to_jiffies(TIMEOUT_MS);
        unsigned long flags;
 
        spin_lock_irqsave(&i2c->lock, flags);
@@ -227,9 +227,9 @@ static int dc_i2c_xfer_msg(struct dc_i2c *i2c, struct i2c_msg *msg, int first,
        dc_i2c_start_msg(i2c, first);
        spin_unlock_irqrestore(&i2c->lock, flags);
 
-       timeout = wait_for_completion_timeout(&i2c->done, timeout);
+       time_left = wait_for_completion_timeout(&i2c->done, time_left);
        dc_i2c_set_irq(i2c, 0);
-       if (timeout == 0) {
+       if (time_left == 0) {
                i2c->state = STATE_IDLE;
                return -ETIMEDOUT;
        }
index 385ef9d9e4d4c00547e69da0b64a56058b82e6e5..d8baca9b610c3b5a6d000978e5bcd162f05ba9ed 100644 (file)
@@ -763,7 +763,7 @@ static bool exynos5_i2c_poll_irqs_timeout(struct exynos5_i2c *i2c,
 static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c,
                              struct i2c_msg *msgs, int stop)
 {
-       unsigned long timeout;
+       unsigned long time_left;
        int ret;
 
        i2c->msg = msgs;
@@ -775,13 +775,13 @@ static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c,
        exynos5_i2c_message_start(i2c, stop);
 
        if (!i2c->atomic)
-               timeout = wait_for_completion_timeout(&i2c->msg_complete,
-                                                     EXYNOS5_I2C_TIMEOUT);
-       else
-               timeout = exynos5_i2c_poll_irqs_timeout(i2c,
+               time_left = wait_for_completion_timeout(&i2c->msg_complete,
                                                        EXYNOS5_I2C_TIMEOUT);
+       else
+               time_left = exynos5_i2c_poll_irqs_timeout(i2c,
+                                                         EXYNOS5_I2C_TIMEOUT);
 
-       if (timeout == 0)
+       if (time_left == 0)
                ret = -ETIMEDOUT;
        else
                ret = i2c->state;
index 8e75515c3ca4784cf94d3245b0fdb1c2fd81401e..a47b9939fa2ce2cb7d5fb99746e65c7da75895fe 100644 (file)
@@ -314,7 +314,7 @@ static void hix5hd2_i2c_message_start(struct hix5hd2_i2c_priv *priv, int stop)
 static int hix5hd2_i2c_xfer_msg(struct hix5hd2_i2c_priv *priv,
                                struct i2c_msg *msgs, int stop)
 {
-       unsigned long timeout;
+       unsigned long time_left;
        int ret;
 
        priv->msg = msgs;
@@ -327,9 +327,9 @@ static int hix5hd2_i2c_xfer_msg(struct hix5hd2_i2c_priv *priv,
        reinit_completion(&priv->msg_complete);
        hix5hd2_i2c_message_start(priv, stop);
 
-       timeout = wait_for_completion_timeout(&priv->msg_complete,
-                                             priv->adap.timeout);
-       if (timeout == 0) {
+       time_left = wait_for_completion_timeout(&priv->msg_complete,
+                                               priv->adap.timeout);
+       if (time_left == 0) {
                priv->state = HIX5I2C_STAT_RW_ERR;
                priv->err = -ETIMEDOUT;
                dev_warn(priv->dev, "%s timeout=%d\n",
index 79870dd7a0146ead83e325a6f2c6b6a8e41a8b4c..d2d2a6dbe29f22d706e369ff84efef6a6663df33 100644 (file)
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
+#include <linux/i2c-mux.h>
 #include <linux/i2c-smbus.h>
 #include <linux/acpi.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
 #include <linux/mutex.h>
 
-#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
+#ifdef CONFIG_I2C_I801_MUX
 #include <linux/gpio/machine.h>
 #include <linux/platform_data/i2c-mux-gpio.h>
 #endif
@@ -263,7 +264,6 @@ struct i801_mux_config {
        char *gpio_chip;
        unsigned values[3];
        int n_values;
-       unsigned classes[3];
        unsigned gpios[2];              /* Relative to gpio_chip->base */
        int n_gpios;
 };
@@ -288,9 +288,10 @@ struct i801_priv {
        int len;
        u8 *data;
 
-#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
+#ifdef CONFIG_I2C_I801_MUX
        struct platform_device *mux_pdev;
        struct gpiod_lookup_table *lookup;
+       struct notifier_block mux_notifier_block;
 #endif
        struct platform_device *tco_pdev;
 
@@ -398,9 +399,7 @@ static int i801_check_post(struct i801_priv *priv, int status)
         * If the SMBus is still busy, we give up
         */
        if (unlikely(status < 0)) {
-               dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
                /* try to stop the current command */
-               dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n");
                outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv));
                usleep_range(1000, 2000);
                outb_p(0, SMBHSTCNT(priv));
@@ -409,7 +408,7 @@ static int i801_check_post(struct i801_priv *priv, int status)
                status = inb_p(SMBHSTSTS(priv));
                if ((status & SMBHSTSTS_HOST_BUSY) ||
                    !(status & SMBHSTSTS_FAILED))
-                       dev_err(&priv->pci_dev->dev,
+                       dev_dbg(&priv->pci_dev->dev,
                                "Failed terminating the transaction\n");
                return -ETIMEDOUT;
        }
@@ -1059,7 +1058,7 @@ static const struct pci_device_id i801_ids[] = {
 MODULE_DEVICE_TABLE(pci, i801_ids);
 
 #if defined CONFIG_X86 && defined CONFIG_DMI
-static unsigned char apanel_addr;
+static unsigned char apanel_addr __ro_after_init;
 
 /* Scan the system ROM for the signature "FJKEYINF" */
 static __init const void __iomem *bios_signature(const void __iomem *bios)
@@ -1298,7 +1297,7 @@ static void i801_probe_optional_slaves(struct i801_priv *priv)
                register_dell_lis3lv02d_i2c_device(priv);
 
        /* Instantiate SPD EEPROMs unless the SMBus is multiplexed */
-#if IS_ENABLED(CONFIG_I2C_MUX_GPIO)
+#ifdef CONFIG_I2C_I801_MUX
        if (!priv->mux_pdev)
 #endif
                i2c_register_spd(&priv->adapter);
@@ -1308,12 +1307,11 @@ static void __init input_apanel_init(void) {}
 static void i801_probe_optional_slaves(struct i801_priv *priv) {}
 #endif /* CONFIG_X86 && CONFIG_DMI */
 
-#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
+#ifdef CONFIG_I2C_I801_MUX
 static struct i801_mux_config i801_mux_config_asus_z8_d12 = {
        .gpio_chip = "gpio_ich",
        .values = { 0x02, 0x03 },
        .n_values = 2,
-       .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD },
        .gpios = { 52, 53 },
        .n_gpios = 2,
 };
@@ -1322,7 +1320,6 @@ static struct i801_mux_config i801_mux_config_asus_z8_d18 = {
        .gpio_chip = "gpio_ich",
        .values = { 0x02, 0x03, 0x01 },
        .n_values = 3,
-       .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD },
        .gpios = { 52, 53 },
        .n_gpios = 2,
 };
@@ -1394,6 +1391,23 @@ static const struct dmi_system_id mux_dmi_table[] = {
        { }
 };
 
+static int i801_notifier_call(struct notifier_block *nb, unsigned long action,
+                             void *data)
+{
+       struct i801_priv *priv = container_of(nb, struct i801_priv, mux_notifier_block);
+       struct device *dev = data;
+
+       if (action != BUS_NOTIFY_ADD_DEVICE ||
+           dev->type != &i2c_adapter_type ||
+           i2c_root_adapter(dev) != &priv->adapter)
+               return NOTIFY_DONE;
+
+       /* Call i2c_register_spd for muxed child segments */
+       i2c_register_spd(to_i2c_adapter(dev));
+
+       return NOTIFY_OK;
+}
+
 /* Setup multiplexing if needed */
 static void i801_add_mux(struct i801_priv *priv)
 {
@@ -1415,7 +1429,6 @@ static void i801_add_mux(struct i801_priv *priv)
        gpio_data.parent = priv->adapter.nr;
        gpio_data.values = mux_config->values;
        gpio_data.n_values = mux_config->n_values;
-       gpio_data.classes = mux_config->classes;
        gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;
 
        /* Register GPIO descriptor lookup table */
@@ -1430,6 +1443,9 @@ static void i801_add_mux(struct i801_priv *priv)
                                               mux_config->gpios[i], "mux", 0);
        gpiod_add_lookup_table(lookup);
 
+       priv->mux_notifier_block.notifier_call = i801_notifier_call;
+       if (bus_register_notifier(&i2c_bus_type, &priv->mux_notifier_block))
+               return;
        /*
         * Register the mux device, we use PLATFORM_DEVID_NONE here
         * because since we are referring to the GPIO chip by name we are
@@ -1451,6 +1467,7 @@ static void i801_add_mux(struct i801_priv *priv)
 
 static void i801_del_mux(struct i801_priv *priv)
 {
+       bus_unregister_notifier(&i2c_bus_type, &priv->mux_notifier_block);
        platform_device_unregister(priv->mux_pdev);
        gpiod_remove_lookup_table(priv->lookup);
 }
index f9d4bfef511c3067dd0359b42152719f6c353f0f..e0e87185f6bbfc7abb18d681a414b73fac0b4a92 100644 (file)
@@ -1124,11 +1124,8 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
                                                      IMG_I2C_TIMEOUT);
                del_timer_sync(&i2c->check_timer);
 
-               if (time_left == 0) {
-                       dev_err(adap->dev.parent, "i2c transfer timed out\n");
+               if (time_left == 0)
                        i2c->msg_status = -ETIMEDOUT;
-                       break;
-               }
 
                if (i2c->msg_status)
                        break;
index 6d72e4e126dde6ba07770b20b358ba74dbda78b8..0197786892a2427b55900da033bbc48f74a0f223 100644 (file)
@@ -99,6 +99,7 @@ struct lpi2c_imx_struct {
        __u8                    *rx_buf;
        __u8                    *tx_buf;
        struct completion       complete;
+       unsigned long           rate_per;
        unsigned int            msglen;
        unsigned int            delivered;
        unsigned int            block_data;
@@ -212,9 +213,7 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)
 
        lpi2c_imx_set_mode(lpi2c_imx);
 
-       clk_rate = clk_get_rate(lpi2c_imx->clks[0].clk);
-       if (!clk_rate)
-               return -EINVAL;
+       clk_rate = lpi2c_imx->rate_per;
 
        if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST)
                filt = 0;
@@ -308,11 +307,11 @@ static int lpi2c_imx_master_disable(struct lpi2c_imx_struct *lpi2c_imx)
 
 static int lpi2c_imx_msg_complete(struct lpi2c_imx_struct *lpi2c_imx)
 {
-       unsigned long timeout;
+       unsigned long time_left;
 
-       timeout = wait_for_completion_timeout(&lpi2c_imx->complete, HZ);
+       time_left = wait_for_completion_timeout(&lpi2c_imx->complete, HZ);
 
-       return timeout ? 0 : -ETIMEDOUT;
+       return time_left ? 0 : -ETIMEDOUT;
 }
 
 static int lpi2c_imx_txfifo_empty(struct lpi2c_imx_struct *lpi2c_imx)
@@ -611,6 +610,20 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
+       /*
+        * Lock the parent clock rate to avoid getting parent clock upon
+        * each transfer
+        */
+       ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clks[0].clk);
+       if (ret)
+               return dev_err_probe(&pdev->dev, ret,
+                                    "can't lock I2C peripheral clock rate\n");
+
+       lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk);
+       if (!lpi2c_imx->rate_per)
+               return dev_err_probe(&pdev->dev, -EINVAL,
+                                    "can't get I2C peripheral clock rate\n");
+
        pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT);
        pm_runtime_use_autosuspend(&pdev->dev);
        pm_runtime_get_noresume(&pdev->dev);
index c74985d77b0ecf34726099b3eded94a2f326d072..655b5d851c48b04d6490d6b3e236f1dac23526c3 100644 (file)
@@ -623,7 +623,6 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
                dma_unmap_single(dev, dma_addr, dma_size, dma_direction);
 
        if (unlikely(!time_left)) {
-               dev_err(dev, "completion wait timed out\n");
                ret = -ETIMEDOUT;
                goto out;
        }
index 55035cca0ae531a326446d4b8923b4e6ef264e6f..7951891d6b97c68f125aeec9dbbbcd03c544ef54 100644 (file)
@@ -565,7 +565,7 @@ static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c,
                                       int idx)
 {
        int ret = 0;
-       long timeout;
+       unsigned long time_left;
        int wait_time = JZ4780_I2C_TIMEOUT * (len + 5);
        unsigned short tmp;
        unsigned long flags;
@@ -600,10 +600,10 @@ static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c,
 
        spin_unlock_irqrestore(&i2c->lock, flags);
 
-       timeout = wait_for_completion_timeout(&i2c->trans_waitq,
-                                             msecs_to_jiffies(wait_time));
+       time_left = wait_for_completion_timeout(&i2c->trans_waitq,
+                                               msecs_to_jiffies(wait_time));
 
-       if (!timeout) {
+       if (!time_left) {
                dev_err(&i2c->adap.dev, "irq read timeout\n");
                dev_dbg(&i2c->adap.dev, "send cmd count:%d  %d\n",
                        i2c->cmd, i2c->cmd_buf[i2c->cmd]);
@@ -627,7 +627,7 @@ static inline int jz4780_i2c_xfer_write(struct jz4780_i2c *i2c,
 {
        int ret = 0;
        int wait_time = JZ4780_I2C_TIMEOUT * (len + 5);
-       long timeout;
+       unsigned long time_left;
        unsigned short tmp;
        unsigned long flags;
 
@@ -655,14 +655,14 @@ static inline int jz4780_i2c_xfer_write(struct jz4780_i2c *i2c,
 
        spin_unlock_irqrestore(&i2c->lock, flags);
 
-       timeout = wait_for_completion_timeout(&i2c->trans_waitq,
-                                             msecs_to_jiffies(wait_time));
-       if (timeout && !i2c->stop_hold) {
+       time_left = wait_for_completion_timeout(&i2c->trans_waitq,
+                                               msecs_to_jiffies(wait_time));
+       if (time_left && !i2c->stop_hold) {
                unsigned short i2c_sta;
                int write_in_process;
 
-               timeout = JZ4780_I2C_TIMEOUT * 100;
-               for (; timeout > 0; timeout--) {
+               time_left = JZ4780_I2C_TIMEOUT * 100;
+               for (; time_left > 0; time_left--) {
                        i2c_sta = jz4780_i2c_readw(i2c, JZ4780_I2C_STA);
 
                        write_in_process = (i2c_sta & JZ4780_I2C_STA_MSTACT) ||
@@ -673,7 +673,7 @@ static inline int jz4780_i2c_xfer_write(struct jz4780_i2c *i2c,
                }
        }
 
-       if (!timeout) {
+       if (!time_left) {
                dev_err(&i2c->adap.dev, "write wait timeout\n");
                ret = -EIO;
        }
index 8d73c0f405ed567ca980331d86ed56eee29d4f53..c4223556b3b8b747c2a374a44f3c3b5b22255e82 100644 (file)
@@ -304,13 +304,12 @@ static void mpc_i2c_setup_512x(struct device_node *node,
                                         struct mpc_i2c *i2c,
                                         u32 clock)
 {
-       struct device_node *node_ctrl;
        void __iomem *ctrl;
        u32 idx;
 
        /* Enable I2C interrupts for mpc5121 */
-       node_ctrl = of_find_compatible_node(NULL, NULL,
-                                           "fsl,mpc5121-i2c-ctrl");
+       struct device_node *node_ctrl __free(device_node) =
+               of_find_compatible_node(NULL, NULL, "fsl,mpc5121-i2c-ctrl");
        if (node_ctrl) {
                ctrl = of_iomap(node_ctrl, 0);
                if (ctrl) {
@@ -321,7 +320,6 @@ static void mpc_i2c_setup_512x(struct device_node *node,
                        setbits32(ctrl, 1 << (24 + idx * 2));
                        iounmap(ctrl);
                }
-               of_node_put(node_ctrl);
        }
 
        /* The clock setup for the 52xx works also fine for the 512x */
@@ -358,11 +356,11 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
 
 static u32 mpc_i2c_get_sec_cfg_8xxx(void)
 {
-       struct device_node *node;
        u32 __iomem *reg;
        u32 val = 0;
 
-       node = of_find_node_by_name(NULL, "global-utilities");
+       struct device_node *node __free(device_node) =
+               of_find_node_by_name(NULL, "global-utilities");
        if (node) {
                const u32 *prop = of_get_property(node, "reg", NULL);
                if (prop) {
@@ -383,7 +381,6 @@ static u32 mpc_i2c_get_sec_cfg_8xxx(void)
                        iounmap(reg);
                }
        }
-       of_node_put(node);
 
        return val;
 }
index 17fb313565b8d3a9cc48562d010c5adb30c6c09f..ad0f02acdb1215a1c04729f97bb14a4d93f88456 100644 (file)
@@ -542,12 +542,9 @@ static int read_i2c(struct nmk_i2c_dev *priv, u16 flags)
 
        xfer_done = nmk_i2c_wait_xfer_done(priv);
 
-       if (!xfer_done) {
-               /* Controller timed out */
-               dev_err(&priv->adev->dev, "read from slave 0x%x timed out\n",
-                       priv->cli.slave_adr);
+       if (!xfer_done)
                status = -ETIMEDOUT;
-       }
+
        return status;
 }
 
index e106af83cef4da5626e534325805aad70be2f617..56a4dabf5a388788ba488b2473d642093706cb24 100644 (file)
@@ -32,7 +32,6 @@
  */
 struct ocores_i2c {
        void __iomem *base;
-       int iobase;
        u32 reg_shift;
        u32 reg_io_width;
        unsigned long flags;
@@ -136,16 +135,6 @@ static inline u8 oc_getreg_32be(struct ocores_i2c *i2c, int reg)
        return ioread32be(i2c->base + (reg << i2c->reg_shift));
 }
 
-static void oc_setreg_io_8(struct ocores_i2c *i2c, int reg, u8 value)
-{
-       outb(value, i2c->iobase + reg);
-}
-
-static inline u8 oc_getreg_io_8(struct ocores_i2c *i2c, int reg)
-{
-       return inb(i2c->iobase + reg);
-}
-
 static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value)
 {
        i2c->setreg(i2c, reg, value);
@@ -618,15 +607,19 @@ static int ocores_i2c_probe(struct platform_device *pdev)
                res = platform_get_resource(pdev, IORESOURCE_IO, 0);
                if (!res)
                        return -EINVAL;
-               i2c->iobase = res->start;
                if (!devm_request_region(&pdev->dev, res->start,
                                         resource_size(res),
                                         pdev->name)) {
                        dev_err(&pdev->dev, "Can't get I/O resource.\n");
                        return -EBUSY;
                }
-               i2c->setreg = oc_setreg_io_8;
-               i2c->getreg = oc_getreg_io_8;
+               i2c->base = devm_ioport_map(&pdev->dev, res->start,
+                                           resource_size(res));
+               if (!i2c->base) {
+                       dev_err(&pdev->dev, "Can't map I/O resource.\n");
+                       return -EBUSY;
+               }
+               i2c->reg_io_width = 1;
        }
 
        pdata = dev_get_platdata(&pdev->dev);
index 845eda70b8cab52a0453c9f4cb545010fba4305d..5b7b942141e725c7f9071c217c728efce067cee6 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/pci.h>
 
 #include "i2c-octeon-core.h"
 
+#define INITIAL_DELTA_HZ               1000000
+#define TWSI_MASTER_CLK_REG_DEF_VAL    0x18
+#define TWSI_MASTER_CLK_REG_OTX2_VAL   0x3
+
 /* interrupt service routine */
 irqreturn_t octeon_i2c_isr(int irq, void *dev_id)
 {
@@ -80,7 +85,7 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c)
 
 static bool octeon_i2c_hlc_test_valid(struct octeon_i2c *i2c)
 {
-       return (__raw_readq(i2c->twsi_base + SW_TWSI(i2c)) & SW_TWSI_V) == 0;
+       return (__raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)) & SW_TWSI_V) == 0;
 }
 
 static void octeon_i2c_hlc_int_clear(struct octeon_i2c *i2c)
@@ -177,13 +182,14 @@ static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c)
 static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
 {
        u8 stat;
+       u64 mode;
 
        /*
         * This is ugly... in HLC mode the status is not in the status register
-        * but in the lower 8 bits of SW_TWSI.
+        * but in the lower 8 bits of OCTEON_REG_SW_TWSI.
         */
        if (i2c->hlc_enabled)
-               stat = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+               stat = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
        else
                stat = octeon_i2c_stat_read(i2c);
 
@@ -239,6 +245,13 @@ static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
        case STAT_RXADDR_NAK:
        case STAT_AD2W_NAK:
                return -ENXIO;
+
+       case STAT_WDOG_TOUT:
+               mode = __raw_readq(i2c->twsi_base + OCTEON_REG_MODE(i2c));
+               /* Set BUS_MON_RST to reset bus monitor */
+               mode |= BUS_MON_RST_MASK;
+               octeon_i2c_writeq_flush(mode, i2c->twsi_base + OCTEON_REG_MODE(i2c));
+               return -EIO;
        default:
                dev_err(i2c->dev, "unhandled state: %d\n", stat);
                return -EIO;
@@ -419,12 +432,12 @@ static int octeon_i2c_hlc_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
        else
                cmd |= SW_TWSI_OP_7;
 
-       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
        ret = octeon_i2c_hlc_wait(i2c);
        if (ret)
                goto err;
 
-       cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+       cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
        if ((cmd & SW_TWSI_R) == 0)
                return octeon_i2c_check_status(i2c, false);
 
@@ -432,7 +445,7 @@ static int octeon_i2c_hlc_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
                msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff;
 
        if (msgs[0].len > 4) {
-               cmd = __raw_readq(i2c->twsi_base + SW_TWSI_EXT(i2c));
+               cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
                for (i = 0; i  < msgs[0].len - 4 && i < 4; i++, j--)
                        msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff;
        }
@@ -469,15 +482,15 @@ static int octeon_i2c_hlc_write(struct octeon_i2c *i2c, struct i2c_msg *msgs)
 
                for (i = 0; i < msgs[0].len - 4 && i < 4; i++, j--)
                        ext |= (u64)msgs[0].buf[j] << (8 * i);
-               octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
+               octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
        }
 
-       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
        ret = octeon_i2c_hlc_wait(i2c);
        if (ret)
                goto err;
 
-       cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+       cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
        if ((cmd & SW_TWSI_R) == 0)
                return octeon_i2c_check_status(i2c, false);
 
@@ -510,19 +523,19 @@ static int octeon_i2c_hlc_comp_read(struct octeon_i2c *i2c, struct i2c_msg *msgs
                cmd |= SW_TWSI_EIA;
                ext = (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
                cmd |= (u64)msgs[0].buf[1] << SW_TWSI_IA_SHIFT;
-               octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
+               octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
        } else {
                cmd |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
        }
 
        octeon_i2c_hlc_int_clear(i2c);
-       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
 
        ret = octeon_i2c_hlc_wait(i2c);
        if (ret)
                goto err;
 
-       cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+       cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
        if ((cmd & SW_TWSI_R) == 0)
                return octeon_i2c_check_status(i2c, false);
 
@@ -530,7 +543,7 @@ static int octeon_i2c_hlc_comp_read(struct octeon_i2c *i2c, struct i2c_msg *msgs
                msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff;
 
        if (msgs[1].len > 4) {
-               cmd = __raw_readq(i2c->twsi_base + SW_TWSI_EXT(i2c));
+               cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
                for (i = 0; i  < msgs[1].len - 4 && i < 4; i++, j--)
                        msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff;
        }
@@ -577,16 +590,16 @@ static int octeon_i2c_hlc_comp_write(struct octeon_i2c *i2c, struct i2c_msg *msg
                set_ext = true;
        }
        if (set_ext)
-               octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
+               octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
 
        octeon_i2c_hlc_int_clear(i2c);
-       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+       octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
 
        ret = octeon_i2c_hlc_wait(i2c);
        if (ret)
                goto err;
 
-       cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+       cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
        if ((cmd & SW_TWSI_R) == 0)
                return octeon_i2c_check_status(i2c, false);
 
@@ -607,25 +620,27 @@ int octeon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
        struct octeon_i2c *i2c = i2c_get_adapdata(adap);
        int i, ret = 0;
 
-       if (num == 1) {
-               if (msgs[0].len > 0 && msgs[0].len <= 8) {
-                       if (msgs[0].flags & I2C_M_RD)
-                               ret = octeon_i2c_hlc_read(i2c, msgs);
-                       else
-                               ret = octeon_i2c_hlc_write(i2c, msgs);
-                       goto out;
-               }
-       } else if (num == 2) {
-               if ((msgs[0].flags & I2C_M_RD) == 0 &&
-                   (msgs[1].flags & I2C_M_RECV_LEN) == 0 &&
-                   msgs[0].len > 0 && msgs[0].len <= 2 &&
-                   msgs[1].len > 0 && msgs[1].len <= 8 &&
-                   msgs[0].addr == msgs[1].addr) {
-                       if (msgs[1].flags & I2C_M_RD)
-                               ret = octeon_i2c_hlc_comp_read(i2c, msgs);
-                       else
-                               ret = octeon_i2c_hlc_comp_write(i2c, msgs);
-                       goto out;
+       if (IS_LS_FREQ(i2c->twsi_freq)) {
+               if (num == 1) {
+                       if (msgs[0].len > 0 && msgs[0].len <= 8) {
+                               if (msgs[0].flags & I2C_M_RD)
+                                       ret = octeon_i2c_hlc_read(i2c, msgs);
+                               else
+                                       ret = octeon_i2c_hlc_write(i2c, msgs);
+                               goto out;
+                       }
+               } else if (num == 2) {
+                       if ((msgs[0].flags & I2C_M_RD) == 0 &&
+                           (msgs[1].flags & I2C_M_RECV_LEN) == 0 &&
+                           msgs[0].len > 0 && msgs[0].len <= 2 &&
+                           msgs[1].len > 0 && msgs[1].len <= 8 &&
+                           msgs[0].addr == msgs[1].addr) {
+                               if (msgs[1].flags & I2C_M_RD)
+                                       ret = octeon_i2c_hlc_comp_read(i2c, msgs);
+                               else
+                                       ret = octeon_i2c_hlc_comp_write(i2c, msgs);
+                               goto out;
+                       }
                }
        }
 
@@ -658,31 +673,64 @@ out:
 void octeon_i2c_set_clock(struct octeon_i2c *i2c)
 {
        int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff;
-       int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000;
+       bool is_plat_otx2;
+       /*
+        * Find divisors to produce target frequency, start with large delta
+        * to cover wider range of divisors, note thp = TCLK half period and
+        * ds is OSCL output frequency divisor.
+        */
+       unsigned int thp, mdiv_min, mdiv = 2, ndiv = 0, ds = 10;
+       unsigned int delta_hz = INITIAL_DELTA_HZ;
+
+       is_plat_otx2 = octeon_i2c_is_otx2(to_pci_dev(i2c->dev));
+
+       if (is_plat_otx2) {
+               thp = TWSI_MASTER_CLK_REG_OTX2_VAL;
+               mdiv_min = 0;
+               if (!IS_LS_FREQ(i2c->twsi_freq))
+                       ds = 15;
+       } else {
+               thp = TWSI_MASTER_CLK_REG_DEF_VAL;
+               mdiv_min = 2;
+       }
 
        for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) {
                /*
                 * An mdiv value of less than 2 seems to not work well
                 * with ds1337 RTCs, so we constrain it to larger values.
                 */
-               for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) {
+               for (mdiv_idx = 15; mdiv_idx >= mdiv_min && delta_hz != 0; mdiv_idx--) {
                        /*
                         * For given ndiv and mdiv values check the
                         * two closest thp values.
                         */
-                       tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10;
+                       tclk = i2c->twsi_freq * (mdiv_idx + 1) * ds;
                        tclk *= (1 << ndiv_idx);
-                       thp_base = (i2c->sys_freq / (tclk * 2)) - 1;
+                       if (is_plat_otx2)
+                               thp_base = (i2c->sys_freq / tclk) - 2;
+                       else
+                               thp_base = (i2c->sys_freq / (tclk * 2)) - 1;
 
                        for (inc = 0; inc <= 1; inc++) {
                                thp_idx = thp_base + inc;
                                if (thp_idx < 5 || thp_idx > 0xff)
                                        continue;
 
-                               foscl = i2c->sys_freq / (2 * (thp_idx + 1));
+                               if (is_plat_otx2)
+                                       foscl = i2c->sys_freq / (thp_idx + 2);
+                               else
+                                       foscl = i2c->sys_freq /
+                                               (2 * (thp_idx + 1));
                                foscl = foscl / (1 << ndiv_idx);
-                               foscl = foscl / (mdiv_idx + 1) / 10;
+                               foscl = foscl / (mdiv_idx + 1) / ds;
+                               if (foscl > i2c->twsi_freq)
+                                       continue;
                                diff = abs(foscl - i2c->twsi_freq);
+                               /*
+                                * Diff holds difference between calculated frequency
+                                * value vs desired frequency.
+                                * Delta_hz is updated with last minimum diff.
+                                */
                                if (diff < delta_hz) {
                                        delta_hz = diff;
                                        thp = thp_idx;
@@ -694,6 +742,17 @@ void octeon_i2c_set_clock(struct octeon_i2c *i2c)
        }
        octeon_i2c_reg_write(i2c, SW_TWSI_OP_TWSI_CLK, thp);
        octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv);
+       if (is_plat_otx2) {
+               u64 mode;
+
+               mode = __raw_readq(i2c->twsi_base + OCTEON_REG_MODE(i2c));
+               /* Set REFCLK_SRC and HS_MODE in TWSX_MODE register */
+               if (!IS_LS_FREQ(i2c->twsi_freq))
+                       mode |= TWSX_MODE_HS_MASK;
+               else
+                       mode &= ~TWSX_MODE_HS_MASK;
+               octeon_i2c_writeq_flush(mode, i2c->twsi_base + OCTEON_REG_MODE(i2c));
+       }
 }
 
 int octeon_i2c_init_lowlevel(struct octeon_i2c *i2c)
index 9bb9f64fdda0392364638ecbaafe3fab5612baf6..7af01864da7522fc9485511e1feb184e8659c74f 100644 (file)
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #include <linux/atomic.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/device.h>
@@ -7,6 +8,7 @@
 #include <linux/i2c-smbus.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/pci.h>
 
 /* Controller command patterns */
 #define SW_TWSI_V              BIT_ULL(63)     /* Valid bit */
@@ -71,6 +73,7 @@
 #define STAT_SLAVE_ACK         0xC8
 #define STAT_AD2W_ACK          0xD0
 #define STAT_AD2W_NAK          0xD8
+#define STAT_WDOG_TOUT         0xF0
 #define STAT_IDLE              0xF8
 
 /* TWSI_INT values */
@@ -92,11 +95,21 @@ struct octeon_i2c_reg_offset {
        unsigned int sw_twsi;
        unsigned int twsi_int;
        unsigned int sw_twsi_ext;
+       unsigned int mode;
 };
 
-#define SW_TWSI(x)     (x->roff.sw_twsi)
-#define TWSI_INT(x)    (x->roff.twsi_int)
-#define SW_TWSI_EXT(x) (x->roff.sw_twsi_ext)
+#define OCTEON_REG_SW_TWSI(x)          ((x)->roff.sw_twsi)
+#define OCTEON_REG_TWSI_INT(x)         ((x)->roff.twsi_int)
+#define OCTEON_REG_SW_TWSI_EXT(x)      ((x)->roff.sw_twsi_ext)
+#define OCTEON_REG_MODE(x)             ((x)->roff.mode)
+
+/* Set REFCLK_SRC and HS_MODE in TWSX_MODE register */
+#define TWSX_MODE_REFCLK_SRC   BIT(4)
+#define TWSX_MODE_HS_MODE      BIT(0)
+#define TWSX_MODE_HS_MASK      (TWSX_MODE_REFCLK_SRC | TWSX_MODE_HS_MODE)
+
+/* Set BUS_MON_RST to reset bus monitor */
+#define BUS_MON_RST_MASK       BIT(3)
 
 struct octeon_i2c {
        wait_queue_head_t queue;
@@ -134,16 +147,16 @@ static inline void octeon_i2c_writeq_flush(u64 val, void __iomem *addr)
  * @eop_reg: Register selector
  * @data: Value to be written
  *
- * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
+ * The I2C core registers are accessed indirectly via the OCTEON_REG_SW_TWSI CSR.
  */
 static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8 data)
 {
        int tries = 1000;
        u64 tmp;
 
-       __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI(i2c));
+       __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
        do {
-               tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+               tmp = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
                if (--tries < 0)
                        return;
        } while ((tmp & SW_TWSI_V) != 0);
@@ -169,9 +182,9 @@ static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
        int tries = 1000;
        u64 tmp;
 
-       __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI(i2c));
+       __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
        do {
-               tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+               tmp = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
                if (--tries < 0) {
                        /* signal that the returned data is invalid */
                        if (error)
@@ -191,24 +204,40 @@ static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
        octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT, NULL)
 
 /**
- * octeon_i2c_read_int - read the TWSI_INT register
+ * octeon_i2c_read_int - read the OCTEON_REG_TWSI_INT register
  * @i2c: The struct octeon_i2c
  *
  * Returns the value of the register.
  */
 static inline u64 octeon_i2c_read_int(struct octeon_i2c *i2c)
 {
-       return __raw_readq(i2c->twsi_base + TWSI_INT(i2c));
+       return __raw_readq(i2c->twsi_base + OCTEON_REG_TWSI_INT(i2c));
 }
 
 /**
- * octeon_i2c_write_int - write the TWSI_INT register
+ * octeon_i2c_write_int - write the OCTEON_REG_TWSI_INT register
  * @i2c: The struct octeon_i2c
  * @data: Value to be written
  */
 static inline void octeon_i2c_write_int(struct octeon_i2c *i2c, u64 data)
 {
-       octeon_i2c_writeq_flush(data, i2c->twsi_base + TWSI_INT(i2c));
+       octeon_i2c_writeq_flush(data, i2c->twsi_base + OCTEON_REG_TWSI_INT(i2c));
+}
+
+#define IS_LS_FREQ(twsi_freq)  ((twsi_freq) <= 400000)
+#define PCI_SUBSYS_DEVID_9XXX  0xB
+#define PCI_SUBSYS_MASK                GENMASK(15, 12)
+/**
+ * octeon_i2c_is_otx2 - check for chip ID
+ * @pdev: PCI dev structure
+ *
+ * Returns true if the device is an OcteonTX2, false otherwise.
+ */
+static inline bool octeon_i2c_is_otx2(struct pci_dev *pdev)
+{
+       u32 chip_id = FIELD_GET(PCI_SUBSYS_MASK, pdev->subsystem_device);
+
+       return (chip_id == PCI_SUBSYS_DEVID_9XXX);
 }
 
 /* Prototypes */
index 42165ef57946ce1aefa76436ca7e31dff2482be1..30a5ea282a8b080eab1a8d99366a1aaa5626b367 100644 (file)
@@ -660,7 +660,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
                             struct i2c_msg *msg, int stop, bool polling)
 {
        struct omap_i2c_dev *omap = i2c_get_adapdata(adap);
-       unsigned long timeout;
+       unsigned long time_left;
        u16 w;
        int ret;
 
@@ -740,19 +740,18 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
         * into arbitration and we're currently unable to recover from it.
         */
        if (!polling) {
-               timeout = wait_for_completion_timeout(&omap->cmd_complete,
-                                                     OMAP_I2C_TIMEOUT);
+               time_left = wait_for_completion_timeout(&omap->cmd_complete,
+                                                       OMAP_I2C_TIMEOUT);
        } else {
                do {
                        omap_i2c_wait(omap);
                        ret = omap_i2c_xfer_data(omap);
                } while (ret == -EAGAIN);
 
-               timeout = !ret;
+               time_left = !ret;
        }
 
-       if (timeout == 0) {
-               dev_err(omap->dev, "controller timed out\n");
+       if (time_left == 0) {
                omap_i2c_reset(omap);
                __omap_i2c_init(omap);
                return -ETIMEDOUT;
index 888ca636f3f3b009ca542747ddca2119a79daa61..f495560bd99c12f0a9eb41c5bb0aa813bf99e7bb 100644 (file)
@@ -826,7 +826,7 @@ static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c)
 static int i2c_pxa_send_mastercode(struct pxa_i2c *i2c)
 {
        u32 icr;
-       long timeout;
+       long time_left;
 
        spin_lock_irq(&i2c->lock);
        i2c->highmode_enter = true;
@@ -837,12 +837,12 @@ static int i2c_pxa_send_mastercode(struct pxa_i2c *i2c)
        writel(icr, _ICR(i2c));
 
        spin_unlock_irq(&i2c->lock);
-       timeout = wait_event_timeout(i2c->wait,
-                       i2c->highmode_enter == false, HZ * 1);
+       time_left = wait_event_timeout(i2c->wait,
+                                      i2c->highmode_enter == false, HZ * 1);
 
        i2c->highmode_enter = false;
 
-       return (timeout == 0) ? I2C_RETRY : 0;
+       return (time_left == 0) ? I2C_RETRY : 0;
 }
 
 /*
@@ -1050,7 +1050,7 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
  */
 static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
 {
-       long timeout;
+       long time_left;
        int ret;
 
        /*
@@ -1095,7 +1095,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
        /*
         * The rest of the processing occurs in the interrupt handler.
         */
-       timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+       time_left = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
        i2c_pxa_stop_message(i2c);
 
        /*
@@ -1103,7 +1103,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
         */
        ret = i2c->msg_idx;
 
-       if (!timeout && i2c->msg_num) {
+       if (!time_left && i2c->msg_num) {
                i2c_pxa_scream_blue_murder(i2c, "timeout with active message");
                i2c_recover_bus(&i2c->adap);
                ret = I2C_RETRY;
index da94df466e83c9d34c6212681c087cafc8a6b788..0a8b95ce35f79336251675d7f7bb491e58765b9d 100644 (file)
@@ -586,7 +586,8 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
 {
        struct dma_slave_config config = {};
        struct gpi_i2c_config peripheral = {};
-       int i, ret = 0, timeout;
+       int i, ret = 0;
+       unsigned long time_left;
        dma_addr_t tx_addr, rx_addr;
        void *tx_buf = NULL, *rx_buf = NULL;
        const struct geni_i2c_clk_fld *itr = gi2c->clk_fld;
@@ -629,12 +630,9 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
 
                dma_async_issue_pending(gi2c->tx_c);
 
-               timeout = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
-               if (!timeout) {
-                       dev_err(gi2c->se.dev, "I2C timeout gpi flags:%d addr:0x%x\n",
-                               gi2c->cur->flags, gi2c->cur->addr);
+               time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
+               if (!time_left)
                        gi2c->err = -ETIMEDOUT;
-               }
 
                if (gi2c->err) {
                        ret = gi2c->err;
index 598102d16677a1e20f264ca26fe4066320851c18..c9b43a3c4bd3c04badea2288806abb912e967cdb 100644 (file)
@@ -793,10 +793,8 @@ static int qup_i2c_bam_schedule_desc(struct qup_i2c_dev *qup)
                dma_async_issue_pending(qup->brx.dma);
        }
 
-       if (!wait_for_completion_timeout(&qup->xfer, qup->xfer_timeout)) {
-               dev_err(qup->dev, "normal trans timed out\n");
+       if (!wait_for_completion_timeout(&qup->xfer, qup->xfer_timeout))
                ret = -ETIMEDOUT;
-       }
 
        if (ret || qup->bus_err || qup->qup_err) {
                reinit_completion(&qup->xfer);
index e43ff483c56ece3a757fd8d0a2fce70e5e15b741..f608b1838cade702bf4efb27df61d516089a6cfe 100644 (file)
 #include <linux/pm_runtime.h>
 #include <linux/reset.h>
 
-#define RIIC_ICCR1     0x00
-#define RIIC_ICCR2     0x04
-#define RIIC_ICMR1     0x08
-#define RIIC_ICMR3     0x10
-#define RIIC_ICSER     0x18
-#define RIIC_ICIER     0x1c
-#define RIIC_ICSR2     0x24
-#define RIIC_ICBRL     0x34
-#define RIIC_ICBRH     0x38
-#define RIIC_ICDRT     0x3c
-#define RIIC_ICDRR     0x40
-
 #define ICCR1_ICE      0x80
 #define ICCR1_IICRST   0x40
 #define ICCR1_SOWP     0x10
 
 #define RIIC_INIT_MSG  -1
 
+enum riic_reg_list {
+       RIIC_ICCR1 = 0,
+       RIIC_ICCR2,
+       RIIC_ICMR1,
+       RIIC_ICMR3,
+       RIIC_ICSER,
+       RIIC_ICIER,
+       RIIC_ICSR2,
+       RIIC_ICBRL,
+       RIIC_ICBRH,
+       RIIC_ICDRT,
+       RIIC_ICDRR,
+       RIIC_REG_END,
+};
+
+struct riic_of_data {
+       u8 regs[RIIC_REG_END];
+};
+
 struct riic_dev {
        void __iomem *base;
        u8 *buf;
@@ -94,6 +101,7 @@ struct riic_dev {
        int bytes_left;
        int err;
        int is_last;
+       const struct riic_of_data *info;
        struct completion msg_done;
        struct i2c_adapter adapter;
        struct clk *clk;
@@ -105,9 +113,19 @@ struct riic_irq_desc {
        char *name;
 };
 
+static inline void riic_writeb(struct riic_dev *riic, u8 val, u8 offset)
+{
+       writeb(val, riic->base + riic->info->regs[offset]);
+}
+
+static inline u8 riic_readb(struct riic_dev *riic, u8 offset)
+{
+       return readb(riic->base + riic->info->regs[offset]);
+}
+
 static inline void riic_clear_set_bit(struct riic_dev *riic, u8 clear, u8 set, u8 reg)
 {
-       writeb((readb(riic->base + reg) & ~clear) | set, riic->base + reg);
+       riic_writeb(riic, (riic_readb(riic, reg) & ~clear) | set, reg);
 }
 
 static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
@@ -119,7 +137,7 @@ static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 
        pm_runtime_get_sync(adap->dev.parent);
 
-       if (readb(riic->base + RIIC_ICCR2) & ICCR2_BBSY) {
+       if (riic_readb(riic, RIIC_ICCR2) & ICCR2_BBSY) {
                riic->err = -EBUSY;
                goto out;
        }
@@ -127,7 +145,7 @@ static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
        reinit_completion(&riic->msg_done);
        riic->err = 0;
 
-       writeb(0, riic->base + RIIC_ICSR2);
+       riic_writeb(riic, 0, RIIC_ICSR2);
 
        for (i = 0, start_bit = ICCR2_ST; i < num; i++) {
                riic->bytes_left = RIIC_INIT_MSG;
@@ -135,9 +153,9 @@ static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
                riic->msg = &msgs[i];
                riic->is_last = (i == num - 1);
 
-               writeb(ICIER_NAKIE | ICIER_TIE, riic->base + RIIC_ICIER);
+               riic_writeb(riic, ICIER_NAKIE | ICIER_TIE, RIIC_ICIER);
 
-               writeb(start_bit, riic->base + RIIC_ICCR2);
+               riic_writeb(riic, start_bit, RIIC_ICCR2);
 
                time_left = wait_for_completion_timeout(&riic->msg_done, riic->adapter.timeout);
                if (time_left == 0)
@@ -191,7 +209,7 @@ static irqreturn_t riic_tdre_isr(int irq, void *data)
         * value could be moved to the shadow shift register right away. So
         * this must be after updates to ICIER (where we want to disable TIE)!
         */
-       writeb(val, riic->base + RIIC_ICDRT);
+       riic_writeb(riic, val, RIIC_ICDRT);
 
        return IRQ_HANDLED;
 }
@@ -200,9 +218,9 @@ static irqreturn_t riic_tend_isr(int irq, void *data)
 {
        struct riic_dev *riic = data;
 
-       if (readb(riic->base + RIIC_ICSR2) & ICSR2_NACKF) {
+       if (riic_readb(riic, RIIC_ICSR2) & ICSR2_NACKF) {
                /* We got a NACKIE */
-               readb(riic->base + RIIC_ICDRR); /* dummy read */
+               riic_readb(riic, RIIC_ICDRR);   /* dummy read */
                riic_clear_set_bit(riic, ICSR2_NACKF, 0, RIIC_ICSR2);
                riic->err = -ENXIO;
        } else if (riic->bytes_left) {
@@ -211,7 +229,7 @@ static irqreturn_t riic_tend_isr(int irq, void *data)
 
        if (riic->is_last || riic->err) {
                riic_clear_set_bit(riic, ICIER_TEIE, ICIER_SPIE, RIIC_ICIER);
-               writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
+               riic_writeb(riic, ICCR2_SP, RIIC_ICCR2);
        } else {
                /* Transfer is complete, but do not send STOP */
                riic_clear_set_bit(riic, ICIER_TEIE, 0, RIIC_ICIER);
@@ -230,7 +248,7 @@ static irqreturn_t riic_rdrf_isr(int irq, void *data)
 
        if (riic->bytes_left == RIIC_INIT_MSG) {
                riic->bytes_left = riic->msg->len;
-               readb(riic->base + RIIC_ICDRR); /* dummy read */
+               riic_readb(riic, RIIC_ICDRR);   /* dummy read */
                return IRQ_HANDLED;
        }
 
@@ -238,7 +256,7 @@ static irqreturn_t riic_rdrf_isr(int irq, void *data)
                /* STOP must come before we set ACKBT! */
                if (riic->is_last) {
                        riic_clear_set_bit(riic, 0, ICIER_SPIE, RIIC_ICIER);
-                       writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
+                       riic_writeb(riic, ICCR2_SP, RIIC_ICCR2);
                }
 
                riic_clear_set_bit(riic, 0, ICMR3_ACKBT, RIIC_ICMR3);
@@ -248,7 +266,7 @@ static irqreturn_t riic_rdrf_isr(int irq, void *data)
        }
 
        /* Reading acks the RIE interrupt */
-       *riic->buf = readb(riic->base + RIIC_ICDRR);
+       *riic->buf = riic_readb(riic, RIIC_ICDRR);
        riic->buf++;
        riic->bytes_left--;
 
@@ -260,10 +278,10 @@ static irqreturn_t riic_stop_isr(int irq, void *data)
        struct riic_dev *riic = data;
 
        /* read back registers to confirm writes have fully propagated */
-       writeb(0, riic->base + RIIC_ICSR2);
-       readb(riic->base + RIIC_ICSR2);
-       writeb(0, riic->base + RIIC_ICIER);
-       readb(riic->base + RIIC_ICIER);
+       riic_writeb(riic, 0, RIIC_ICSR2);
+       riic_readb(riic, RIIC_ICSR2);
+       riic_writeb(riic, 0, RIIC_ICIER);
+       riic_readb(riic, RIIC_ICIER);
 
        complete(&riic->msg_done);
 
@@ -365,15 +383,15 @@ static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t)
                 t->scl_rise_ns / (1000000000 / rate), cks, brl, brh);
 
        /* Changing the order of accessing IICRST and ICE may break things! */
-       writeb(ICCR1_IICRST | ICCR1_SOWP, riic->base + RIIC_ICCR1);
+       riic_writeb(riic, ICCR1_IICRST | ICCR1_SOWP, RIIC_ICCR1);
        riic_clear_set_bit(riic, 0, ICCR1_ICE, RIIC_ICCR1);
 
-       writeb(ICMR1_CKS(cks), riic->base + RIIC_ICMR1);
-       writeb(brh | ICBR_RESERVED, riic->base + RIIC_ICBRH);
-       writeb(brl | ICBR_RESERVED, riic->base + RIIC_ICBRL);
+       riic_writeb(riic, ICMR1_CKS(cks), RIIC_ICMR1);
+       riic_writeb(riic, brh | ICBR_RESERVED, RIIC_ICBRH);
+       riic_writeb(riic, brl | ICBR_RESERVED, RIIC_ICBRL);
 
-       writeb(0, riic->base + RIIC_ICSER);
-       writeb(ICMR3_ACKWP | ICMR3_RDRFS, riic->base + RIIC_ICMR3);
+       riic_writeb(riic, 0, RIIC_ICSER);
+       riic_writeb(riic, ICMR3_ACKWP | ICMR3_RDRFS, RIIC_ICMR3);
 
        riic_clear_set_bit(riic, ICCR1_IICRST, 0, RIIC_ICCR1);
 
@@ -443,6 +461,8 @@ static int riic_i2c_probe(struct platform_device *pdev)
                }
        }
 
+       riic->info = of_device_get_match_data(&pdev->dev);
+
        adap = &riic->adapter;
        i2c_set_adapdata(adap, riic);
        strscpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name));
@@ -481,14 +501,47 @@ static void riic_i2c_remove(struct platform_device *pdev)
        struct riic_dev *riic = platform_get_drvdata(pdev);
 
        pm_runtime_get_sync(&pdev->dev);
-       writeb(0, riic->base + RIIC_ICIER);
+       riic_writeb(riic, 0, RIIC_ICIER);
        pm_runtime_put(&pdev->dev);
        i2c_del_adapter(&riic->adapter);
        pm_runtime_disable(&pdev->dev);
 }
 
+static const struct riic_of_data riic_rz_a_info = {
+       .regs = {
+               [RIIC_ICCR1] = 0x00,
+               [RIIC_ICCR2] = 0x04,
+               [RIIC_ICMR1] = 0x08,
+               [RIIC_ICMR3] = 0x10,
+               [RIIC_ICSER] = 0x18,
+               [RIIC_ICIER] = 0x1c,
+               [RIIC_ICSR2] = 0x24,
+               [RIIC_ICBRL] = 0x34,
+               [RIIC_ICBRH] = 0x38,
+               [RIIC_ICDRT] = 0x3c,
+               [RIIC_ICDRR] = 0x40,
+       },
+};
+
+static const struct riic_of_data riic_rz_v2h_info = {
+       .regs = {
+               [RIIC_ICCR1] = 0x00,
+               [RIIC_ICCR2] = 0x01,
+               [RIIC_ICMR1] = 0x02,
+               [RIIC_ICMR3] = 0x04,
+               [RIIC_ICSER] = 0x06,
+               [RIIC_ICIER] = 0x07,
+               [RIIC_ICSR2] = 0x09,
+               [RIIC_ICBRL] = 0x10,
+               [RIIC_ICBRH] = 0x11,
+               [RIIC_ICDRT] = 0x12,
+               [RIIC_ICDRR] = 0x13,
+       },
+};
+
 static const struct of_device_id riic_i2c_dt_ids[] = {
-       { .compatible = "renesas,riic-rz", },
+       { .compatible = "renesas,riic-rz", .data = &riic_rz_a_info },
+       { .compatible = "renesas,riic-r9a09g057", .data = &riic_rz_v2h_info },
        { /* Sentinel */ },
 };
 
index 086fdf262e7b60e26c48727f6f8f586615674117..beca61700c89c96bdfb9e444357e9d5fa5016850 100644 (file)
@@ -1060,7 +1060,8 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
                                struct i2c_msg *msgs, int num, bool polling)
 {
        struct rk3x_i2c *i2c = (struct rk3x_i2c *)adap->algo_data;
-       unsigned long timeout, flags;
+       unsigned long flags;
+       long time_left;
        u32 val;
        int ret = 0;
        int i;
@@ -1092,23 +1093,20 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
                if (!polling) {
                        rk3x_i2c_start(i2c);
 
-                       timeout = wait_event_timeout(i2c->wait, !i2c->busy,
-                                                    msecs_to_jiffies(WAIT_TIMEOUT));
+                       time_left = wait_event_timeout(i2c->wait, !i2c->busy,
+                                                      msecs_to_jiffies(WAIT_TIMEOUT));
                } else {
                        disable_irq(i2c->irq);
                        rk3x_i2c_start(i2c);
 
-                       timeout = rk3x_i2c_wait_xfer_poll(i2c);
+                       time_left = rk3x_i2c_wait_xfer_poll(i2c);
 
                        enable_irq(i2c->irq);
                }
 
                spin_lock_irqsave(&i2c->lock, flags);
 
-               if (timeout == 0) {
-                       dev_err(i2c->dev, "timeout, ipd: 0x%02x, state: %d\n",
-                               i2c_readl(i2c, REG_IPD), i2c->state);
-
+               if (time_left == 0) {
                        /* Force a STOP condition without interrupt */
                        i2c_writel(i2c, 0, REG_IEN);
                        val = i2c_readl(i2c, REG_CON) & REG_CON_TUNING_MASK;
index 275f7c42165cde7881bad16433c9150f653af91f..01419c738cfc4f727dddba0d3d53284042e80d83 100644 (file)
@@ -685,7 +685,7 @@ static void s3c24xx_i2c_wait_idle(struct s3c24xx_i2c *i2c)
 static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
                              struct i2c_msg *msgs, int num)
 {
-       unsigned long timeout = 0;
+       long time_left = 0;
        int ret;
 
        ret = s3c24xx_i2c_set_master(i2c);
@@ -715,7 +715,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
                                dev_err(i2c->dev, "deal with arbitration loss\n");
                }
        } else {
-               timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+               time_left = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
        }
 
        ret = i2c->msg_idx;
@@ -724,7 +724,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
         * Having these next two as dev_err() makes life very
         * noisy when doing an i2cdetect
         */
-       if (timeout == 0)
+       if (time_left == 0)
                dev_dbg(i2c->dev, "timeout\n");
        else if (ret != num)
                dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
index c65ac3d7eadc5b58c5d9e29d9a6ec0d894e2e844..f86c29737df124dd9d65e4b29ecaf17bd2d3bc5c 100644 (file)
@@ -688,7 +688,6 @@ static int sh_mobile_xfer(struct sh_mobile_i2c_data *pd,
                }
 
                if (!time_left) {
-                       dev_err(pd->dev, "Transfer request timed out\n");
                        if (pd->dma_direction != DMA_NONE)
                                sh_mobile_i2c_cleanup_dma(pd, true);
 
index ce2333408904bdceccf55877c2b572481194e11d..5e01fe3dbb63f1dd1fa12ed3a7ec683d767fde02 100644 (file)
@@ -647,7 +647,7 @@ static int st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg,
 {
        struct st_i2c_client *c = &i2c_dev->client;
        u32 ctl, i2c, it;
-       unsigned long timeout;
+       unsigned long time_left;
        int ret;
 
        c->addr         = i2c_8bit_addr_from_msg(msg);
@@ -685,15 +685,12 @@ static int st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg,
                st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STRTG);
        }
 
-       timeout = wait_for_completion_timeout(&i2c_dev->complete,
-                       i2c_dev->adap.timeout);
+       time_left = wait_for_completion_timeout(&i2c_dev->complete,
+                                               i2c_dev->adap.timeout);
        ret = c->result;
 
-       if (!timeout) {
-               dev_err(i2c_dev->dev, "Write to slave 0x%x timed out\n",
-                               c->addr);
+       if (!time_left)
                ret = -ETIMEDOUT;
-       }
 
        i2c = SSC_I2C_STOPG | SSC_I2C_REPSTRTG;
        st_i2c_clr_bits(i2c_dev->base + SSC_I2C, i2c);
index 859ac0cf7f6cb156a5bde7a5ad81be6440f5eed9..f8b12be6ef55b02fa0b8dad3292e53c79da1e0a2 100644 (file)
@@ -681,7 +681,7 @@ static int stm32f4_i2c_xfer_msg(struct stm32f4_i2c_dev *i2c_dev,
 {
        struct stm32f4_i2c_msg *f4_msg = &i2c_dev->msg;
        void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR1;
-       unsigned long timeout;
+       unsigned long time_left;
        u32 mask;
        int ret;
 
@@ -706,11 +706,11 @@ static int stm32f4_i2c_xfer_msg(struct stm32f4_i2c_dev *i2c_dev,
                stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
        }
 
-       timeout = wait_for_completion_timeout(&i2c_dev->complete,
-                                             i2c_dev->adap.timeout);
+       time_left = wait_for_completion_timeout(&i2c_dev->complete,
+                                               i2c_dev->adap.timeout);
        ret = f4_msg->result;
 
-       if (!timeout)
+       if (!time_left)
                ret = -ETIMEDOUT;
 
        return ret;
index 01210452216b333abd64e06451524784a537bca8..cfee2d9c09de36829f9e1f2dcea9f0b0f4d28e51 100644 (file)
@@ -1789,7 +1789,7 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
        struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
        struct stm32_i2c_dma *dma = i2c_dev->dma;
        struct device *dev = i2c_dev->dev;
-       unsigned long timeout;
+       unsigned long time_left;
        int i, ret;
 
        f7_msg->addr = addr;
@@ -1809,8 +1809,8 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
        if (ret)
                goto pm_free;
 
-       timeout = wait_for_completion_timeout(&i2c_dev->complete,
-                                             i2c_dev->adap.timeout);
+       time_left = wait_for_completion_timeout(&i2c_dev->complete,
+                                               i2c_dev->adap.timeout);
        ret = f7_msg->result;
        if (ret) {
                if (i2c_dev->use_dma)
@@ -1826,7 +1826,7 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
                goto pm_free;
        }
 
-       if (!timeout) {
+       if (!time_left) {
                dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr);
                if (i2c_dev->use_dma)
                        dmaengine_terminate_sync(dma->chan_using);
index bbea521b05dda7461736487ad3837aede5589ea4..31ecb2c7e9783517e7a3a7d2bd3ce415e857cda3 100644 (file)
@@ -311,7 +311,7 @@ static int synquacer_i2c_doxfer(struct synquacer_i2c *i2c,
                                struct i2c_msg *msgs, int num)
 {
        unsigned char bsr;
-       unsigned long timeout;
+       unsigned long time_left;
        int ret;
 
        synquacer_i2c_hw_init(i2c);
@@ -335,9 +335,9 @@ static int synquacer_i2c_doxfer(struct synquacer_i2c *i2c,
                return ret;
        }
 
-       timeout = wait_for_completion_timeout(&i2c->completion,
-                                       msecs_to_jiffies(i2c->timeout_ms));
-       if (timeout == 0) {
+       time_left = wait_for_completion_timeout(&i2c->completion,
+                                               msecs_to_jiffies(i2c->timeout_ms));
+       if (time_left == 0) {
                dev_dbg(i2c->dev, "timeout\n");
                return -EAGAIN;
        }
@@ -550,17 +550,13 @@ static int synquacer_i2c_probe(struct platform_device *pdev)
        device_property_read_u32(&pdev->dev, "socionext,pclk-rate",
                                 &i2c->pclkrate);
 
-       i2c->pclk = devm_clk_get(&pdev->dev, "pclk");
-       if (PTR_ERR(i2c->pclk) == -EPROBE_DEFER)
-               return -EPROBE_DEFER;
-       if (!IS_ERR_OR_NULL(i2c->pclk)) {
-               dev_dbg(&pdev->dev, "clock source %p\n", i2c->pclk);
+       i2c->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
+       if (IS_ERR(i2c->pclk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(i2c->pclk),
+                                    "failed to get and enable clock\n");
 
-               ret = clk_prepare_enable(i2c->pclk);
-               if (ret)
-                       return dev_err_probe(&pdev->dev, ret, "failed to enable clock\n");
-               i2c->pclkrate = clk_get_rate(i2c->pclk);
-       }
+       dev_dbg(&pdev->dev, "clock source %p\n", i2c->pclk);
+       i2c->pclkrate = clk_get_rate(i2c->pclk);
 
        if (i2c->pclkrate < SYNQUACER_I2C_MIN_CLK_RATE ||
            i2c->pclkrate > SYNQUACER_I2C_MAX_CLK_RATE)
@@ -615,8 +611,6 @@ static void synquacer_i2c_remove(struct platform_device *pdev)
        struct synquacer_i2c *i2c = platform_get_drvdata(pdev);
 
        i2c_del_adapter(&i2c->adapter);
-       if (!IS_ERR(i2c->pclk))
-               clk_disable_unprepare(i2c->pclk);
 };
 
 static const struct of_device_id synquacer_i2c_dt_ids[] __maybe_unused = {
index 920d5a8cbf4c753b316d2256caeadc319246581e..85b31edc558dff21a54120ea2f8b01e3dd8a3f00 100644 (file)
@@ -1331,7 +1331,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
                dmaengine_terminate_sync(i2c_dev->dma_chan);
 
                if (!time_left && !completion_done(&i2c_dev->dma_complete)) {
-                       dev_err(i2c_dev->dev, "DMA transfer timed out\n");
                        tegra_i2c_init(i2c_dev);
                        return -ETIMEDOUT;
                }
@@ -1351,7 +1350,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
        tegra_i2c_mask_irq(i2c_dev, int_mask);
 
        if (time_left == 0) {
-               dev_err(i2c_dev->dev, "I2C transfer timed out\n");
                tegra_i2c_init(i2c_dev);
                return -ETIMEDOUT;
        }
index a77cd86fe75ed7401bc041b27c651b9fedf67285..32d0e3930b675484138084e1bbed2e7cf898e1e1 100644 (file)
@@ -27,7 +27,8 @@
 
 #define PCI_DEVICE_ID_THUNDER_TWSI     0xa012
 
-#define SYS_FREQ_DEFAULT               700000000
+#define SYS_FREQ_DEFAULT               800000000
+#define OTX2_REF_FREQ_DEFAULT          100000000
 
 #define TWSI_INT_ENA_W1C               0x1028
 #define TWSI_INT_ENA_W1S               0x1030
@@ -99,7 +100,8 @@ static void thunder_i2c_clock_enable(struct device *dev, struct octeon_i2c *i2c)
                i2c->sys_freq = clk_get_rate(i2c->clk);
        } else {
                /* ACPI */
-               device_property_read_u32(dev, "sclk", &i2c->sys_freq);
+               if (device_property_read_u32(dev, "sclk", &i2c->sys_freq))
+                       device_property_read_u32(dev, "ioclk", &i2c->sys_freq);
        }
 
 skip:
@@ -165,6 +167,7 @@ static int thunder_i2c_probe_pci(struct pci_dev *pdev,
        i2c->roff.sw_twsi = 0x1000;
        i2c->roff.twsi_int = 0x1010;
        i2c->roff.sw_twsi_ext = 0x1018;
+       i2c->roff.mode = 0x1038;
 
        i2c->dev = dev;
        pci_set_drvdata(pdev, i2c);
@@ -205,6 +208,12 @@ static int thunder_i2c_probe_pci(struct pci_dev *pdev,
        if (ret)
                goto error;
 
+       /*
+        * For OcteonTX2 chips, set reference frequency to 100MHz
+        * as refclk_src in TWSI_MODE register defaults to 100MHz.
+        */
+       if (octeon_i2c_is_otx2(pdev) && IS_LS_FREQ(i2c->twsi_freq))
+               i2c->sys_freq = OTX2_REF_FREQ_DEFAULT;
        octeon_i2c_set_clock(i2c);
 
        i2c->adap = thunderx_i2c_ops;
index dbc91c7c3788ff8b5700de5598d29032404dc8bb..6c3dac2cf568fa44b4353028202ac0c2603fbe79 100644 (file)
@@ -358,7 +358,6 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
        spin_unlock_irqrestore(&priv->lock, flags);
 
        if (!time_left) {
-               dev_err(&adap->dev, "transaction timeout.\n");
                uniphier_fi2c_recover(priv);
                return -ETIMEDOUT;
        }
index 854ac25b586285a1d79e1c2f7e0fe6ad504016e8..e1b4c80e028545fedf296b56c3361a9cc7a6e7b8 100644 (file)
@@ -71,10 +71,8 @@ static int uniphier_i2c_xfer_byte(struct i2c_adapter *adap, u32 txdata,
        writel(txdata, priv->membase + UNIPHIER_I2C_DTRM);
 
        time_left = wait_for_completion_timeout(&priv->comp, adap->timeout);
-       if (unlikely(!time_left)) {
-               dev_err(&adap->dev, "transaction timeout\n");
+       if (unlikely(!time_left))
                return -ETIMEDOUT;
-       }
 
        rxdata = readl(priv->membase + UNIPHIER_I2C_DREC);
        if (rxdatap)
diff --git a/drivers/i2c/busses/i2c-viai2c-common.c b/drivers/i2c/busses/i2c-viai2c-common.c
new file mode 100644 (file)
index 0000000..1844d13
--- /dev/null
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <linux/of_irq.h>
+#include "i2c-viai2c-common.h"
+
+int viai2c_wait_bus_not_busy(struct viai2c *i2c)
+{
+       unsigned long timeout;
+
+       timeout = jiffies + VIAI2C_TIMEOUT;
+       while (!(readw(i2c->base + VIAI2C_REG_CSR) & VIAI2C_CSR_READY_MASK)) {
+               if (time_after(jiffies, timeout)) {
+                       dev_warn(i2c->dev, "timeout waiting for bus ready\n");
+                       return -EBUSY;
+               }
+               msleep(20);
+       }
+
+       return 0;
+}
+
+static int viai2c_write(struct viai2c *i2c, struct i2c_msg *pmsg, int last)
+{
+       u16 val, tcr_val = i2c->tcr;
+
+       i2c->last = last;
+
+       if (pmsg->len == 0) {
+               /*
+                * We still need to run through the while (..) once, so
+                * start at -1 and break out early from the loop
+                */
+               i2c->xfered_len = -1;
+               writew(0, i2c->base + VIAI2C_REG_CDR);
+       } else {
+               writew(pmsg->buf[0] & 0xFF, i2c->base + VIAI2C_REG_CDR);
+       }
+
+       if (i2c->platform == VIAI2C_PLAT_WMT && !(pmsg->flags & I2C_M_NOSTART)) {
+               val = readw(i2c->base + VIAI2C_REG_CR);
+               val &= ~VIAI2C_CR_TX_END;
+               val |= VIAI2C_CR_CPU_RDY;
+               writew(val, i2c->base + VIAI2C_REG_CR);
+       }
+
+       reinit_completion(&i2c->complete);
+
+       tcr_val |= pmsg->addr & VIAI2C_TCR_ADDR_MASK;
+
+       writew(tcr_val, i2c->base + VIAI2C_REG_TCR);
+
+       if (i2c->platform == VIAI2C_PLAT_WMT && pmsg->flags & I2C_M_NOSTART) {
+               val = readw(i2c->base + VIAI2C_REG_CR);
+               val |= VIAI2C_CR_CPU_RDY;
+               writew(val, i2c->base + VIAI2C_REG_CR);
+       }
+
+       if (!wait_for_completion_timeout(&i2c->complete, VIAI2C_TIMEOUT))
+               return -ETIMEDOUT;
+
+       return i2c->ret;
+}
+
+static int viai2c_read(struct viai2c *i2c, struct i2c_msg *pmsg, bool first)
+{
+       u16 val, tcr_val = i2c->tcr;
+
+       val = readw(i2c->base + VIAI2C_REG_CR);
+       val &= ~(VIAI2C_CR_TX_END | VIAI2C_CR_RX_END);
+
+       if (i2c->platform == VIAI2C_PLAT_WMT && !(pmsg->flags & I2C_M_NOSTART))
+               val |= VIAI2C_CR_CPU_RDY;
+
+       if (pmsg->len == 1)
+               val |= VIAI2C_CR_RX_END;
+
+       writew(val, i2c->base + VIAI2C_REG_CR);
+
+       reinit_completion(&i2c->complete);
+
+       tcr_val |= VIAI2C_TCR_READ | (pmsg->addr & VIAI2C_TCR_ADDR_MASK);
+
+       writew(tcr_val, i2c->base + VIAI2C_REG_TCR);
+
+       if ((i2c->platform == VIAI2C_PLAT_WMT && (pmsg->flags & I2C_M_NOSTART)) ||
+           (i2c->platform == VIAI2C_PLAT_ZHAOXIN && !first)) {
+               val = readw(i2c->base + VIAI2C_REG_CR);
+               val |= VIAI2C_CR_CPU_RDY;
+               writew(val, i2c->base + VIAI2C_REG_CR);
+       }
+
+       if (!wait_for_completion_timeout(&i2c->complete, VIAI2C_TIMEOUT))
+               return -ETIMEDOUT;
+
+       return i2c->ret;
+}
+
+int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+       struct i2c_msg *pmsg;
+       int i;
+       int ret = 0;
+       struct viai2c *i2c = i2c_get_adapdata(adap);
+
+       i2c->mode = VIAI2C_BYTE_MODE;
+       for (i = 0; ret >= 0 && i < num; i++) {
+               pmsg = &msgs[i];
+               if (i2c->platform == VIAI2C_PLAT_WMT && !(pmsg->flags & I2C_M_NOSTART)) {
+                       ret = viai2c_wait_bus_not_busy(i2c);
+                       if (ret < 0)
+                               return ret;
+               }
+
+               i2c->msg = pmsg;
+               i2c->xfered_len = 0;
+
+               if (pmsg->flags & I2C_M_RD)
+                       ret = viai2c_read(i2c, pmsg, i == 0);
+               else
+                       ret = viai2c_write(i2c, pmsg, (i + 1) == num);
+       }
+
+       return (ret < 0) ? ret : i;
+}
+
+/*
+ * Main process of the byte mode xfer
+ *
+ * Return value indicates whether the transfer is complete
+ *  1: all the data has been successfully transferred
+ *  0: there is still data that needs to be transferred
+ *  -EIO: error occurred
+ */
+static int viai2c_irq_xfer(struct viai2c *i2c)
+{
+       u16 val;
+       struct i2c_msg *msg = i2c->msg;
+       u8 read = msg->flags & I2C_M_RD;
+       void __iomem *base = i2c->base;
+
+       if (read) {
+               msg->buf[i2c->xfered_len] = readw(base + VIAI2C_REG_CDR) >> 8;
+
+               val = readw(base + VIAI2C_REG_CR) | VIAI2C_CR_CPU_RDY;
+               if (i2c->xfered_len == msg->len - 2)
+                       val |= VIAI2C_CR_RX_END;
+               writew(val, base + VIAI2C_REG_CR);
+       } else {
+               val = readw(base + VIAI2C_REG_CSR);
+               if (val & VIAI2C_CSR_RCV_NOT_ACK)
+                       return -EIO;
+
+               /* I2C_SMBUS_QUICK */
+               if (msg->len == 0) {
+                       val = VIAI2C_CR_TX_END | VIAI2C_CR_CPU_RDY | VIAI2C_CR_ENABLE;
+                       writew(val, base + VIAI2C_REG_CR);
+                       return 1;
+               }
+
+               if ((i2c->xfered_len + 1) == msg->len) {
+                       if (i2c->platform == VIAI2C_PLAT_WMT && !i2c->last)
+                               writew(VIAI2C_CR_ENABLE, base + VIAI2C_REG_CR);
+                       else if (i2c->platform == VIAI2C_PLAT_ZHAOXIN && i2c->last)
+                               writeb(VIAI2C_CR_TX_END, base + VIAI2C_REG_CR);
+               } else {
+                       writew(msg->buf[i2c->xfered_len + 1] & 0xFF, base + VIAI2C_REG_CDR);
+                       writew(VIAI2C_CR_CPU_RDY | VIAI2C_CR_ENABLE, base + VIAI2C_REG_CR);
+               }
+       }
+
+       i2c->xfered_len++;
+
+       return i2c->xfered_len == msg->len;
+}
+
+int __weak viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq)
+{
+       return 0;
+}
+
+static irqreturn_t viai2c_isr(int irq, void *data)
+{
+       struct viai2c *i2c = data;
+       u8 status;
+
+       /* save the status and write-clear it */
+       status = readw(i2c->base + VIAI2C_REG_ISR);
+       if (!status && i2c->platform == VIAI2C_PLAT_ZHAOXIN)
+               return IRQ_NONE;
+
+       writew(status, i2c->base + VIAI2C_REG_ISR);
+
+       i2c->ret = 0;
+       if (status & VIAI2C_ISR_NACK_ADDR)
+               i2c->ret = -EIO;
+
+       if (i2c->platform == VIAI2C_PLAT_WMT && (status & VIAI2C_ISR_SCL_TIMEOUT))
+               i2c->ret = -ETIMEDOUT;
+
+       if (!i2c->ret) {
+               if (i2c->mode == VIAI2C_BYTE_MODE)
+                       i2c->ret = viai2c_irq_xfer(i2c);
+               else
+                       i2c->ret = viai2c_fifo_irq_xfer(i2c, true);
+       }
+
+       /* All the data has been successfully transferred or error occurred */
+       if (i2c->ret)
+               complete(&i2c->complete);
+
+       return IRQ_HANDLED;
+}
+
+int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat)
+{
+       int err;
+       int irq_flags;
+       struct viai2c *i2c;
+       struct device_node *np = pdev->dev.of_node;
+
+       i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
+       if (!i2c)
+               return -ENOMEM;
+
+       i2c->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+       if (IS_ERR(i2c->base))
+               return PTR_ERR(i2c->base);
+
+       if (plat == VIAI2C_PLAT_WMT) {
+               irq_flags = 0;
+               i2c->irq = irq_of_parse_and_map(np, 0);
+               if (!i2c->irq)
+                       return -EINVAL;
+       } else if (plat == VIAI2C_PLAT_ZHAOXIN) {
+               irq_flags = IRQF_SHARED;
+               i2c->irq = platform_get_irq(pdev, 0);
+               if (i2c->irq < 0)
+                       return i2c->irq;
+       } else {
+               return dev_err_probe(&pdev->dev, -EINVAL, "wrong platform type\n");
+       }
+
+       i2c->platform = plat;
+
+       err = devm_request_irq(&pdev->dev, i2c->irq, viai2c_isr,
+                              irq_flags, pdev->name, i2c);
+       if (err)
+               return dev_err_probe(&pdev->dev, err,
+                               "failed to request irq %i\n", i2c->irq);
+
+       i2c->dev = &pdev->dev;
+       init_completion(&i2c->complete);
+       platform_set_drvdata(pdev, i2c);
+
+       *pi2c = i2c;
+       return 0;
+}
diff --git a/drivers/i2c/busses/i2c-viai2c-common.h b/drivers/i2c/busses/i2c-viai2c-common.h
new file mode 100644 (file)
index 0000000..81e827c
--- /dev/null
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef __I2C_VIAI2C_COMMON_H_
+#define __I2C_VIAI2C_COMMON_H_
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+/* REG_CR Bit fields */
+#define VIAI2C_REG_CR          0x00
+#define VIAI2C_CR_ENABLE               BIT(0)
+#define VIAI2C_CR_RX_END               BIT(1)
+#define VIAI2C_CR_TX_END               BIT(2)
+#define VIAI2C_CR_CPU_RDY              BIT(3)
+#define VIAI2C_CR_END_MASK             GENMASK(2, 1)
+
+/* REG_TCR Bit fields */
+#define VIAI2C_REG_TCR         0x02
+#define VIAI2C_TCR_HS_MODE             BIT(13)
+#define VIAI2C_TCR_READ                        BIT(14)
+#define VIAI2C_TCR_FAST                        BIT(15)
+#define VIAI2C_TCR_ADDR_MASK           GENMASK(6, 0)
+
+/* REG_CSR Bit fields */
+#define VIAI2C_REG_CSR         0x04
+#define VIAI2C_CSR_RCV_NOT_ACK         BIT(0)
+#define VIAI2C_CSR_RCV_ACK_MASK                BIT(0)
+#define VIAI2C_CSR_READY_MASK          BIT(1)
+
+/* REG_ISR Bit fields */
+#define VIAI2C_REG_ISR         0x06
+#define VIAI2C_ISR_NACK_ADDR           BIT(0)
+#define VIAI2C_ISR_BYTE_END            BIT(1)
+#define VIAI2C_ISR_SCL_TIMEOUT         BIT(2)
+#define VIAI2C_ISR_MASK_ALL            GENMASK(2, 0)
+
+/* REG_IMR Bit fields */
+#define VIAI2C_REG_IMR         0x08
+#define VIAI2C_IMR_BYTE                        BIT(1)
+#define VIAI2C_IMR_ENABLE_ALL          GENMASK(2, 0)
+
+#define VIAI2C_REG_CDR         0x0A
+#define VIAI2C_REG_TR          0x0C
+#define VIAI2C_REG_MCR         0x0E
+
+#define VIAI2C_TIMEOUT         (msecs_to_jiffies(1000))
+
+enum {
+       VIAI2C_PLAT_WMT,
+       VIAI2C_PLAT_ZHAOXIN
+};
+
+enum {
+       VIAI2C_BYTE_MODE,
+       VIAI2C_FIFO_MODE
+};
+
+struct viai2c {
+       struct i2c_adapter      adapter;
+       struct completion       complete;
+       struct device           *dev;
+       void __iomem            *base;
+       struct clk              *clk;
+       u16                     tcr;
+       int                     irq;
+       u16                     xfered_len;
+       struct i2c_msg          *msg;
+       int                     ret;
+       bool                    last;
+       unsigned int            mode;
+       unsigned int            platform;
+       void                    *pltfm_priv;
+};
+
+int viai2c_wait_bus_not_busy(struct viai2c *i2c);
+int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num);
+int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat);
+int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq);
+
+#endif
diff --git a/drivers/i2c/busses/i2c-viai2c-wmt.c b/drivers/i2c/busses/i2c-viai2c-wmt.c
new file mode 100644 (file)
index 0000000..e1988f9
--- /dev/null
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  Wondermedia I2C Master Mode Driver
+ *
+ *  Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ *  Derived from GPLv2+ licensed source:
+ *  - Copyright (C) 2008 WonderMedia Technologies, Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include "i2c-viai2c-common.h"
+
+#define REG_SLAVE_CR   0x10
+#define REG_SLAVE_SR   0x12
+#define REG_SLAVE_ISR  0x14
+#define REG_SLAVE_IMR  0x16
+#define REG_SLAVE_DR   0x18
+#define REG_SLAVE_TR   0x1A
+
+/* REG_TR */
+#define SCL_TIMEOUT(x)         (((x) & 0xFF) << 8)
+#define TR_STD                 0x0064
+#define TR_HS                  0x0019
+
+/* REG_MCR */
+#define MCR_APB_96M            7
+#define MCR_APB_166M           12
+
+static u32 wmt_i2c_func(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART;
+}
+
+static const struct i2c_algorithm wmt_i2c_algo = {
+       .master_xfer    = viai2c_xfer,
+       .functionality  = wmt_i2c_func,
+};
+
+static int wmt_i2c_reset_hardware(struct viai2c *i2c)
+{
+       int err;
+
+       err = clk_prepare_enable(i2c->clk);
+       if (err) {
+               dev_err(i2c->dev, "failed to enable clock\n");
+               return err;
+       }
+
+       err = clk_set_rate(i2c->clk, 20000000);
+       if (err) {
+               dev_err(i2c->dev, "failed to set clock = 20Mhz\n");
+               clk_disable_unprepare(i2c->clk);
+               return err;
+       }
+
+       writew(0, i2c->base + VIAI2C_REG_CR);
+       writew(MCR_APB_166M, i2c->base + VIAI2C_REG_MCR);
+       writew(VIAI2C_ISR_MASK_ALL, i2c->base + VIAI2C_REG_ISR);
+       writew(VIAI2C_IMR_ENABLE_ALL, i2c->base + VIAI2C_REG_IMR);
+       writew(VIAI2C_CR_ENABLE, i2c->base + VIAI2C_REG_CR);
+       readw(i2c->base + VIAI2C_REG_CSR);              /* read clear */
+       writew(VIAI2C_ISR_MASK_ALL, i2c->base + VIAI2C_REG_ISR);
+
+       if (i2c->tcr == VIAI2C_TCR_FAST)
+               writew(SCL_TIMEOUT(128) | TR_HS, i2c->base + VIAI2C_REG_TR);
+       else
+               writew(SCL_TIMEOUT(128) | TR_STD, i2c->base + VIAI2C_REG_TR);
+
+       return 0;
+}
+
+static int wmt_i2c_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct viai2c *i2c;
+       struct i2c_adapter *adap;
+       int err;
+       u32 clk_rate;
+
+       err = viai2c_init(pdev, &i2c, VIAI2C_PLAT_WMT);
+       if (err)
+               return err;
+
+       i2c->clk = of_clk_get(np, 0);
+       if (IS_ERR(i2c->clk)) {
+               dev_err(&pdev->dev, "unable to request clock\n");
+               return PTR_ERR(i2c->clk);
+       }
+
+       err = of_property_read_u32(np, "clock-frequency", &clk_rate);
+       if (!err && clk_rate == I2C_MAX_FAST_MODE_FREQ)
+               i2c->tcr = VIAI2C_TCR_FAST;
+
+       adap = &i2c->adapter;
+       i2c_set_adapdata(adap, i2c);
+       strscpy(adap->name, "WMT I2C adapter", sizeof(adap->name));
+       adap->owner = THIS_MODULE;
+       adap->algo = &wmt_i2c_algo;
+       adap->dev.parent = &pdev->dev;
+       adap->dev.of_node = pdev->dev.of_node;
+
+       err = wmt_i2c_reset_hardware(i2c);
+       if (err) {
+               dev_err(&pdev->dev, "error initializing hardware\n");
+               return err;
+       }
+
+       err = i2c_add_adapter(adap);
+       if (err)
+               /* wmt_i2c_reset_hardware() enables i2c_dev->clk */
+               clk_disable_unprepare(i2c->clk);
+
+       return err;
+}
+
+static void wmt_i2c_remove(struct platform_device *pdev)
+{
+       struct viai2c *i2c = platform_get_drvdata(pdev);
+
+       /* Disable interrupts, clock and delete adapter */
+       writew(0, i2c->base + VIAI2C_REG_IMR);
+       clk_disable_unprepare(i2c->clk);
+       i2c_del_adapter(&i2c->adapter);
+}
+
+static const struct of_device_id wmt_i2c_dt_ids[] = {
+       { .compatible = "wm,wm8505-i2c" },
+       { /* Sentinel */ },
+};
+
+static struct platform_driver wmt_i2c_driver = {
+       .probe          = wmt_i2c_probe,
+       .remove_new     = wmt_i2c_remove,
+       .driver         = {
+               .name   = "wmt-i2c",
+               .of_match_table = wmt_i2c_dt_ids,
+       },
+};
+
+module_platform_driver(wmt_i2c_driver);
+
+MODULE_DESCRIPTION("Wondermedia I2C master-mode bus adapter");
+MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(of, wmt_i2c_dt_ids);
diff --git a/drivers/i2c/busses/i2c-viai2c-zhaoxin.c b/drivers/i2c/busses/i2c-viai2c-zhaoxin.c
new file mode 100644 (file)
index 0000000..7e3ac2a
--- /dev/null
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  Copyright(c) 2024 Shanghai Zhaoxin Semiconductor Corporation.
+ *                    All rights reserved.
+ */
+
+#include <linux/acpi.h>
+#include "i2c-viai2c-common.h"
+
+/*
+ * registers
+ */
+/* Zhaoxin specific register bit fields */
+/* REG_CR Bit fields */
+#define   ZXI2C_CR_MST_RST             BIT(7)
+#define   ZXI2C_CR_FIFO_MODE           BIT(14)
+/* REG_ISR/IMR Bit fields */
+#define   ZXI2C_IRQ_FIFONACK           BIT(4)
+#define   ZXI2C_IRQ_FIFOEND            BIT(3)
+#define   ZXI2C_IRQ_MASK               (VIAI2C_ISR_MASK_ALL \
+                                       | ZXI2C_IRQ_FIFOEND \
+                                       | ZXI2C_IRQ_FIFONACK)
+/* Zhaoxin specific registers */
+#define ZXI2C_REG_CLK          0x10
+#define   ZXI2C_CLK_50M                        BIT(0)
+#define ZXI2C_REG_REV          0x11
+#define ZXI2C_REG_HCR          0x12
+#define   ZXI2C_HCR_RST_FIFO           GENMASK(1, 0)
+#define ZXI2C_REG_HTDR         0x13
+#define ZXI2C_REG_HRDR         0x14
+#define ZXI2C_REG_HTLR         0x15
+#define ZXI2C_REG_HRLR         0x16
+#define ZXI2C_REG_HWCNTR       0x18
+#define ZXI2C_REG_HRCNTR       0x19
+
+/* parameters Constants */
+#define ZXI2C_GOLD_FSTP_100K   0xF3
+#define ZXI2C_GOLD_FSTP_400K   0x38
+#define ZXI2C_GOLD_FSTP_1M     0x13
+#define ZXI2C_GOLD_FSTP_3400K  0x37
+#define ZXI2C_HS_MASTER_CODE   (0x08 << 8)
+
+#define ZXI2C_FIFO_SIZE                32
+
+struct viai2c_zhaoxin {
+       u8                      hrv;
+       u16                     tr;
+       u16                     mcr;
+       u16                     xfer_len;
+};
+
+/* 'irq == true' means in interrupt context */
+int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq)
+{
+       u16 i;
+       u8 tmp;
+       struct i2c_msg *msg = i2c->msg;
+       void __iomem *base = i2c->base;
+       bool read = !!(msg->flags & I2C_M_RD);
+       struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
+
+       if (irq) {
+               /* get the received data */
+               if (read)
+                       for (i = 0; i < priv->xfer_len; i++)
+                               msg->buf[i2c->xfered_len + i] = ioread8(base + ZXI2C_REG_HRDR);
+
+               i2c->xfered_len += priv->xfer_len;
+               if (i2c->xfered_len == msg->len)
+                       return 1;
+       }
+
+       /* reset fifo buffer */
+       tmp = ioread8(base + ZXI2C_REG_HCR);
+       iowrite8(tmp | ZXI2C_HCR_RST_FIFO, base + ZXI2C_REG_HCR);
+
+       /* set xfer len */
+       priv->xfer_len = min_t(u16, msg->len - i2c->xfered_len, ZXI2C_FIFO_SIZE);
+       if (read) {
+               iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HRLR);
+       } else {
+               iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HTLR);
+               /* set write data */
+               for (i = 0; i < priv->xfer_len; i++)
+                       iowrite8(msg->buf[i2c->xfered_len + i], base + ZXI2C_REG_HTDR);
+       }
+
+       /* prepare to stop transmission */
+       if (priv->hrv && msg->len == (i2c->xfered_len + priv->xfer_len)) {
+               tmp = ioread8(base + VIAI2C_REG_CR);
+               tmp |= read ? VIAI2C_CR_RX_END : VIAI2C_CR_TX_END;
+               iowrite8(tmp, base + VIAI2C_REG_CR);
+       }
+
+       if (irq) {
+               /* continue transmission */
+               tmp = ioread8(base + VIAI2C_REG_CR);
+               iowrite8(tmp |= VIAI2C_CR_CPU_RDY, base + VIAI2C_REG_CR);
+       } else {
+               u16 tcr_val = i2c->tcr;
+
+               /* start transmission */
+               tcr_val |= read ? VIAI2C_TCR_READ : 0;
+               writew(tcr_val | msg->addr, base + VIAI2C_REG_TCR);
+       }
+
+       return 0;
+}
+
+static int zxi2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+       u8 tmp;
+       int ret;
+       struct viai2c *i2c = (struct viai2c *)i2c_get_adapdata(adap);
+       struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
+       void __iomem *base = i2c->base;
+
+       ret = viai2c_wait_bus_not_busy(i2c);
+       if (ret)
+               return ret;
+
+       tmp = ioread8(base + VIAI2C_REG_CR);
+       tmp &= ~(VIAI2C_CR_RX_END | VIAI2C_CR_TX_END);
+
+       if (num == 1 && msgs->len >= 2 && (priv->hrv || msgs->len <= ZXI2C_FIFO_SIZE)) {
+               /* enable fifo mode */
+               iowrite16(ZXI2C_CR_FIFO_MODE | tmp, base + VIAI2C_REG_CR);
+               /* clear irq status */
+               iowrite8(ZXI2C_IRQ_MASK, base + VIAI2C_REG_ISR);
+               /* enable fifo irq */
+               iowrite8(VIAI2C_ISR_NACK_ADDR | ZXI2C_IRQ_FIFOEND, base + VIAI2C_REG_IMR);
+
+               i2c->msg = msgs;
+               i2c->mode = VIAI2C_FIFO_MODE;
+               priv->xfer_len = 0;
+               i2c->xfered_len = 0;
+
+               viai2c_fifo_irq_xfer(i2c, 0);
+
+               if (!wait_for_completion_timeout(&i2c->complete, VIAI2C_TIMEOUT))
+                       return -ETIMEDOUT;
+
+               ret = i2c->ret;
+       } else {
+               /* enable byte mode */
+               iowrite16(tmp, base + VIAI2C_REG_CR);
+               /* clear irq status */
+               iowrite8(ZXI2C_IRQ_MASK, base + VIAI2C_REG_ISR);
+               /* enable byte irq */
+               iowrite8(VIAI2C_ISR_NACK_ADDR | VIAI2C_IMR_BYTE, base + VIAI2C_REG_IMR);
+
+               ret = viai2c_xfer(adap, msgs, num);
+               if (ret == -ETIMEDOUT)
+                       iowrite16(tmp | VIAI2C_CR_END_MASK, base + VIAI2C_REG_CR);
+       }
+       /* dis interrupt */
+       iowrite8(0, base + VIAI2C_REG_IMR);
+
+       return ret;
+}
+
+static u32 zxi2c_func(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm zxi2c_algorithm = {
+       .master_xfer    = zxi2c_master_xfer,
+       .functionality  = zxi2c_func,
+};
+
+static const struct i2c_adapter_quirks zxi2c_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN | I2C_AQ_COMB_WRITE_THEN_READ,
+};
+
+static const u32 zxi2c_speed_params_table[][3] = {
+       /* speed, ZXI2C_TCR, ZXI2C_FSTP */
+       { I2C_MAX_STANDARD_MODE_FREQ, 0, ZXI2C_GOLD_FSTP_100K },
+       { I2C_MAX_FAST_MODE_FREQ, VIAI2C_TCR_FAST, ZXI2C_GOLD_FSTP_400K },
+       { I2C_MAX_FAST_MODE_PLUS_FREQ, VIAI2C_TCR_FAST, ZXI2C_GOLD_FSTP_1M },
+       { I2C_MAX_HIGH_SPEED_MODE_FREQ, VIAI2C_TCR_HS_MODE | VIAI2C_TCR_FAST,
+         ZXI2C_GOLD_FSTP_3400K },
+};
+
+static void zxi2c_set_bus_speed(struct viai2c *i2c)
+{
+       struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
+
+       iowrite16(priv->tr, i2c->base + VIAI2C_REG_TR);
+       iowrite8(ZXI2C_CLK_50M, i2c->base + ZXI2C_REG_CLK);
+       iowrite16(priv->mcr, i2c->base + VIAI2C_REG_MCR);
+}
+
+static void zxi2c_get_bus_speed(struct viai2c *i2c)
+{
+       u8 i, count;
+       u8 fstp;
+       const u32 *params;
+       struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
+       u32 acpi_speed = i2c_acpi_find_bus_speed(i2c->dev);
+
+       count = ARRAY_SIZE(zxi2c_speed_params_table);
+       for (i = 0; i < count; i++)
+               if (acpi_speed == zxi2c_speed_params_table[i][0])
+                       break;
+       /* if not found, use 400k as default */
+       i = i < count ? i : 1;
+
+       params = zxi2c_speed_params_table[i];
+       fstp = ioread8(i2c->base + VIAI2C_REG_TR);
+       if (abs(fstp - params[2]) > 0x10) {
+               /*
+                * if BIOS setting value far from golden value,
+                * use golden value and warn user
+                */
+               dev_warn(i2c->dev, "FW FSTP[%x] might cause wrong timings, dropped\n", fstp);
+               priv->tr = params[2] | 0xff00;
+       } else {
+               priv->tr = fstp | 0xff00;
+       }
+
+       i2c->tcr = params[1];
+       priv->mcr = ioread16(i2c->base + VIAI2C_REG_MCR);
+       /* for Hs-mode, use 0x80 as master code */
+       if (params[0] == I2C_MAX_HIGH_SPEED_MODE_FREQ)
+               priv->mcr |= ZXI2C_HS_MASTER_CODE;
+
+       dev_info(i2c->dev, "speed mode is %s\n", i2c_freq_mode_string(params[0]));
+}
+
+static int zxi2c_probe(struct platform_device *pdev)
+{
+       int error;
+       struct viai2c *i2c;
+       struct i2c_adapter *adap;
+       struct viai2c_zhaoxin *priv;
+
+       error = viai2c_init(pdev, &i2c, VIAI2C_PLAT_ZHAOXIN);
+       if (error)
+               return error;
+
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       i2c->pltfm_priv = priv;
+
+       zxi2c_get_bus_speed(i2c);
+       zxi2c_set_bus_speed(i2c);
+
+       priv->hrv = ioread8(i2c->base + ZXI2C_REG_REV);
+
+       adap = &i2c->adapter;
+       adap->owner = THIS_MODULE;
+       adap->algo = &zxi2c_algorithm;
+       adap->quirks = &zxi2c_quirks;
+       adap->dev.parent = &pdev->dev;
+       ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev));
+       snprintf(adap->name, sizeof(adap->name), "zhaoxin-%s-%s",
+                dev_name(pdev->dev.parent), dev_name(i2c->dev));
+       i2c_set_adapdata(adap, i2c);
+
+       return devm_i2c_add_adapter(&pdev->dev, adap);
+}
+
+static int __maybe_unused zxi2c_resume(struct device *dev)
+{
+       struct viai2c *i2c = dev_get_drvdata(dev);
+
+       iowrite8(ZXI2C_CR_MST_RST, i2c->base + VIAI2C_REG_CR);
+       zxi2c_set_bus_speed(i2c);
+
+       return 0;
+}
+
+static const struct dev_pm_ops zxi2c_pm = {
+       SET_SYSTEM_SLEEP_PM_OPS(NULL, zxi2c_resume)
+};
+
+static const struct acpi_device_id zxi2c_acpi_match[] = {
+       {"IIC1D17", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(acpi, zxi2c_acpi_match);
+
+static struct platform_driver zxi2c_driver = {
+       .probe = zxi2c_probe,
+       .driver = {
+               .name = "i2c_zhaoxin",
+               .acpi_match_table = zxi2c_acpi_match,
+               .pm = &zxi2c_pm,
+       },
+};
+
+module_platform_driver(zxi2c_driver);
+
+MODULE_AUTHOR("HansHu@zhaoxin.com");
+MODULE_DESCRIPTION("Shanghai Zhaoxin IIC driver");
+MODULE_LICENSE("GPL");
index 9e153b5b0e8e425b2b3113a09aa879096ba6142b..3784b07f537164a4b6134f81c73835e61d548291 100644 (file)
@@ -416,7 +416,6 @@ static void vprbrd_i2c_remove(struct platform_device *pdev)
 
 static struct platform_driver vprbrd_i2c_driver = {
        .driver.name    = "viperboard-i2c",
-       .driver.owner   = THIS_MODULE,
        .probe          = vprbrd_i2c_probe,
        .remove_new     = vprbrd_i2c_remove,
 };
diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c
deleted file mode 100644 (file)
index 198afee..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *  Wondermedia I2C Master Mode Driver
- *
- *  Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
- *
- *  Derived from GPLv2+ licensed source:
- *  - Copyright (C) 2008 WonderMedia Technologies, Inc.
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/platform_device.h>
-
-#define REG_CR         0x00
-#define REG_TCR                0x02
-#define REG_CSR                0x04
-#define REG_ISR                0x06
-#define REG_IMR                0x08
-#define REG_CDR                0x0A
-#define REG_TR         0x0C
-#define REG_MCR                0x0E
-#define REG_SLAVE_CR   0x10
-#define REG_SLAVE_SR   0x12
-#define REG_SLAVE_ISR  0x14
-#define REG_SLAVE_IMR  0x16
-#define REG_SLAVE_DR   0x18
-#define REG_SLAVE_TR   0x1A
-
-/* REG_CR Bit fields */
-#define CR_TX_NEXT_ACK         0x0000
-#define CR_ENABLE              0x0001
-#define CR_TX_NEXT_NO_ACK      0x0002
-#define CR_TX_END              0x0004
-#define CR_CPU_RDY             0x0008
-#define SLAV_MODE_SEL          0x8000
-
-/* REG_TCR Bit fields */
-#define TCR_STANDARD_MODE      0x0000
-#define TCR_MASTER_WRITE       0x0000
-#define TCR_HS_MODE            0x2000
-#define TCR_MASTER_READ                0x4000
-#define TCR_FAST_MODE          0x8000
-#define TCR_SLAVE_ADDR_MASK    0x007F
-
-/* REG_ISR Bit fields */
-#define ISR_NACK_ADDR          0x0001
-#define ISR_BYTE_END           0x0002
-#define ISR_SCL_TIMEOUT                0x0004
-#define ISR_WRITE_ALL          0x0007
-
-/* REG_IMR Bit fields */
-#define IMR_ENABLE_ALL         0x0007
-
-/* REG_CSR Bit fields */
-#define CSR_RCV_NOT_ACK                0x0001
-#define CSR_RCV_ACK_MASK       0x0001
-#define CSR_READY_MASK         0x0002
-
-/* REG_TR */
-#define SCL_TIMEOUT(x)         (((x) & 0xFF) << 8)
-#define TR_STD                 0x0064
-#define TR_HS                  0x0019
-
-/* REG_MCR */
-#define MCR_APB_96M            7
-#define MCR_APB_166M           12
-
-#define WMT_I2C_TIMEOUT                (msecs_to_jiffies(1000))
-
-struct wmt_i2c_dev {
-       struct i2c_adapter      adapter;
-       struct completion       complete;
-       struct device           *dev;
-       void __iomem            *base;
-       struct clk              *clk;
-       u16                     tcr;
-       int                     irq;
-       u16                     cmd_status;
-};
-
-static int wmt_i2c_wait_bus_not_busy(struct wmt_i2c_dev *i2c_dev)
-{
-       unsigned long timeout;
-
-       timeout = jiffies + WMT_I2C_TIMEOUT;
-       while (!(readw(i2c_dev->base + REG_CSR) & CSR_READY_MASK)) {
-               if (time_after(jiffies, timeout)) {
-                       dev_warn(i2c_dev->dev, "timeout waiting for bus ready\n");
-                       return -EBUSY;
-               }
-               msleep(20);
-       }
-
-       return 0;
-}
-
-static int wmt_check_status(struct wmt_i2c_dev *i2c_dev)
-{
-       int ret = 0;
-       unsigned long wait_result;
-
-       wait_result = wait_for_completion_timeout(&i2c_dev->complete,
-                                               msecs_to_jiffies(500));
-       if (!wait_result)
-               return -ETIMEDOUT;
-
-       if (i2c_dev->cmd_status & ISR_NACK_ADDR)
-               ret = -EIO;
-
-       if (i2c_dev->cmd_status & ISR_SCL_TIMEOUT)
-               ret = -ETIMEDOUT;
-
-       return ret;
-}
-
-static int wmt_i2c_write(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg,
-                        int last)
-{
-       u16 val, tcr_val = i2c_dev->tcr;
-       int ret;
-       int xfer_len = 0;
-
-       if (pmsg->len == 0) {
-               /*
-                * We still need to run through the while (..) once, so
-                * start at -1 and break out early from the loop
-                */
-               xfer_len = -1;
-               writew(0, i2c_dev->base + REG_CDR);
-       } else {
-               writew(pmsg->buf[0] & 0xFF, i2c_dev->base + REG_CDR);
-       }
-
-       if (!(pmsg->flags & I2C_M_NOSTART)) {
-               val = readw(i2c_dev->base + REG_CR);
-               val &= ~CR_TX_END;
-               val |= CR_CPU_RDY;
-               writew(val, i2c_dev->base + REG_CR);
-       }
-
-       reinit_completion(&i2c_dev->complete);
-
-       tcr_val |= (TCR_MASTER_WRITE | (pmsg->addr & TCR_SLAVE_ADDR_MASK));
-
-       writew(tcr_val, i2c_dev->base + REG_TCR);
-
-       if (pmsg->flags & I2C_M_NOSTART) {
-               val = readw(i2c_dev->base + REG_CR);
-               val |= CR_CPU_RDY;
-               writew(val, i2c_dev->base + REG_CR);
-       }
-
-       while (xfer_len < pmsg->len) {
-               ret = wmt_check_status(i2c_dev);
-               if (ret)
-                       return ret;
-
-               xfer_len++;
-
-               val = readw(i2c_dev->base + REG_CSR);
-               if ((val & CSR_RCV_ACK_MASK) == CSR_RCV_NOT_ACK) {
-                       dev_dbg(i2c_dev->dev, "write RCV NACK error\n");
-                       return -EIO;
-               }
-
-               if (pmsg->len == 0) {
-                       val = CR_TX_END | CR_CPU_RDY | CR_ENABLE;
-                       writew(val, i2c_dev->base + REG_CR);
-                       break;
-               }
-
-               if (xfer_len == pmsg->len) {
-                       if (last != 1)
-                               writew(CR_ENABLE, i2c_dev->base + REG_CR);
-               } else {
-                       writew(pmsg->buf[xfer_len] & 0xFF, i2c_dev->base +
-                                                               REG_CDR);
-                       writew(CR_CPU_RDY | CR_ENABLE, i2c_dev->base + REG_CR);
-               }
-       }
-
-       return 0;
-}
-
-static int wmt_i2c_read(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg)
-{
-       u16 val, tcr_val = i2c_dev->tcr;
-       int ret;
-       u32 xfer_len = 0;
-
-       val = readw(i2c_dev->base + REG_CR);
-       val &= ~(CR_TX_END | CR_TX_NEXT_NO_ACK);
-
-       if (!(pmsg->flags & I2C_M_NOSTART))
-               val |= CR_CPU_RDY;
-
-       if (pmsg->len == 1)
-               val |= CR_TX_NEXT_NO_ACK;
-
-       writew(val, i2c_dev->base + REG_CR);
-
-       reinit_completion(&i2c_dev->complete);
-
-       tcr_val |= TCR_MASTER_READ | (pmsg->addr & TCR_SLAVE_ADDR_MASK);
-
-       writew(tcr_val, i2c_dev->base + REG_TCR);
-
-       if (pmsg->flags & I2C_M_NOSTART) {
-               val = readw(i2c_dev->base + REG_CR);
-               val |= CR_CPU_RDY;
-               writew(val, i2c_dev->base + REG_CR);
-       }
-
-       while (xfer_len < pmsg->len) {
-               ret = wmt_check_status(i2c_dev);
-               if (ret)
-                       return ret;
-
-               pmsg->buf[xfer_len] = readw(i2c_dev->base + REG_CDR) >> 8;
-               xfer_len++;
-
-               val = readw(i2c_dev->base + REG_CR) | CR_CPU_RDY;
-               if (xfer_len == pmsg->len - 1)
-                       val |= CR_TX_NEXT_NO_ACK;
-               writew(val, i2c_dev->base + REG_CR);
-       }
-
-       return 0;
-}
-
-static int wmt_i2c_xfer(struct i2c_adapter *adap,
-                       struct i2c_msg msgs[],
-                       int num)
-{
-       struct i2c_msg *pmsg;
-       int i;
-       int ret = 0;
-       struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
-
-       for (i = 0; ret >= 0 && i < num; i++) {
-               pmsg = &msgs[i];
-               if (!(pmsg->flags & I2C_M_NOSTART)) {
-                       ret = wmt_i2c_wait_bus_not_busy(i2c_dev);
-                       if (ret < 0)
-                               return ret;
-               }
-
-               if (pmsg->flags & I2C_M_RD)
-                       ret = wmt_i2c_read(i2c_dev, pmsg);
-               else
-                       ret = wmt_i2c_write(i2c_dev, pmsg, (i + 1) == num);
-       }
-
-       return (ret < 0) ? ret : i;
-}
-
-static u32 wmt_i2c_func(struct i2c_adapter *adap)
-{
-       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART;
-}
-
-static const struct i2c_algorithm wmt_i2c_algo = {
-       .master_xfer    = wmt_i2c_xfer,
-       .functionality  = wmt_i2c_func,
-};
-
-static irqreturn_t wmt_i2c_isr(int irq, void *data)
-{
-       struct wmt_i2c_dev *i2c_dev = data;
-
-       /* save the status and write-clear it */
-       i2c_dev->cmd_status = readw(i2c_dev->base + REG_ISR);
-       writew(i2c_dev->cmd_status, i2c_dev->base + REG_ISR);
-
-       complete(&i2c_dev->complete);
-
-       return IRQ_HANDLED;
-}
-
-static int wmt_i2c_reset_hardware(struct wmt_i2c_dev *i2c_dev)
-{
-       int err;
-
-       err = clk_prepare_enable(i2c_dev->clk);
-       if (err) {
-               dev_err(i2c_dev->dev, "failed to enable clock\n");
-               return err;
-       }
-
-       err = clk_set_rate(i2c_dev->clk, 20000000);
-       if (err) {
-               dev_err(i2c_dev->dev, "failed to set clock = 20Mhz\n");
-               clk_disable_unprepare(i2c_dev->clk);
-               return err;
-       }
-
-       writew(0, i2c_dev->base + REG_CR);
-       writew(MCR_APB_166M, i2c_dev->base + REG_MCR);
-       writew(ISR_WRITE_ALL, i2c_dev->base + REG_ISR);
-       writew(IMR_ENABLE_ALL, i2c_dev->base + REG_IMR);
-       writew(CR_ENABLE, i2c_dev->base + REG_CR);
-       readw(i2c_dev->base + REG_CSR);         /* read clear */
-       writew(ISR_WRITE_ALL, i2c_dev->base + REG_ISR);
-
-       if (i2c_dev->tcr == TCR_FAST_MODE)
-               writew(SCL_TIMEOUT(128) | TR_HS, i2c_dev->base + REG_TR);
-       else
-               writew(SCL_TIMEOUT(128) | TR_STD, i2c_dev->base + REG_TR);
-
-       return 0;
-}
-
-static int wmt_i2c_probe(struct platform_device *pdev)
-{
-       struct device_node *np = pdev->dev.of_node;
-       struct wmt_i2c_dev *i2c_dev;
-       struct i2c_adapter *adap;
-       int err;
-       u32 clk_rate;
-
-       i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
-       if (!i2c_dev)
-               return -ENOMEM;
-
-       i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
-       if (IS_ERR(i2c_dev->base))
-               return PTR_ERR(i2c_dev->base);
-
-       i2c_dev->irq = irq_of_parse_and_map(np, 0);
-       if (!i2c_dev->irq) {
-               dev_err(&pdev->dev, "irq missing or invalid\n");
-               return -EINVAL;
-       }
-
-       i2c_dev->clk = of_clk_get(np, 0);
-       if (IS_ERR(i2c_dev->clk)) {
-               dev_err(&pdev->dev, "unable to request clock\n");
-               return PTR_ERR(i2c_dev->clk);
-       }
-
-       err = of_property_read_u32(np, "clock-frequency", &clk_rate);
-       if (!err && (clk_rate == I2C_MAX_FAST_MODE_FREQ))
-               i2c_dev->tcr = TCR_FAST_MODE;
-
-       i2c_dev->dev = &pdev->dev;
-
-       err = devm_request_irq(&pdev->dev, i2c_dev->irq, wmt_i2c_isr, 0,
-                                                       "i2c", i2c_dev);
-       if (err) {
-               dev_err(&pdev->dev, "failed to request irq %i\n", i2c_dev->irq);
-               return err;
-       }
-
-       adap = &i2c_dev->adapter;
-       i2c_set_adapdata(adap, i2c_dev);
-       strscpy(adap->name, "WMT I2C adapter", sizeof(adap->name));
-       adap->owner = THIS_MODULE;
-       adap->algo = &wmt_i2c_algo;
-       adap->dev.parent = &pdev->dev;
-       adap->dev.of_node = pdev->dev.of_node;
-
-       init_completion(&i2c_dev->complete);
-
-       err = wmt_i2c_reset_hardware(i2c_dev);
-       if (err) {
-               dev_err(&pdev->dev, "error initializing hardware\n");
-               return err;
-       }
-
-       err = i2c_add_adapter(adap);
-       if (err)
-               goto err_disable_clk;
-
-       platform_set_drvdata(pdev, i2c_dev);
-
-       return 0;
-
-err_disable_clk:
-       clk_disable_unprepare(i2c_dev->clk);
-       return err;
-}
-
-static void wmt_i2c_remove(struct platform_device *pdev)
-{
-       struct wmt_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
-
-       /* Disable interrupts, clock and delete adapter */
-       writew(0, i2c_dev->base + REG_IMR);
-       clk_disable_unprepare(i2c_dev->clk);
-       i2c_del_adapter(&i2c_dev->adapter);
-}
-
-static const struct of_device_id wmt_i2c_dt_ids[] = {
-       { .compatible = "wm,wm8505-i2c" },
-       { /* Sentinel */ },
-};
-
-static struct platform_driver wmt_i2c_driver = {
-       .probe          = wmt_i2c_probe,
-       .remove_new     = wmt_i2c_remove,
-       .driver         = {
-               .name   = "wmt-i2c",
-               .of_match_table = wmt_i2c_dt_ids,
-       },
-};
-
-module_platform_driver(wmt_i2c_driver);
-
-MODULE_DESCRIPTION("Wondermedia I2C master-mode bus adapter");
-MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(of, wmt_i2c_dt_ids);
index d6037a3286690593d57f29cfb8c72467f472c4e3..14ae0cfc325efbeb38e52707bf3bc5f4c7dd90c7 100644 (file)
@@ -445,6 +445,11 @@ static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
        return i2c_find_device_by_fwnode(acpi_fwnode_handle(adev));
 }
 
+static struct i2c_adapter *i2c_acpi_find_adapter_by_adev(struct acpi_device *adev)
+{
+       return i2c_find_adapter_by_fwnode(acpi_fwnode_handle(adev));
+}
+
 static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
                           void *arg)
 {
@@ -471,11 +476,17 @@ static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
                        break;
 
                client = i2c_acpi_find_client_by_adev(adev);
-               if (!client)
-                       break;
+               if (client) {
+                       i2c_unregister_device(client);
+                       put_device(&client->dev);
+               }
+
+               adapter = i2c_acpi_find_adapter_by_adev(adev);
+               if (adapter) {
+                       acpi_unbind_one(&adapter->dev);
+                       put_device(&adapter->dev);
+               }
 
-               i2c_unregister_device(client);
-               put_device(&client->dev);
                break;
        }
 
index 57ff09f18c371dd28cdbe989d144f546e24ec8a3..fda72e8be885071c556df0cfb2174e91ef660f88 100644 (file)
@@ -127,19 +127,6 @@ static u32 i2c_mux_functionality(struct i2c_adapter *adap)
        return parent->algo->functionality(parent);
 }
 
-/* Return all parent classes, merged */
-static unsigned int i2c_mux_parent_classes(struct i2c_adapter *parent)
-{
-       unsigned int class = 0;
-
-       do {
-               class |= parent->class;
-               parent = i2c_parent_is_i2c_adapter(parent);
-       } while (parent);
-
-       return class;
-}
-
 static void i2c_mux_lock_bus(struct i2c_adapter *adapter, unsigned int flags)
 {
        struct i2c_mux_priv *priv = adapter->algo_data;
@@ -281,8 +268,7 @@ static const struct i2c_lock_operations i2c_parent_lock_ops = {
 };
 
 int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
-                       u32 force_nr, u32 chan_id,
-                       unsigned int class)
+                       u32 force_nr, u32 chan_id)
 {
        struct i2c_adapter *parent = muxc->parent;
        struct i2c_mux_priv *priv;
@@ -340,14 +326,6 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
        else
                priv->adap.lock_ops = &i2c_parent_lock_ops;
 
-       /* Sanity check on class */
-       if (i2c_mux_parent_classes(parent) & class & ~I2C_CLASS_DEPRECATED)
-               dev_err(&parent->dev,
-                       "Segment %d behind mux can't share classes with ancestors\n",
-                       chan_id);
-       else
-               priv->adap.class = class;
-
        /*
         * Try to populate the mux adapter's of_node, expands to
         * nothing if !CONFIG_OF.
index 24168e9f7df4c15299b72846d23c8d62bb5410cc..7aa6e795d833d6c31f6978cdbd518dadaa4a8588 100644 (file)
@@ -167,7 +167,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
        }
 
        /* Actually add the mux adapter */
-       ret = i2c_mux_add_adapter(muxc, 0, 0, 0);
+       ret = i2c_mux_add_adapter(muxc, 0, 0);
        if (ret)
                i2c_put_adapter(muxc->parent);
 
index 6b979a0a6ab86a1bbc36a80435f993b8a35fbdab..d6bbb8b683333673cb2704331d49cb08342f5451 100644 (file)
@@ -206,9 +206,8 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
 
        for (i = 0; i < mux->data.n_values; i++) {
                u32 nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0;
-               unsigned int class = mux->data.classes ? mux->data.classes[i] : 0;
 
-               ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], class);
+               ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i]);
                if (ret)
                        goto add_adapter_failed;
        }
index 8305661e12539b6bfff279f3165eb5d216d6a55a..10d63307b14d0108ccd7947cf302094c88467fc4 100644 (file)
@@ -124,7 +124,7 @@ static int i2c_mux_probe(struct platform_device *pdev)
                        goto err_children;
                }
 
-               ret = i2c_mux_add_adapter(muxc, 0, chan, 0);
+               ret = i2c_mux_add_adapter(muxc, 0, chan);
                if (ret)
                        goto err_children;
        }
index 23766d853e7674c2f78364c981573b7a6c49b386..19a7c370946d4743f701786e4376217b357c2220 100644 (file)
@@ -279,7 +279,7 @@ static int ltc4306_probe(struct i2c_client *client)
 
        /* Now create an adapter for each channel */
        for (num = 0; num < chip->nchans; num++) {
-               ret = i2c_mux_add_adapter(muxc, 0, num, 0);
+               ret = i2c_mux_add_adapter(muxc, 0, num);
                if (ret) {
                        i2c_mux_del_adapters(muxc);
                        return ret;
index 4c6ed1d58c79a311bee5634bd6d7fbc6140676d3..3f06aa3331a780ed28033137784349dd32bed432 100644 (file)
@@ -154,7 +154,7 @@ static int mlxcpld_mux_probe(struct platform_device *pdev)
 
        /* Create an adapter for each channel. */
        for (num = 0; num < pdata->num_adaps; num++) {
-               err = i2c_mux_add_adapter(muxc, 0, pdata->chan_ids[num], 0);
+               err = i2c_mux_add_adapter(muxc, 0, pdata->chan_ids[num]);
                if (err)
                        goto virt_reg_failed;
        }
index ce0fb69249a8fa4a7f696ba4bbe0e7ca461717be..e28694d991fb07ab1148de950da80189fd6f133a 100644 (file)
@@ -314,7 +314,7 @@ static int pca9541_probe(struct i2c_client *client)
 
        i2c_set_clientdata(client, muxc);
 
-       ret = i2c_mux_add_adapter(muxc, 0, 0, 0);
+       ret = i2c_mux_add_adapter(muxc, 0, 0);
        if (ret)
                return ret;
 
index c3f4ff08ac3851a620d77e69caccdb95a2cc0ccb..6f84018258c458e6be5b7eaf2bcf31ca1b03acd7 100644 (file)
@@ -644,7 +644,7 @@ static int pca954x_probe(struct i2c_client *client)
 
        /* Now create an adapter for each channel */
        for (num = 0; num < data->chip->nchans; num++) {
-               ret = i2c_mux_add_adapter(muxc, 0, num, 0);
+               ret = i2c_mux_add_adapter(muxc, 0, num);
                if (ret)
                        goto fail_cleanup;
        }
index 6ebca7bfd8a2652ec5e7bf1abef21a35992d38ac..02aaf0781e9c8260a87d3abe1b7272991e486b98 100644 (file)
@@ -151,7 +151,7 @@ static int i2c_mux_pinctrl_probe(struct platform_device *pdev)
 
        /* Do not add any adapter for the idle state (if it's there at all). */
        for (i = 0; i < num_names - !!muxc->deselect; i++) {
-               ret = i2c_mux_add_adapter(muxc, 0, i, 0);
+               ret = i2c_mux_add_adapter(muxc, 0, i);
                if (ret)
                        goto err_del_adapter;
        }
index 8489971babd37b55ef794ebd8ec8446d9797acca..ef765fcd33f54765242236fd3314e531e7b81fd0 100644 (file)
@@ -213,7 +213,7 @@ static int i2c_mux_reg_probe(struct platform_device *pdev)
        for (i = 0; i < mux->data.n_values; i++) {
                nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0;
 
-               ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], 0);
+               ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i]);
                if (ret)
                        goto err_del_mux_adapters;
        }
index 52b6feed26379a78bfab3af3180b4cec19c936ea..29ecfa6fd633505ae0e9aa1653d90bb5f73dcb1e 100644 (file)
@@ -72,7 +72,7 @@ static int mpu3050_i2c_probe(struct i2c_client *client)
        else {
                mpu3050->i2cmux->priv = mpu3050;
                /* Ignore failure, not critical */
-               i2c_mux_add_adapter(mpu3050->i2cmux, 0, 0, 0);
+               i2c_mux_add_adapter(mpu3050->i2cmux, 0, 0);
        }
 
        return 0;
index 410ea39fd495a693aebd365647c3e47c38c5976a..0e03137fb3d40d4753989522cf5168ef358a1014 100644 (file)
@@ -142,7 +142,7 @@ static int inv_mpu_probe(struct i2c_client *client)
                if (!st->muxc)
                        return -ENOMEM;
                st->muxc->priv = dev_get_drvdata(&client->dev);
-               result = i2c_mux_add_adapter(st->muxc, 0, 0, 0);
+               result = i2c_mux_add_adapter(st->muxc, 0, 0);
                if (result)
                        return result;
                result = inv_mpu_acpi_create_mux_client(client);
index a829c89792a4325e14c1d0012cc3c74b9983c62e..5afdbe244596b346cd8f1fb44c95dfbadab36a7a 100644 (file)
@@ -1480,7 +1480,7 @@ static int af9013_probe(struct i2c_client *client)
                goto err_regmap_exit;
        }
        state->muxc->priv = state;
-       ret = i2c_mux_add_adapter(state->muxc, 0, 0, 0);
+       ret = i2c_mux_add_adapter(state->muxc, 0, 0);
        if (ret)
                goto err_regmap_exit;
 
index 231b45632ad5a3f7337302015319a0277261de90..b25d11be8611b4ad68eb7904046b0a571a6851e2 100644 (file)
@@ -2208,7 +2208,7 @@ static int lgdt3306a_probe(struct i2c_client *client)
                goto err_kfree;
        }
        state->muxc->priv = client;
-       ret = i2c_mux_add_adapter(state->muxc, 0, 0, 0);
+       ret = i2c_mux_add_adapter(state->muxc, 0, 0);
        if (ret)
                goto err_kfree;
 
index 389548fa2e0c47ddc395d5485c2066fcf5954b2e..5a03485686d96e91d648ecb8e3a151b77b08364d 100644 (file)
@@ -1873,7 +1873,7 @@ static int m88ds3103_probe(struct i2c_client *client)
                goto err_kfree;
        }
        dev->muxc->priv = dev;
-       ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0);
+       ret = i2c_mux_add_adapter(dev->muxc, 0, 0);
        if (ret)
                goto err_kfree;
 
index 35c969fd2cb5e6ceabe746388631691793e6081c..30d10fe4b33e3405192e2b3da7f0ab16c5ade4c8 100644 (file)
@@ -838,7 +838,7 @@ static int rtl2830_probe(struct i2c_client *client)
                goto err_regmap_exit;
        }
        dev->muxc->priv = client;
-       ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0);
+       ret = i2c_mux_add_adapter(dev->muxc, 0, 0);
        if (ret)
                goto err_regmap_exit;
 
index 601cf45c39358c46b334cd971078e1bab255f03a..5142820b1b3d973dcd8beebc16883a809400fa2d 100644 (file)
@@ -1082,7 +1082,7 @@ static int rtl2832_probe(struct i2c_client *client)
                goto err_regmap_exit;
        }
        dev->muxc->priv = dev;
-       ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0);
+       ret = i2c_mux_add_adapter(dev->muxc, 0, 0);
        if (ret)
                goto err_regmap_exit;
 
index dae1f2153e8be2b7615ef9cc3f8ed79517174a72..26828fd41e6843a0ac2e51c38c8dce35ae59058d 100644 (file)
@@ -744,7 +744,7 @@ static int si2168_probe(struct i2c_client *client)
                goto err_kfree;
        }
        dev->muxc->priv = client;
-       ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0);
+       ret = i2c_mux_add_adapter(dev->muxc, 0, 0);
        if (ret)
                goto err_kfree;
 
index d685d445cf23ae197e148b47b0e55aa875026c4a..dfcb3fc033500eb19fc79a1f7e35e79193c115ab 100644 (file)
@@ -383,7 +383,7 @@ static int max9286_i2c_mux_init(struct max9286_priv *priv)
        for_each_source(priv, source) {
                unsigned int index = to_index(priv, source);
 
-               ret = i2c_mux_add_adapter(priv->mux, 0, index, 0);
+               ret = i2c_mux_add_adapter(priv->mux, 0, index);
                if (ret < 0)
                        goto error;
        }
index c6659253c6fbc06fc6075a5d14857b66740dd08c..6da8e7943d94a38a8d38ec3944d80fedfb44f76b 100644 (file)
@@ -567,10 +567,7 @@ int cx231xx_i2c_mux_create(struct cx231xx *dev)
 
 int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no)
 {
-       return i2c_mux_add_adapter(dev->muxc,
-                                  0,
-                                  mux_no /* chan_id */,
-                                  0 /* class */);
+       return i2c_mux_add_adapter(dev->muxc, 0, mux_no);
 }
 
 void cx231xx_i2c_mux_unregister(struct cx231xx *dev)
index a8c01c953a295e40b8979d10dd40c4ba3aa3717c..445ad13dab9801c76aa9b6e6f7cefcae711d015d 100644 (file)
@@ -2811,7 +2811,7 @@ static int unittest_i2c_mux_probe(struct i2c_client *client)
        if (!muxc)
                return -ENOMEM;
        for (i = 0; i < nchans; i++) {
-               if (i2c_mux_add_adapter(muxc, 0, i, 0)) {
+               if (i2c_mux_add_adapter(muxc, 0, i)) {
                        dev_err(dev, "Failed to register mux #%d\n", i);
                        i2c_mux_del_adapters(muxc);
                        return -ENODEV;
index 9e4141cffbf930db67d1128d901eb7d5476d0bf8..933b04806d10d82dc2f5080cfdd0e2ae4954f486 100644 (file)
@@ -358,7 +358,7 @@ static int sbsm_probe(struct i2c_client *client)
        /* register muxed i2c channels. One for each supported battery */
        for (i = 0; i < SBSM_MAX_BATS; ++i) {
                if (data->supported_bats & BIT(i)) {
-                       ret = i2c_mux_add_adapter(data->muxc, 0, i + 1, 0);
+                       ret = i2c_mux_add_adapter(data->muxc, 0, i + 1);
                        if (ret)
                                break;
                }
index 98ef73b7c8fd945b840b9225170d8661e195b707..1784ac7afb116ce64e9e9fca1ee127c2bbbd2fb9 100644 (file)
@@ -56,8 +56,7 @@ struct i2c_adapter *i2c_root_adapter(struct device *dev);
  * callback functions to perform hardware-specific mux control.
  */
 int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
-                       u32 force_nr, u32 chan_id,
-                       unsigned int class);
+                       u32 force_nr, u32 chan_id);
 
 void i2c_mux_del_adapters(struct i2c_mux_core *muxc);
 
index 5e4c2c272a7348d37454182a22bdaf71c100bf36..816a4cd3ccb5559d82291687bc448690f76dae8b 100644 (file)
@@ -18,7 +18,6 @@
  * @values: Array of bitmasks of GPIO settings (low/high) for each
  *     position
  * @n_values: Number of multiplexer positions (busses to instantiate)
- * @classes: Optional I2C auto-detection classes
  * @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used
  */
 struct i2c_mux_gpio_platform_data {
@@ -26,7 +25,6 @@ struct i2c_mux_gpio_platform_data {
        int base_nr;
        const unsigned *values;
        int n_values;
-       const unsigned *classes;
        unsigned idle;
 };