Merge branch 'i2c/for-mergewindow' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 4 Jul 2021 18:47:18 +0000 (11:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 4 Jul 2021 18:47:18 +0000 (11:47 -0700)
Pull i2c updates from Wolfram Sang:

 - core supports now bus regulators controlling power for SCL/SDA

 - quite some DT binding conversions to YAML

 - added a seperate DT binding for the optional SMBus Alert feature

 - documentation with examples how to deal with I2C sysfs files

 - some bigger rework for the i801 driver

 - and a few usual driver updates

* 'i2c/for-mergewindow' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (42 commits)
  i2c: ali1535: mention that the device should not be disabled
  i2c: mpc: Restore reread of I2C status register
  i2c: core-smbus: Expose PEC calculate function for generic use
  Documentation: i2c: Add doc for I2C sysfs
  i2c: core: Disable client irq on reboot/shutdown
  dt-bindings: i2c: update bindings for MT8195 SoC
  i2c: imx: Fix some checkpatch warnings
  i2c: davinci: Simplify with dev_err_probe()
  i2c: cadence: Simplify with dev_err_probe()
  i2c: xiic: Simplify with dev_err_probe()
  i2c: cadence: Clear HOLD bit before xfer_size register rolls over
  dt-bindings: i2c: ce4100: Replace "ti,pcf8575" by "nxp,pcf8575"
  i2c: i801: Improve i801_setup_hstcfg
  i2c: i801: Use driver name constant instead of function dev_driver_string
  i2c: i801: Simplify initialization of i2c_board_info in i801_probe_optional_slaves
  i2c: i801: Improve status polling
  i2c: cht-wc: Replace of_node by NULL
  i2c: riic: Add RZ/G2L support
  dt-bindings: i2c: renesas,riic: Document RZ/G2L I2C controller
  dt-bindings: i2c: renesas,iic: Convert to json-schema
  ...

35 files changed:
Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt
Documentation/devicetree/bindings/i2c/i2c-omap.txt [deleted file]
Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt
Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt
Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml
Documentation/devicetree/bindings/i2c/i2c.txt
Documentation/devicetree/bindings/i2c/renesas,i2c.txt [deleted file]
Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt [deleted file]
Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/renesas,iic.txt [deleted file]
Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/renesas,riic.txt [deleted file]
Documentation/devicetree/bindings/i2c/renesas,riic.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml [new file with mode: 0644]
Documentation/i2c/i2c-sysfs.rst [new file with mode: 0644]
MAINTAINERS
drivers/i2c/busses/i2c-ali1535.c
drivers/i2c/busses/i2c-aspeed.c
drivers/i2c/busses/i2c-cadence.c
drivers/i2c/busses/i2c-cht-wc.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-mt65xx.c
drivers/i2c/busses/i2c-qcom-cci.c
drivers/i2c/busses/i2c-rcar.c
drivers/i2c/busses/i2c-riic.c
drivers/i2c/busses/i2c-stm32f7.c
drivers/i2c/busses/i2c-xiic.c
drivers/i2c/i2c-core-base.c
drivers/i2c/i2c-core-smbus.c
include/linux/i2c.h

index 7f0194f..5ea216a 100644 (file)
@@ -15,6 +15,7 @@ Required properties:
       "mediatek,mt8173-i2c": for MediaTek MT8173
       "mediatek,mt8183-i2c": for MediaTek MT8183
       "mediatek,mt8192-i2c": for MediaTek MT8192
+      "mediatek,mt8195-i2c", "mediatek,mt8192-i2c": for MediaTek MT8195
       "mediatek,mt8516-i2c", "mediatek,mt2712-i2c": for MediaTek MT8516
   - reg: physical base address of the controller and dma base, length of memory
     mapped region.
@@ -32,6 +33,7 @@ Optional properties:
   - mediatek,have-pmic: platform can control i2c form special pmic side.
     Only mt6589 and mt8135 support this feature.
   - mediatek,use-push-pull: IO config use push-pull mode.
+  - vbus-supply: phandle to the regulator that provides power to SCL/SDA.
 
 Example:
 
index e00d2b9..d4cf105 100644 (file)
@@ -62,7 +62,6 @@ Example:
                                reg = <0x3c>;
                                pwms = <&pwm 4 3000>;
                                reset-gpios = <&gpio2 7 1>;
-                               reset-active-low;
                        };
                };
 
diff --git a/Documentation/devicetree/bindings/i2c/i2c-omap.txt b/Documentation/devicetree/bindings/i2c/i2c-omap.txt
deleted file mode 100644 (file)
index a425b91..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-I2C for OMAP platforms
-
-Required properties :
-- compatible : Must be
-       "ti,omap2420-i2c" for OMAP2420 SoCs
-       "ti,omap2430-i2c" for OMAP2430 SoCs
-       "ti,omap3-i2c" for OMAP3 SoCs
-       "ti,omap4-i2c" for OMAP4+ SoCs
-       "ti,am654-i2c", "ti,omap4-i2c" for AM654 SoCs
-       "ti,j721e-i2c", "ti,omap4-i2c" for J721E SoCs
-       "ti,am64-i2c", "ti,omap4-i2c" for AM64 SoCs
-- ti,hwmods : Must be "i2c<n>", n being the instance number (1-based)
-- #address-cells = <1>;
-- #size-cells = <0>;
-
-Recommended properties :
-- clock-frequency : Desired I2C bus clock frequency in Hz. Otherwise
-  the default 100 kHz frequency will be used.
-
-Optional properties:
-- Child nodes conforming to i2c bus binding
-
-Note: Current implementation will fetch base address, irq and dma
-from omap hwmod data base during device registration.
-Future plan is to migrate hwmod data base contents into device tree
-blob so that, all the required data will be used from device tree dts
-file.
-
-Examples :
-
-i2c1: i2c@0 {
-    compatible = "ti,omap3-i2c";
-    #address-cells = <1>;
-    #size-cells = <0>;
-    ti,hwmods = "i2c1";
-    clock-frequency = <400000>;
-};
index 569b162..1ff6f84 100644 (file)
@@ -71,7 +71,7 @@ This is an example which is used on FalconFalls:
                        /* This I2C controller has one gpio controller */
                        gpio@26 {
                                #gpio-cells = <2>;
-                               compatible = "ti,pcf8575";
+                               compatible = "nxp,pcf8575";
                                reg = <0x26>;
                                gpio-controller;
                        };
@@ -85,7 +85,7 @@ This is an example which is used on FalconFalls:
 
                        gpio@26 {
                                #gpio-cells = <2>;
-                               compatible = "ti,pcf8575";
+                               compatible = "nxp,pcf8575";
                                reg = <0x26>;
                                gpio-controller;
                        };
index c6668b7..7b9fc0c 100644 (file)
@@ -9,6 +9,7 @@ PROPERTIES:
                "qcom,msm8916-cci"
                "qcom,msm8996-cci"
                "qcom,sdm845-cci"
+               "qcom,sm8250-cci"
 
 - reg
        Usage: required
@@ -41,8 +42,8 @@ PROPERTIES:
 
 SUBNODES:
 
-The CCI provides I2C masters for one (msm8916) or two i2c busses (msm8996 and
-sdm845), described as subdevices named "i2c-bus@0" and "i2c-bus@1".
+The CCI provides I2C masters for one (msm8916) or two i2c busses (msm8996,
+sdm845 and sm8250), described as subdevices named "i2c-bus@0" and "i2c-bus@1".
 
 PROPERTIES:
 
index 7f254d7..5339dd4 100644 (file)
@@ -36,6 +36,7 @@ properties:
               - rockchip,px30-i2c
               - rockchip,rk3308-i2c
               - rockchip,rk3328-i2c
+              - rockchip,rk3568-i2c
           - const: rockchip,rk3399-i2c
 
   reg:
index df41f72..b864916 100644 (file)
@@ -89,8 +89,11 @@ wants to support one of the below features, it should adapt these bindings.
 
 - smbus
        states that additional SMBus restrictions and features apply to this bus.
-       Examples of features are SMBusHostNotify and SMBusAlert. Examples of
-       restrictions are more reserved addresses and timeout definitions.
+       An example of feature is SMBusHostNotify. Examples of restrictions are
+       more reserved addresses and timeout definitions.
+
+- smbus-alert
+       states that the optional SMBus-Alert feature apply to this bus.
 
 Required properties (per child device)
 --------------------------------------
diff --git a/Documentation/devicetree/bindings/i2c/renesas,i2c.txt b/Documentation/devicetree/bindings/i2c/renesas,i2c.txt
deleted file mode 100644 (file)
index 5762d2d..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-I2C for R-Car platforms
-
-Required properties:
-- compatible:
-       "renesas,i2c-r8a7742" if the device is a part of a R8A7742 SoC.
-       "renesas,i2c-r8a7743" if the device is a part of a R8A7743 SoC.
-       "renesas,i2c-r8a7744" if the device is a part of a R8A7744 SoC.
-       "renesas,i2c-r8a7745" if the device is a part of a R8A7745 SoC.
-       "renesas,i2c-r8a77470" if the device is a part of a R8A77470 SoC.
-       "renesas,i2c-r8a774a1" if the device is a part of a R8A774A1 SoC.
-       "renesas,i2c-r8a774b1" if the device is a part of a R8A774B1 SoC.
-       "renesas,i2c-r8a774c0" if the device is a part of a R8A774C0 SoC.
-       "renesas,i2c-r8a774e1" if the device is a part of a R8A774E1 SoC.
-       "renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC.
-       "renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC.
-       "renesas,i2c-r8a7790" if the device is a part of a R8A7790 SoC.
-       "renesas,i2c-r8a7791" if the device is a part of a R8A7791 SoC.
-       "renesas,i2c-r8a7792" if the device is a part of a R8A7792 SoC.
-       "renesas,i2c-r8a7793" if the device is a part of a R8A7793 SoC.
-       "renesas,i2c-r8a7794" if the device is a part of a R8A7794 SoC.
-       "renesas,i2c-r8a7795" if the device is a part of a R8A7795 SoC.
-       "renesas,i2c-r8a7796" if the device is a part of a R8A77960 SoC.
-       "renesas,i2c-r8a77961" if the device is a part of a R8A77961 SoC.
-       "renesas,i2c-r8a77965" if the device is a part of a R8A77965 SoC.
-       "renesas,i2c-r8a77970" if the device is a part of a R8A77970 SoC.
-       "renesas,i2c-r8a77980" if the device is a part of a R8A77980 SoC.
-       "renesas,i2c-r8a77990" if the device is a part of a R8A77990 SoC.
-       "renesas,i2c-r8a77995" if the device is a part of a R8A77995 SoC.
-       "renesas,i2c-r8a779a0" if the device is a part of a R8A779A0 SoC.
-       "renesas,rcar-gen1-i2c" for a generic R-Car Gen1 compatible device.
-       "renesas,rcar-gen2-i2c" for a generic R-Car Gen2 or RZ/G1 compatible
-                               device.
-       "renesas,rcar-gen3-i2c" for a generic R-Car Gen3 or RZ/G2 compatible
-                               device.
-       "renesas,i2c-rcar" (deprecated)
-
-       When compatible with the generic version, nodes must list the
-       SoC-specific version corresponding to the platform first followed
-       by the generic version.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-- interrupts: interrupt specifier.
-
-Optional properties:
-- clock-frequency: desired I2C bus clock frequency in Hz. The absence of this
-  property indicates the default frequency 100 kHz.
-- clocks: clock specifier.
-- dmas: Must contain a list of two references to DMA specifiers, one for
-  transmission, and one for reception.
-- dma-names: Must contain a list of two DMA names, "tx" and "rx".
-
-- i2c-scl-falling-time-ns: see i2c.txt
-- i2c-scl-internal-delay-ns: see i2c.txt
-- i2c-scl-rising-time-ns: see i2c.txt
-
-Examples :
-
-i2c0: i2c@e6508000 {
-       #address-cells = <1>;
-       #size-cells = <0>;
-       compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c";
-       reg = <0 0xe6508000 0 0x40>;
-       interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
-       clocks = <&mstp9_clks R8A7791_CLK_I2C0>;
-       clock-frequency = <400000>;
-};
diff --git a/Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt b/Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt
deleted file mode 100644 (file)
index 5ed1ea1..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-Device tree configuration for Renesas EMEV2 IIC controller
-
-Required properties:
-- compatible      : "renesas,iic-emev2"
-- reg             : address start and address range size of device
-- interrupts      : specifier for the IIC controller interrupt
-- clocks          : phandle to the IP core SCLK
-- clock-names     : must be "sclk"
-- #address-cells  : should be <1>
-- #size-cells     : should be <0>
-
-Example:
-
-       iic0: i2c@e0070000 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "renesas,iic-emev2";
-               reg = <0xe0070000 0x28>;
-               interrupts = <0 32 IRQ_TYPE_EDGE_RISING>;
-               clocks = <&iic0_sclk>;
-               clock-names = "sclk";
-       };
diff --git a/Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml b/Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml
new file mode 100644 (file)
index 0000000..17c1102
--- /dev/null
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/renesas,iic-emev2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas EMMA Mobile EV2 IIC Interface
+
+maintainers:
+  - Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#
+
+properties:
+  compatible:
+    const: renesas,iic-emev2
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: sclk
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - '#address-cells'
+  - '#size-cells'
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    iic0: i2c@e0070000 {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            compatible = "renesas,iic-emev2";
+            reg = <0xe0070000 0x28>;
+            interrupts = <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>;
+            clocks = <&iic0_sclk>;
+            clock-names = "sclk";
+    };
diff --git a/Documentation/devicetree/bindings/i2c/renesas,iic.txt b/Documentation/devicetree/bindings/i2c/renesas,iic.txt
deleted file mode 100644 (file)
index 93d4128..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-Device tree configuration for Renesas IIC (sh_mobile) driver
-
-Required properties:
-- compatible      :
-                       - "renesas,iic-r8a73a4" (R-Mobile APE6)
-                       - "renesas,iic-r8a7740" (R-Mobile A1)
-                       - "renesas,iic-r8a7742" (RZ/G1H)
-                       - "renesas,iic-r8a7743" (RZ/G1M)
-                       - "renesas,iic-r8a7744" (RZ/G1N)
-                       - "renesas,iic-r8a7745" (RZ/G1E)
-                       - "renesas,iic-r8a774a1" (RZ/G2M)
-                       - "renesas,iic-r8a774b1" (RZ/G2N)
-                       - "renesas,iic-r8a774c0" (RZ/G2E)
-                       - "renesas,iic-r8a774e1" (RZ/G2H)
-                       - "renesas,iic-r8a7790" (R-Car H2)
-                       - "renesas,iic-r8a7791" (R-Car M2-W)
-                       - "renesas,iic-r8a7792" (R-Car V2H)
-                       - "renesas,iic-r8a7793" (R-Car M2-N)
-                       - "renesas,iic-r8a7794" (R-Car E2)
-                       - "renesas,iic-r8a7795" (R-Car H3)
-                       - "renesas,iic-r8a7796" (R-Car M3-W)
-                       - "renesas,iic-r8a77961" (R-Car M3-W+)
-                       - "renesas,iic-r8a77965" (R-Car M3-N)
-                       - "renesas,iic-r8a77990" (R-Car E3)
-                       - "renesas,iic-sh73a0" (SH-Mobile AG5)
-                       - "renesas,rcar-gen2-iic" (generic R-Car Gen2 or RZ/G1
-                                                       compatible device)
-                       - "renesas,rcar-gen3-iic" (generic R-Car Gen3 or RZ/G2
-                                                       compatible device)
-                       - "renesas,rmobile-iic" (generic device)
-
-                       When compatible with a generic R-Car version, nodes
-                       must list the SoC-specific version corresponding to
-                       the platform first followed by the generic R-Car
-                       version.
-
-                       When compatible with "renesas,rmobile-iic" it should
-                       be the last compatibility string listed.
-
-                       The r8a77990 (R-Car E3) and r8a774c0 (RZ/G2E)
-                       controllers are not considered compatible with
-                       "renesas,rcar-gen3-iic" or "renesas,rmobile-iic"
-                       due to the absence of automatic transmission registers.
-
-- reg             : address start and address range size of device
-- interrupts      : interrupt of device
-- clocks          : clock for device
-- #address-cells  : should be <1>
-- #size-cells     : should be <0>
-
-Optional properties:
-- clock-frequency : frequency of bus clock in Hz. Default 100kHz if unset.
-- dmas            : Must contain a list of two references to DMA
-                   specifiers, one for transmission, and one for
-                   reception.
-- dma-names       : Must contain a list of two DMA names, "tx" and "rx".
-
-
-Pinctrl properties might be needed, too. See there.
-
-Example:
-
-       iic0: i2c@e6500000 {
-               compatible = "renesas,iic-r8a7790", "renesas,rcar-gen2-iic",
-                            "renesas,rmobile-iic";
-               reg = <0 0xe6500000 0 0x425>;
-               interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&mstp3_clks R8A7790_CLK_IIC0>;
-               clock-frequency = <400000>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-       };
diff --git a/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml b/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml
new file mode 100644 (file)
index 0000000..052aad4
--- /dev/null
@@ -0,0 +1,158 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/renesas,rcar-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas R-Car I2C Controller
+
+maintainers:
+  - Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - renesas,i2c-r8a7778      # R-Car M1A
+              - renesas,i2c-r8a7779      # R-Car H1
+          - const: renesas,rcar-gen1-i2c # R-Car Gen1
+
+      - items:
+          - enum:
+              - renesas,i2c-r8a7742      # RZ/G1H
+              - renesas,i2c-r8a7743      # RZ/G1M
+              - renesas,i2c-r8a7744      # RZ/G1N
+              - renesas,i2c-r8a7745      # RZ/G1E
+              - renesas,i2c-r8a77470     # RZ/G1C
+              - renesas,i2c-r8a7790      # R-Car H2
+              - renesas,i2c-r8a7791      # R-Car M2-W
+              - renesas,i2c-r8a7792      # R-Car V2H
+              - renesas,i2c-r8a7793      # R-Car M2-N
+              - renesas,i2c-r8a7794      # R-Car E2
+          - const: renesas,rcar-gen2-i2c # R-Car Gen2 and RZ/G1
+
+      - items:
+          - enum:
+              - renesas,i2c-r8a774a1     # RZ/G2M
+              - renesas,i2c-r8a774b1     # RZ/G2N
+              - renesas,i2c-r8a774c0     # RZ/G2E
+              - renesas,i2c-r8a774e1     # RZ/G2H
+              - renesas,i2c-r8a7795      # R-Car H3
+              - renesas,i2c-r8a7796      # R-Car M3-W
+              - renesas,i2c-r8a77961     # R-Car M3-W+
+              - renesas,i2c-r8a77965     # R-Car M3-N
+              - renesas,i2c-r8a77970     # R-Car V3M
+              - renesas,i2c-r8a77980     # R-Car V3H
+              - renesas,i2c-r8a77990     # R-Car E3
+              - renesas,i2c-r8a77995     # R-Car D3
+              - renesas,i2c-r8a779a0     # R-Car V3U
+          - const: renesas,rcar-gen3-i2c # R-Car Gen3 and RZ/G2
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clock-frequency:
+    description:
+      Desired I2C bus clock frequency in Hz. The absence of this property
+      indicates the default frequency 100 kHz.
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  dmas:
+    minItems: 2
+    maxItems: 4
+    description:
+      Must contain a list of pairs of references to DMA specifiers, one for
+      transmission, and one for reception.
+
+  dma-names:
+    minItems: 2
+    maxItems: 4
+    items:
+      enum:
+        - tx
+        - rx
+
+  i2c-scl-falling-time-ns:
+    default: 35
+    description:
+      Number of nanoseconds the SCL signal takes to fall; t(f) in the I2C
+      specification.
+
+  i2c-scl-internal-delay-ns:
+    default: 50
+    description:
+      Number of nanoseconds the IP core additionally needs to setup SCL.
+
+  i2c-scl-rising-time-ns:
+    default: 200
+    description:
+      Number of nanoseconds the SCL signal takes to rise; t(r) in the I2C
+      specification.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - power-domains
+  - '#address-cells'
+  - '#size-cells'
+
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - renesas,rcar-gen1-i2c
+              - renesas,rcar-gen2-i2c
+    then:
+      properties:
+        dmas: false
+        dma-names: false
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - renesas,rcar-gen2-i2c
+              - renesas,rcar-gen3-i2c
+    then:
+      required:
+        - resets
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/r8a7791-cpg-mssr.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/r8a7791-sysc.h>
+
+    i2c0: i2c@e6508000 {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c";
+            reg = <0xe6508000 0x40>;
+            interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+            clock-frequency = <400000>;
+            clocks = <&cpg CPG_MOD 931>;
+            power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+            resets = <&cpg 931>;
+            i2c-scl-internal-delay-ns = <6>;
+    };
diff --git a/Documentation/devicetree/bindings/i2c/renesas,riic.txt b/Documentation/devicetree/bindings/i2c/renesas,riic.txt
deleted file mode 100644 (file)
index e26fe3a..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-Device tree configuration for Renesas RIIC driver
-
-Required properties:
-- compatible      :
-       "renesas,riic-r7s72100" if the device is a part of a R7S72100 SoC.
-       "renesas,riic-r7s9210" if the device is a part of a R7S9210 SoC.
-       "renesas,riic-rz" for a generic RZ/A compatible device.
-- reg             : address start and address range size of device
-- interrupts      : 8 interrupts (TEI, RI, TI, SPI, STI, NAKI, ALI, TMOI)
-- clock-frequency : frequency of bus clock in Hz
-- #address-cells  : should be <1>
-- #size-cells     : should be <0>
-
-Pinctrl properties might be needed, too. See there.
-
-Example:
-
-       i2c0: i2c@fcfee000 {
-               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
-               reg = <0xfcfee000 0x44>;
-               interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 158 IRQ_TYPE_EDGE_RISING>,
-                            <0 159 IRQ_TYPE_EDGE_RISING>,
-                            <0 160 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 161 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 162 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 163 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 164 IRQ_TYPE_LEVEL_HIGH>;
-               clock-frequency = <100000>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-       };
diff --git a/Documentation/devicetree/bindings/i2c/renesas,riic.yaml b/Documentation/devicetree/bindings/i2c/renesas,riic.yaml
new file mode 100644 (file)
index 0000000..52d92ec
--- /dev/null
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/renesas,riic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/A and RZ/G2L I2C Bus Interface (RIIC)
+
+maintainers:
+  - Chris Brandt <chris.brandt@renesas.com>
+  - Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - renesas,riic-r7s72100   # RZ/A1H
+          - renesas,riic-r7s9210    # RZ/A2M
+          - renesas,riic-r9a07g044  # RZ/G2{L,LC}
+      - const: renesas,riic-rz      # RZ/A or RZ/G2L
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Transmit End Interrupt (TEI)
+      - description: Receive Data Full Interrupt (RI)
+      - description: Transmit Data Empty Interrupt (TI)
+      - description: Stop Condition Detection Interrupt (SPI)
+      - description: Start Condition Detection Interrupt (STI)
+      - description: NACK Reception Interrupt (NAKI)
+      - description: Arbitration-Lost Interrupt (ALI)
+      - description: Timeout Interrupt (TMOI)
+
+  clock-frequency:
+    description:
+      Desired I2C bus clock frequency in Hz. The absence of this property
+      indicates the default frequency 100 kHz.
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-frequency
+  - power-domains
+  - '#address-cells'
+  - '#size-cells'
+
+if:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - renesas,riic-r9a07g044
+then:
+  required:
+    - resets
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/r7s72100-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    i2c0: i2c@fcfee000 {
+            compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+            reg = <0xfcfee000 0x44>;
+            interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 158 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 159 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&mstp9_clks R7S72100_CLK_I2C0>;
+            clock-frequency = <100000>;
+            power-domains = <&cpg_clocks>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+    };
diff --git a/Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml b/Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml
new file mode 100644 (file)
index 0000000..04e4ffd
--- /dev/null
@@ -0,0 +1,149 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/renesas,rmobile-iic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas R-Mobile I2C Bus Interface (IIC)
+
+maintainers:
+  - Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - renesas,iic-r8a73a4      # R-Mobile APE6
+              - renesas,iic-r8a7740      # R-Mobile A1
+              - renesas,iic-sh73a0       # SH-Mobile AG5
+          - const: renesas,rmobile-iic   # Generic
+
+      - items:
+          - enum:
+              - renesas,iic-r8a7742      # RZ/G1H
+              - renesas,iic-r8a7743      # RZ/G1M
+              - renesas,iic-r8a7744      # RZ/G1N
+              - renesas,iic-r8a7745      # RZ/G1E
+              - renesas,iic-r8a7790      # R-Car H2
+              - renesas,iic-r8a7791      # R-Car M2-W
+              - renesas,iic-r8a7792      # R-Car V2H
+              - renesas,iic-r8a7793      # R-Car M2-N
+              - renesas,iic-r8a7794      # R-Car E2
+          - const: renesas,rcar-gen2-iic # R-Car Gen2 and RZ/G1
+          - const: renesas,rmobile-iic   # Generic
+
+      - items:
+          - enum:
+              - renesas,iic-r8a774a1     # RZ/G2M
+              - renesas,iic-r8a774b1     # RZ/G2N
+              - renesas,iic-r8a774c0     # RZ/G2E
+              - renesas,iic-r8a774e1     # RZ/G2H
+              - renesas,iic-r8a7795      # R-Car H3
+              - renesas,iic-r8a7796      # R-Car M3-W
+              - renesas,iic-r8a77961     # R-Car M3-W+
+              - renesas,iic-r8a77965     # R-Car M3-N
+              - renesas,iic-r8a77990     # R-Car E3
+          - const: renesas,rcar-gen3-iic # R-Car Gen3 and RZ/G2
+          - const: renesas,rmobile-iic   # Generic
+
+  reg:
+    maxItems: 1
+
+  interrupts: true
+
+  clock-frequency:
+    description:
+      Desired I2C bus clock frequency in Hz. The absence of this property
+      indicates the default frequency 100 kHz.
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  dmas:
+    minItems: 2
+    maxItems: 4
+    description:
+      Must contain a list of pairs of references to DMA specifiers, one for
+      transmission, and one for reception.
+
+  dma-names:
+    minItems: 2
+    maxItems: 4
+    items:
+      enum:
+        - tx
+        - rx
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - power-domains
+  - '#address-cells'
+  - '#size-cells'
+
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - renesas,iic-r8a7740
+              - renesas,iic-sh73a0
+    then:
+      properties:
+        interrupts:
+          items:
+            - description: Arbitration Lost Interrupt (ALI)
+            - description: Non-acknowledge Detection Interrupt (TACKI)
+            - description: Wait Interrupt (WAITI)
+            - description: Data Transmit Enable interrupt (DTEI)
+    else:
+      properties:
+        interrupts:
+          items:
+            - description: Single combined interrupt
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - renesas,rcar-gen2-iic
+              - renesas,rcar-gen3-iic
+    then:
+      required:
+        - resets
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/r8a7790-cpg-mssr.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/r8a7790-sysc.h>
+
+    iic0: i2c@e6500000 {
+            compatible = "renesas,iic-r8a7790", "renesas,rcar-gen2-iic",
+                         "renesas,rmobile-iic";
+            reg = <0xe6500000 0x425>;
+            interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cpg CPG_MOD 318>;
+            clock-frequency = <400000>;
+            dmas = <&dmac0 0x61>, <&dmac0 0x62>, <&dmac1 0x61>, <&dmac1 0x62>;
+            dma-names = "tx", "rx", "tx", "rx";
+            power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+            resets = <&cpg 318>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+    };
diff --git a/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml b/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml
new file mode 100644 (file)
index 0000000..ff165ad
--- /dev/null
@@ -0,0 +1,102 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/ti,omap4-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Bindings for I2C controllers on TI's OMAP and K3 SoCs
+
+maintainers:
+  - Vignesh Raghavendra <vigneshr@ti.com>
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - ti,omap2420-i2c
+          - ti,omap2430-i2c
+          - ti,omap3-i2c
+          - ti,omap4-i2c
+      - items:
+          - enum:
+              - ti,am4372-i2c
+              - ti,am64-i2c
+              - ti,am654-i2c
+              - ti,j721e-i2c
+          - const: ti,omap4-i2c
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: fck
+
+  clock-frequency: true
+
+  power-domains: true
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+  ti,hwmods:
+    description:
+      Must be "i2c<n>", n being the instance number (1-based).
+      This property is applicable only on legacy platforms mainly omap2/3
+      and ti81xx and should not be used on other platforms.
+    $ref: /schemas/types.yaml#/definitions/string
+    deprecated: true
+
+# subnode's properties
+patternProperties:
+  "@[0-9a-f]+$":
+    type: object
+    description:
+      Flash device uses the below defined properties in the subnode.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+if:
+  properties:
+    compatible:
+      oneOf:
+        - const: ti,omap2420-i2c
+        - const: ti,omap2430-i2c
+        - const: ti,omap3-i2c
+        - const: ti,omap4-i2c
+
+then:
+  properties:
+    ti,hwmods:
+      items:
+        - pattern: "^i2c([1-9])$"
+
+else:
+  properties:
+    ti,hwmods: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    main_i2c0: i2c@2000000 {
+            compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+            reg = <0x2000000 0x100>;
+            interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+         };
diff --git a/Documentation/i2c/i2c-sysfs.rst b/Documentation/i2c/i2c-sysfs.rst
new file mode 100644 (file)
index 0000000..6b68b95
--- /dev/null
@@ -0,0 +1,395 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===============
+Linux I2C Sysfs
+===============
+
+Overview
+========
+
+I2C topology can be complex because of the existence of I2C MUX
+(I2C Multiplexer). The Linux
+kernel abstracts the MUX channels into logical I2C bus numbers. However, there
+is a gap of knowledge to map from the I2C bus physical number and MUX topology
+to logical I2C bus number. This doc is aimed to fill in this gap, so the
+audience (hardware engineers and new software developers for example) can learn
+the concept of logical I2C buses in the kernel, by knowing the physical I2C
+topology and navigating through the I2C sysfs in Linux shell. This knowledge is
+useful and essential to use ``i2c-tools`` for the purpose of development and
+debugging.
+
+Target audience
+---------------
+
+People who need to use Linux shell to interact with I2C subsystem on a system
+which the Linux is running on.
+
+Prerequisites
+-------------
+
+1.  Knowledge of general Linux shell file system commands and operations.
+
+2.  General knowledge of I2C, I2C MUX and I2C topology.
+
+Location of I2C Sysfs
+=====================
+
+Typically, the Linux Sysfs filesystem is mounted at the ``/sys`` directory,
+so you can find the I2C Sysfs under ``/sys/bus/i2c/devices``
+where you can directly ``cd`` to it.
+There is a list of symbolic links under that directory. The links that
+start with ``i2c-`` are I2C buses, which may be either physical or logical. The
+other links that begin with numbers and end with numbers are I2C devices, where
+the first number is I2C bus number, and the second number is I2C address.
+
+Google Pixel 3 phone for example::
+
+  blueline:/sys/bus/i2c/devices $ ls
+  0-0008  0-0061  1-0028  3-0043  4-0036  4-0041  i2c-1  i2c-3
+  0-000c  0-0066  2-0049  4-000b  4-0040  i2c-0   i2c-2  i2c-4
+
+``i2c-2`` is an I2C bus whose number is 2, and ``2-0049`` is an I2C device
+on bus 2 address 0x49 bound with a kernel driver.
+
+Terminologies
+=============
+
+First, let us define a couple of terminologies to avoid confusions in the later
+sections.
+
+(Physical) I2C Bus Controller
+-----------------------------
+
+The hardware system that the Linux kernel is running on may have multiple
+physical I2C bus controllers. The controllers are hardware and physical, and the
+system may define multiple registers in the memory space to manipulate the
+controllers. Linux kernel has I2C bus drivers under source directory
+``drivers/i2c/busses`` to translate kernel I2C API into register
+operations for different systems. This terminology is not limited to Linux
+kernel only.
+
+I2C Bus Physical Number
+-----------------------
+
+For each physical I2C bus controller, the system vendor may assign a physical
+number to each controller. For example, the first I2C bus controller which has
+the lowest register addresses may be called ``I2C-0``.
+
+Logical I2C Bus
+---------------
+
+Every I2C bus number you see in Linux I2C Sysfs is a logical I2C bus with a
+number assigned. This is similar to the fact that software code is usually
+written upon virtual memory space, instead of physical memory space.
+
+Each logical I2C bus may be an abstraction of a physical I2C bus controller, or
+an abstraction of a channel behind an I2C MUX. In case it is an abstraction of a
+MUX channel, whenever we access an I2C device via a such logical bus, the kernel
+will switch the I2C MUX for you to the proper channel as part of the
+abstraction.
+
+Physical I2C Bus
+----------------
+
+If the logical I2C bus is a direct abstraction of a physical I2C bus controller,
+let us call it a physical I2C bus.
+
+Caveat
+------
+
+This may be a confusing part for people who only know about the physical I2C
+design of a board. It is actually possible to rename the I2C bus physical number
+to a different number in logical I2C bus level in Device Tree Source (DTS) under
+section ``aliases``. See
+`arch/arm/boot/dts/nuvoton-npcm730-gsj.dts
+<../../arch/arm/boot/dts/nuvoton-npcm730-gsj.dts>`_
+for an example of DTS file.
+
+Best Practice: **(To kernel software developers)** It is better to keep the I2C
+bus physical number the same as their corresponding logical I2C bus number,
+instead of renaming or mapping them, so that it may be less confusing to other
+users. These physical I2C buses can be served as good starting points for I2C
+MUX fanouts. For the following examples, we will assume that the physical I2C
+bus has a number same as their I2C bus physical number.
+
+Walk through Logical I2C Bus
+============================
+
+For the following content, we will use a more complex I2C topology as an
+example. Here is a brief graph for the I2C topology. If you do not understand
+this graph at the first glance, do not be afraid to continue reading this doc
+and review it when you finish reading.
+
+::
+
+  i2c-7 (physical I2C bus controller 7)
+  `-- 7-0071 (4-channel I2C MUX at 0x71)
+      |-- i2c-60 (channel-0)
+      |-- i2c-73 (channel-1)
+      |   |-- 73-0040 (I2C sensor device with hwmon directory)
+      |   |-- 73-0070 (I2C MUX at 0x70, exists in DTS, but failed to probe)
+      |   `-- 73-0072 (8-channel I2C MUX at 0x72)
+      |       |-- i2c-78 (channel-0)
+      |       |-- ... (channel-1...6, i2c-79...i2c-84)
+      |       `-- i2c-85 (channel-7)
+      |-- i2c-86 (channel-2)
+      `-- i2c-203 (channel-3)
+
+Distinguish Physical and Logical I2C Bus
+----------------------------------------
+
+One simple way to distinguish between a physical I2C bus and a logical I2C bus,
+is to read the symbolic link ``device`` under the I2C bus directory by using
+command ``ls -l`` or ``readlink``.
+
+An alternative symbolic link to check is ``mux_device``. This link only exists
+in logical I2C bus directory which is fanned out from another I2C bus.
+Reading this link will also tell you which I2C MUX device created
+this logical I2C bus.
+
+If the symbolic link points to a directory ending with ``.i2c``, it should be a
+physical I2C bus, directly abstracting a physical I2C bus controller. For
+example::
+
+  $ readlink /sys/bus/i2c/devices/i2c-7/device
+  ../../f0087000.i2c
+  $ ls /sys/bus/i2c/devices/i2c-7/mux_device
+  ls: /sys/bus/i2c/devices/i2c-7/mux_device: No such file or directory
+
+In this case, ``i2c-7`` is a physical I2C bus, so it does not have the symbolic
+link ``mux_device`` under its directory. And if the kernel software developer
+follows the common practice by not renaming physical I2C buses, this should also
+mean the physical I2C bus controller 7 of the system.
+
+On the other hand, if the symbolic link points to another I2C bus, the I2C bus
+presented by the current directory has to be a logical bus. The I2C bus pointed
+by the link is the parent bus which may be either a physical I2C bus or a
+logical one. In this case, the I2C bus presented by the current directory
+abstracts an I2C MUX channel under the parent bus.
+
+For example::
+
+  $ readlink /sys/bus/i2c/devices/i2c-73/device
+  ../../i2c-7
+  $ readlink /sys/bus/i2c/devices/i2c-73/mux_device
+  ../7-0071
+
+``i2c-73`` is a logical bus fanout by an I2C MUX under ``i2c-7``
+whose I2C address is 0x71.
+Whenever we access an I2C device with bus 73, the kernel will always
+switch the I2C MUX addressed 0x71 to the proper channel for you as part of the
+abstraction.
+
+Finding out Logical I2C Bus Number
+----------------------------------
+
+In this section, we will describe how to find out the logical I2C bus number
+representing certain I2C MUX channels based on the knowledge of physical
+hardware I2C topology.
+
+In this example, we have a system which has a physical I2C bus 7 and not renamed
+in DTS. There is a 4-channel MUX at address 0x71 on that bus. There is another
+8-channel MUX at address 0x72 behind the channel 1 of the 0x71 MUX. Let us
+navigate through Sysfs and find out the logical I2C bus number of the channel 3
+of the 0x72 MUX.
+
+First of all, let us go to the directory of ``i2c-7``::
+
+  ~$ cd /sys/bus/i2c/devices/i2c-7
+  /sys/bus/i2c/devices/i2c-7$ ls
+  7-0071         i2c-60         name           subsystem
+  delete_device  i2c-73         new_device     uevent
+  device         i2c-86         of_node
+  i2c-203        i2c-dev        power
+
+There, we see the 0x71 MUX as ``7-0071``. Go inside it::
+
+  /sys/bus/i2c/devices/i2c-7$ cd 7-0071/
+  /sys/bus/i2c/devices/i2c-7/7-0071$ ls -l
+  channel-0   channel-3   modalias    power
+  channel-1   driver      name        subsystem
+  channel-2   idle_state  of_node     uevent
+
+Read the link ``channel-1`` using ``readlink`` or ``ls -l``::
+
+  /sys/bus/i2c/devices/i2c-7/7-0071$ readlink channel-1
+  ../i2c-73
+
+We find out that the channel 1 of 0x71 MUX on ``i2c-7`` is assigned
+with a logical I2C bus number of 73.
+Let us continue the journey to directory ``i2c-73`` in either ways::
+
+  # cd to i2c-73 under I2C Sysfs root
+  /sys/bus/i2c/devices/i2c-7/7-0071$ cd /sys/bus/i2c/devices/i2c-73
+  /sys/bus/i2c/devices/i2c-73$
+
+  # cd the channel symbolic link
+  /sys/bus/i2c/devices/i2c-7/7-0071$ cd channel-1
+  /sys/bus/i2c/devices/i2c-7/7-0071/channel-1$
+
+  # cd the link content
+  /sys/bus/i2c/devices/i2c-7/7-0071$ cd ../i2c-73
+  /sys/bus/i2c/devices/i2c-7/i2c-73$
+
+Either ways, you will end up in the directory of ``i2c-73``. Similar to above,
+we can now find the 0x72 MUX and what logical I2C bus numbers
+that its channels are assigned::
+
+  /sys/bus/i2c/devices/i2c-73$ ls
+  73-0040        device         i2c-83         new_device
+  73-004e        i2c-78         i2c-84         of_node
+  73-0050        i2c-79         i2c-85         power
+  73-0070        i2c-80         i2c-dev        subsystem
+  73-0072        i2c-81         mux_device     uevent
+  delete_device  i2c-82         name
+  /sys/bus/i2c/devices/i2c-73$ cd 73-0072
+  /sys/bus/i2c/devices/i2c-73/73-0072$ ls
+  channel-0   channel-4   driver      of_node
+  channel-1   channel-5   idle_state  power
+  channel-2   channel-6   modalias    subsystem
+  channel-3   channel-7   name        uevent
+  /sys/bus/i2c/devices/i2c-73/73-0072$ readlink channel-3
+  ../i2c-81
+
+There, we find out the logical I2C bus number of the channel 3 of the 0x72 MUX
+is 81. We can later use this number to switch to its own I2C Sysfs directory or
+issue ``i2c-tools`` commands.
+
+Tip: Once you understand the I2C topology with MUX, command
+`i2cdetect -l
+<https://manpages.debian.org/unstable/i2c-tools/i2cdetect.8.en.html>`_
+in
+`I2C Tools
+<https://i2c.wiki.kernel.org/index.php/I2C_Tools>`_
+can give you
+an overview of the I2C topology easily, if it is available on your system. For
+example::
+
+  $ i2cdetect -l | grep -e '\-73' -e _7 | sort -V
+  i2c-7   i2c             npcm_i2c_7                              I2C adapter
+  i2c-73  i2c             i2c-7-mux (chan_id 1)                   I2C adapter
+  i2c-78  i2c             i2c-73-mux (chan_id 0)                  I2C adapter
+  i2c-79  i2c             i2c-73-mux (chan_id 1)                  I2C adapter
+  i2c-80  i2c             i2c-73-mux (chan_id 2)                  I2C adapter
+  i2c-81  i2c             i2c-73-mux (chan_id 3)                  I2C adapter
+  i2c-82  i2c             i2c-73-mux (chan_id 4)                  I2C adapter
+  i2c-83  i2c             i2c-73-mux (chan_id 5)                  I2C adapter
+  i2c-84  i2c             i2c-73-mux (chan_id 6)                  I2C adapter
+  i2c-85  i2c             i2c-73-mux (chan_id 7)                  I2C adapter
+
+Pinned Logical I2C Bus Number
+-----------------------------
+
+If not specified in DTS, when an I2C MUX driver is applied and the MUX device is
+successfully probed, the kernel will assign the MUX channels with a logical bus
+number based on the current biggest logical bus number incrementally. For
+example, if the system has ``i2c-15`` as the highest logical bus number, and a
+4-channel MUX is applied successfully, we will have ``i2c-16`` for the
+MUX channel 0, and all the way to ``i2c-19`` for the MUX channel 3.
+
+The kernel software developer is able to pin the fanout MUX channels to a static
+logical I2C bus number in the DTS. This doc will not go through the details on
+how to implement this in DTS, but we can see an example in:
+`arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts
+<../../arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts>`_
+
+In the above example, there is an 8-channel I2C MUX at address 0x70 on physical
+I2C bus 2. The channel 2 of the MUX is defined as ``imux18`` in DTS,
+and pinned to logical I2C bus number 18 with the line of ``i2c18 = &imux18;``
+in section ``aliases``.
+
+Take it further, it is possible to design a logical I2C bus number schema that
+can be easily remembered by humans or calculated arithmetically. For example, we
+can pin the fanout channels of a MUX on bus 3 to start at 30. So 30 will be the
+logical bus number of the channel 0 of the MUX on bus 3, and 37 will be the
+logical bus number of the channel 7 of the MUX on bus 3.
+
+I2C Devices
+===========
+
+In previous sections, we mostly covered the I2C bus. In this section, let us see
+what we can learn from the I2C device directory whose link name is in the format
+of ``${bus}-${addr}``. The ``${bus}`` part in the name is a logical I2C bus
+decimal number, while the ``${addr}`` part is a hex number of the I2C address
+of each device.
+
+I2C Device Directory Content
+----------------------------
+
+Inside each I2C device directory, there is a file named ``name``.
+This file tells what device name it was used for the kernel driver to
+probe this device. Use command ``cat`` to read its content. For example::
+
+  /sys/bus/i2c/devices/i2c-73$ cat 73-0040/name
+  ina230
+  /sys/bus/i2c/devices/i2c-73$ cat 73-0070/name
+  pca9546
+  /sys/bus/i2c/devices/i2c-73$ cat 73-0072/name
+  pca9547
+
+There is a symbolic link named ``driver`` to tell what Linux kernel driver was
+used to probe this device::
+
+  /sys/bus/i2c/devices/i2c-73$ readlink -f 73-0040/driver
+  /sys/bus/i2c/drivers/ina2xx
+  /sys/bus/i2c/devices/i2c-73$ readlink -f 73-0072/driver
+  /sys/bus/i2c/drivers/pca954x
+
+But if the link ``driver`` does not exist at the first place,
+it may mean that the kernel driver failed to probe this device due to
+some errors. The error may be found in ``dmesg``::
+
+  /sys/bus/i2c/devices/i2c-73$ ls 73-0070/driver
+  ls: 73-0070/driver: No such file or directory
+  /sys/bus/i2c/devices/i2c-73$ dmesg | grep 73-0070
+  pca954x 73-0070: probe failed
+  pca954x 73-0070: probe failed
+
+Depending on what the I2C device is and what kernel driver was used to probe the
+device, we may have different content in the device directory.
+
+I2C MUX Device
+--------------
+
+While you may be already aware of this in previous sections, an I2C MUX device
+will have symbolic link ``channel-*`` inside its device directory.
+These symbolic links point to their logical I2C bus directories::
+
+  /sys/bus/i2c/devices/i2c-73$ ls -l 73-0072/channel-*
+  lrwxrwxrwx ... 73-0072/channel-0 -> ../i2c-78
+  lrwxrwxrwx ... 73-0072/channel-1 -> ../i2c-79
+  lrwxrwxrwx ... 73-0072/channel-2 -> ../i2c-80
+  lrwxrwxrwx ... 73-0072/channel-3 -> ../i2c-81
+  lrwxrwxrwx ... 73-0072/channel-4 -> ../i2c-82
+  lrwxrwxrwx ... 73-0072/channel-5 -> ../i2c-83
+  lrwxrwxrwx ... 73-0072/channel-6 -> ../i2c-84
+  lrwxrwxrwx ... 73-0072/channel-7 -> ../i2c-85
+
+I2C Sensor Device / Hwmon
+-------------------------
+
+I2C sensor device is also common to see. If they are bound by a kernel hwmon
+(Hardware Monitoring) driver successfully, you will see a ``hwmon`` directory
+inside the I2C device directory. Keep digging into it, you will find the Hwmon
+Sysfs for the I2C sensor device::
+
+  /sys/bus/i2c/devices/i2c-73/73-0040/hwmon/hwmon17$ ls
+  curr1_input        in0_lcrit_alarm    name               subsystem
+  device             in1_crit           power              uevent
+  in0_crit           in1_crit_alarm     power1_crit        update_interval
+  in0_crit_alarm     in1_input          power1_crit_alarm
+  in0_input          in1_lcrit          power1_input
+  in0_lcrit          in1_lcrit_alarm    shunt_resistor
+
+For more info on the Hwmon Sysfs, refer to the doc:
+
+`Naming and data format standards for sysfs files
+<../hwmon/sysfs-interface.rst>`_
+
+Instantiate I2C Devices in I2C Sysfs
+------------------------------------
+
+Refer to the doc:
+
+`How to instantiate I2C devices, Method 4: Instantiate from user-space
+<instantiating-devices.rst#method-4-instantiate-from-user-space>`_
index fe901f3..3ccd3b0 100644 (file)
@@ -13494,7 +13494,7 @@ M:      Vignesh R <vigneshr@ti.com>
 L:     linux-omap@vger.kernel.org
 L:     linux-i2c@vger.kernel.org
 S:     Maintained
-F:     Documentation/devicetree/bindings/i2c/i2c-omap.txt
+F:     Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml
 F:     drivers/i2c/busses/i2c-omap.c
 
 OMAP IMAGING SUBSYSTEM (OMAP3 ISP and OMAP4 ISS)
@@ -15722,8 +15722,9 @@ F:      drivers/clk/renesas/
 
 RENESAS EMEV2 I2C DRIVER
 M:     Wolfram Sang <wsa+renesas@sang-engineering.com>
+L:     linux-renesas-soc@vger.kernel.org
 S:     Supported
-F:     Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt
+F:     Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml
 F:     drivers/i2c/busses/i2c-emev2.c
 
 RENESAS ETHERNET DRIVERS
@@ -15743,9 +15744,10 @@ F:     drivers/iio/adc/rcar-gyroadc.c
 
 RENESAS R-CAR I2C DRIVERS
 M:     Wolfram Sang <wsa+renesas@sang-engineering.com>
+L:     linux-renesas-soc@vger.kernel.org
 S:     Supported
-F:     Documentation/devicetree/bindings/i2c/renesas,i2c.txt
-F:     Documentation/devicetree/bindings/i2c/renesas,iic.txt
+F:     Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml
+F:     Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml
 F:     drivers/i2c/busses/i2c-rcar.c
 F:     drivers/i2c/busses/i2c-sh_mobile.c
 
@@ -15760,8 +15762,9 @@ F:      drivers/thermal/rcar_thermal.c
 
 RENESAS RIIC DRIVER
 M:     Chris Brandt <chris.brandt@renesas.com>
+L:     linux-renesas-soc@vger.kernel.org
 S:     Supported
-F:     Documentation/devicetree/bindings/i2c/renesas,riic.txt
+F:     Documentation/devicetree/bindings/i2c/renesas,riic.yaml
 F:     drivers/i2c/busses/i2c-riic.c
 
 RENESAS USB PHY DRIVER
index fb93152..ee83c45 100644 (file)
@@ -508,6 +508,11 @@ static void ali1535_remove(struct pci_dev *dev)
 {
        i2c_del_adapter(&ali1535_adapter);
        release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
+
+       /*
+        * do not call pci_disable_device(dev) since it can cause hard hangs on
+        * some systems during power-off
+        */
 }
 
 static struct pci_driver ali1535_driver = {
index 724bf30..67e8b97 100644 (file)
@@ -727,10 +727,14 @@ static void __aspeed_i2c_reg_slave(struct aspeed_i2c_bus *bus, u16 slave_addr)
 {
        u32 addr_reg_val, func_ctrl_reg_val;
 
-       /* Set slave addr. */
-       addr_reg_val = readl(bus->base + ASPEED_I2C_DEV_ADDR_REG);
-       addr_reg_val &= ~ASPEED_I2CD_DEV_ADDR_MASK;
-       addr_reg_val |= slave_addr & ASPEED_I2CD_DEV_ADDR_MASK;
+       /*
+        * Set slave addr.  Reserved bits can all safely be written with zeros
+        * on all of ast2[456]00, so zero everything else to ensure we only
+        * enable a single slave address (ast2500 has two, ast2600 has three,
+        * the enable bits for which are also in this register) so that we don't
+        * end up with additional phantom devices responding on the bus.
+        */
+       addr_reg_val = slave_addr & ASPEED_I2CD_DEV_ADDR_MASK;
        writel(addr_reg_val, bus->base + ASPEED_I2C_DEV_ADDR_REG);
 
        /* Turn on slave mode. */
index 66aafa7..20aa339 100644 (file)
@@ -578,6 +578,11 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
 {
        unsigned int ctrl_reg;
        unsigned int isr_status;
+       unsigned long flags;
+       bool hold_clear = false;
+       bool irq_save = false;
+
+       u32 addr;
 
        id->p_recv_buf = id->p_msg->buf;
        id->recv_count = id->p_msg->len;
@@ -618,14 +623,43 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
                cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET);
        }
 
-       /* Set the slave address in address register - triggers operation */
-       cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK,
-                                               CDNS_I2C_ADDR_OFFSET);
-       /* Clear the bus hold flag if bytes to receive is less than FIFO size */
+       /* Determine hold_clear based on number of bytes to receive and hold flag */
        if (!id->bus_hold_flag &&
-               ((id->p_msg->flags & I2C_M_RECV_LEN) != I2C_M_RECV_LEN) &&
-               (id->recv_count <= CDNS_I2C_FIFO_DEPTH))
-                       cdns_i2c_clear_bus_hold(id);
+           ((id->p_msg->flags & I2C_M_RECV_LEN) != I2C_M_RECV_LEN) &&
+           (id->recv_count <= CDNS_I2C_FIFO_DEPTH)) {
+               if (cdns_i2c_readreg(CDNS_I2C_CR_OFFSET) & CDNS_I2C_CR_HOLD) {
+                       hold_clear = true;
+                       if (id->quirks & CDNS_I2C_BROKEN_HOLD_BIT)
+                               irq_save = true;
+               }
+       }
+
+       addr = id->p_msg->addr;
+       addr &= CDNS_I2C_ADDR_MASK;
+
+       if (hold_clear) {
+               ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET) & ~CDNS_I2C_CR_HOLD;
+               /*
+                * 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
+                * register overflow to 0xFF. To satisfy this timing requirement,
+                * disable the interrupts on current processor core between register
+                * writes to slave address register and control register.
+                */
+               if (irq_save)
+                       local_irq_save(flags);
+
+               cdns_i2c_writereg(addr, CDNS_I2C_ADDR_OFFSET);
+               cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET);
+               /* Read it back to avoid bufferring and make sure write happens */
+               cdns_i2c_readreg(CDNS_I2C_CR_OFFSET);
+
+               if (irq_save)
+                       local_irq_restore(flags);
+       } else {
+               cdns_i2c_writereg(addr, CDNS_I2C_ADDR_OFFSET);
+       }
+
        cdns_i2c_writereg(CDNS_I2C_ENABLED_INTR_MASK, CDNS_I2C_IER_OFFSET);
 }
 
@@ -1217,11 +1251,10 @@ static int cdns_i2c_probe(struct platform_device *pdev)
                 "Cadence I2C at %08lx", (unsigned long)r_mem->start);
 
        id->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(id->clk)) {
-               if (PTR_ERR(id->clk) != -EPROBE_DEFER)
-                       dev_err(&pdev->dev, "input clock not found.\n");
-               return PTR_ERR(id->clk);
-       }
+       if (IS_ERR(id->clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(id->clk),
+                                    "input clock not found.\n");
+
        ret = clk_prepare_enable(id->clk);
        if (ret)
                dev_err(&pdev->dev, "Unable to enable clock.\n");
index 08f491e..1cf68f8 100644 (file)
@@ -354,8 +354,7 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
                return ret;
 
        /* Alloc and register client IRQ */
-       adap->irq_domain = irq_domain_add_linear(pdev->dev.of_node, 1,
-                                                &irq_domain_simple_ops, NULL);
+       adap->irq_domain = irq_domain_add_linear(NULL, 1, &irq_domain_simple_ops, NULL);
        if (!adap->irq_domain)
                return -ENOMEM;
 
index 232a767..e9d0732 100644 (file)
@@ -768,10 +768,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
        if (irq <= 0) {
                if (!irq)
                        irq = -ENXIO;
-               if (irq != -EPROBE_DEFER)
-                       dev_err(&pdev->dev,
-                               "can't get irq resource ret=%d\n", irq);
-               return irq;
+               return dev_err_probe(&pdev->dev, irq, "can't get irq resource\n");
        }
 
        dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_i2c_dev),
index 04a1e38..aa3f60e 100644 (file)
@@ -88,6 +88,8 @@
  * See the file Documentation/i2c/busses/i2c-i801.rst for details.
  */
 
+#define DRV_NAME       "i801_smbus"
+
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <linux/wait.h>
+#include <linux/completion.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/itco_wdt.h>
 
 /* PCI Address Constants */
 #define SMBBAR         4
-#define SMBPCICTL      0x004
-#define SMBPCISTS      0x006
 #define SMBHSTCFG      0x040
 #define TCOBASE                0x050
 #define TCOCTL         0x054
 #define SBREG_SMBCTRL          0xc6000c
 #define SBREG_SMBCTRL_DNV      0xcf000c
 
-/* Host status bits for SMBPCISTS */
-#define SMBPCISTS_INTS         BIT(3)
-
-/* Control bits for SMBPCICTL */
-#define SMBPCICTL_INTDIS       BIT(10)
-
 /* Host configuration bits for SMBHSTCFG */
 #define SMBHSTCFG_HST_EN       BIT(0)
 #define SMBHSTCFG_SMB_SMI_EN   BIT(1)
 #define SMBAUXCTL_CRC          BIT(0)
 #define SMBAUXCTL_E32B         BIT(1)
 
-/* Other settings */
-#define MAX_RETRIES            400
-
 /* I801 command constants */
 #define I801_QUICK             0x00
 #define I801_BYTE              0x04
@@ -270,7 +261,7 @@ struct i801_priv {
        unsigned int features;
 
        /* isr processing */
-       wait_queue_head_t waitq;
+       struct completion done;
        u8 status;
 
        /* Command state used by isr for byte-by-byte block transactions */
@@ -453,67 +444,53 @@ static int i801_check_post(struct i801_priv *priv, int status)
 /* Wait for BUSY being cleared and either INTR or an error flag being set */
 static int i801_wait_intr(struct i801_priv *priv)
 {
-       int timeout = 0;
-       int status;
+       unsigned long timeout = jiffies + priv->adapter.timeout;
+       int status, busy;
 
-       /* We will always wait for a fraction of a second! */
        do {
                usleep_range(250, 500);
                status = inb_p(SMBHSTSTS(priv));
-       } while (((status & SMBHSTSTS_HOST_BUSY) ||
-                 !(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR))) &&
-                (timeout++ < MAX_RETRIES));
+               busy = status & SMBHSTSTS_HOST_BUSY;
+               status &= STATUS_ERROR_FLAGS | SMBHSTSTS_INTR;
+               if (!busy && status)
+                       return status;
+       } while (time_is_after_eq_jiffies(timeout));
 
-       if (timeout > MAX_RETRIES) {
-               dev_dbg(&priv->pci_dev->dev, "INTR Timeout!\n");
-               return -ETIMEDOUT;
-       }
-       return status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR);
+       return -ETIMEDOUT;
 }
 
 /* Wait for either BYTE_DONE or an error flag being set */
 static int i801_wait_byte_done(struct i801_priv *priv)
 {
-       int timeout = 0;
+       unsigned long timeout = jiffies + priv->adapter.timeout;
        int status;
 
-       /* We will always wait for a fraction of a second! */
        do {
                usleep_range(250, 500);
                status = inb_p(SMBHSTSTS(priv));
-       } while (!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) &&
-                (timeout++ < MAX_RETRIES));
+               if (status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE))
+                       return status & STATUS_ERROR_FLAGS;
+       } while (time_is_after_eq_jiffies(timeout));
 
-       if (timeout > MAX_RETRIES) {
-               dev_dbg(&priv->pci_dev->dev, "BYTE_DONE Timeout!\n");
-               return -ETIMEDOUT;
-       }
-       return status & STATUS_ERROR_FLAGS;
+       return -ETIMEDOUT;
 }
 
 static int i801_transaction(struct i801_priv *priv, int xact)
 {
        int status;
-       int result;
+       unsigned long result;
        const struct i2c_adapter *adap = &priv->adapter;
 
-       result = i801_check_pre(priv);
-       if (result < 0)
-               return result;
+       status = i801_check_pre(priv);
+       if (status < 0)
+               return status;
 
        if (priv->features & FEATURE_IRQ) {
+               reinit_completion(&priv->done);
                outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START,
                       SMBHSTCNT(priv));
-               result = wait_event_timeout(priv->waitq,
-                                           (status = priv->status),
-                                           adap->timeout);
-               if (!result) {
-                       status = -ETIMEDOUT;
-                       dev_warn(&priv->pci_dev->dev,
-                                "Timeout waiting for interrupt!\n");
-               }
-               priv->status = 0;
-               return i801_check_post(priv, status);
+               result = wait_for_completion_timeout(&priv->done, adap->timeout);
+               return i801_check_post(priv, result ? priv->status : -ETIMEDOUT);
        }
 
        /* the current contents of SMBHSTCNT can be overwritten, since PEC,
@@ -638,7 +615,7 @@ static irqreturn_t i801_host_notify_isr(struct i801_priv *priv)
  *      DEV_ERR - Invalid command, NAK or communication timeout
  *      BUS_ERR - SMI# transaction collision
  *      FAILED - transaction was canceled due to a KILL request
- *    When any of these occur, update ->status and wake up the waitq.
+ *    When any of these occur, update ->status and signal completion.
  *    ->status must be cleared before kicking off the next transaction.
  *
  * 2) For byte-by-byte (I2C read/write) transactions, one BYTE_DONE interrupt
@@ -653,8 +630,8 @@ static irqreturn_t i801_isr(int irq, void *dev_id)
        u8 status;
 
        /* Confirm this is our interrupt */
-       pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists);
-       if (!(pcists & SMBPCISTS_INTS))
+       pci_read_config_word(priv->pci_dev, PCI_STATUS, &pcists);
+       if (!(pcists & PCI_STATUS_INTERRUPT))
                return IRQ_NONE;
 
        if (priv->features & FEATURE_HOST_NOTIFY) {
@@ -675,7 +652,7 @@ static irqreturn_t i801_isr(int irq, void *dev_id)
        if (status) {
                outb_p(status, SMBHSTSTS(priv));
                priv->status = status;
-               wake_up(&priv->waitq);
+               complete(&priv->done);
        }
 
        return IRQ_HANDLED;
@@ -694,15 +671,15 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
        int i, len;
        int smbcmd;
        int status;
-       int result;
+       unsigned long result;
        const struct i2c_adapter *adap = &priv->adapter;
 
        if (command == I2C_SMBUS_BLOCK_PROC_CALL)
                return -EOPNOTSUPP;
 
-       result = i801_check_pre(priv);
-       if (result < 0)
-               return result;
+       status = i801_check_pre(priv);
+       if (status < 0)
+               return status;
 
        len = data->block[0];
 
@@ -726,17 +703,10 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
                priv->count = 0;
                priv->data = &data->block[1];
 
+               reinit_completion(&priv->done);
                outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv));
-               result = wait_event_timeout(priv->waitq,
-                                           (status = priv->status),
-                                           adap->timeout);
-               if (!result) {
-                       status = -ETIMEDOUT;
-                       dev_warn(&priv->pci_dev->dev,
-                                "Timeout waiting for interrupt!\n");
-               }
-               priv->status = 0;
-               return i801_check_post(priv, status);
+               result = wait_for_completion_timeout(&priv->done, adap->timeout);
+               return i801_check_post(priv, result ? priv->status : -ETIMEDOUT);
        }
 
        for (i = 1; i <= len; i++) {
@@ -1322,11 +1292,11 @@ static void i801_probe_optional_slaves(struct i801_priv *priv)
                return;
 
        if (apanel_addr) {
-               struct i2c_board_info info;
+               struct i2c_board_info info = {
+                       .addr = apanel_addr,
+                       .type = "fujitsu_apanel",
+               };
 
-               memset(&info, 0, sizeof(struct i2c_board_info));
-               info.addr = apanel_addr;
-               strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
                i2c_new_client_device(&priv->adapter, &info);
        }
 
@@ -1715,19 +1685,17 @@ static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; }
 static inline void i801_acpi_remove(struct i801_priv *priv) { }
 #endif
 
-static unsigned char i801_setup_hstcfg(struct i801_priv *priv)
+static void i801_setup_hstcfg(struct i801_priv *priv)
 {
        unsigned char hstcfg = priv->original_hstcfg;
 
        hstcfg &= ~SMBHSTCFG_I2C_EN;    /* SMBus timing */
        hstcfg |= SMBHSTCFG_HST_EN;
        pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hstcfg);
-       return hstcfg;
 }
 
 static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       unsigned char temp;
        int err, i;
        struct i801_priv *priv;
 
@@ -1838,8 +1806,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
        if (i801_acpi_probe(priv))
                return -ENODEV;
 
-       err = pcim_iomap_regions(dev, 1 << SMBBAR,
-                                dev_driver_string(&dev->dev));
+       err = pcim_iomap_regions(dev, 1 << SMBBAR, DRV_NAME);
        if (err) {
                dev_err(&dev->dev,
                        "Failed to request SMBus region 0x%lx-0x%Lx\n",
@@ -1850,16 +1817,16 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
        }
 
        pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &priv->original_hstcfg);
-       temp = i801_setup_hstcfg(priv);
+       i801_setup_hstcfg(priv);
        if (!(priv->original_hstcfg & SMBHSTCFG_HST_EN))
                dev_info(&dev->dev, "Enabling SMBus device\n");
 
-       if (temp & SMBHSTCFG_SMB_SMI_EN) {
+       if (priv->original_hstcfg & SMBHSTCFG_SMB_SMI_EN) {
                dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
                /* Disable SMBus interrupt feature if SMBus using SMI# */
                priv->features &= ~FEATURE_IRQ;
        }
-       if (temp & SMBHSTCFG_SPD_WD)
+       if (priv->original_hstcfg & SMBHSTCFG_SPD_WD)
                dev_info(&dev->dev, "SPD Write Disable is set\n");
 
        /* Clear special mode bits */
@@ -1881,24 +1848,23 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
                u16 pcictl, pcists;
 
                /* Complain if an interrupt is already pending */
-               pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists);
-               if (pcists & SMBPCISTS_INTS)
+               pci_read_config_word(priv->pci_dev, PCI_STATUS, &pcists);
+               if (pcists & PCI_STATUS_INTERRUPT)
                        dev_warn(&dev->dev, "An interrupt is pending!\n");
 
                /* Check if interrupts have been disabled */
-               pci_read_config_word(priv->pci_dev, SMBPCICTL, &pcictl);
-               if (pcictl & SMBPCICTL_INTDIS) {
+               pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pcictl);
+               if (pcictl & PCI_COMMAND_INTX_DISABLE) {
                        dev_info(&dev->dev, "Interrupts are disabled\n");
                        priv->features &= ~FEATURE_IRQ;
                }
        }
 
        if (priv->features & FEATURE_IRQ) {
-               init_waitqueue_head(&priv->waitq);
+               init_completion(&priv->done);
 
                err = devm_request_irq(&dev->dev, dev->irq, i801_isr,
-                                      IRQF_SHARED,
-                                      dev_driver_string(&dev->dev), priv);
+                                      IRQF_SHARED, DRV_NAME, priv);
                if (err) {
                        dev_err(&dev->dev, "Failed to allocate irq %d: %d\n",
                                dev->irq, err);
@@ -1988,7 +1954,7 @@ static int i801_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(i801_pm_ops, i801_suspend, i801_resume);
 
 static struct pci_driver i801_driver = {
-       .name           = "i801_smbus",
+       .name           = DRV_NAME,
        .id_table       = i801_ids,
        .probe          = i801_probe,
        .remove         = i801_remove,
index dc5ca71..d5b5f08 100644 (file)
@@ -170,11 +170,11 @@ enum imx_i2c_type {
 
 struct imx_i2c_hwdata {
        enum imx_i2c_type       devtype;
-       unsigned                regshift;
+       unsigned int            regshift;
        struct imx_i2c_clk_pair *clk_div;
-       unsigned                ndivs;
-       unsigned                i2sr_clr_opcode;
-       unsigned                i2cr_ien_opcode;
+       unsigned int            ndivs;
+       unsigned int            i2sr_clr_opcode;
+       unsigned int            i2cr_ien_opcode;
 };
 
 struct imx_i2c_dma {
@@ -452,8 +452,6 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool a
        unsigned long orig_jiffies = jiffies;
        unsigned int temp;
 
-       dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
-
        while (1) {
                temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
 
@@ -599,8 +597,6 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx, bool atomic)
        unsigned int temp = 0;
        int result;
 
-       dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
-
        imx_i2c_write_reg(i2c_imx->ifdr, i2c_imx, IMX_I2C_IFDR);
        /* Enable I2C controller */
        imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
@@ -635,7 +631,6 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx, bool atomic)
 
        if (!i2c_imx->stopped) {
                /* Stop I2C transaction */
-               dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
                temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
                if (!(temp & I2CR_MSTA))
                        i2c_imx->stopped = 1;
@@ -1167,8 +1162,6 @@ static int i2c_imx_xfer_common(struct i2c_adapter *adapter,
        bool is_lastmsg = false;
        struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
 
-       dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
-
        /* Start I2C transfer */
        result = i2c_imx_start(i2c_imx, atomic);
        if (result) {
@@ -1371,8 +1364,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
        dma_addr_t phy_addr;
        const struct imx_i2c_hwdata *match;
 
-       dev_dbg(&pdev->dev, "<%s>\n", __func__);
-
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
                return irq;
@@ -1395,7 +1386,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
                                platform_get_device_id(pdev)->driver_data;
 
        /* Setup i2c_imx driver structure */
-       strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
+       strscpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
        i2c_imx->adapter.owner          = THIS_MODULE;
        i2c_imx->adapter.algo           = &i2c_imx_algo;
        i2c_imx->adapter.dev.parent     = &pdev->dev;
index dcca9c2..6d5014e 100644 (file)
@@ -635,6 +635,8 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
 
        status = readb(i2c->base + MPC_I2C_SR);
        if (status & CSR_MIF) {
+               /* Read again to allow register to stabilise */
+               status = readb(i2c->base + MPC_I2C_SR);
                writeb(0, i2c->base + MPC_I2C_SR);
                mpc_i2c_do_intr(i2c, status);
                return IRQ_HANDLED;
index 4e9fb6b..4ca716e 100644 (file)
@@ -1225,6 +1225,13 @@ static int mtk_i2c_probe(struct platform_device *pdev)
        i2c->adap.quirks = i2c->dev_comp->quirks;
        i2c->adap.timeout = 2 * HZ;
        i2c->adap.retries = 1;
+       i2c->adap.bus_regulator = devm_regulator_get_optional(&pdev->dev, "vbus");
+       if (IS_ERR(i2c->adap.bus_regulator)) {
+               if (PTR_ERR(i2c->adap.bus_regulator) == -ENODEV)
+                       i2c->adap.bus_regulator = NULL;
+               else
+                       return PTR_ERR(i2c->adap.bus_regulator);
+       }
 
        ret = mtk_i2c_parse_dt(pdev->dev.of_node, i2c);
        if (ret)
@@ -1286,7 +1293,7 @@ static int mtk_i2c_probe(struct platform_device *pdev)
 
        ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq,
                               IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE,
-                              I2C_DRV_NAME, i2c);
+                              dev_name(&pdev->dev), i2c);
        if (ret < 0) {
                dev_err(&pdev->dev,
                        "Request I2C IRQ %d fail\n", irq);
index c63d554..c1de8eb 100644 (file)
@@ -769,6 +769,7 @@ static const struct of_device_id cci_dt_match[] = {
        { .compatible = "qcom,msm8916-cci", .data = &cci_v1_data},
        { .compatible = "qcom,msm8996-cci", .data = &cci_v2_data},
        { .compatible = "qcom,sdm845-cci", .data = &cci_v2_data},
+       { .compatible = "qcom,sm8250-cci", .data = &cci_v2_data},
        {}
 };
 MODULE_DEVICE_TABLE(of, cci_dt_match);
index 327c092..bff9913 100644 (file)
@@ -1013,7 +1013,6 @@ static const struct of_device_id rcar_i2c_dt_ids[] = {
        { .compatible = "renesas,i2c-r8a7794", .data = (void *)I2C_RCAR_GEN2 },
        { .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 },
        { .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 },
-       { .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_GEN1 },    /* Deprecated */
        { .compatible = "renesas,rcar-gen1-i2c", .data = (void *)I2C_RCAR_GEN1 },
        { .compatible = "renesas,rcar-gen2-i2c", .data = (void *)I2C_RCAR_GEN2 },
        { .compatible = "renesas,rcar-gen3-i2c", .data = (void *)I2C_RCAR_GEN3 },
index 4eccc0f..78b8444 100644 (file)
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/reset.h>
 
 #define RIIC_ICCR1     0x00
 #define RIIC_ICCR2     0x04
 
 #define RIIC_INIT_MSG  -1
 
+enum riic_type {
+       RIIC_RZ_A,
+       RIIC_RZ_G2L,
+};
+
 struct riic_dev {
        void __iomem *base;
        u8 *buf;
@@ -395,7 +402,9 @@ static int riic_i2c_probe(struct platform_device *pdev)
        struct i2c_adapter *adap;
        struct resource *res;
        struct i2c_timings i2c_t;
+       struct reset_control *rstc;
        int i, ret;
+       enum riic_type type;
 
        riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL);
        if (!riic)
@@ -412,6 +421,17 @@ static int riic_i2c_probe(struct platform_device *pdev)
                return PTR_ERR(riic->clk);
        }
 
+       type = (enum riic_type)of_device_get_match_data(&pdev->dev);
+       if (type == RIIC_RZ_G2L) {
+               rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+               if (IS_ERR(rstc)) {
+                       dev_err(&pdev->dev, "Error: missing reset ctrl\n");
+                       return PTR_ERR(rstc);
+               }
+
+               reset_control_deassert(rstc);
+       }
+
        for (i = 0; i < ARRAY_SIZE(riic_irqs); i++) {
                res = platform_get_resource(pdev, IORESOURCE_IRQ, riic_irqs[i].res_num);
                if (!res)
@@ -472,7 +492,8 @@ static int riic_i2c_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id riic_i2c_dt_ids[] = {
-       { .compatible = "renesas,riic-rz" },
+       { .compatible = "renesas,riic-r9a07g044", .data = (void *)RIIC_RZ_G2L },
+       { .compatible = "renesas,riic-rz", .data = (void *)RIIC_RZ_A },
        { /* Sentinel */ },
 };
 
index 0138317..b9b19a2 100644 (file)
@@ -51,6 +51,7 @@
 
 /* STM32F7 I2C control 1 */
 #define STM32F7_I2C_CR1_PECEN                  BIT(23)
+#define STM32F7_I2C_CR1_ALERTEN                        BIT(22)
 #define STM32F7_I2C_CR1_SMBHEN                 BIT(20)
 #define STM32F7_I2C_CR1_WUPEN                  BIT(18)
 #define STM32F7_I2C_CR1_SBC                    BIT(16)
                                (((n) & STM32F7_I2C_ISR_ADDCODE_MASK) >> 17)
 #define STM32F7_I2C_ISR_DIR                    BIT(16)
 #define STM32F7_I2C_ISR_BUSY                   BIT(15)
+#define STM32F7_I2C_ISR_ALERT                  BIT(13)
 #define STM32F7_I2C_ISR_PECERR                 BIT(11)
 #define STM32F7_I2C_ISR_ARLO                   BIT(9)
 #define STM32F7_I2C_ISR_BERR                   BIT(8)
 #define STM32F7_I2C_ISR_TXE                    BIT(0)
 
 /* STM32F7 I2C Interrupt Clear */
+#define STM32F7_I2C_ICR_ALERTCF                        BIT(13)
 #define STM32F7_I2C_ICR_PECCF                  BIT(11)
 #define STM32F7_I2C_ICR_ARLOCF                 BIT(9)
 #define STM32F7_I2C_ICR_BERRCF                 BIT(8)
@@ -278,6 +281,17 @@ struct stm32f7_i2c_msg {
        u8 smbus_buf[I2C_SMBUS_BLOCK_MAX + 3] __aligned(4);
 };
 
+/**
+ * struct stm32f7_i2c_alert - SMBus alert specific data
+ * @setup: platform data for the smbus_alert i2c client
+ * @ara: I2C slave device used to respond to the SMBus Alert with Alert
+ * Response Address
+ */
+struct stm32f7_i2c_alert {
+       struct i2c_smbus_alert_setup setup;
+       struct i2c_client *ara;
+};
+
 /**
  * struct stm32f7_i2c_dev - private data of the controller
  * @adap: I2C adapter for this controller
@@ -310,6 +324,7 @@ struct stm32f7_i2c_msg {
  * @analog_filter: boolean to indicate enabling of the analog filter
  * @dnf_dt: value of digital filter requested via dt
  * @dnf: value of digital filter to apply
+ * @alert: SMBus alert specific data
  */
 struct stm32f7_i2c_dev {
        struct i2c_adapter adap;
@@ -341,6 +356,7 @@ struct stm32f7_i2c_dev {
        bool analog_filter;
        u32 dnf_dt;
        u32 dnf;
+       struct stm32f7_i2c_alert *alert;
 };
 
 /*
@@ -1624,6 +1640,13 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
                f7_msg->result = -EINVAL;
        }
 
+       if (status & STM32F7_I2C_ISR_ALERT) {
+               dev_dbg(dev, "<%s>: SMBus alert received\n", __func__);
+               writel_relaxed(STM32F7_I2C_ICR_ALERTCF, base + STM32F7_I2C_ICR);
+               i2c_handle_smbus_alert(i2c_dev->alert->ara);
+               return IRQ_HANDLED;
+       }
+
        if (!i2c_dev->slave_running) {
                u32 mask;
                /* Disable interrupts */
@@ -1990,6 +2013,42 @@ static void stm32f7_i2c_disable_smbus_host(struct stm32f7_i2c_dev *i2c_dev)
        }
 }
 
+static int stm32f7_i2c_enable_smbus_alert(struct stm32f7_i2c_dev *i2c_dev)
+{
+       struct stm32f7_i2c_alert *alert;
+       struct i2c_adapter *adap = &i2c_dev->adap;
+       struct device *dev = i2c_dev->dev;
+       void __iomem *base = i2c_dev->base;
+
+       alert = devm_kzalloc(dev, sizeof(*alert), GFP_KERNEL);
+       if (!alert)
+               return -ENOMEM;
+
+       alert->ara = i2c_new_smbus_alert_device(adap, &alert->setup);
+       if (IS_ERR(alert->ara))
+               return PTR_ERR(alert->ara);
+
+       i2c_dev->alert = alert;
+
+       /* Enable SMBus Alert */
+       stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, STM32F7_I2C_CR1_ALERTEN);
+
+       return 0;
+}
+
+static void stm32f7_i2c_disable_smbus_alert(struct stm32f7_i2c_dev *i2c_dev)
+{
+       struct stm32f7_i2c_alert *alert = i2c_dev->alert;
+       void __iomem *base = i2c_dev->base;
+
+       if (alert) {
+               /* Disable SMBus Alert */
+               stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1,
+                                    STM32F7_I2C_CR1_ALERTEN);
+               i2c_unregister_device(alert->ara);
+       }
+}
+
 static u32 stm32f7_i2c_func(struct i2c_adapter *adap)
 {
        struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
@@ -2173,6 +2232,16 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
                }
        }
 
+       if (of_property_read_bool(pdev->dev.of_node, "smbus-alert")) {
+               ret = stm32f7_i2c_enable_smbus_alert(i2c_dev);
+               if (ret) {
+                       dev_err(i2c_dev->dev,
+                               "failed to enable SMBus alert protocol (%d)\n",
+                               ret);
+                       goto i2c_disable_smbus_host;
+               }
+       }
+
        dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr);
 
        pm_runtime_mark_last_busy(i2c_dev->dev);
@@ -2180,6 +2249,9 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
 
        return 0;
 
+i2c_disable_smbus_host:
+       stm32f7_i2c_disable_smbus_host(i2c_dev);
+
 i2c_adapter_remove:
        i2c_del_adapter(adap);
 
@@ -2214,6 +2286,7 @@ static int stm32f7_i2c_remove(struct platform_device *pdev)
 {
        struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
 
+       stm32f7_i2c_disable_smbus_alert(i2c_dev);
        stm32f7_i2c_disable_smbus_host(i2c_dev);
 
        i2c_del_adapter(&i2c_dev->adap);
index 2a8568b..bb93db9 100644 (file)
@@ -798,11 +798,10 @@ static int xiic_i2c_probe(struct platform_device *pdev)
        init_waitqueue_head(&i2c->wait);
 
        i2c->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(i2c->clk)) {
-               if (PTR_ERR(i2c->clk) != -EPROBE_DEFER)
-                       dev_err(&pdev->dev, "input clock not found.\n");
-               return PTR_ERR(i2c->clk);
-       }
+       if (IS_ERR(i2c->clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk),
+                                    "input clock not found.\n");
+
        ret = clk_prepare_enable(i2c->clk);
        if (ret) {
                dev_err(&pdev->dev, "Unable to enable clock.\n");
index 5a97e4a..84f12bf 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/i2c-smbus.h>
 #include <linux/idr.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/irqflags.h>
 #include <linux/jump_label.h>
 #include <linux/kernel.h>
@@ -399,7 +400,8 @@ static int i2c_gpio_init_recovery(struct i2c_adapter *adap)
 static int i2c_init_recovery(struct i2c_adapter *adap)
 {
        struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
-       char *err_str, *err_level = KERN_ERR;
+       bool is_error_level = true;
+       char *err_str;
 
        if (!bri)
                return 0;
@@ -409,7 +411,7 @@ static int i2c_init_recovery(struct i2c_adapter *adap)
 
        if (!bri->recover_bus) {
                err_str = "no suitable method provided";
-               err_level = KERN_DEBUG;
+               is_error_level = false;
                goto err;
        }
 
@@ -436,7 +438,10 @@ static int i2c_init_recovery(struct i2c_adapter *adap)
 
        return 0;
  err:
-       dev_printk(err_level, &adap->dev, "Not using recovery: %s\n", err_str);
+       if (is_error_level)
+               dev_err(&adap->dev, "Not using recovery: %s\n", err_str);
+       else
+               dev_dbg(&adap->dev, "Not using recovery: %s\n", err_str);
        adap->bus_recovery_info = NULL;
 
        return -EINVAL;
@@ -461,12 +466,14 @@ static int i2c_smbus_host_notify_to_irq(const struct i2c_client *client)
 static int i2c_device_probe(struct device *dev)
 {
        struct i2c_client       *client = i2c_verify_client(dev);
+       struct i2c_adapter      *adap;
        struct i2c_driver       *driver;
        int status;
 
        if (!client)
                return 0;
 
+       adap = client->adapter;
        client->irq = client->init_irq;
 
        if (!client->irq) {
@@ -532,6 +539,14 @@ static int i2c_device_probe(struct device *dev)
 
        dev_dbg(dev, "probe\n");
 
+       if (adap->bus_regulator) {
+               status = regulator_enable(adap->bus_regulator);
+               if (status < 0) {
+                       dev_err(&adap->dev, "Failed to enable bus regulator\n");
+                       goto err_clear_wakeup_irq;
+               }
+       }
+
        status = of_clk_set_defaults(dev->of_node, false);
        if (status < 0)
                goto err_clear_wakeup_irq;
@@ -589,8 +604,10 @@ put_sync_adapter:
 static int i2c_device_remove(struct device *dev)
 {
        struct i2c_client       *client = to_i2c_client(dev);
+       struct i2c_adapter      *adap;
        struct i2c_driver       *driver;
 
+       adap = client->adapter;
        driver = to_i2c_driver(dev->driver);
        if (driver->remove) {
                int status;
@@ -605,6 +622,8 @@ static int i2c_device_remove(struct device *dev)
        devres_release_group(&client->dev, client->devres_group_id);
 
        dev_pm_domain_detach(&client->dev, true);
+       if (!pm_runtime_status_suspended(&client->dev) && adap->bus_regulator)
+               regulator_disable(adap->bus_regulator);
 
        dev_pm_clear_wake_irq(&client->dev);
        device_init_wakeup(&client->dev, false);
@@ -617,6 +636,86 @@ static int i2c_device_remove(struct device *dev)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int i2c_resume_early(struct device *dev)
+{
+       struct i2c_client *client = i2c_verify_client(dev);
+       int err;
+
+       if (!client)
+               return 0;
+
+       if (pm_runtime_status_suspended(&client->dev) &&
+               client->adapter->bus_regulator) {
+               err = regulator_enable(client->adapter->bus_regulator);
+               if (err)
+                       return err;
+       }
+
+       return pm_generic_resume_early(&client->dev);
+}
+
+static int i2c_suspend_late(struct device *dev)
+{
+       struct i2c_client *client = i2c_verify_client(dev);
+       int err;
+
+       if (!client)
+               return 0;
+
+       err = pm_generic_suspend_late(&client->dev);
+       if (err)
+               return err;
+
+       if (!pm_runtime_status_suspended(&client->dev) &&
+               client->adapter->bus_regulator)
+               return regulator_disable(client->adapter->bus_regulator);
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int i2c_runtime_resume(struct device *dev)
+{
+       struct i2c_client *client = i2c_verify_client(dev);
+       int err;
+
+       if (!client)
+               return 0;
+
+       if (client->adapter->bus_regulator) {
+               err = regulator_enable(client->adapter->bus_regulator);
+               if (err)
+                       return err;
+       }
+
+       return pm_generic_runtime_resume(&client->dev);
+}
+
+static int i2c_runtime_suspend(struct device *dev)
+{
+       struct i2c_client *client = i2c_verify_client(dev);
+       int err;
+
+       if (!client)
+               return 0;
+
+       err = pm_generic_runtime_suspend(&client->dev);
+       if (err)
+               return err;
+
+       if (client->adapter->bus_regulator)
+               return regulator_disable(client->adapter->bus_regulator);
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops i2c_device_pm = {
+       SET_LATE_SYSTEM_SLEEP_PM_OPS(i2c_suspend_late, i2c_resume_early)
+       SET_RUNTIME_PM_OPS(i2c_runtime_suspend, i2c_runtime_resume, NULL)
+};
+
 static void i2c_device_shutdown(struct device *dev)
 {
        struct i2c_client *client = i2c_verify_client(dev);
@@ -627,6 +726,8 @@ static void i2c_device_shutdown(struct device *dev)
        driver = to_i2c_driver(dev->driver);
        if (driver->shutdown)
                driver->shutdown(client);
+       else if (client->irq > 0)
+               disable_irq(client->irq);
 }
 
 static void i2c_client_dev_release(struct device *dev)
@@ -674,6 +775,7 @@ struct bus_type i2c_bus_type = {
        .probe          = i2c_device_probe,
        .remove         = i2c_device_remove,
        .shutdown       = i2c_device_shutdown,
+       .pm             = &i2c_device_pm,
 };
 EXPORT_SYMBOL_GPL(i2c_bus_type);
 
index d2d32c0..e5b2d14 100644 (file)
@@ -37,8 +37,15 @@ static u8 crc8(u16 data)
        return (u8)(data >> 8);
 }
 
-/* Incremental CRC8 over count bytes in the array pointed to by p */
-static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
+/**
+ * i2c_smbus_pec - Incremental CRC8 over the given input data array
+ * @crc: previous return crc8 value
+ * @p: pointer to data buffer.
+ * @count: number of bytes in data buffer.
+ *
+ * Incremental CRC8 over count bytes in the array pointed to by p
+ */
+u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
 {
        int i;
 
@@ -46,6 +53,7 @@ static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
                crc = crc8((crc ^ p[i]) << 8);
        return crc;
 }
+EXPORT_SYMBOL(i2c_smbus_pec);
 
 /* Assume a 7-bit address, which is reasonable for SMBus */
 static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg)
index e8f2ac8..685f8c7 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/device.h>      /* for struct device */
 #include <linux/sched.h>       /* for completion */
 #include <linux/mutex.h>
+#include <linux/regulator/consumer.h>
 #include <linux/rtmutex.h>
 #include <linux/irqdomain.h>           /* for Host Notify IRQ */
 #include <linux/of.h>          /* for struct device_node */
@@ -147,6 +148,7 @@ s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
 /* Now follow the 'nice' access routines. These also document the calling
    conventions of i2c_smbus_xfer. */
 
+u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count);
 s32 i2c_smbus_read_byte(const struct i2c_client *client);
 s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value);
 s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command);
@@ -729,6 +731,7 @@ struct i2c_adapter {
        const struct i2c_adapter_quirks *quirks;
 
        struct irq_domain *host_notify_domain;
+       struct regulator *bus_regulator;
 };
 #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)