Commit 855ff900 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c/for-mergewindow' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

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
  ...
parents d2500a0c 9d633683
...@@ -15,6 +15,7 @@ Required properties: ...@@ -15,6 +15,7 @@ Required properties:
"mediatek,mt8173-i2c": for MediaTek MT8173 "mediatek,mt8173-i2c": for MediaTek MT8173
"mediatek,mt8183-i2c": for MediaTek MT8183 "mediatek,mt8183-i2c": for MediaTek MT8183
"mediatek,mt8192-i2c": for MediaTek MT8192 "mediatek,mt8192-i2c": for MediaTek MT8192
"mediatek,mt8195-i2c", "mediatek,mt8192-i2c": for MediaTek MT8195
"mediatek,mt8516-i2c", "mediatek,mt2712-i2c": for MediaTek MT8516 "mediatek,mt8516-i2c", "mediatek,mt2712-i2c": for MediaTek MT8516
- reg: physical base address of the controller and dma base, length of memory - reg: physical base address of the controller and dma base, length of memory
mapped region. mapped region.
...@@ -32,6 +33,7 @@ Optional properties: ...@@ -32,6 +33,7 @@ Optional properties:
- mediatek,have-pmic: platform can control i2c form special pmic side. - mediatek,have-pmic: platform can control i2c form special pmic side.
Only mt6589 and mt8135 support this feature. Only mt6589 and mt8135 support this feature.
- mediatek,use-push-pull: IO config use push-pull mode. - mediatek,use-push-pull: IO config use push-pull mode.
- vbus-supply: phandle to the regulator that provides power to SCL/SDA.
Example: Example:
......
...@@ -62,7 +62,6 @@ Example: ...@@ -62,7 +62,6 @@ Example:
reg = <0x3c>; reg = <0x3c>;
pwms = <&pwm 4 3000>; pwms = <&pwm 4 3000>;
reset-gpios = <&gpio2 7 1>; reset-gpios = <&gpio2 7 1>;
reset-active-low;
}; };
}; };
......
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>;
};
...@@ -71,7 +71,7 @@ This is an example which is used on FalconFalls: ...@@ -71,7 +71,7 @@ This is an example which is used on FalconFalls:
/* This I2C controller has one gpio controller */ /* This I2C controller has one gpio controller */
gpio@26 { gpio@26 {
#gpio-cells = <2>; #gpio-cells = <2>;
compatible = "ti,pcf8575"; compatible = "nxp,pcf8575";
reg = <0x26>; reg = <0x26>;
gpio-controller; gpio-controller;
}; };
...@@ -85,7 +85,7 @@ This is an example which is used on FalconFalls: ...@@ -85,7 +85,7 @@ This is an example which is used on FalconFalls:
gpio@26 { gpio@26 {
#gpio-cells = <2>; #gpio-cells = <2>;
compatible = "ti,pcf8575"; compatible = "nxp,pcf8575";
reg = <0x26>; reg = <0x26>;
gpio-controller; gpio-controller;
}; };
......
...@@ -9,6 +9,7 @@ PROPERTIES: ...@@ -9,6 +9,7 @@ PROPERTIES:
"qcom,msm8916-cci" "qcom,msm8916-cci"
"qcom,msm8996-cci" "qcom,msm8996-cci"
"qcom,sdm845-cci" "qcom,sdm845-cci"
"qcom,sm8250-cci"
- reg - reg
Usage: required Usage: required
...@@ -41,8 +42,8 @@ PROPERTIES: ...@@ -41,8 +42,8 @@ PROPERTIES:
SUBNODES: SUBNODES:
The CCI provides I2C masters for one (msm8916) or two i2c busses (msm8996 and The CCI provides I2C masters for one (msm8916) or two i2c busses (msm8996,
sdm845), described as subdevices named "i2c-bus@0" and "i2c-bus@1". sdm845 and sm8250), described as subdevices named "i2c-bus@0" and "i2c-bus@1".
PROPERTIES: PROPERTIES:
......
...@@ -36,6 +36,7 @@ properties: ...@@ -36,6 +36,7 @@ properties:
- rockchip,px30-i2c - rockchip,px30-i2c
- rockchip,rk3308-i2c - rockchip,rk3308-i2c
- rockchip,rk3328-i2c - rockchip,rk3328-i2c
- rockchip,rk3568-i2c
- const: rockchip,rk3399-i2c - const: rockchip,rk3399-i2c
reg: reg:
......
...@@ -89,8 +89,11 @@ wants to support one of the below features, it should adapt these bindings. ...@@ -89,8 +89,11 @@ wants to support one of the below features, it should adapt these bindings.
- smbus - smbus
states that additional SMBus restrictions and features apply to this bus. states that additional SMBus restrictions and features apply to this bus.
Examples of features are SMBusHostNotify and SMBusAlert. Examples of An example of feature is SMBusHostNotify. Examples of restrictions are
restrictions are more reserved addresses and timeout definitions. more reserved addresses and timeout definitions.
- smbus-alert
states that the optional SMBus-Alert feature apply to this bus.
Required properties (per child device) Required properties (per child device)
-------------------------------------- --------------------------------------
......
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>;
};
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";
};
# 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";
};
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>;
};
# 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>;
};
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>;
};
# 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>;
};
# 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>;
};
# 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>;
};
This diff is collapsed.
...@@ -13494,7 +13494,7 @@ M: Vignesh R <vigneshr@ti.com> ...@@ -13494,7 +13494,7 @@ M: Vignesh R <vigneshr@ti.com>
L: linux-omap@vger.kernel.org L: linux-omap@vger.kernel.org
L: linux-i2c@vger.kernel.org L: linux-i2c@vger.kernel.org
S: Maintained 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 F: drivers/i2c/busses/i2c-omap.c
OMAP IMAGING SUBSYSTEM (OMAP3 ISP and OMAP4 ISS) OMAP IMAGING SUBSYSTEM (OMAP3 ISP and OMAP4 ISS)
...@@ -15722,8 +15722,9 @@ F: drivers/clk/renesas/ ...@@ -15722,8 +15722,9 @@ F: drivers/clk/renesas/
RENESAS EMEV2 I2C DRIVER RENESAS EMEV2 I2C DRIVER
M: Wolfram Sang <wsa+renesas@sang-engineering.com> M: Wolfram Sang <wsa+renesas@sang-engineering.com>
L: linux-renesas-soc@vger.kernel.org
S: Supported 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 F: drivers/i2c/busses/i2c-emev2.c
RENESAS ETHERNET DRIVERS RENESAS ETHERNET DRIVERS
...@@ -15743,9 +15744,10 @@ F: drivers/iio/adc/rcar-gyroadc.c ...@@ -15743,9 +15744,10 @@ F: drivers/iio/adc/rcar-gyroadc.c
RENESAS R-CAR I2C DRIVERS RENESAS R-CAR I2C DRIVERS
M: Wolfram Sang <wsa+renesas@sang-engineering.com> M: Wolfram Sang <wsa+renesas@sang-engineering.com>
L: linux-renesas-soc@vger.kernel.org
S: Supported S: Supported
F: Documentation/devicetree/bindings/i2c/renesas,i2c.txt F: Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml
F: Documentation/devicetree/bindings/i2c/renesas,iic.txt F: Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml
F: drivers/i2c/busses/i2c-rcar.c F: drivers/i2c/busses/i2c-rcar.c
F: drivers/i2c/busses/i2c-sh_mobile.c F: drivers/i2c/busses/i2c-sh_mobile.c
...@@ -15760,8 +15762,9 @@ F: drivers/thermal/rcar_thermal.c ...@@ -15760,8 +15762,9 @@ F: drivers/thermal/rcar_thermal.c
RENESAS RIIC DRIVER RENESAS RIIC DRIVER
M: Chris Brandt <chris.brandt@renesas.com> M: Chris Brandt <chris.brandt@renesas.com>
L: linux-renesas-soc@vger.kernel.org
S: Supported 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 F: drivers/i2c/busses/i2c-riic.c
RENESAS USB PHY DRIVER RENESAS USB PHY DRIVER
......
...@@ -508,6 +508,11 @@ static void ali1535_remove(struct pci_dev *dev) ...@@ -508,6 +508,11 @@ static void ali1535_remove(struct pci_dev *dev)
{ {
i2c_del_adapter(&ali1535_adapter); i2c_del_adapter(&ali1535_adapter);
release_region(ali1535_smba, ALI1535_SMB_IOSIZE); 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 = { static struct pci_driver ali1535_driver = {
......
...@@ -727,10 +727,14 @@ static void __aspeed_i2c_reg_slave(struct aspeed_i2c_bus *bus, u16 slave_addr) ...@@ -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; u32 addr_reg_val, func_ctrl_reg_val;
/* Set slave addr. */ /*
addr_reg_val = readl(bus->base + ASPEED_I2C_DEV_ADDR_REG); * Set slave addr. Reserved bits can all safely be written with zeros
addr_reg_val &= ~ASPEED_I2CD_DEV_ADDR_MASK; * on all of ast2[456]00, so zero everything else to ensure we only
addr_reg_val |= slave_addr & ASPEED_I2CD_DEV_ADDR_MASK; * 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); writel(addr_reg_val, bus->base + ASPEED_I2C_DEV_ADDR_REG);
/* Turn on slave mode. */ /* Turn on slave mode. */
......
...@@ -578,6 +578,11 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) ...@@ -578,6 +578,11 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
{ {
unsigned int ctrl_reg; unsigned int ctrl_reg;
unsigned int isr_status; 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->p_recv_buf = id->p_msg->buf;
id->recv_count = id->p_msg->len; id->recv_count = id->p_msg->len;
...@@ -618,14 +623,43 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) ...@@ -618,14 +623,43 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET); cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET);
} }
/* Set the slave address in address register - triggers operation */ /* Determine hold_clear based on number of bytes to receive and hold flag */
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 */
if (!id->bus_hold_flag && if (!id->bus_hold_flag &&
((id->p_msg->flags & I2C_M_RECV_LEN) != I2C_M_RECV_LEN) && ((id->p_msg->flags & I2C_M_RECV_LEN) != I2C_M_RECV_LEN) &&
(id->recv_count <= CDNS_I2C_FIFO_DEPTH)) (id->recv_count <= CDNS_I2C_FIFO_DEPTH)) {
cdns_i2c_clear_bus_hold(id); 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); 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) ...@@ -1217,11 +1251,10 @@ static int cdns_i2c_probe(struct platform_device *pdev)
"Cadence I2C at %08lx", (unsigned long)r_mem->start); "Cadence I2C at %08lx", (unsigned long)r_mem->start);
id->clk = devm_clk_get(&pdev->dev, NULL); id->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(id->clk)) { if (IS_ERR(id->clk))
if (PTR_ERR(id->clk) != -EPROBE_DEFER) return dev_err_probe(&pdev->dev, PTR_ERR(id->clk),
dev_err(&pdev->dev, "input clock not found.\n"); "input clock not found.\n");
return PTR_ERR(id->clk);
}
ret = clk_prepare_enable(id->clk); ret = clk_prepare_enable(id->clk);
if (ret) if (ret)
dev_err(&pdev->dev, "Unable to enable clock.\n"); dev_err(&pdev->dev, "Unable to enable clock.\n");
......
...@@ -354,8 +354,7 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev) ...@@ -354,8 +354,7 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
return ret; return ret;
/* Alloc and register client IRQ */ /* Alloc and register client IRQ */
adap->irq_domain = irq_domain_add_linear(pdev->dev.of_node, 1, adap->irq_domain = irq_domain_add_linear(NULL, 1, &irq_domain_simple_ops, NULL);
&irq_domain_simple_ops, NULL);
if (!adap->irq_domain) if (!adap->irq_domain)
return -ENOMEM; return -ENOMEM;
......
...@@ -768,10 +768,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) ...@@ -768,10 +768,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
if (irq <= 0) { if (irq <= 0) {
if (!irq) if (!irq)
irq = -ENXIO; irq = -ENXIO;
if (irq != -EPROBE_DEFER) return dev_err_probe(&pdev->dev, irq, "can't get irq resource\n");
dev_err(&pdev->dev,
"can't get irq resource ret=%d\n", irq);
return irq;
} }
dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_i2c_dev), dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_i2c_dev),
......
...@@ -88,6 +88,8 @@ ...@@ -88,6 +88,8 @@
* See the file Documentation/i2c/busses/i2c-i801.rst for details. * See the file Documentation/i2c/busses/i2c-i801.rst for details.
*/ */
#define DRV_NAME "i801_smbus"
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
...@@ -103,7 +105,7 @@ ...@@ -103,7 +105,7 @@
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/wait.h> #include <linux/completion.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/itco_wdt.h> #include <linux/platform_data/itco_wdt.h>
...@@ -131,8 +133,6 @@ ...@@ -131,8 +133,6 @@
/* PCI Address Constants */ /* PCI Address Constants */
#define SMBBAR 4 #define SMBBAR 4
#define SMBPCICTL 0x004
#define SMBPCISTS 0x006
#define SMBHSTCFG 0x040 #define SMBHSTCFG 0x040
#define TCOBASE 0x050 #define TCOBASE 0x050
#define TCOCTL 0x054 #define TCOCTL 0x054
...@@ -141,12 +141,6 @@ ...@@ -141,12 +141,6 @@
#define SBREG_SMBCTRL 0xc6000c #define SBREG_SMBCTRL 0xc6000c
#define SBREG_SMBCTRL_DNV 0xcf000c #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 */ /* Host configuration bits for SMBHSTCFG */
#define SMBHSTCFG_HST_EN BIT(0) #define SMBHSTCFG_HST_EN BIT(0)
#define SMBHSTCFG_SMB_SMI_EN BIT(1) #define SMBHSTCFG_SMB_SMI_EN BIT(1)
...@@ -164,9 +158,6 @@ ...@@ -164,9 +158,6 @@
#define SMBAUXCTL_CRC BIT(0) #define SMBAUXCTL_CRC BIT(0)
#define SMBAUXCTL_E32B BIT(1) #define SMBAUXCTL_E32B BIT(1)
/* Other settings */
#define MAX_RETRIES 400
/* I801 command constants */ /* I801 command constants */
#define I801_QUICK 0x00 #define I801_QUICK 0x00
#define I801_BYTE 0x04 #define I801_BYTE 0x04
...@@ -270,7 +261,7 @@ struct i801_priv { ...@@ -270,7 +261,7 @@ struct i801_priv {
unsigned int features; unsigned int features;
/* isr processing */ /* isr processing */
wait_queue_head_t waitq; struct completion done;
u8 status; u8 status;
/* Command state used by isr for byte-by-byte block transactions */ /* 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) ...@@ -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 */ /* Wait for BUSY being cleared and either INTR or an error flag being set */
static int i801_wait_intr(struct i801_priv *priv) static int i801_wait_intr(struct i801_priv *priv)
{ {
int timeout = 0; unsigned long timeout = jiffies + priv->adapter.timeout;
int status; int status, busy;
/* We will always wait for a fraction of a second! */
do { do {
usleep_range(250, 500); usleep_range(250, 500);
status = inb_p(SMBHSTSTS(priv)); status = inb_p(SMBHSTSTS(priv));
} while (((status & SMBHSTSTS_HOST_BUSY) || busy = status & SMBHSTSTS_HOST_BUSY;
!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR))) && status &= STATUS_ERROR_FLAGS | SMBHSTSTS_INTR;
(timeout++ < MAX_RETRIES)); if (!busy && status)
return status;
} while (time_is_after_eq_jiffies(timeout));
if (timeout > MAX_RETRIES) { return -ETIMEDOUT;
dev_dbg(&priv->pci_dev->dev, "INTR Timeout!\n");
return -ETIMEDOUT;
}
return status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR);
} }
/* Wait for either BYTE_DONE or an error flag being set */ /* Wait for either BYTE_DONE or an error flag being set */
static int i801_wait_byte_done(struct i801_priv *priv) static int i801_wait_byte_done(struct i801_priv *priv)
{ {
int timeout = 0; unsigned long timeout = jiffies + priv->adapter.timeout;
int status; int status;
/* We will always wait for a fraction of a second! */
do { do {
usleep_range(250, 500); usleep_range(250, 500);
status = inb_p(SMBHSTSTS(priv)); status = inb_p(SMBHSTSTS(priv));
} while (!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) && if (status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE))
(timeout++ < MAX_RETRIES)); return status & STATUS_ERROR_FLAGS;
} while (time_is_after_eq_jiffies(timeout));
if (timeout > MAX_RETRIES) { return -ETIMEDOUT;
dev_dbg(&priv->pci_dev->dev, "BYTE_DONE Timeout!\n");
return -ETIMEDOUT;
}
return status & STATUS_ERROR_FLAGS;
} }
static int i801_transaction(struct i801_priv *priv, int xact) static int i801_transaction(struct i801_priv *priv, int xact)
{ {
int status; int status;
int result; unsigned long result;
const struct i2c_adapter *adap = &priv->adapter; const struct i2c_adapter *adap = &priv->adapter;
result = i801_check_pre(priv); status = i801_check_pre(priv);
if (result < 0) if (status < 0)
return result; return status;
if (priv->features & FEATURE_IRQ) { if (priv->features & FEATURE_IRQ) {
reinit_completion(&priv->done);
outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START, outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START,
SMBHSTCNT(priv)); SMBHSTCNT(priv));
result = wait_event_timeout(priv->waitq, result = wait_for_completion_timeout(&priv->done, adap->timeout);
(status = priv->status), return i801_check_post(priv, result ? priv->status : -ETIMEDOUT);
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);
} }
/* the current contents of SMBHSTCNT can be overwritten, since PEC, /* 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) ...@@ -638,7 +615,7 @@ static irqreturn_t i801_host_notify_isr(struct i801_priv *priv)
* DEV_ERR - Invalid command, NAK or communication timeout * DEV_ERR - Invalid command, NAK or communication timeout
* BUS_ERR - SMI# transaction collision * BUS_ERR - SMI# transaction collision
* FAILED - transaction was canceled due to a KILL request * 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. * ->status must be cleared before kicking off the next transaction.
* *
* 2) For byte-by-byte (I2C read/write) transactions, one BYTE_DONE interrupt * 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) ...@@ -653,8 +630,8 @@ static irqreturn_t i801_isr(int irq, void *dev_id)
u8 status; u8 status;
/* Confirm this is our interrupt */ /* Confirm this is our interrupt */
pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists); pci_read_config_word(priv->pci_dev, PCI_STATUS, &pcists);
if (!(pcists & SMBPCISTS_INTS)) if (!(pcists & PCI_STATUS_INTERRUPT))
return IRQ_NONE; return IRQ_NONE;
if (priv->features & FEATURE_HOST_NOTIFY) { if (priv->features & FEATURE_HOST_NOTIFY) {
...@@ -675,7 +652,7 @@ static irqreturn_t i801_isr(int irq, void *dev_id) ...@@ -675,7 +652,7 @@ static irqreturn_t i801_isr(int irq, void *dev_id)
if (status) { if (status) {
outb_p(status, SMBHSTSTS(priv)); outb_p(status, SMBHSTSTS(priv));
priv->status = status; priv->status = status;
wake_up(&priv->waitq); complete(&priv->done);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -694,15 +671,15 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, ...@@ -694,15 +671,15 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
int i, len; int i, len;
int smbcmd; int smbcmd;
int status; int status;
int result; unsigned long result;
const struct i2c_adapter *adap = &priv->adapter; const struct i2c_adapter *adap = &priv->adapter;
if (command == I2C_SMBUS_BLOCK_PROC_CALL) if (command == I2C_SMBUS_BLOCK_PROC_CALL)
return -EOPNOTSUPP; return -EOPNOTSUPP;
result = i801_check_pre(priv); status = i801_check_pre(priv);
if (result < 0) if (status < 0)
return result; return status;
len = data->block[0]; len = data->block[0];
...@@ -726,17 +703,10 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, ...@@ -726,17 +703,10 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
priv->count = 0; priv->count = 0;
priv->data = &data->block[1]; priv->data = &data->block[1];
reinit_completion(&priv->done);
outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv)); outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv));
result = wait_event_timeout(priv->waitq, result = wait_for_completion_timeout(&priv->done, adap->timeout);
(status = priv->status), return i801_check_post(priv, result ? priv->status : -ETIMEDOUT);
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);
} }
for (i = 1; i <= len; i++) { for (i = 1; i <= len; i++) {
...@@ -1322,11 +1292,11 @@ static void i801_probe_optional_slaves(struct i801_priv *priv) ...@@ -1322,11 +1292,11 @@ static void i801_probe_optional_slaves(struct i801_priv *priv)
return; return;
if (apanel_addr) { 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); i2c_new_client_device(&priv->adapter, &info);
} }
...@@ -1715,19 +1685,17 @@ static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; } ...@@ -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) { } static inline void i801_acpi_remove(struct i801_priv *priv) { }
#endif #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; unsigned char hstcfg = priv->original_hstcfg;
hstcfg &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ hstcfg &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
hstcfg |= SMBHSTCFG_HST_EN; hstcfg |= SMBHSTCFG_HST_EN;
pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hstcfg); 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) static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
{ {
unsigned char temp;
int err, i; int err, i;
struct i801_priv *priv; struct i801_priv *priv;
...@@ -1838,8 +1806,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -1838,8 +1806,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (i801_acpi_probe(priv)) if (i801_acpi_probe(priv))
return -ENODEV; return -ENODEV;
err = pcim_iomap_regions(dev, 1 << SMBBAR, err = pcim_iomap_regions(dev, 1 << SMBBAR, DRV_NAME);
dev_driver_string(&dev->dev));
if (err) { if (err) {
dev_err(&dev->dev, dev_err(&dev->dev,
"Failed to request SMBus region 0x%lx-0x%Lx\n", "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) ...@@ -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); 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)) if (!(priv->original_hstcfg & SMBHSTCFG_HST_EN))
dev_info(&dev->dev, "Enabling SMBus device\n"); 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"); dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
/* Disable SMBus interrupt feature if SMBus using SMI# */ /* Disable SMBus interrupt feature if SMBus using SMI# */
priv->features &= ~FEATURE_IRQ; 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"); dev_info(&dev->dev, "SPD Write Disable is set\n");
/* Clear special mode bits */ /* Clear special mode bits */
...@@ -1881,24 +1848,23 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -1881,24 +1848,23 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
u16 pcictl, pcists; u16 pcictl, pcists;
/* Complain if an interrupt is already pending */ /* Complain if an interrupt is already pending */
pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists); pci_read_config_word(priv->pci_dev, PCI_STATUS, &pcists);
if (pcists & SMBPCISTS_INTS) if (pcists & PCI_STATUS_INTERRUPT)
dev_warn(&dev->dev, "An interrupt is pending!\n"); dev_warn(&dev->dev, "An interrupt is pending!\n");
/* Check if interrupts have been disabled */ /* Check if interrupts have been disabled */
pci_read_config_word(priv->pci_dev, SMBPCICTL, &pcictl); pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pcictl);
if (pcictl & SMBPCICTL_INTDIS) { if (pcictl & PCI_COMMAND_INTX_DISABLE) {
dev_info(&dev->dev, "Interrupts are disabled\n"); dev_info(&dev->dev, "Interrupts are disabled\n");
priv->features &= ~FEATURE_IRQ; priv->features &= ~FEATURE_IRQ;
} }
} }
if (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, err = devm_request_irq(&dev->dev, dev->irq, i801_isr,
IRQF_SHARED, IRQF_SHARED, DRV_NAME, priv);
dev_driver_string(&dev->dev), priv);
if (err) { if (err) {
dev_err(&dev->dev, "Failed to allocate irq %d: %d\n", dev_err(&dev->dev, "Failed to allocate irq %d: %d\n",
dev->irq, err); dev->irq, err);
...@@ -1988,7 +1954,7 @@ static int i801_resume(struct device *dev) ...@@ -1988,7 +1954,7 @@ static int i801_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(i801_pm_ops, i801_suspend, i801_resume); static SIMPLE_DEV_PM_OPS(i801_pm_ops, i801_suspend, i801_resume);
static struct pci_driver i801_driver = { static struct pci_driver i801_driver = {
.name = "i801_smbus", .name = DRV_NAME,
.id_table = i801_ids, .id_table = i801_ids,
.probe = i801_probe, .probe = i801_probe,
.remove = i801_remove, .remove = i801_remove,
......
...@@ -170,11 +170,11 @@ enum imx_i2c_type { ...@@ -170,11 +170,11 @@ enum imx_i2c_type {
struct imx_i2c_hwdata { struct imx_i2c_hwdata {
enum imx_i2c_type devtype; enum imx_i2c_type devtype;
unsigned regshift; unsigned int regshift;
struct imx_i2c_clk_pair *clk_div; struct imx_i2c_clk_pair *clk_div;
unsigned ndivs; unsigned int ndivs;
unsigned i2sr_clr_opcode; unsigned int i2sr_clr_opcode;
unsigned i2cr_ien_opcode; unsigned int i2cr_ien_opcode;
}; };
struct imx_i2c_dma { 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 ...@@ -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 long orig_jiffies = jiffies;
unsigned int temp; unsigned int temp;
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
while (1) { while (1) {
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR); 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) ...@@ -599,8 +597,6 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx, bool atomic)
unsigned int temp = 0; unsigned int temp = 0;
int result; int result;
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
imx_i2c_write_reg(i2c_imx->ifdr, i2c_imx, IMX_I2C_IFDR); imx_i2c_write_reg(i2c_imx->ifdr, i2c_imx, IMX_I2C_IFDR);
/* Enable I2C controller */ /* Enable I2C controller */
imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR); 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) ...@@ -635,7 +631,6 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx, bool atomic)
if (!i2c_imx->stopped) { if (!i2c_imx->stopped) {
/* Stop I2C transaction */ /* Stop I2C transaction */
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
if (!(temp & I2CR_MSTA)) if (!(temp & I2CR_MSTA))
i2c_imx->stopped = 1; i2c_imx->stopped = 1;
...@@ -1167,8 +1162,6 @@ static int i2c_imx_xfer_common(struct i2c_adapter *adapter, ...@@ -1167,8 +1162,6 @@ static int i2c_imx_xfer_common(struct i2c_adapter *adapter,
bool is_lastmsg = false; bool is_lastmsg = false;
struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter); struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
/* Start I2C transfer */ /* Start I2C transfer */
result = i2c_imx_start(i2c_imx, atomic); result = i2c_imx_start(i2c_imx, atomic);
if (result) { if (result) {
...@@ -1371,8 +1364,6 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -1371,8 +1364,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
dma_addr_t phy_addr; dma_addr_t phy_addr;
const struct imx_i2c_hwdata *match; const struct imx_i2c_hwdata *match;
dev_dbg(&pdev->dev, "<%s>\n", __func__);
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) if (irq < 0)
return irq; return irq;
...@@ -1395,7 +1386,7 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -1395,7 +1386,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
platform_get_device_id(pdev)->driver_data; platform_get_device_id(pdev)->driver_data;
/* Setup i2c_imx driver structure */ /* 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.owner = THIS_MODULE;
i2c_imx->adapter.algo = &i2c_imx_algo; i2c_imx->adapter.algo = &i2c_imx_algo;
i2c_imx->adapter.dev.parent = &pdev->dev; i2c_imx->adapter.dev.parent = &pdev->dev;
......
...@@ -635,6 +635,8 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) ...@@ -635,6 +635,8 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
status = readb(i2c->base + MPC_I2C_SR); status = readb(i2c->base + MPC_I2C_SR);
if (status & CSR_MIF) { 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); writeb(0, i2c->base + MPC_I2C_SR);
mpc_i2c_do_intr(i2c, status); mpc_i2c_do_intr(i2c, status);
return IRQ_HANDLED; return IRQ_HANDLED;
......
...@@ -1225,6 +1225,13 @@ static int mtk_i2c_probe(struct platform_device *pdev) ...@@ -1225,6 +1225,13 @@ static int mtk_i2c_probe(struct platform_device *pdev)
i2c->adap.quirks = i2c->dev_comp->quirks; i2c->adap.quirks = i2c->dev_comp->quirks;
i2c->adap.timeout = 2 * HZ; i2c->adap.timeout = 2 * HZ;
i2c->adap.retries = 1; 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); ret = mtk_i2c_parse_dt(pdev->dev.of_node, i2c);
if (ret) if (ret)
...@@ -1286,7 +1293,7 @@ static int mtk_i2c_probe(struct platform_device *pdev) ...@@ -1286,7 +1293,7 @@ static int mtk_i2c_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq,
IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE, IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE,
I2C_DRV_NAME, i2c); dev_name(&pdev->dev), i2c);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Request I2C IRQ %d fail\n", irq); "Request I2C IRQ %d fail\n", irq);
......
...@@ -769,6 +769,7 @@ static const struct of_device_id cci_dt_match[] = { ...@@ -769,6 +769,7 @@ static const struct of_device_id cci_dt_match[] = {
{ .compatible = "qcom,msm8916-cci", .data = &cci_v1_data}, { .compatible = "qcom,msm8916-cci", .data = &cci_v1_data},
{ .compatible = "qcom,msm8996-cci", .data = &cci_v2_data}, { .compatible = "qcom,msm8996-cci", .data = &cci_v2_data},
{ .compatible = "qcom,sdm845-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); MODULE_DEVICE_TABLE(of, cci_dt_match);
......
...@@ -1013,7 +1013,6 @@ static const struct of_device_id rcar_i2c_dt_ids[] = { ...@@ -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-r8a7794", .data = (void *)I2C_RCAR_GEN2 },
{ .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 }, { .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 },
{ .compatible = "renesas,i2c-r8a7796", .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-gen1-i2c", .data = (void *)I2C_RCAR_GEN1 },
{ .compatible = "renesas,rcar-gen2-i2c", .data = (void *)I2C_RCAR_GEN2 }, { .compatible = "renesas,rcar-gen2-i2c", .data = (void *)I2C_RCAR_GEN2 },
{ .compatible = "renesas,rcar-gen3-i2c", .data = (void *)I2C_RCAR_GEN3 }, { .compatible = "renesas,rcar-gen3-i2c", .data = (void *)I2C_RCAR_GEN3 },
......
...@@ -42,8 +42,10 @@ ...@@ -42,8 +42,10 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/reset.h>
#define RIIC_ICCR1 0x00 #define RIIC_ICCR1 0x00
#define RIIC_ICCR2 0x04 #define RIIC_ICCR2 0x04
...@@ -86,6 +88,11 @@ ...@@ -86,6 +88,11 @@
#define RIIC_INIT_MSG -1 #define RIIC_INIT_MSG -1
enum riic_type {
RIIC_RZ_A,
RIIC_RZ_G2L,
};
struct riic_dev { struct riic_dev {
void __iomem *base; void __iomem *base;
u8 *buf; u8 *buf;
...@@ -395,7 +402,9 @@ static int riic_i2c_probe(struct platform_device *pdev) ...@@ -395,7 +402,9 @@ static int riic_i2c_probe(struct platform_device *pdev)
struct i2c_adapter *adap; struct i2c_adapter *adap;
struct resource *res; struct resource *res;
struct i2c_timings i2c_t; struct i2c_timings i2c_t;
struct reset_control *rstc;
int i, ret; int i, ret;
enum riic_type type;
riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL); riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL);
if (!riic) if (!riic)
...@@ -412,6 +421,17 @@ static int riic_i2c_probe(struct platform_device *pdev) ...@@ -412,6 +421,17 @@ static int riic_i2c_probe(struct platform_device *pdev)
return PTR_ERR(riic->clk); 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++) { for (i = 0; i < ARRAY_SIZE(riic_irqs); i++) {
res = platform_get_resource(pdev, IORESOURCE_IRQ, riic_irqs[i].res_num); res = platform_get_resource(pdev, IORESOURCE_IRQ, riic_irqs[i].res_num);
if (!res) if (!res)
...@@ -472,7 +492,8 @@ static int riic_i2c_remove(struct platform_device *pdev) ...@@ -472,7 +492,8 @@ static int riic_i2c_remove(struct platform_device *pdev)
} }
static const struct of_device_id riic_i2c_dt_ids[] = { 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 */ }, { /* Sentinel */ },
}; };
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
/* STM32F7 I2C control 1 */ /* STM32F7 I2C control 1 */
#define STM32F7_I2C_CR1_PECEN BIT(23) #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_SMBHEN BIT(20)
#define STM32F7_I2C_CR1_WUPEN BIT(18) #define STM32F7_I2C_CR1_WUPEN BIT(18)
#define STM32F7_I2C_CR1_SBC BIT(16) #define STM32F7_I2C_CR1_SBC BIT(16)
...@@ -125,6 +126,7 @@ ...@@ -125,6 +126,7 @@
(((n) & STM32F7_I2C_ISR_ADDCODE_MASK) >> 17) (((n) & STM32F7_I2C_ISR_ADDCODE_MASK) >> 17)
#define STM32F7_I2C_ISR_DIR BIT(16) #define STM32F7_I2C_ISR_DIR BIT(16)
#define STM32F7_I2C_ISR_BUSY BIT(15) #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_PECERR BIT(11)
#define STM32F7_I2C_ISR_ARLO BIT(9) #define STM32F7_I2C_ISR_ARLO BIT(9)
#define STM32F7_I2C_ISR_BERR BIT(8) #define STM32F7_I2C_ISR_BERR BIT(8)
...@@ -138,6 +140,7 @@ ...@@ -138,6 +140,7 @@
#define STM32F7_I2C_ISR_TXE BIT(0) #define STM32F7_I2C_ISR_TXE BIT(0)
/* STM32F7 I2C Interrupt Clear */ /* STM32F7 I2C Interrupt Clear */
#define STM32F7_I2C_ICR_ALERTCF BIT(13)
#define STM32F7_I2C_ICR_PECCF BIT(11) #define STM32F7_I2C_ICR_PECCF BIT(11)
#define STM32F7_I2C_ICR_ARLOCF BIT(9) #define STM32F7_I2C_ICR_ARLOCF BIT(9)
#define STM32F7_I2C_ICR_BERRCF BIT(8) #define STM32F7_I2C_ICR_BERRCF BIT(8)
...@@ -278,6 +281,17 @@ struct stm32f7_i2c_msg { ...@@ -278,6 +281,17 @@ struct stm32f7_i2c_msg {
u8 smbus_buf[I2C_SMBUS_BLOCK_MAX + 3] __aligned(4); 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 * struct stm32f7_i2c_dev - private data of the controller
* @adap: I2C adapter for this controller * @adap: I2C adapter for this controller
...@@ -310,6 +324,7 @@ struct stm32f7_i2c_msg { ...@@ -310,6 +324,7 @@ struct stm32f7_i2c_msg {
* @analog_filter: boolean to indicate enabling of the analog filter * @analog_filter: boolean to indicate enabling of the analog filter
* @dnf_dt: value of digital filter requested via dt * @dnf_dt: value of digital filter requested via dt
* @dnf: value of digital filter to apply * @dnf: value of digital filter to apply
* @alert: SMBus alert specific data
*/ */
struct stm32f7_i2c_dev { struct stm32f7_i2c_dev {
struct i2c_adapter adap; struct i2c_adapter adap;
...@@ -341,6 +356,7 @@ struct stm32f7_i2c_dev { ...@@ -341,6 +356,7 @@ struct stm32f7_i2c_dev {
bool analog_filter; bool analog_filter;
u32 dnf_dt; u32 dnf_dt;
u32 dnf; u32 dnf;
struct stm32f7_i2c_alert *alert;
}; };
/* /*
...@@ -1624,6 +1640,13 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data) ...@@ -1624,6 +1640,13 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
f7_msg->result = -EINVAL; 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) { if (!i2c_dev->slave_running) {
u32 mask; u32 mask;
/* Disable interrupts */ /* Disable interrupts */
...@@ -1990,6 +2013,42 @@ static void stm32f7_i2c_disable_smbus_host(struct stm32f7_i2c_dev *i2c_dev) ...@@ -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) static u32 stm32f7_i2c_func(struct i2c_adapter *adap)
{ {
struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(adap); struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
...@@ -2173,6 +2232,16 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) ...@@ -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); dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr);
pm_runtime_mark_last_busy(i2c_dev->dev); pm_runtime_mark_last_busy(i2c_dev->dev);
...@@ -2180,6 +2249,9 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) ...@@ -2180,6 +2249,9 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
return 0; return 0;
i2c_disable_smbus_host:
stm32f7_i2c_disable_smbus_host(i2c_dev);
i2c_adapter_remove: i2c_adapter_remove:
i2c_del_adapter(adap); i2c_del_adapter(adap);
...@@ -2214,6 +2286,7 @@ static int stm32f7_i2c_remove(struct platform_device *pdev) ...@@ -2214,6 +2286,7 @@ static int stm32f7_i2c_remove(struct platform_device *pdev)
{ {
struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(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); stm32f7_i2c_disable_smbus_host(i2c_dev);
i2c_del_adapter(&i2c_dev->adap); i2c_del_adapter(&i2c_dev->adap);
......
...@@ -798,11 +798,10 @@ static int xiic_i2c_probe(struct platform_device *pdev) ...@@ -798,11 +798,10 @@ static int xiic_i2c_probe(struct platform_device *pdev)
init_waitqueue_head(&i2c->wait); init_waitqueue_head(&i2c->wait);
i2c->clk = devm_clk_get(&pdev->dev, NULL); i2c->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(i2c->clk)) { if (IS_ERR(i2c->clk))
if (PTR_ERR(i2c->clk) != -EPROBE_DEFER) return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk),
dev_err(&pdev->dev, "input clock not found.\n"); "input clock not found.\n");
return PTR_ERR(i2c->clk);
}
ret = clk_prepare_enable(i2c->clk); ret = clk_prepare_enable(i2c->clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Unable to enable clock.\n"); dev_err(&pdev->dev, "Unable to enable clock.\n");
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/i2c-smbus.h> #include <linux/i2c-smbus.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irqflags.h> #include <linux/irqflags.h>
#include <linux/jump_label.h> #include <linux/jump_label.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -399,7 +400,8 @@ static int i2c_gpio_init_recovery(struct i2c_adapter *adap) ...@@ -399,7 +400,8 @@ static int i2c_gpio_init_recovery(struct i2c_adapter *adap)
static int i2c_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; 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) if (!bri)
return 0; return 0;
...@@ -409,7 +411,7 @@ static int i2c_init_recovery(struct i2c_adapter *adap) ...@@ -409,7 +411,7 @@ static int i2c_init_recovery(struct i2c_adapter *adap)
if (!bri->recover_bus) { if (!bri->recover_bus) {
err_str = "no suitable method provided"; err_str = "no suitable method provided";
err_level = KERN_DEBUG; is_error_level = false;
goto err; goto err;
} }
...@@ -436,7 +438,10 @@ static int i2c_init_recovery(struct i2c_adapter *adap) ...@@ -436,7 +438,10 @@ static int i2c_init_recovery(struct i2c_adapter *adap)
return 0; return 0;
err: 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; adap->bus_recovery_info = NULL;
return -EINVAL; return -EINVAL;
...@@ -461,12 +466,14 @@ static int i2c_smbus_host_notify_to_irq(const struct i2c_client *client) ...@@ -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) static int i2c_device_probe(struct device *dev)
{ {
struct i2c_client *client = i2c_verify_client(dev); struct i2c_client *client = i2c_verify_client(dev);
struct i2c_adapter *adap;
struct i2c_driver *driver; struct i2c_driver *driver;
int status; int status;
if (!client) if (!client)
return 0; return 0;
adap = client->adapter;
client->irq = client->init_irq; client->irq = client->init_irq;
if (!client->irq) { if (!client->irq) {
...@@ -532,6 +539,14 @@ static int i2c_device_probe(struct device *dev) ...@@ -532,6 +539,14 @@ static int i2c_device_probe(struct device *dev)
dev_dbg(dev, "probe\n"); 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); status = of_clk_set_defaults(dev->of_node, false);
if (status < 0) if (status < 0)
goto err_clear_wakeup_irq; goto err_clear_wakeup_irq;
...@@ -589,8 +604,10 @@ static int i2c_device_probe(struct device *dev) ...@@ -589,8 +604,10 @@ static int i2c_device_probe(struct device *dev)
static int i2c_device_remove(struct device *dev) static int i2c_device_remove(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct i2c_adapter *adap;
struct i2c_driver *driver; struct i2c_driver *driver;
adap = client->adapter;
driver = to_i2c_driver(dev->driver); driver = to_i2c_driver(dev->driver);
if (driver->remove) { if (driver->remove) {
int status; int status;
...@@ -605,6 +622,8 @@ static int i2c_device_remove(struct device *dev) ...@@ -605,6 +622,8 @@ static int i2c_device_remove(struct device *dev)
devres_release_group(&client->dev, client->devres_group_id); devres_release_group(&client->dev, client->devres_group_id);
dev_pm_domain_detach(&client->dev, true); 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); dev_pm_clear_wake_irq(&client->dev);
device_init_wakeup(&client->dev, false); device_init_wakeup(&client->dev, false);
...@@ -617,6 +636,86 @@ static int i2c_device_remove(struct device *dev) ...@@ -617,6 +636,86 @@ static int i2c_device_remove(struct device *dev)
return 0; 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) static void i2c_device_shutdown(struct device *dev)
{ {
struct i2c_client *client = i2c_verify_client(dev); struct i2c_client *client = i2c_verify_client(dev);
...@@ -627,6 +726,8 @@ static void i2c_device_shutdown(struct device *dev) ...@@ -627,6 +726,8 @@ static void i2c_device_shutdown(struct device *dev)
driver = to_i2c_driver(dev->driver); driver = to_i2c_driver(dev->driver);
if (driver->shutdown) if (driver->shutdown)
driver->shutdown(client); driver->shutdown(client);
else if (client->irq > 0)
disable_irq(client->irq);
} }
static void i2c_client_dev_release(struct device *dev) static void i2c_client_dev_release(struct device *dev)
...@@ -674,6 +775,7 @@ struct bus_type i2c_bus_type = { ...@@ -674,6 +775,7 @@ struct bus_type i2c_bus_type = {
.probe = i2c_device_probe, .probe = i2c_device_probe,
.remove = i2c_device_remove, .remove = i2c_device_remove,
.shutdown = i2c_device_shutdown, .shutdown = i2c_device_shutdown,
.pm = &i2c_device_pm,
}; };
EXPORT_SYMBOL_GPL(i2c_bus_type); EXPORT_SYMBOL_GPL(i2c_bus_type);
......
...@@ -37,8 +37,15 @@ static u8 crc8(u16 data) ...@@ -37,8 +37,15 @@ static u8 crc8(u16 data)
return (u8)(data >> 8); 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; int i;
...@@ -46,6 +53,7 @@ static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count) ...@@ -46,6 +53,7 @@ static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
crc = crc8((crc ^ p[i]) << 8); crc = crc8((crc ^ p[i]) << 8);
return crc; return crc;
} }
EXPORT_SYMBOL(i2c_smbus_pec);
/* Assume a 7-bit address, which is reasonable for SMBus */ /* Assume a 7-bit address, which is reasonable for SMBus */
static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg) static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg)
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/device.h> /* for struct device */ #include <linux/device.h> /* for struct device */
#include <linux/sched.h> /* for completion */ #include <linux/sched.h> /* for completion */
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/regulator/consumer.h>
#include <linux/rtmutex.h> #include <linux/rtmutex.h>
#include <linux/irqdomain.h> /* for Host Notify IRQ */ #include <linux/irqdomain.h> /* for Host Notify IRQ */
#include <linux/of.h> /* for struct device_node */ #include <linux/of.h> /* for struct device_node */
...@@ -147,6 +148,7 @@ s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, ...@@ -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 /* Now follow the 'nice' access routines. These also document the calling
conventions of i2c_smbus_xfer. */ 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_read_byte(const struct i2c_client *client);
s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value); 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); s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command);
...@@ -729,6 +731,7 @@ struct i2c_adapter { ...@@ -729,6 +731,7 @@ struct i2c_adapter {
const struct i2c_adapter_quirks *quirks; const struct i2c_adapter_quirks *quirks;
struct irq_domain *host_notify_domain; struct irq_domain *host_notify_domain;
struct regulator *bus_regulator;
}; };
#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment