Commit 80dc7593 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'i2c-for-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c updates from Wolfram Sang:

 - new drivers: Microchip CoreI2C, Renesas RZV2M

 - quite some DT schema conversions and extensions

 - and a bunch of driver updates and improvements

* tag 'i2c-for-5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (37 commits)
  i2c: extend documentation about retvals of master_xfer functions
  i2c: mux-gpmux: Add of_node_put() when breaking out of loop
  dt-bindings: i2c: i2c-rk3x: Document Rockchip RV1126
  i2c: qcom-geni: Use the correct return value
  i2c: cadence: Support PEC for SMBus block read
  i2c: qcom-geni: Propagate GENI_ABORT_DONE to geni_i2c_abort_xfer()
  i2c: brcmstb: Use dev_name() for adapter name
  i2c: Add Renesas RZ/V2M controller
  dt-bindings: i2c: Document RZ/V2M I2C controller
  i2c: mlxcpld: Add callback to notify probing completion
  i2c: scmi: Replace open coded device_get_match_data()
  i2c: stm32: add support for the STM32MP13 soc
  dt-bindings: i2c: st,stm32-i2c: add entry for stm32mp13
  dt-bindings: i2c: i2c-rk3x: add rk3588 compatible
  i2c: add support for microchip fpga i2c controllers
  i2c: i801: Add support for Intel Meteor Lake-P
  dt-bindings: i2c: nomadik: Add power domain to binding
  dt-bindings: i2c: nomadik: Drop unused voltage supply from example
  i2c: Fix a potential use after free
  i2c: hisi: use HZ_PER_KHZ macro in units.h
  ...
parents f86d1fbb a1182149
# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/arm,i2c-versatile.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: I2C Controller on ARM Ltd development platforms
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
properties:
compatible:
const: arm,versatile-i2c
reg:
maxItems: 1
required:
- compatible
- reg
unevaluatedProperties: false
...
I2C for Nomadik based systems
Required (non-standard) properties:
- Nil
Recommended (non-standard) properties:
- clock-frequency : Maximum bus clock frequency for the device
Optional (non-standard) properties:
- Nil
Example :
i2c@80004000 {
compatible = "stericsson,db8500-i2c", "st,nomadik-i2c";
reg = <0x80004000 0x1000>;
interrupts = <0 21 0x4>;
#address-cells = <1>;
#size-cells = <0>;
v-i2c-supply = <&db8500_vape_reg>;
clock-frequency = <400000>;
};
Device tree configuration for i2c-ocores
Required properties:
- compatible : "opencores,i2c-ocores"
"aeroflexgaisler,i2cmst"
"sifive,fu540-c000-i2c", "sifive,i2c0"
For Opencore based I2C IP block reimplemented in
FU540-C000 SoC.
"sifive,fu740-c000-i2c", "sifive,i2c0"
For Opencore based I2C IP block reimplemented in
FU740-C000 SoC.
Please refer to sifive-blocks-ip-versioning.txt for
additional details.
- reg : bus address start and address range size of device
- clocks : handle to the controller clock; see the note below.
Mutually exclusive with opencores,ip-clock-frequency
- opencores,ip-clock-frequency: frequency of the controller clock in Hz;
see the note below. Mutually exclusive with clocks
- #address-cells : should be <1>
- #size-cells : should be <0>
Optional properties:
- interrupts : interrupt number.
- clock-frequency : frequency of bus clock in Hz; see the note below.
Defaults to 100 KHz when the property is not specified
- reg-shift : device register offsets are shifted by this value
- reg-io-width : io register width in bytes (1, 2 or 4)
- regstep : deprecated, use reg-shift above
Note
clock-frequency property is meant to control the bus frequency for i2c bus
drivers, but it was incorrectly used to specify i2c controller input clock
frequency. So the following rules are set to fix this situation:
- if clock-frequency is present and neither opencores,ip-clock-frequency nor
clocks are, then clock-frequency specifies i2c controller clock frequency.
This is to keep backwards compatibility with setups using old DTB. i2c bus
frequency is fixed at 100 KHz.
- if clocks is present it specifies i2c controller clock. clock-frequency
property specifies i2c bus frequency.
- if opencores,ip-clock-frequency is present it specifies i2c controller
clock frequency. clock-frequency property specifies i2c bus frequency.
Examples:
i2c0: ocores@a0000000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "opencores,i2c-ocores";
reg = <0xa0000000 0x8>;
interrupts = <10>;
opencores,ip-clock-frequency = <20000000>;
reg-shift = <0>; /* 8 bit registers */
reg-io-width = <1>; /* 8 bit read/write */
dummy@60 {
compatible = "dummy";
reg = <0x60>;
};
};
or
i2c0: ocores@a0000000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "opencores,i2c-ocores";
reg = <0xa0000000 0x8>;
interrupts = <10>;
clocks = <&osc>;
clock-frequency = <400000>; /* i2c bus frequency 400 KHz */
reg-shift = <0>; /* 8 bit registers */
reg-io-width = <1>; /* 8 bit read/write */
dummy@60 {
compatible = "dummy";
reg = <0x60>;
};
};
......@@ -7,6 +7,7 @@ PROPERTIES:
Value type: <string>
Definition: must be one of:
"qcom,msm8916-cci"
"qcom,msm8974-cci"
"qcom,msm8996-cci"
"qcom,sdm845-cci"
"qcom,sm8250-cci"
......@@ -43,9 +44,9 @@ PROPERTIES:
SUBNODES:
The CCI provides I2C masters for one (msm8916) or two i2c busses (msm8996,
sdm845, sm8250 and sm8450), described as subdevices named "i2c-bus@0" and
"i2c-bus@1".
The CCI provides I2C masters for one (msm8916) or two i2c busses (msm8974,
msm8996, sdm845, sm8250 and sm8450), described as subdevices named "i2c-bus@0"
and "i2c-bus@1".
PROPERTIES:
......
......@@ -37,6 +37,8 @@ properties:
- rockchip,rk3308-i2c
- rockchip,rk3328-i2c
- rockchip,rk3568-i2c
- rockchip,rk3588-i2c
- rockchip,rv1126-i2c
- const: rockchip,rk3399-i2c
reg:
......
i2c Controller on ARM Versatile platform:
Required properties:
- compatible : Must be "arm,versatile-i2c";
- reg
- #address-cells = <1>;
- #size-cells = <0>;
Optional properties:
- Child nodes conforming to i2c bus binding
......@@ -7,17 +7,18 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: nuvoton NPCM7XX I2C Controller Device Tree Bindings
description: |
The NPCM750x includes sixteen I2C bus controllers. All Controllers support
both master and slave mode. Each controller can switch between master and slave
at run time (i.e. IPMB mode). Each controller has two 16 byte HW FIFO for TX and
RX.
I2C bus controllers of the NPCM series support both master and
slave mode. Each controller can switch between master and slave at run time
(i.e. IPMB mode). HW FIFO for TX and RX are supported.
maintainers:
- Tali Perry <tali.perry1@gmail.com>
properties:
compatible:
const: nuvoton,npcm750-i2c
enum:
- nuvoton,npcm750-i2c
- nuvoton,npcm845-i2c
reg:
maxItems: 1
......@@ -36,6 +37,10 @@ properties:
default: 100000
enum: [100000, 400000, 1000000]
nuvoton,sys-mgr:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of system manager register node.
required:
- compatible
- reg
......@@ -44,6 +49,15 @@ required:
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
- if:
properties:
compatible:
contains:
const: nuvoton,npcm845-i2c
then:
required:
- nuvoton,sys-mgr
unevaluatedProperties: false
......@@ -57,6 +71,7 @@ examples:
clock-frequency = <100000>;
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
compatible = "nuvoton,npcm750-i2c";
nuvoton,sys-mgr = <&gcr>;
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/opencores,i2c-ocores.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: OpenCores I2C controller
maintainers:
- Peter Korsgaard <peter@korsgaard.com>
- Andrew Lunn <andrew@lunn.ch>
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
properties:
compatible:
oneOf:
- items:
- enum:
- sifive,fu740-c000-i2c # Opencore based IP block FU740-C000 SoC
- sifive,fu540-c000-i2c # Opencore based IP block FU540-C000 SoC
- const: sifive,i2c0
- enum:
- opencores,i2c-ocores
- aeroflexgaisler,i2cmst
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
clock-frequency:
description: |
clock-frequency property is meant to control the bus frequency for i2c bus
drivers, but it was incorrectly used to specify i2c controller input clock
frequency. So the following rules are set to fix this situation:
- if clock-frequency is present and neither opencores,ip-clock-frequency nor
clocks are, then clock-frequency specifies i2c controller clock frequency.
This is to keep backwards compatibility with setups using old DTB. i2c bus
frequency is fixed at 100 KHz.
- if clocks is present it specifies i2c controller clock. clock-frequency
property specifies i2c bus frequency.
- if opencores,ip-clock-frequency is present it specifies i2c controller
clock frequency. clock-frequency property specifies i2c bus frequency.
default: 100000
reg-io-width:
description: |
io register width in bytes
enum: [1, 2, 4]
reg-shift:
description: |
device register offsets are shifted by this value
default: 0
regstep:
description: |
deprecated, use reg-shift above
deprecated: true
opencores,ip-clock-frequency:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Frequency of the controller clock in Hz. Mutually exclusive with clocks.
See the note above.
required:
- compatible
- reg
- "#address-cells"
- "#size-cells"
oneOf:
- required:
- opencores,ip-clock-frequency
- required:
- clocks
unevaluatedProperties: false
examples:
- |
i2c@a0000000 {
compatible = "opencores,i2c-ocores";
reg = <0xa0000000 0x8>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <10>;
opencores,ip-clock-frequency = <20000000>;
reg-shift = <0>; /* 8 bit registers */
reg-io-width = <1>; /* 8 bit read/write */
};
i2c@b0000000 {
compatible = "opencores,i2c-ocores";
reg = <0xa0000000 0x8>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <10>;
clocks = <&osc>;
clock-frequency = <400000>; /* i2c bus frequency 400 KHz */
reg-shift = <0>; /* 8 bit registers */
reg-io-width = <1>; /* 8 bit read/write */
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/renesas,rzv2m.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas RZ/V2M I2C Bus Interface
maintainers:
- Phil Edworthy <phil.edworthy@renesas.com>
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
properties:
compatible:
items:
- enum:
- renesas,i2c-r9a09g011 # RZ/V2M
- const: renesas,rzv2m-i2c
reg:
maxItems: 1
interrupts:
items:
- description: Data transmission/reception interrupt
- description: Status interrupt
interrupt-names:
items:
- const: tia
- const: tis
clock-frequency:
default: 100000
enum: [ 100000, 400000 ]
description:
Desired I2C bus clock frequency in Hz.
clocks:
maxItems: 1
power-domains:
maxItems: 1
resets:
maxItems: 1
required:
- compatible
- reg
- interrupts
- interrupt-names
- clocks
- power-domains
- resets
- '#address-cells'
- '#size-cells'
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/r9a09g011-cpg.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
i2c0: i2c@a4030000 {
compatible = "renesas,i2c-r9a09g011", "renesas,rzv2m-i2c";
reg = <0xa4030000 0x80>;
interrupts = <GIC_SPI 232 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 236 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "tia", "tis";
clocks = <&cpg CPG_MOD R9A09G011_IIC_PCLK0>;
resets = <&cpg R9A09G011_IIC_GPA_PRESETN>;
power-domains = <&cpg>;
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/st,nomadik-i2c.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ST Microelectronics Nomadik I2C Bindings
description: The Nomadik I2C host controller began its life in the ST
Microelectronics STn8800 SoC, and was then inherited into STn8810 and
STn8815. It was part of the prototype STn8500 which then became ST-Ericsson
DB8500 after the merge of these two companies wireless divisions.
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
# Need a custom select here or 'arm,primecell' will match on lots of nodes
select:
properties:
compatible:
contains:
enum:
- st,nomadik-i2c
required:
- compatible
properties:
compatible:
oneOf:
# The variant found in STn8815
- items:
- const: st,nomadik-i2c
- const: arm,primecell
# The variant found in DB8500
- items:
- const: stericsson,db8500-i2c
- const: st,nomadik-i2c
- const: arm,primecell
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 2
clock-names:
oneOf:
# Clock name in STn8815
- items:
- const: mclk
- const: apb_pclk
# Clock name in DB8500
- items:
- const: i2cclk
- const: apb_pclk
power-domains:
maxItems: 1
resets:
maxItems: 1
clock-frequency:
minimum: 1
maximum: 400000
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/reset/stericsson,db8500-prcc-reset.h>
#include <dt-bindings/arm/ux500_pm_domains.h>
i2c@80004000 {
compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
reg = <0x80004000 0x1000>;
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <400000>;
clocks = <&prcc_kclk 3 3>, <&prcc_pclk 3 3>;
clock-names = "i2cclk", "apb_pclk";
power-domains = <&pm_domains DOMAIN_VAPE>;
resets = <&prcc_reset DB8500_PRCC_3 DB8500_PRCC_3_RESET_I2C0>;
};
i2c@101f8000 {
compatible = "st,nomadik-i2c", "arm,primecell";
reg = <0x101f8000 0x1000>;
interrupt-parent = <&vica>;
interrupts = <20>;
clock-frequency = <100000>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&i2c0clk>, <&pclki2c0>;
clock-names = "mclk", "apb_pclk";
};
...
......@@ -17,6 +17,7 @@ allOf:
contains:
enum:
- st,stm32f7-i2c
- st,stm32mp13-i2c
- st,stm32mp15-i2c
then:
properties:
......@@ -45,6 +46,7 @@ properties:
enum:
- st,stm32f4-i2c
- st,stm32f7-i2c
- st,stm32mp13-i2c
- st,stm32mp15-i2c
reg:
......
......@@ -46,6 +46,7 @@ Supported adapters:
* Intel Emmitsburg (PCH)
* Intel Alder Lake (PCH)
* Intel Raptor Lake (PCH)
* Intel Meteor Lake (SOC)
Datasheets: Publicly available at the Intel website
......
......@@ -1525,7 +1525,7 @@ F: Documentation/devicetree/bindings/arm/arm,versatile.yaml
F: Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml
F: Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml
F: Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml
F: Documentation/devicetree/bindings/i2c/i2c-versatile.txt
F: Documentation/devicetree/bindings/i2c/arm,i2c-versatile.yaml
F: Documentation/devicetree/bindings/interrupt-controller/arm,versatile-fpga-irq.txt
F: Documentation/devicetree/bindings/mtd/mtd-physmap.yaml
F: arch/arm/boot/dts/arm-realview-*
......@@ -2424,7 +2424,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
F: Documentation/devicetree/bindings/arm/ste-*
F: Documentation/devicetree/bindings/arm/ux500.yaml
F: Documentation/devicetree/bindings/arm/ux500/
F: Documentation/devicetree/bindings/i2c/i2c-nomadik.txt
F: Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml
F: arch/arm/boot/dts/ste-*
F: arch/arm/mach-nomadik/
F: arch/arm/mach-ux500/
......@@ -15075,7 +15075,7 @@ M: Peter Korsgaard <peter@korsgaard.com>
M: Andrew Lunn <andrew@lunn.ch>
L: linux-i2c@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/i2c/i2c-ocores.txt
F: Documentation/devicetree/bindings/i2c/opencores,i2c-ocores.yaml
F: Documentation/i2c/busses/i2c-ocores.rst
F: drivers/i2c/busses/i2c-ocores.c
F: include/linux/platform_data/i2c-ocores.h
......
......@@ -156,6 +156,7 @@ config I2C_I801
Emmitsburg (PCH)
Alder Lake (PCH)
Raptor Lake (PCH)
Meteor Lake (SOC)
This driver can also be built as a module. If so, the module
will be called i2c-i801.
......@@ -781,6 +782,17 @@ config I2C_MESON
If you say yes to this option, support will be included for the
I2C interface on the Amlogic Meson family of SoCs.
config I2C_MICROCHIP_CORE
tristate "Microchip FPGA I2C controller"
depends on SOC_MICROCHIP_POLARFIRE || COMPILE_TEST
depends on OF
help
If you say yes to this option, support will be included for the
I2C interface on Microchip FPGAs.
This driver can also be built as a module. If so, the module will be
called i2c-microchip-core.
config I2C_MPC
tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
depends on PPC
......@@ -838,13 +850,13 @@ config I2C_NOMADIK
I2C interface from ST-Ericsson's Nomadik and Ux500 architectures,
as well as the STA2X11 PCIe I/O HUB.
config I2C_NPCM7XX
config I2C_NPCM
tristate "Nuvoton I2C Controller"
depends on ARCH_NPCM7XX || COMPILE_TEST
depends on ARCH_NPCM || COMPILE_TEST
help
If you say yes to this option, support will be included for the
Nuvoton I2C controller, which is available on the NPCM7xx BMC
controller.
Nuvoton I2C controller, which is available on the NPCM BMC
controllers.
Driver can also support slave mode (select I2C_SLAVE).
config I2C_OCORES
......@@ -984,6 +996,16 @@ config I2C_RK3X
This driver can also be built as a module. If so, the module will
be called i2c-rk3x.
config I2C_RZV2M
tristate "Renesas RZ/V2M adapter"
depends on ARCH_RENESAS || COMPILE_TEST
help
If you say yes to this option, support will be included for the
Renesas RZ/V2M I2C interface.
This driver can also be built as a module. If so, the module
will be called i2c-rzv2m.
config I2C_S3C2410
tristate "S3C/Exynos I2C Driver"
depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || \
......
......@@ -78,13 +78,14 @@ obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o
obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o
obj-$(CONFIG_I2C_LPC2K) += i2c-lpc2k.o
obj-$(CONFIG_I2C_MESON) += i2c-meson.o
obj-$(CONFIG_I2C_MICROCHIP_CORE) += i2c-microchip-corei2c.o
obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
obj-$(CONFIG_I2C_MT65XX) += i2c-mt65xx.o
obj-$(CONFIG_I2C_MT7621) += i2c-mt7621.o
obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
obj-$(CONFIG_I2C_MXS) += i2c-mxs.o
obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o
obj-$(CONFIG_I2C_NPCM7XX) += i2c-npcm7xx.o
obj-$(CONFIG_I2C_NPCM) += i2c-npcm7xx.o
obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
obj-$(CONFIG_I2C_OWL) += i2c-owl.o
......@@ -101,6 +102,7 @@ obj-$(CONFIG_I2C_QCOM_GENI) += i2c-qcom-geni.o
obj-$(CONFIG_I2C_QUP) += i2c-qup.o
obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
obj-$(CONFIG_I2C_RK3X) += i2c-rk3x.o
obj-$(CONFIG_I2C_RZV2M) += i2c-rzv2m.o
obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o
......
......@@ -684,9 +684,7 @@ static int brcmstb_i2c_probe(struct platform_device *pdev)
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
strlcpy(adap->name, "Broadcom STB : ", sizeof(adap->name));
if (int_name)
strlcat(adap->name, int_name, sizeof(adap->name));
strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
adap->algo = &brcmstb_i2c_algo;
adap->dev.parent = &pdev->dev;
adap->dev.of_node = pdev->dev.of_node;
......
......@@ -573,8 +573,13 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET);
ctrl_reg |= CDNS_I2C_CR_RW | CDNS_I2C_CR_CLR_FIFO;
/*
* Receive up to I2C_SMBUS_BLOCK_MAX data bytes, plus one message length
* byte, plus one checksum byte if PEC is enabled. p_msg->len will be 2 if
* PEC is enabled, otherwise 1.
*/
if (id->p_msg->flags & I2C_M_RECV_LEN)
id->recv_count = I2C_SMBUS_BLOCK_MAX + 1;
id->recv_count = I2C_SMBUS_BLOCK_MAX + id->p_msg->len;
id->curr_recv_count = id->recv_count;
......@@ -789,6 +794,9 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg,
if (id->err_status & CDNS_I2C_IXR_ARB_LOST)
return -EAGAIN;
if (msg->flags & I2C_M_RECV_LEN)
msg->len += min_t(unsigned int, msg->buf[0], I2C_SMBUS_BLOCK_MAX);
return 0;
}
......
......@@ -15,6 +15,7 @@
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/units.h>
#define HISI_I2C_FRAME_CTRL 0x0000
#define HISI_I2C_FRAME_CTRL_SPEED_MODE GENMASK(1, 0)
......@@ -80,8 +81,6 @@
#define HISI_I2C_TX_F_AE_THRESH 1
#define HISI_I2C_RX_F_AF_THRESH 60
#define HZ_PER_KHZ 1000
#define NSEC_TO_CYCLES(ns, clk_rate_khz) \
DIV_ROUND_UP_ULL((clk_rate_khz) * (ns), NSEC_PER_MSEC)
......
......@@ -76,6 +76,7 @@
* Alder Lake-P (PCH) 0x51a3 32 hard yes yes yes
* Alder Lake-M (PCH) 0x54a3 32 hard yes yes yes
* Raptor Lake-S (PCH) 0x7a23 32 hard yes yes yes
* Meteor Lake-P (SOC) 0x7e22 32 hard yes yes yes
*
* Features supported by this driver:
* Software PEC no
......@@ -231,6 +232,7 @@
#define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4
#define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS 0x7a23
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3
#define PCI_DEVICE_ID_INTEL_METEOR_LAKE_P_SMBUS 0x7e22
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22
#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_SMBUS 0x8ca2
#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS 0x8d22
......@@ -1049,6 +1051,7 @@ static const struct pci_device_id i801_ids[] = {
{ PCI_DEVICE_DATA(INTEL, ALDER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, ALDER_LAKE_M_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, RAPTOR_LAKE_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, METEOR_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ 0, }
};
......
This diff is collapsed.
......@@ -560,6 +560,10 @@ static int mlxcpld_i2c_probe(struct platform_device *pdev)
if (err)
goto mlxcpld_i2_probe_failed;
/* Notify caller when adapter is added. */
if (pdata && pdata->completion_notify)
pdata->completion_notify(pdata->handle, mlxcpld_i2c_adapter.nr);
return 0;
mlxcpld_i2_probe_failed:
......
......@@ -150,6 +150,7 @@ struct mv64xxx_i2c_data {
/* Clk div is 2 to the power n, not 2 to the power n + 1 */
bool clk_n_base_0;
struct i2c_bus_recovery_info rinfo;
bool atomic;
};
static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
......@@ -179,7 +180,10 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
u32 dir = 0;
drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;
MV64XXX_I2C_REG_CONTROL_TWSIEN;
if (!drv_data->atomic)
drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_INTEN;
if (msg->flags & I2C_M_RD)
dir = 1;
......@@ -409,7 +413,8 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
case MV64XXX_I2C_ACTION_RCV_DATA_STOP:
drv_data->msg->buf[drv_data->byte_posn++] =
readl(drv_data->reg_base + drv_data->reg_offsets.data);
drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
if (!drv_data->atomic)
drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
drv_data->reg_base + drv_data->reg_offsets.control);
drv_data->block = 0;
......@@ -427,7 +432,8 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
drv_data->rc = -EIO;
fallthrough;
case MV64XXX_I2C_ACTION_SEND_STOP:
drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
if (!drv_data->atomic)
drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
drv_data->reg_base + drv_data->reg_offsets.control);
drv_data->block = 0;
......@@ -575,6 +581,17 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
spin_unlock_irqrestore(&drv_data->lock, flags);
}
static void mv64xxx_i2c_wait_polling(struct mv64xxx_i2c_data *drv_data)
{
ktime_t timeout = ktime_add_ms(ktime_get(), drv_data->adapter.timeout);
while (READ_ONCE(drv_data->block) &&
ktime_compare(ktime_get(), timeout) < 0) {
udelay(5);
mv64xxx_i2c_intr(0, drv_data);
}
}
static int
mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
int is_last)
......@@ -590,7 +607,11 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
mv64xxx_i2c_send_start(drv_data);
spin_unlock_irqrestore(&drv_data->lock, flags);
mv64xxx_i2c_wait_for_completion(drv_data);
if (!drv_data->atomic)
mv64xxx_i2c_wait_for_completion(drv_data);
else
mv64xxx_i2c_wait_polling(drv_data);
return drv_data->rc;
}
......@@ -717,7 +738,7 @@ mv64xxx_i2c_functionality(struct i2c_adapter *adap)
}
static int
mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
mv64xxx_i2c_xfer_core(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
int rc, ret = num;
......@@ -730,7 +751,7 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
drv_data->msgs = msgs;
drv_data->num_msgs = num;
if (mv64xxx_i2c_can_offload(drv_data))
if (mv64xxx_i2c_can_offload(drv_data) && !drv_data->atomic)
rc = mv64xxx_i2c_offload_xfer(drv_data);
else
rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[0], num == 1);
......@@ -747,8 +768,27 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
return ret;
}
static int
mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
drv_data->atomic = 0;
return mv64xxx_i2c_xfer_core(adap, msgs, num);
}
static int mv64xxx_i2c_xfer_atomic(struct i2c_adapter *adap,
struct i2c_msg msgs[], int num)
{
struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
drv_data->atomic = 1;
return mv64xxx_i2c_xfer_core(adap, msgs, num);
}
static const struct i2c_algorithm mv64xxx_i2c_algo = {
.master_xfer = mv64xxx_i2c_xfer,
.master_xfer_atomic = mv64xxx_i2c_xfer_atomic,
.functionality = mv64xxx_i2c_functionality,
};
......@@ -1047,14 +1087,6 @@ mv64xxx_i2c_remove(struct platform_device *pd)
return 0;
}
static void
mv64xxx_i2c_shutdown(struct platform_device *pd)
{
pm_runtime_disable(&pd->dev);
if (!pm_runtime_status_suspended(&pd->dev))
mv64xxx_i2c_runtime_suspend(&pd->dev);
}
static const struct dev_pm_ops mv64xxx_i2c_pm_ops = {
SET_RUNTIME_PM_OPS(mv64xxx_i2c_runtime_suspend,
mv64xxx_i2c_runtime_resume, NULL)
......@@ -1065,7 +1097,6 @@ static const struct dev_pm_ops mv64xxx_i2c_pm_ops = {
static struct platform_driver mv64xxx_i2c_driver = {
.probe = mv64xxx_i2c_probe,
.remove = mv64xxx_i2c_remove,
.shutdown = mv64xxx_i2c_shutdown,
.driver = {
.name = MV64XXX_I2C_CTLR_NAME,
.pm = &mv64xxx_i2c_pm_ops,
......
......@@ -799,7 +799,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
if (!i2c)
return -ENOMEM;
i2c->dev_type = (enum mxs_i2c_devtype)of_device_get_match_data(&pdev->dev);
i2c->dev_type = (uintptr_t)of_device_get_match_data(&pdev->dev);
i2c->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->regs))
......
This diff is collapsed.
......@@ -541,6 +541,7 @@ static int cci_probe(struct platform_device *pdev)
return -ENOENT;
for_each_available_child_of_node(dev->of_node, child) {
struct cci_master *master;
u32 idx;
ret = of_property_read_u32(child, "reg", &idx);
......@@ -555,27 +556,27 @@ static int cci_probe(struct platform_device *pdev)
continue;
}
cci->master[idx].adap.quirks = &cci->data->quirks;
cci->master[idx].adap.algo = &cci_algo;
cci->master[idx].adap.dev.parent = dev;
cci->master[idx].adap.dev.of_node = of_node_get(child);
cci->master[idx].master = idx;
cci->master[idx].cci = cci;
master = &cci->master[idx];
master->adap.quirks = &cci->data->quirks;
master->adap.algo = &cci_algo;
master->adap.dev.parent = dev;
master->adap.dev.of_node = of_node_get(child);
master->master = idx;
master->cci = cci;
i2c_set_adapdata(&cci->master[idx].adap, &cci->master[idx]);
snprintf(cci->master[idx].adap.name,
sizeof(cci->master[idx].adap.name), "Qualcomm-CCI");
i2c_set_adapdata(&master->adap, master);
snprintf(master->adap.name, sizeof(master->adap.name), "Qualcomm-CCI");
cci->master[idx].mode = I2C_MODE_STANDARD;
master->mode = I2C_MODE_STANDARD;
ret = of_property_read_u32(child, "clock-frequency", &val);
if (!ret) {
if (val == I2C_MAX_FAST_MODE_FREQ)
cci->master[idx].mode = I2C_MODE_FAST;
master->mode = I2C_MODE_FAST;
else if (val == I2C_MAX_FAST_MODE_PLUS_FREQ)
cci->master[idx].mode = I2C_MODE_FAST_PLUS;
master->mode = I2C_MODE_FAST_PLUS;
}
init_completion(&cci->master[idx].irq_complete);
init_completion(&master->irq_complete);
}
/* Memory */
......@@ -725,6 +726,40 @@ static const struct cci_data cci_v1_data = {
},
};
static const struct cci_data cci_v1_5_data = {
.num_masters = 2,
.queue_size = { 64, 16 },
.quirks = {
.max_write_len = 10,
.max_read_len = 12,
},
.cci_clk_rate = 19200000,
.params[I2C_MODE_STANDARD] = {
.thigh = 78,
.tlow = 114,
.tsu_sto = 28,
.tsu_sta = 28,
.thd_dat = 10,
.thd_sta = 77,
.tbuf = 118,
.scl_stretch_en = 0,
.trdhld = 6,
.tsp = 1
},
.params[I2C_MODE_FAST] = {
.thigh = 20,
.tlow = 28,
.tsu_sto = 21,
.tsu_sta = 21,
.thd_dat = 13,
.thd_sta = 18,
.tbuf = 32,
.scl_stretch_en = 0,
.trdhld = 6,
.tsp = 3
},
};
static const struct cci_data cci_v2_data = {
.num_masters = 2,
.queue_size = { 64, 16 },
......@@ -773,6 +808,7 @@ static const struct cci_data cci_v2_data = {
static const struct of_device_id cci_dt_match[] = {
{ .compatible = "qcom,msm8916-cci", .data = &cci_v1_data},
{ .compatible = "qcom,msm8974-cci", .data = &cci_v1_5_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},
......
......@@ -97,6 +97,7 @@ struct geni_i2c_dev {
struct dma_chan *tx_c;
struct dma_chan *rx_c;
bool gpi_mode;
bool abort_done;
};
struct geni_i2c_err_log {
......@@ -203,9 +204,18 @@ static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err)
dev_dbg(gi2c->se.dev, "len:%d, slv-addr:0x%x, RD/WR:%d\n",
gi2c->cur->len, gi2c->cur->addr, gi2c->cur->flags);
if (err != NACK && err != GENI_ABORT_DONE) {
switch (err) {
case GENI_ABORT_DONE:
gi2c->abort_done = true;
break;
case NACK:
case GENI_TIMEOUT:
dev_dbg(gi2c->se.dev, "%s\n", gi2c_log[err].msg);
break;
default:
dev_err(gi2c->se.dev, "%s\n", gi2c_log[err].msg);
geni_i2c_err_misc(gi2c);
break;
}
}
......@@ -311,21 +321,21 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)
static void geni_i2c_abort_xfer(struct geni_i2c_dev *gi2c)
{
u32 val;
unsigned long time_left = ABORT_TIMEOUT;
unsigned long flags;
spin_lock_irqsave(&gi2c->lock, flags);
geni_i2c_err(gi2c, GENI_TIMEOUT);
gi2c->cur = NULL;
gi2c->abort_done = false;
geni_se_abort_m_cmd(&gi2c->se);
spin_unlock_irqrestore(&gi2c->lock, flags);
do {
time_left = wait_for_completion_timeout(&gi2c->done, time_left);
val = readl_relaxed(gi2c->se.base + SE_GENI_M_IRQ_STATUS);
} while (!(val & M_CMD_ABORT_EN) && time_left);
} while (!gi2c->abort_done && time_left);
if (!(val & M_CMD_ABORT_EN))
if (!time_left)
dev_err(gi2c->se.dev, "Timeout abort_m_cmd\n");
}
......@@ -688,7 +698,7 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
pm_runtime_put_autosuspend(gi2c->se.dev);
gi2c->cur = NULL;
gi2c->err = 0;
return num;
return ret;
}
static u32 geni_i2c_func(struct i2c_adapter *adap)
......
This diff is collapsed.
......@@ -30,7 +30,7 @@ struct acpi_smbus_cmi {
u8 cap_info:1;
u8 cap_read:1;
u8 cap_write:1;
struct smbus_methods_t *methods;
const struct smbus_methods_t *methods;
};
static const struct smbus_methods_t smbus_methods = {
......@@ -361,7 +361,6 @@ static acpi_status acpi_smbus_cmi_query_methods(acpi_handle handle, u32 level,
static int acpi_smbus_cmi_add(struct acpi_device *device)
{
struct acpi_smbus_cmi *smbus_cmi;
const struct acpi_device_id *id;
int ret;
smbus_cmi = kzalloc(sizeof(struct acpi_smbus_cmi), GFP_KERNEL);
......@@ -369,6 +368,7 @@ static int acpi_smbus_cmi_add(struct acpi_device *device)
return -ENOMEM;
smbus_cmi->handle = device->handle;
smbus_cmi->methods = device_get_match_data(&device->dev);
strcpy(acpi_device_name(device), ACPI_SMBUS_HC_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_SMBUS_HC_CLASS);
device->driver_data = smbus_cmi;
......@@ -376,11 +376,6 @@ static int acpi_smbus_cmi_add(struct acpi_device *device)
smbus_cmi->cap_read = 0;
smbus_cmi->cap_write = 0;
for (id = acpi_smbus_cmi_ids; id->id[0]; id++)
if (!strcmp(id->id, acpi_device_hid(device)))
smbus_cmi->methods =
(struct smbus_methods_t *) id->driver_data;
acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1,
acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL);
......
......@@ -410,6 +410,12 @@ static const struct stm32f7_i2c_setup stm32mp15_setup = {
.fmp_clr_offset = 0x40,
};
static const struct stm32f7_i2c_setup stm32mp13_setup = {
.rise_time = STM32F7_I2C_RISE_TIME_DEFAULT,
.fall_time = STM32F7_I2C_FALL_TIME_DEFAULT,
.fmp_clr_offset = 0x4,
};
static inline void stm32f7_i2c_set_bits(void __iomem *reg, u32 mask)
{
writel_relaxed(readl_relaxed(reg) | mask, reg);
......@@ -2468,6 +2474,7 @@ static const struct dev_pm_ops stm32f7_i2c_pm_ops = {
static const struct of_device_id stm32f7_i2c_match[] = {
{ .compatible = "st,stm32f7-i2c", .data = &stm32f7_setup},
{ .compatible = "st,stm32mp15-i2c", .data = &stm32mp15_setup},
{ .compatible = "st,stm32mp13-i2c", .data = &stm32mp13_setup},
{},
};
MODULE_DEVICE_TABLE(of, stm32f7_i2c_match);
......
......@@ -367,7 +367,7 @@ static void xiic_fill_tx_fifo(struct xiic_i2c *i2c)
}
}
static void xiic_wakeup(struct xiic_i2c *i2c, int code)
static void xiic_wakeup(struct xiic_i2c *i2c, enum xilinx_i2c_state code)
{
i2c->tx_msg = NULL;
i2c->rx_msg = NULL;
......@@ -383,7 +383,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
u32 clr = 0;
int xfer_more = 0;
int wakeup_req = 0;
int wakeup_code = 0;
enum xilinx_i2c_state wakeup_code = STATE_DONE;
int ret;
/* Get the interrupt Status from the IPIF. There is no clearing of
......
......@@ -1023,15 +1023,9 @@ static int dummy_probe(struct i2c_client *client,
return 0;
}
static int dummy_remove(struct i2c_client *client)
{
return 0;
}
static struct i2c_driver dummy_driver = {
.driver.name = "dummy",
.probe = dummy_probe,
.remove = dummy_remove,
.id_table = dummy_id,
};
......@@ -2467,8 +2461,9 @@ void i2c_put_adapter(struct i2c_adapter *adap)
if (!adap)
return;
put_device(&adap->dev);
module_put(adap->owner);
/* Should be last, otherwise we risk use-after-free with 'adap' */
put_device(&adap->dev);
}
EXPORT_SYMBOL(i2c_put_adapter);
......
......@@ -134,6 +134,7 @@ static int i2c_mux_probe(struct platform_device *pdev)
return 0;
err_children:
of_node_put(child);
i2c_mux_del_adapters(muxc);
err_parent:
i2c_put_adapter(parent);
......
......@@ -537,7 +537,8 @@ i2c_register_board_info(int busnum, struct i2c_board_info const *info,
*
* The return codes from the ``master_xfer{_atomic}`` fields should indicate the
* type of error code that occurred during the transfer, as documented in the
* Kernel Documentation file Documentation/i2c/fault-codes.rst.
* Kernel Documentation file Documentation/i2c/fault-codes.rst. Otherwise, the
* number of messages executed should be returned.
*/
struct i2c_algorithm {
/*
......
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