aboutsummaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/Kconfig2
-rw-r--r--drivers/i2c/busses/Kconfig53
-rw-r--r--drivers/i2c/busses/Makefile3
-rw-r--r--drivers/i2c/busses/i2c-ali1535.c8
-rw-r--r--drivers/i2c/busses/i2c-ali1563.c2
-rw-r--r--drivers/i2c/busses/i2c-ali15x3.c6
-rw-r--r--drivers/i2c/busses/i2c-altera.c4
-rw-r--r--drivers/i2c/busses/i2c-amd-mp2-plat.c8
-rw-r--r--drivers/i2c/busses/i2c-at91-master.c1
-rw-r--r--drivers/i2c/busses/i2c-at91-slave.c3
-rw-r--r--drivers/i2c/busses/i2c-au1550.c15
-rw-r--r--drivers/i2c/busses/i2c-bcm-iproc.c2
-rw-r--r--drivers/i2c/busses/i2c-bcm-kona.c13
-rw-r--r--drivers/i2c/busses/i2c-bcm2835.c11
-rw-r--r--drivers/i2c/busses/i2c-brcmstb.c11
-rw-r--r--drivers/i2c/busses/i2c-cadence.c3
-rw-r--r--drivers/i2c/busses/i2c-ccgx-ucsi.c1
-rw-r--r--drivers/i2c/busses/i2c-cht-wc.c8
-rw-r--r--drivers/i2c/busses/i2c-cp2615.c10
-rw-r--r--drivers/i2c/busses/i2c-cpm.c4
-rw-r--r--drivers/i2c/busses/i2c-cros-ec-tunnel.c4
-rw-r--r--drivers/i2c/busses/i2c-davinci.c18
-rw-r--r--drivers/i2c/busses/i2c-designware-pcidrv.c2
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c11
-rw-r--r--drivers/i2c/busses/i2c-designware-slave.c2
-rw-r--r--drivers/i2c/busses/i2c-digicolor.c12
-rw-r--r--drivers/i2c/busses/i2c-diolan-u2c.c2
-rw-r--r--drivers/i2c/busses/i2c-dln2.c4
-rw-r--r--drivers/i2c/busses/i2c-exynos5.c12
-rw-r--r--drivers/i2c/busses/i2c-fsi.c56
-rw-r--r--drivers/i2c/busses/i2c-gpio.c8
-rw-r--r--drivers/i2c/busses/i2c-highlander.c2
-rw-r--r--drivers/i2c/busses/i2c-hisi.c8
-rw-r--r--drivers/i2c/busses/i2c-hix5hd2.c14
-rw-r--r--drivers/i2c/busses/i2c-i801.c56
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c27
-rw-r--r--drivers/i2c/busses/i2c-img-scb.c5
-rw-r--r--drivers/i2c/busses/i2c-imx-lpi2c.c25
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c15
-rw-r--r--drivers/i2c/busses/i2c-isch.c2
-rw-r--r--drivers/i2c/busses/i2c-ismt.c1
-rw-r--r--drivers/i2c/busses/i2c-jz4780.c26
-rw-r--r--drivers/i2c/busses/i2c-kempld.c4
-rw-r--r--drivers/i2c/busses/i2c-ljca.c20
-rw-r--r--drivers/i2c/busses/i2c-lpc2k.c10
-rw-r--r--drivers/i2c/busses/i2c-ls2x.c11
-rw-r--r--drivers/i2c/busses/i2c-mlxcpld.c14
-rw-r--r--drivers/i2c/busses/i2c-mpc.c15
-rw-r--r--drivers/i2c/busses/i2c-mt7621.c26
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c12
-rw-r--r--drivers/i2c/busses/i2c-nomadik.c8
-rw-r--r--drivers/i2c/busses/i2c-nvidia-gpu.c7
-rw-r--r--drivers/i2c/busses/i2c-ocores.c31
-rw-r--r--drivers/i2c/busses/i2c-octeon-core.c147
-rw-r--r--drivers/i2c/busses/i2c-octeon-core.h57
-rw-r--r--drivers/i2c/busses/i2c-octeon-platdrv.c2
-rw-r--r--drivers/i2c/busses/i2c-omap.c47
-rw-r--r--drivers/i2c/busses/i2c-opal.c10
-rw-r--r--drivers/i2c/busses/i2c-owl.c12
-rw-r--r--drivers/i2c/busses/i2c-parport.c1
-rw-r--r--drivers/i2c/busses/i2c-pasemi-core.c6
-rw-r--r--drivers/i2c/busses/i2c-piix4.c11
-rw-r--r--drivers/i2c/busses/i2c-pnx.c48
-rw-r--r--drivers/i2c/busses/i2c-powermac.c14
-rw-r--r--drivers/i2c/busses/i2c-pxa-pci.c2
-rw-r--r--drivers/i2c/busses/i2c-pxa.c15
-rw-r--r--drivers/i2c/busses/i2c-qcom-geni.c10
-rw-r--r--drivers/i2c/busses/i2c-qup.c5
-rw-r--r--drivers/i2c/busses/i2c-rcar.c40
-rw-r--r--drivers/i2c/busses/i2c-riic.c133
-rw-r--r--drivers/i2c/busses/i2c-rk3x.c34
-rw-r--r--drivers/i2c/busses/i2c-robotfuzz-osif.c4
-rw-r--r--drivers/i2c/busses/i2c-rzv2m.c12
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c6
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c1
-rw-r--r--drivers/i2c/busses/i2c-sis5595.c2
-rw-r--r--drivers/i2c/busses/i2c-sprd.c16
-rw-r--r--drivers/i2c/busses/i2c-st.c19
-rw-r--r--drivers/i2c/busses/i2c-stm32f4.c16
-rw-r--r--drivers/i2c/busses/i2c-stm32f7.c8
-rw-r--r--drivers/i2c/busses/i2c-sun6i-p2wi.c20
-rw-r--r--drivers/i2c/busses/i2c-synquacer.c27
-rw-r--r--drivers/i2c/busses/i2c-taos-evm.c2
-rw-r--r--drivers/i2c/busses/i2c-tegra-bpmp.c4
-rw-r--r--drivers/i2c/busses/i2c-tegra.c2
-rw-r--r--drivers/i2c/busses/i2c-thunderx-pcidrv.c15
-rw-r--r--drivers/i2c/busses/i2c-tiny-usb.c6
-rw-r--r--drivers/i2c/busses/i2c-uniphier-f.c27
-rw-r--r--drivers/i2c/busses/i2c-uniphier.c19
-rw-r--r--drivers/i2c/busses/i2c-viai2c-common.c203
-rw-r--r--drivers/i2c/busses/i2c-viai2c-common.h85
-rw-r--r--drivers/i2c/busses/i2c-viai2c-wmt.c184
-rw-r--r--drivers/i2c/busses/i2c-viai2c-zhaoxin.c367
-rw-r--r--drivers/i2c/busses/i2c-viperboard.c11
-rw-r--r--drivers/i2c/busses/i2c-virtio.c2
-rw-r--r--drivers/i2c/busses/i2c-wmt.c421
-rw-r--r--drivers/i2c/busses/i2c-xiic.c9
-rw-r--r--drivers/i2c/i2c-core-acpi.c19
-rw-r--r--drivers/i2c/i2c-core-base.c5
-rw-r--r--drivers/i2c/i2c-dev.c12
-rw-r--r--drivers/i2c/i2c-mux.c24
-rw-r--r--drivers/i2c/i2c-slave-testunit.c14
-rw-r--r--drivers/i2c/i2c-smbus.c23
-rw-r--r--drivers/i2c/muxes/i2c-arb-gpio-challenge.c2
-rw-r--r--drivers/i2c/muxes/i2c-mux-gpio.c17
-rw-r--r--drivers/i2c/muxes/i2c-mux-gpmux.c2
-rw-r--r--drivers/i2c/muxes/i2c-mux-ltc4306.c2
-rw-r--r--drivers/i2c/muxes/i2c-mux-mlxcpld.c2
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca9541.c4
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca954x.c2
-rw-r--r--drivers/i2c/muxes/i2c-mux-pinctrl.c2
-rw-r--r--drivers/i2c/muxes/i2c-mux-reg.c2
112 files changed, 1719 insertions, 1133 deletions
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 9388823bb0bb..44710267d669 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -135,7 +135,7 @@ config I2C_SLAVE_EEPROM
Documentation/i2c/slave-eeprom-backend.rst for further details.
config I2C_SLAVE_TESTUNIT
- tristate "I2C eeprom testunit driver"
+ tristate "I2C testunit driver"
help
This backend can be used to trigger test cases for I2C bus masters
which require a remote device with certain capabilities, e.g.
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 97989c914260..a22f9125322a 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -18,7 +18,7 @@ config I2C_CCGX_UCSI
config I2C_ALI1535
tristate "ALI 1535"
- depends on PCI
+ depends on PCI && HAS_IOPORT
help
If you say yes to this option, support will be included for the SMB
Host controller on Acer Labs Inc. (ALI) M1535 South Bridges. The SMB
@@ -30,7 +30,7 @@ config I2C_ALI1535
config I2C_ALI1563
tristate "ALI 1563"
- depends on PCI
+ depends on PCI && HAS_IOPORT
help
If you say yes to this option, support will be included for the SMB
Host controller on Acer Labs Inc. (ALI) M1563 South Bridges. The SMB
@@ -42,7 +42,7 @@ config I2C_ALI1563
config I2C_ALI15X3
tristate "ALI 15x3"
- depends on PCI
+ depends on PCI && HAS_IOPORT
help
If you say yes to this option, support will be included for the
Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces.
@@ -52,7 +52,7 @@ config I2C_ALI15X3
config I2C_AMD756
tristate "AMD 756/766/768/8111 and nVidia nForce"
- depends on PCI
+ depends on PCI && HAS_IOPORT
help
If you say yes to this option, support will be included for the AMD
756/766/768 mainboard I2C interfaces. The driver also includes
@@ -77,7 +77,7 @@ config I2C_AMD756_S4882
config I2C_AMD8111
tristate "AMD 8111"
- depends on PCI
+ depends on PCI && HAS_IOPORT
help
If you say yes to this option, support will be included for the
second (SMBus 2.0) AMD 8111 mainboard I2C interface.
@@ -107,7 +107,7 @@ config I2C_HIX5HD2
config I2C_I801
tristate "Intel 82801 (ICH/PCH)"
- depends on PCI
+ depends on PCI && HAS_IOPORT
select P2SB if X86
select CHECK_SIGNATURE if X86 && DMI
select I2C_SMBUS
@@ -159,13 +159,22 @@ config I2C_I801
Raptor Lake (PCH)
Meteor Lake (SOC and PCH)
Birch Stream (SOC)
+ Arrow Lake (SOC)
This driver can also be built as a module. If so, the module
will be called i2c-i801.
+config I2C_I801_MUX
+ def_bool I2C_I801
+ depends on DMI && I2C_MUX_GPIO
+ depends on !(I2C_I801=y && I2C_MUX=m)
+ help
+ Optional support for multiplexed SMBUS on certain systems with
+ more than 8 memory slots.
+
config I2C_ISCH
tristate "Intel SCH SMBus 1.0"
- depends on PCI
+ depends on PCI && HAS_IOPORT
select LPC_SCH
help
Say Y here if you want to use SMBus controller on the Intel SCH
@@ -186,7 +195,8 @@ config I2C_ISMT
config I2C_PIIX4
tristate "Intel PIIX4 and compatible (ATI/AMD/Serverworks/Broadcom/SMSC)"
- depends on PCI
+ depends on PCI && HAS_IOPORT
+ select I2C_SMBUS
help
If you say yes to this option, support will be included for the Intel
PIIX4 family of mainboard I2C interfaces. Specifically, the following
@@ -232,7 +242,7 @@ config I2C_CHT_WC
config I2C_NFORCE2
tristate "Nvidia nForce2, nForce3 and nForce4"
- depends on PCI
+ depends on PCI && HAS_IOPORT
help
If you say yes to this option, support will be included for the Nvidia
nForce2, nForce3 and nForce4 families of mainboard I2C interfaces.
@@ -265,7 +275,7 @@ config I2C_NVIDIA_GPU
config I2C_SIS5595
tristate "SiS 5595"
- depends on PCI
+ depends on PCI && HAS_IOPORT
help
If you say yes to this option, support will be included for the
SiS5595 SMBus (a subset of I2C) interface.
@@ -275,7 +285,7 @@ config I2C_SIS5595
config I2C_SIS630
tristate "SiS 630/730/964"
- depends on PCI
+ depends on PCI && HAS_IOPORT
help
If you say yes to this option, support will be included for the
SiS630, SiS730 and SiS964 SMBus (a subset of I2C) interface.
@@ -285,7 +295,7 @@ config I2C_SIS630
config I2C_SIS96X
tristate "SiS 96x"
- depends on PCI
+ depends on PCI && HAS_IOPORT
help
If you say yes to this option, support will be included for the SiS
96x SMBus (a subset of I2C) interfaces. Specifically, the following
@@ -303,7 +313,7 @@ config I2C_SIS96X
config I2C_VIA
tristate "VIA VT82C586B"
- depends on PCI
+ depends on PCI && HAS_IOPORT
select I2C_ALGOBIT
help
If you say yes to this option, support will be included for the VIA
@@ -314,7 +324,7 @@ config I2C_VIA
config I2C_VIAPRO
tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx/VX900"
- depends on PCI
+ depends on PCI && HAS_IOPORT
help
If you say yes to this option, support will be included for the VIA
VT82C596 and later SMBus interface. Specifically, the following
@@ -336,6 +346,16 @@ config I2C_VIAPRO
if ACPI
+config I2C_ZHAOXIN
+ tristate "Zhaoxin I2C Interface"
+ depends on PCI || COMPILE_TEST
+ help
+ If you say yes to this option, support will be included for the
+ ZHAOXIN I2C interface
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-zhaoxin.
+
comment "ACPI drivers"
config I2C_SCMI
@@ -500,7 +520,7 @@ config I2C_BRCMSTB
config I2C_CADENCE
tristate "Cadence I2C Controller"
- depends on ARCH_ZYNQ || ARM64 || XTENSA || COMPILE_TEST
+ depends on ARCH_ZYNQ || ARM64 || XTENSA || RISCV || COMPILE_TEST
help
Say yes here to select Cadence I2C Host Controller. This controller is
e.g. used by Xilinx Zynq.
@@ -839,7 +859,7 @@ config I2C_MT65XX
config I2C_MT7621
tristate "MT7621/MT7628 I2C Controller"
- depends on (RALINK && (SOC_MT7620 || SOC_MT7621)) || COMPILE_TEST
+ depends on (RALINK && (SOC_MT7620 || SOC_MT7621)) || ARCH_AIROHA || COMPILE_TEST
help
Say Y here to include support for I2C controller in the
MediaTek MT7621/MT7628 SoCs.
@@ -1397,6 +1417,7 @@ config I2C_ICY
config I2C_MLXCPLD
tristate "Mellanox I2C driver"
depends on X86_64 || (ARM64 && ACPI) || COMPILE_TEST
+ depends on HAS_IOPORT
help
This exposes the Mellanox platform I2C busses to the linux I2C layer
for X86 and ARM64/ACPI based systems.
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index aa0ee8ecd6f2..78d0561339e5 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o
obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o
obj-$(CONFIG_I2C_VIA) += i2c-via.o
obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
+obj-$(CONFIG_I2C_ZHAOXIN) += i2c-viai2c-zhaoxin.o i2c-viai2c-common.o
# Mac SMBus host controller drivers
obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
@@ -118,7 +119,7 @@ obj-$(CONFIG_I2C_TEGRA_BPMP) += i2c-tegra-bpmp.o
obj-$(CONFIG_I2C_UNIPHIER) += i2c-uniphier.o
obj-$(CONFIG_I2C_UNIPHIER_F) += i2c-uniphier-f.o
obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
-obj-$(CONFIG_I2C_WMT) += i2c-wmt.o
+obj-$(CONFIG_I2C_WMT) += i2c-viai2c-wmt.o i2c-viai2c-common.o
i2c-octeon-objs := i2c-octeon-core.o i2c-octeon-platdrv.o
obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o
i2c-thunderx-objs := i2c-octeon-core.o i2c-thunderx-pcidrv.o
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
index 461eb23f9d47..9d7b4efe26ad 100644
--- a/drivers/i2c/busses/i2c-ali1535.c
+++ b/drivers/i2c/busses/i2c-ali1535.c
@@ -285,10 +285,8 @@ static int ali1535_transaction(struct i2c_adapter *adap)
&& (timeout++ < MAX_TIMEOUT));
/* If the SMBus is still busy, we give up */
- if (timeout > MAX_TIMEOUT) {
+ if (timeout > MAX_TIMEOUT)
result = -ETIMEDOUT;
- dev_err(&adap->dev, "SMBus Timeout!\n");
- }
if (temp & ALI1535_STS_FAIL) {
result = -EIO;
@@ -313,10 +311,8 @@ static int ali1535_transaction(struct i2c_adapter *adap)
}
/* check to see if the "command complete" indication is set */
- if (!(temp & ALI1535_STS_DONE)) {
+ if (!(temp & ALI1535_STS_DONE))
result = -ETIMEDOUT;
- dev_err(&adap->dev, "Error: command never completed\n");
- }
dev_dbg(&adap->dev, "Transaction (post): STS=%02x, TYP=%02x, "
"CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
index 307fb0666ecb..ee4fd66dedb0 100644
--- a/drivers/i2c/busses/i2c-ali1563.c
+++ b/drivers/i2c/busses/i2c-ali1563.c
@@ -99,7 +99,6 @@ static int ali1563_transaction(struct i2c_adapter *a, int size)
return 0;
if (!timeout) {
- dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n");
/* Issue 'kill' to host controller */
outb_p(HST_CNTL2_KILL, SMB_HST_CNTL2);
data = inb_p(SMB_HST_STS);
@@ -439,4 +438,5 @@ static struct pci_driver ali1563_pci_driver = {
module_pci_driver(ali1563_pci_driver);
+MODULE_DESCRIPTION("i2c driver for the ALi 1563 Southbridge");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
index d2fa30deb054..4761c7208102 100644
--- a/drivers/i2c/busses/i2c-ali15x3.c
+++ b/drivers/i2c/busses/i2c-ali15x3.c
@@ -39,7 +39,7 @@
We make sure that the SMB is enabled. We leave the ACPI alone.
This driver controls the SMB Host only.
- The SMB Slave controller on the M15X3 is not enabled.
+ The SMB Target controller on the M15X3 is not enabled.
This driver does not use interrupts.
*/
@@ -294,10 +294,8 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
&& (timeout++ < MAX_TIMEOUT));
/* If the SMBus is still busy, we give up */
- if (timeout > MAX_TIMEOUT) {
+ if (timeout > MAX_TIMEOUT)
result = -ETIMEDOUT;
- dev_err(&adap->dev, "SMBus Timeout!\n");
- }
if (temp & ALI15X3_STS_TERM) {
result = -EIO;
diff --git a/drivers/i2c/busses/i2c-altera.c b/drivers/i2c/busses/i2c-altera.c
index 252fbd175fb1..f4dde08a3b92 100644
--- a/drivers/i2c/busses/i2c-altera.c
+++ b/drivers/i2c/busses/i2c-altera.c
@@ -168,7 +168,7 @@ static void altr_i2c_init(struct altr_i2c_dev *idev)
/* SDA Hold Time, 300ns */
writel(3 * clk_mhz / 10, idev->base + ALTR_I2C_SDA_HOLD);
- /* Mask all master interrupt bits */
+ /* Mask all interrupt bits */
altr_i2c_int_enable(idev, ALTR_I2C_ALL_IRQ, false);
}
@@ -376,7 +376,7 @@ static u32 altr_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm altr_i2c_algo = {
- .master_xfer = altr_i2c_xfer,
+ .xfer = altr_i2c_xfer,
.functionality = altr_i2c_func,
};
diff --git a/drivers/i2c/busses/i2c-amd-mp2-plat.c b/drivers/i2c/busses/i2c-amd-mp2-plat.c
index 112fe2bc5662..d3ac1c77a509 100644
--- a/drivers/i2c/busses/i2c-amd-mp2-plat.c
+++ b/drivers/i2c/busses/i2c-amd-mp2-plat.c
@@ -97,17 +97,17 @@ static void i2c_amd_cmd_completion(struct amd_i2c_common *i2c_common)
static int i2c_amd_check_cmd_completion(struct amd_i2c_dev *i2c_dev)
{
struct amd_i2c_common *i2c_common = &i2c_dev->common;
- unsigned long timeout;
+ unsigned long time_left;
- timeout = wait_for_completion_timeout(&i2c_dev->cmd_complete,
- i2c_dev->adap.timeout);
+ time_left = wait_for_completion_timeout(&i2c_dev->cmd_complete,
+ i2c_dev->adap.timeout);
if ((i2c_common->reqcmd == i2c_read ||
i2c_common->reqcmd == i2c_write) &&
i2c_common->msg->len > 32)
i2c_amd_dma_unmap(i2c_common);
- if (timeout == 0) {
+ if (time_left == 0) {
amd_mp2_rw_timeout(i2c_common);
return -ETIMEDOUT;
}
diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c
index d311981d3e60..ee3b469ddfb9 100644
--- a/drivers/i2c/busses/i2c-at91-master.c
+++ b/drivers/i2c/busses/i2c-at91-master.c
@@ -591,7 +591,6 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
dev->adapter.timeout);
if (time_left == 0) {
dev->transfer_status |= at91_twi_read(dev, AT91_TWI_SR);
- dev_err(dev->dev, "controller timed out\n");
at91_init_twi_bus(dev);
ret = -ETIMEDOUT;
goto error;
diff --git a/drivers/i2c/busses/i2c-at91-slave.c b/drivers/i2c/busses/i2c-at91-slave.c
index d6eeea5166c0..131a67d9d4a6 100644
--- a/drivers/i2c/busses/i2c-at91-slave.c
+++ b/drivers/i2c/busses/i2c-at91-slave.c
@@ -106,8 +106,7 @@ static int at91_unreg_slave(struct i2c_client *slave)
static u32 at91_twi_func(struct i2c_adapter *adapter)
{
- return I2C_FUNC_SLAVE | I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
- | I2C_FUNC_SMBUS_READ_BLOCK_DATA;
+ return I2C_FUNC_SLAVE;
}
static const struct i2c_algorithm at91_twi_algorithm_slave = {
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
index 8e43f25c117e..902e420e761e 100644
--- a/drivers/i2c/busses/i2c-au1550.c
+++ b/drivers/i2c/busses/i2c-au1550.c
@@ -81,11 +81,10 @@ static int wait_ack(struct i2c_au1550_data *adap)
return 0;
}
-static int wait_master_done(struct i2c_au1550_data *adap)
+static int wait_controller_done(struct i2c_au1550_data *adap)
{
int i;
- /* Wait for Master Done. */
for (i = 0; i < 2 * adap->xfer_timeout; i++) {
if ((RD(adap, PSC_SMBEVNT) & PSC_SMBEVNT_MD) != 0)
return 0;
@@ -120,12 +119,12 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q)
if (q)
addr |= PSC_SMBTXRX_STP;
- /* Put byte into fifo, start up master. */
+ /* Put byte into fifo, start up controller */
WR(adap, PSC_SMBTXRX, addr);
WR(adap, PSC_SMBPCR, PSC_SMBPCR_MS);
if (wait_ack(adap))
return -EIO;
- return (q) ? wait_master_done(adap) : 0;
+ return (q) ? wait_controller_done(adap) : 0;
}
static int wait_for_rx_byte(struct i2c_au1550_data *adap, unsigned char *out)
@@ -175,7 +174,7 @@ static int i2c_read(struct i2c_au1550_data *adap, unsigned char *buf,
/* The last byte has to indicate transfer done. */
WR(adap, PSC_SMBTXRX, PSC_SMBTXRX_STP);
- if (wait_master_done(adap))
+ if (wait_controller_done(adap))
return -EIO;
buf[i] = (unsigned char)(RD(adap, PSC_SMBTXRX) & 0xff);
@@ -204,7 +203,7 @@ static int i2c_write(struct i2c_au1550_data *adap, unsigned char *buf,
data = buf[i];
data |= PSC_SMBTXRX_STP;
WR(adap, PSC_SMBTXRX, data);
- if (wait_master_done(adap))
+ if (wait_controller_done(adap))
return -EIO;
return 0;
}
@@ -246,8 +245,8 @@ static u32 au1550_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm au1550_algo = {
- .master_xfer = au1550_xfer,
- .functionality = au1550_func,
+ .xfer = au1550_xfer,
+ .functionality = au1550_func,
};
static void i2c_au1550_setup(struct i2c_au1550_data *priv)
diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c
index e905734c26a0..133d02899c6b 100644
--- a/drivers/i2c/busses/i2c-bcm-iproc.c
+++ b/drivers/i2c/busses/i2c-bcm-iproc.c
@@ -811,8 +811,6 @@ static int bcm_iproc_i2c_xfer_wait(struct bcm_iproc_i2c_dev *iproc_i2c,
}
if (!time_left && !iproc_i2c->xfer_is_done) {
- dev_err(iproc_i2c->device, "transaction timed out\n");
-
/* flush both TX/RX FIFOs */
val = BIT(M_FIFO_RX_FLUSH_SHIFT) | BIT(M_FIFO_TX_FLUSH_SHIFT);
iproc_i2c_wr_reg(iproc_i2c, M_FIFO_CTRL_OFFSET, val);
diff --git a/drivers/i2c/busses/i2c-bcm-kona.c b/drivers/i2c/busses/i2c-bcm-kona.c
index a57088ec2b06..eb5c46a8f824 100644
--- a/drivers/i2c/busses/i2c-bcm-kona.c
+++ b/drivers/i2c/busses/i2c-bcm-kona.c
@@ -85,7 +85,7 @@
#define STD_EXT_CLK_FREQ 13000000UL
#define HS_EXT_CLK_FREQ 104000000UL
-#define MASTERCODE 0x08 /* Mastercodes are 0000_1xxxb */
+#define CONTROLLER_CODE 0x08 /* Controller codes are 0000_1xxxb */
#define I2C_TIMEOUT 100 /* msecs */
@@ -544,8 +544,8 @@ static int bcm_kona_i2c_switch_to_hs(struct bcm_kona_i2c_dev *dev)
{
int rc;
- /* Send mastercode at standard speed */
- rc = bcm_kona_i2c_write_byte(dev, MASTERCODE, 1);
+ /* Send controller code at standard speed */
+ rc = bcm_kona_i2c_write_byte(dev, CONTROLLER_CODE, 1);
if (rc < 0) {
pr_err("High speed handshake failed\n");
return rc;
@@ -587,7 +587,6 @@ static int bcm_kona_i2c_switch_to_std(struct bcm_kona_i2c_dev *dev)
return rc;
}
-/* Master transfer function */
static int bcm_kona_i2c_xfer(struct i2c_adapter *adapter,
struct i2c_msg msgs[], int num)
{
@@ -637,7 +636,7 @@ static int bcm_kona_i2c_xfer(struct i2c_adapter *adapter,
}
}
- /* Send slave address */
+ /* Send target address */
if (!(pmsg->flags & I2C_M_NOSTART)) {
rc = bcm_kona_i2c_do_addr(dev, pmsg);
if (rc < 0) {
@@ -697,7 +696,7 @@ static uint32_t bcm_kona_i2c_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm bcm_algo = {
- .master_xfer = bcm_kona_i2c_xfer,
+ .xfer = bcm_kona_i2c_xfer,
.functionality = bcm_kona_i2c_functionality,
};
@@ -722,7 +721,7 @@ static int bcm_kona_i2c_assign_bus_speed(struct bcm_kona_i2c_dev *dev)
dev->std_cfg = &std_cfg_table[BCM_SPD_1MHZ];
break;
case I2C_MAX_HIGH_SPEED_MODE_FREQ:
- /* Send mastercode at 100k */
+ /* Send controller code at 100k */
dev->std_cfg = &std_cfg_table[BCM_SPD_100K];
dev->hs_cfg = &hs_cfg_table[BCM_SPD_3P4MHZ];
break;
diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
index b92de1944221..ae42e37052a8 100644
--- a/drivers/i2c/busses/i2c-bcm2835.c
+++ b/drivers/i2c/busses/i2c-bcm2835.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * BCM2835 master mode driver
+ * BCM2835 I2C controller driver
*/
#include <linux/clk.h>
@@ -25,7 +25,7 @@
#define BCM2835_I2C_DEL 0x18
/*
* 16-bit field for the number of SCL cycles to wait after rising SCL
- * before deciding the slave is not responding. 0 disables the
+ * before deciding the target is not responding. 0 disables the
* timeout detection.
*/
#define BCM2835_I2C_CLKT 0x1c
@@ -223,7 +223,7 @@ static void bcm2835_drain_rxfifo(struct bcm2835_i2c_dev *i2c_dev)
/*
* Repeated Start Condition (Sr)
* The BCM2835 ARM Peripherals datasheet mentions a way to trigger a Sr when it
- * talks about reading from a slave with 10 bit address. This is achieved by
+ * talks about reading from a target with 10 bit address. This is achieved by
* issuing a write, poll the I2CS.TA flag and wait for it to be set, and then
* issue a read.
* A comment in https://github.com/raspberrypi/linux/issues/254 shows how the
@@ -370,7 +370,6 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
if (!time_left) {
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C,
BCM2835_I2C_C_CLEAR);
- dev_err(i2c_dev->dev, "i2c transfer timed out\n");
return -ETIMEDOUT;
}
@@ -391,8 +390,8 @@ static u32 bcm2835_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm bcm2835_i2c_algo = {
- .master_xfer = bcm2835_i2c_xfer,
- .functionality = bcm2835_i2c_func,
+ .xfer = bcm2835_i2c_xfer,
+ .functionality = bcm2835_i2c_func,
};
/*
diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c
index 38f276c99193..83b85011e377 100644
--- a/drivers/i2c/busses/i2c-brcmstb.c
+++ b/drivers/i2c/busses/i2c-brcmstb.c
@@ -67,7 +67,7 @@
/* BSC block register map structure to cache fields to be written */
struct bsc_regs {
- u32 chip_address; /* slave address */
+ u32 chip_address; /* target address */
u32 data_in[N_DATA_REGS]; /* tx data buffer*/
u32 cnt_reg; /* rx/tx data length */
u32 ctl_reg; /* control register */
@@ -320,7 +320,7 @@ cmd_out:
return rc;
}
-/* Actual data transfer through the BSC master */
+/* Actual data transfer through the BSC controller */
static int brcmstb_i2c_xfer_bsc_data(struct brcmstb_i2c_dev *dev,
u8 *buf, unsigned int len,
struct i2c_msg *pmsg)
@@ -441,7 +441,6 @@ static int brcmstb_i2c_do_addr(struct brcmstb_i2c_dev *dev,
return 0;
}
-/* Master transfer function */
static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,
struct i2c_msg msgs[], int num)
{
@@ -473,7 +472,7 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,
brcmstb_set_i2c_start_stop(dev, cond);
- /* Send slave address */
+ /* Send target address */
if (!(pmsg->flags & I2C_M_NOSTART)) {
rc = brcmstb_i2c_do_addr(dev, pmsg);
if (rc < 0) {
@@ -545,8 +544,8 @@ static u32 brcmstb_i2c_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm brcmstb_i2c_algo = {
- .master_xfer = brcmstb_i2c_xfer,
- .master_xfer_atomic = brcmstb_i2c_xfer_atomic,
+ .xfer = brcmstb_i2c_xfer,
+ .xfer_atomic = brcmstb_i2c_xfer_atomic,
.functionality = brcmstb_i2c_functionality,
};
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
index 4bb7d6756947..87b9ba95b2e1 100644
--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -633,6 +633,7 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
if (hold_clear) {
ctrl_reg &= ~CDNS_I2C_CR_HOLD;
+ ctrl_reg &= ~CDNS_I2C_CR_CLR_FIFO;
/*
* In case of Xilinx Zynq SOC, clear the HOLD bit before transfer size
* register reaches '0'. This is an IP bug which causes transfer size
@@ -789,8 +790,6 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg,
time_left = wait_for_completion_timeout(&id->xfer_done, msg_timeout);
if (time_left == 0) {
cdns_i2c_master_reset(adap);
- dev_err(id->adap.dev.parent,
- "timeout waiting on completion\n");
return -ETIMEDOUT;
}
diff --git a/drivers/i2c/busses/i2c-ccgx-ucsi.c b/drivers/i2c/busses/i2c-ccgx-ucsi.c
index 092dc92dea9f..d97233862a6c 100644
--- a/drivers/i2c/busses/i2c-ccgx-ucsi.c
+++ b/drivers/i2c/busses/i2c-ccgx-ucsi.c
@@ -27,4 +27,5 @@ struct i2c_client *i2c_new_ccgx_ucsi(struct i2c_adapter *adapter, int irq,
}
EXPORT_SYMBOL_GPL(i2c_new_ccgx_ucsi);
+MODULE_DESCRIPTION("Instantiate UCSI device for Cypress CCGx Type-C controller");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c
index 0209933b9a84..52e3000626c5 100644
--- a/drivers/i2c/busses/i2c-cht-wc.c
+++ b/drivers/i2c/busses/i2c-cht-wc.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Intel CHT Whiskey Cove PMIC I2C Master driver
+ * Intel CHT Whiskey Cove PMIC I2C controller driver
* Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
*
* Based on various non upstream patches to support the CHT Whiskey Cove PMIC:
@@ -106,7 +106,7 @@ static irqreturn_t cht_wc_i2c_adap_thread_handler(int id, void *data)
return IRQ_HANDLED;
}
-static u32 cht_wc_i2c_adap_master_func(struct i2c_adapter *adap)
+static u32 cht_wc_i2c_adap_func(struct i2c_adapter *adap)
{
/* This i2c adapter only supports SMBUS byte transfers */
return I2C_FUNC_SMBUS_BYTE_DATA;
@@ -168,7 +168,7 @@ static int cht_wc_i2c_adap_smbus_xfer(struct i2c_adapter *_adap, u16 addr,
}
static const struct i2c_algorithm cht_wc_i2c_adap_algo = {
- .functionality = cht_wc_i2c_adap_master_func,
+ .functionality = cht_wc_i2c_adap_func,
.smbus_xfer = cht_wc_i2c_adap_smbus_xfer,
};
@@ -554,6 +554,6 @@ static struct platform_driver cht_wc_i2c_adap_driver = {
};
module_platform_driver(cht_wc_i2c_adap_driver);
-MODULE_DESCRIPTION("Intel CHT Whiskey Cove PMIC I2C Master driver");
+MODULE_DESCRIPTION("Intel CHT Whiskey Cove PMIC I2C controller driver");
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-cp2615.c b/drivers/i2c/busses/i2c-cp2615.c
index cf3747d87034..e7720ea4045e 100644
--- a/drivers/i2c/busses/i2c-cp2615.c
+++ b/drivers/i2c/busses/i2c-cp2615.c
@@ -60,11 +60,11 @@ enum cp2615_i2c_status {
CP2615_CFG_LOCKED = -6,
/* read_len or write_len out of range */
CP2615_INVALID_PARAM = -4,
- /* I2C slave did not ACK in time */
+ /* I2C target did not ACK in time */
CP2615_TIMEOUT,
/* I2C bus busy */
CP2615_BUS_BUSY,
- /* I2C bus error (ie. device NAK'd the request) */
+ /* I2C bus error (ie. target NAK'd the request) */
CP2615_BUS_ERROR,
CP2615_SUCCESS
};
@@ -211,7 +211,7 @@ out:
}
static int
-cp2615_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+cp2615_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
struct usb_interface *usbif = adap->algo_data;
int i = 0, ret = 0;
@@ -250,8 +250,8 @@ cp2615_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm cp2615_i2c_algo = {
- .master_xfer = cp2615_i2c_master_xfer,
- .functionality = cp2615_i2c_func,
+ .xfer = cp2615_i2c_xfer,
+ .functionality = cp2615_i2c_func,
};
/*
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
index 4404b4aac676..4794ec066eb0 100644
--- a/drivers/i2c/busses/i2c-cpm.c
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -402,7 +402,7 @@ static u32 cpm_i2c_func(struct i2c_adapter *adap)
/* -----exported algorithm data: ------------------------------------- */
static const struct i2c_algorithm cpm_i2c_algo = {
- .master_xfer = cpm_i2c_xfer,
+ .xfer = cpm_i2c_xfer,
.functionality = cpm_i2c_func,
};
@@ -570,7 +570,7 @@ static int cpm_i2c_setup(struct cpm_i2c *cpm)
out_8(&cpm->i2c_reg->i2brg, brg);
out_8(&cpm->i2c_reg->i2mod, 0x00);
- out_8(&cpm->i2c_reg->i2com, I2COM_MASTER); /* Master mode */
+ out_8(&cpm->i2c_reg->i2com, I2COM_MASTER);
/* Disable interrupts. */
out_8(&cpm->i2c_reg->i2cmr, 0);
diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c
index 2737fd8abd32..ab2688bd4d33 100644
--- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c
+++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c
@@ -235,8 +235,8 @@ static u32 ec_i2c_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm ec_i2c_algorithm = {
- .master_xfer = ec_i2c_xfer,
- .functionality = ec_i2c_functionality,
+ .xfer = ec_i2c_xfer,
+ .functionality = ec_i2c_functionality,
};
static int ec_i2c_probe(struct platform_device *pdev)
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 02b3b1160fb0..c4fb5e9ab506 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -263,7 +263,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
/* compute clock dividers */
i2c_davinci_calc_clk_dividers(dev);
- /* Respond at reserved "SMBus Host" slave address" (and zero);
+ /* Respond at reserved "SMBus Host" target address" (and zero);
* we seem to have no option to not respond...
*/
davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, DAVINCI_I2C_OWN_ADDRESS);
@@ -407,8 +407,8 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev)
}
/*
- * Low level master read/write transaction. This function is called
- * from i2c_davinci_xfer.
+ * Low level read/write transaction. This function is called from
+ * i2c_davinci_xfer.
*/
static int
i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
@@ -428,7 +428,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
if (pdata->bus_delay)
udelay(pdata->bus_delay);
- /* set the slave address */
+ /* set the target address */
davinci_i2c_write_reg(dev, DAVINCI_I2C_SAR_REG, msg->addr);
dev->buf = msg->buf;
@@ -440,10 +440,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
reinit_completion(&dev->cmd_complete);
dev->cmd_err = 0;
- /* Take I2C out of reset and configure it as master */
+ /* Take I2C out of reset and configure it as controller */
flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST;
- /* if the slave address is ten bit address, enable XA bit */
if (msg->flags & I2C_M_TEN)
flag |= DAVINCI_I2C_MDR_XA;
if (!(msg->flags & I2C_M_RD))
@@ -489,7 +488,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
time_left = wait_for_completion_timeout(&dev->cmd_complete,
dev->adapter.timeout);
if (!time_left) {
- dev_err(dev->dev, "controller timed out\n");
i2c_recover_bus(adap);
dev->buf_len = 0;
return -ETIMEDOUT;
@@ -688,7 +686,7 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
break;
case DAVINCI_I2C_IVR_AAS:
- dev_dbg(dev->dev, "Address as slave interrupt\n");
+ dev_dbg(dev->dev, "Address as target interrupt\n");
break;
default:
@@ -745,8 +743,8 @@ static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev)
#endif
static const struct i2c_algorithm i2c_davinci_algo = {
- .master_xfer = i2c_davinci_xfer,
- .functionality = i2c_davinci_func,
+ .xfer = i2c_davinci_xfer,
+ .functionality = i2c_davinci_func,
};
static const struct of_device_id davinci_i2c_of_match[] = {
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
index 9be9a2658e1f..a1b379a1e904 100644
--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
@@ -424,8 +424,6 @@ static struct pci_driver dw_i2c_driver = {
};
module_pci_driver(dw_i2c_driver);
-/* Work with hotplug and coldplug */
-MODULE_ALIAS("i2c_designware-pci");
MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
MODULE_DESCRIPTION("Synopsys DesignWare PCI I2C bus adapter");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 4ab41ba39d55..df3dc1e8093e 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -46,6 +46,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "INT33C3", 0 },
{ "INT3432", 0 },
{ "INT3433", 0 },
+ { "INTC10EF", 0 },
{ "80860F41", ACCESS_NO_IRQ_SUSPEND },
{ "808622C1", ACCESS_NO_IRQ_SUSPEND },
{ "AMD0010", ACCESS_INTR_MASK },
@@ -100,7 +101,7 @@ static int bt1_i2c_write(void *context, unsigned int reg, unsigned int val)
BT1_I2C_CTL_GO | BT1_I2C_CTL_WR | (reg & BT1_I2C_CTL_ADDR_MASK));
}
-static struct regmap_config bt1_i2c_cfg = {
+static const struct regmap_config bt1_i2c_cfg = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
@@ -479,8 +480,11 @@ static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend, dw_i2c_plat_runtime_resume, NULL)
};
-/* Work with hotplug and coldplug */
-MODULE_ALIAS("platform:i2c_designware");
+static const struct platform_device_id dw_i2c_platform_ids[] = {
+ { "i2c_designware" },
+ {}
+};
+MODULE_DEVICE_TABLE(platform, dw_i2c_platform_ids);
static struct platform_driver dw_i2c_driver = {
.probe = dw_i2c_plat_probe,
@@ -491,6 +495,7 @@ static struct platform_driver dw_i2c_driver = {
.acpi_match_table = ACPI_PTR(dw_i2c_acpi_match),
.pm = pm_ptr(&dw_i2c_dev_pm_ops),
},
+ .id_table = dw_i2c_platform_ids,
};
static int __init dw_i2c_init_driver(void)
diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c
index 2e079cf20bb5..78e2c47e3d7d 100644
--- a/drivers/i2c/busses/i2c-designware-slave.c
+++ b/drivers/i2c/busses/i2c-designware-slave.c
@@ -220,7 +220,7 @@ static const struct i2c_algorithm i2c_dw_algo = {
void i2c_dw_configure_slave(struct dw_i2c_dev *dev)
{
- dev->functionality = I2C_FUNC_SLAVE | DW_IC_DEFAULT_FUNCTIONALITY;
+ dev->functionality = I2C_FUNC_SLAVE;
dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL |
DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED;
diff --git a/drivers/i2c/busses/i2c-digicolor.c b/drivers/i2c/busses/i2c-digicolor.c
index 3462f2bc0fa8..3e6b80e59b90 100644
--- a/drivers/i2c/busses/i2c-digicolor.c
+++ b/drivers/i2c/busses/i2c-digicolor.c
@@ -213,7 +213,7 @@ out:
static int dc_i2c_xfer_msg(struct dc_i2c *i2c, struct i2c_msg *msg, int first,
int last)
{
- unsigned long timeout = msecs_to_jiffies(TIMEOUT_MS);
+ unsigned long time_left = msecs_to_jiffies(TIMEOUT_MS);
unsigned long flags;
spin_lock_irqsave(&i2c->lock, flags);
@@ -227,9 +227,9 @@ static int dc_i2c_xfer_msg(struct dc_i2c *i2c, struct i2c_msg *msg, int first,
dc_i2c_start_msg(i2c, first);
spin_unlock_irqrestore(&i2c->lock, flags);
- timeout = wait_for_completion_timeout(&i2c->done, timeout);
+ time_left = wait_for_completion_timeout(&i2c->done, time_left);
dc_i2c_set_irq(i2c, 0);
- if (timeout == 0) {
+ if (time_left == 0) {
i2c->state = STATE_IDLE;
return -ETIMEDOUT;
}
@@ -281,8 +281,8 @@ static u32 dc_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm dc_i2c_algorithm = {
- .master_xfer = dc_i2c_xfer,
- .functionality = dc_i2c_func,
+ .xfer = dc_i2c_xfer,
+ .functionality = dc_i2c_func,
};
static int dc_i2c_probe(struct platform_device *pdev)
@@ -372,5 +372,5 @@ static struct platform_driver dc_i2c_driver = {
module_platform_driver(dc_i2c_driver);
MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
-MODULE_DESCRIPTION("Conexant Digicolor I2C master driver");
+MODULE_DESCRIPTION("Conexant Digicolor I2C controller driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/i2c/busses/i2c-diolan-u2c.c b/drivers/i2c/busses/i2c-diolan-u2c.c
index b48b7888936f..c02459405b26 100644
--- a/drivers/i2c/busses/i2c-diolan-u2c.c
+++ b/drivers/i2c/busses/i2c-diolan-u2c.c
@@ -414,7 +414,7 @@ static u32 diolan_usb_func(struct i2c_adapter *a)
}
static const struct i2c_algorithm diolan_usb_algorithm = {
- .master_xfer = diolan_usb_xfer,
+ .xfer = diolan_usb_xfer,
.functionality = diolan_usb_func,
};
diff --git a/drivers/i2c/busses/i2c-dln2.c b/drivers/i2c/busses/i2c-dln2.c
index 631109c7a098..11ed055143d3 100644
--- a/drivers/i2c/busses/i2c-dln2.c
+++ b/drivers/i2c/busses/i2c-dln2.c
@@ -175,7 +175,7 @@ static u32 dln2_i2c_func(struct i2c_adapter *a)
}
static const struct i2c_algorithm dln2_i2c_usb_algorithm = {
- .master_xfer = dln2_i2c_xfer,
+ .xfer = dln2_i2c_xfer,
.functionality = dln2_i2c_func,
};
@@ -251,6 +251,6 @@ static struct platform_driver dln2_i2c_driver = {
module_platform_driver(dln2_i2c_driver);
MODULE_AUTHOR("Laurentiu Palcu <laurentiu.palcu@intel.com>");
-MODULE_DESCRIPTION("Driver for the Diolan DLN2 I2C master interface");
+MODULE_DESCRIPTION("Driver for the Diolan DLN2 I2C controller interface");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:dln2-i2c");
diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
index 385ef9d9e4d4..d8baca9b610c 100644
--- a/drivers/i2c/busses/i2c-exynos5.c
+++ b/drivers/i2c/busses/i2c-exynos5.c
@@ -763,7 +763,7 @@ static bool exynos5_i2c_poll_irqs_timeout(struct exynos5_i2c *i2c,
static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c,
struct i2c_msg *msgs, int stop)
{
- unsigned long timeout;
+ unsigned long time_left;
int ret;
i2c->msg = msgs;
@@ -775,13 +775,13 @@ static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c,
exynos5_i2c_message_start(i2c, stop);
if (!i2c->atomic)
- timeout = wait_for_completion_timeout(&i2c->msg_complete,
- EXYNOS5_I2C_TIMEOUT);
- else
- timeout = exynos5_i2c_poll_irqs_timeout(i2c,
+ time_left = wait_for_completion_timeout(&i2c->msg_complete,
EXYNOS5_I2C_TIMEOUT);
+ else
+ time_left = exynos5_i2c_poll_irqs_timeout(i2c,
+ EXYNOS5_I2C_TIMEOUT);
- if (timeout == 0)
+ if (time_left == 0)
ret = -ETIMEDOUT;
else
ret = i2c->state;
diff --git a/drivers/i2c/busses/i2c-fsi.c b/drivers/i2c/busses/i2c-fsi.c
index 10332693edf0..ae016a9431da 100644
--- a/drivers/i2c/busses/i2c-fsi.c
+++ b/drivers/i2c/busses/i2c-fsi.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * FSI-attached I2C master algorithm
+ * FSI-attached I2C controller algorithm
*
* Copyright 2018 IBM Corporation
*
@@ -145,7 +145,7 @@
/* choose timeout length from legacy driver; it's well tested */
#define I2C_ABORT_TIMEOUT msecs_to_jiffies(100)
-struct fsi_i2c_master {
+struct fsi_i2c_ctrl {
struct fsi_device *fsi;
u8 fifo_size;
struct list_head ports;
@@ -155,7 +155,7 @@ struct fsi_i2c_master {
struct fsi_i2c_port {
struct list_head list;
struct i2c_adapter adapter;
- struct fsi_i2c_master *master;
+ struct fsi_i2c_ctrl *ctrl;
u16 port;
u16 xfrd;
};
@@ -183,7 +183,7 @@ static int fsi_i2c_write_reg(struct fsi_device *fsi, unsigned int reg,
return fsi_device_write(fsi, reg, &data_be, sizeof(data_be));
}
-static int fsi_i2c_dev_init(struct fsi_i2c_master *i2c)
+static int fsi_i2c_dev_init(struct fsi_i2c_ctrl *i2c)
{
int rc;
u32 mode = I2C_MODE_ENHANCED, extended_status, watermark;
@@ -214,7 +214,7 @@ static int fsi_i2c_dev_init(struct fsi_i2c_master *i2c)
static int fsi_i2c_set_port(struct fsi_i2c_port *port)
{
int rc;
- struct fsi_device *fsi = port->master->fsi;
+ struct fsi_device *fsi = port->ctrl->fsi;
u32 mode, dummy = 0;
rc = fsi_i2c_read_reg(fsi, I2C_FSI_MODE, &mode);
@@ -236,7 +236,7 @@ static int fsi_i2c_set_port(struct fsi_i2c_port *port)
static int fsi_i2c_start(struct fsi_i2c_port *port, struct i2c_msg *msg,
bool stop)
{
- struct fsi_i2c_master *i2c = port->master;
+ struct fsi_i2c_ctrl *i2c = port->ctrl;
u32 cmd = I2C_CMD_WITH_START | I2C_CMD_WITH_ADDR;
port->xfrd = 0;
@@ -268,7 +268,7 @@ static int fsi_i2c_write_fifo(struct fsi_i2c_port *port, struct i2c_msg *msg,
{
int write;
int rc;
- struct fsi_i2c_master *i2c = port->master;
+ struct fsi_i2c_ctrl *i2c = port->ctrl;
int bytes_to_write = i2c->fifo_size - fifo_count;
int bytes_remaining = msg->len - port->xfrd;
@@ -294,7 +294,7 @@ static int fsi_i2c_read_fifo(struct fsi_i2c_port *port, struct i2c_msg *msg,
{
int read;
int rc;
- struct fsi_i2c_master *i2c = port->master;
+ struct fsi_i2c_ctrl *i2c = port->ctrl;
int bytes_to_read;
int xfr_remaining = msg->len - port->xfrd;
u32 dummy;
@@ -330,7 +330,7 @@ static int fsi_i2c_get_scl(struct i2c_adapter *adap)
{
u32 stat = 0;
struct fsi_i2c_port *port = adap->algo_data;
- struct fsi_i2c_master *i2c = port->master;
+ struct fsi_i2c_ctrl *i2c = port->ctrl;
fsi_i2c_read_reg(i2c->fsi, I2C_FSI_STAT, &stat);
@@ -341,7 +341,7 @@ static void fsi_i2c_set_scl(struct i2c_adapter *adap, int val)
{
u32 dummy = 0;
struct fsi_i2c_port *port = adap->algo_data;
- struct fsi_i2c_master *i2c = port->master;
+ struct fsi_i2c_ctrl *i2c = port->ctrl;
if (val)
fsi_i2c_write_reg(i2c->fsi, I2C_FSI_SET_SCL, &dummy);
@@ -353,7 +353,7 @@ static int fsi_i2c_get_sda(struct i2c_adapter *adap)
{
u32 stat = 0;
struct fsi_i2c_port *port = adap->algo_data;
- struct fsi_i2c_master *i2c = port->master;
+ struct fsi_i2c_ctrl *i2c = port->ctrl;
fsi_i2c_read_reg(i2c->fsi, I2C_FSI_STAT, &stat);
@@ -364,7 +364,7 @@ static void fsi_i2c_set_sda(struct i2c_adapter *adap, int val)
{
u32 dummy = 0;
struct fsi_i2c_port *port = adap->algo_data;
- struct fsi_i2c_master *i2c = port->master;
+ struct fsi_i2c_ctrl *i2c = port->ctrl;
if (val)
fsi_i2c_write_reg(i2c->fsi, I2C_FSI_SET_SDA, &dummy);
@@ -377,7 +377,7 @@ static void fsi_i2c_prepare_recovery(struct i2c_adapter *adap)
int rc;
u32 mode;
struct fsi_i2c_port *port = adap->algo_data;
- struct fsi_i2c_master *i2c = port->master;
+ struct fsi_i2c_ctrl *i2c = port->ctrl;
rc = fsi_i2c_read_reg(i2c->fsi, I2C_FSI_MODE, &mode);
if (rc)
@@ -392,7 +392,7 @@ static void fsi_i2c_unprepare_recovery(struct i2c_adapter *adap)
int rc;
u32 mode;
struct fsi_i2c_port *port = adap->algo_data;
- struct fsi_i2c_master *i2c = port->master;
+ struct fsi_i2c_ctrl *i2c = port->ctrl;
rc = fsi_i2c_read_reg(i2c->fsi, I2C_FSI_MODE, &mode);
if (rc)
@@ -402,7 +402,7 @@ static void fsi_i2c_unprepare_recovery(struct i2c_adapter *adap)
fsi_i2c_write_reg(i2c->fsi, I2C_FSI_MODE, &mode);
}
-static int fsi_i2c_reset_bus(struct fsi_i2c_master *i2c,
+static int fsi_i2c_reset_bus(struct fsi_i2c_ctrl *i2c,
struct fsi_i2c_port *port)
{
int rc;
@@ -435,7 +435,7 @@ static int fsi_i2c_reset_bus(struct fsi_i2c_master *i2c,
return fsi_i2c_dev_init(i2c);
}
-static int fsi_i2c_reset_engine(struct fsi_i2c_master *i2c, u16 port)
+static int fsi_i2c_reset_engine(struct fsi_i2c_ctrl *i2c, u16 port)
{
int rc;
u32 mode, dummy = 0;
@@ -478,7 +478,7 @@ static int fsi_i2c_abort(struct fsi_i2c_port *port, u32 status)
unsigned long start;
u32 cmd = I2C_CMD_WITH_STOP;
u32 stat;
- struct fsi_i2c_master *i2c = port->master;
+ struct fsi_i2c_ctrl *i2c = port->ctrl;
struct fsi_device *fsi = i2c->fsi;
rc = fsi_i2c_reset_engine(i2c, port->port);
@@ -505,7 +505,7 @@ static int fsi_i2c_abort(struct fsi_i2c_port *port, u32 status)
if (rc)
return rc;
- /* wait until we see command complete in the master */
+ /* wait until we see command complete in the controller */
start = jiffies;
do {
@@ -579,7 +579,7 @@ static int fsi_i2c_wait(struct fsi_i2c_port *port, struct i2c_msg *msg,
unsigned long start = jiffies;
do {
- rc = fsi_i2c_read_reg(port->master->fsi, I2C_FSI_STAT,
+ rc = fsi_i2c_read_reg(port->ctrl->fsi, I2C_FSI_STAT,
&status);
if (rc)
return rc;
@@ -609,10 +609,10 @@ static int fsi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
int i, rc;
unsigned long start_time;
struct fsi_i2c_port *port = adap->algo_data;
- struct fsi_i2c_master *master = port->master;
+ struct fsi_i2c_ctrl *ctrl = port->ctrl;
struct i2c_msg *msg;
- mutex_lock(&master->lock);
+ mutex_lock(&ctrl->lock);
rc = fsi_i2c_set_port(port);
if (rc)
@@ -633,7 +633,7 @@ static int fsi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
}
unlock:
- mutex_unlock(&master->lock);
+ mutex_unlock(&ctrl->lock);
return rc ? : num;
}
@@ -654,7 +654,7 @@ static struct i2c_bus_recovery_info fsi_i2c_bus_recovery_info = {
};
static const struct i2c_algorithm fsi_i2c_algorithm = {
- .master_xfer = fsi_i2c_xfer,
+ .xfer = fsi_i2c_xfer,
.functionality = fsi_i2c_functionality,
};
@@ -676,7 +676,7 @@ static struct device_node *fsi_i2c_find_port_of_node(struct device_node *fsi,
static int fsi_i2c_probe(struct device *dev)
{
- struct fsi_i2c_master *i2c;
+ struct fsi_i2c_ctrl *i2c;
struct fsi_i2c_port *port;
struct device_node *np;
u32 port_no, ports, stat;
@@ -699,7 +699,7 @@ static int fsi_i2c_probe(struct device *dev)
return rc;
ports = FIELD_GET(I2C_STAT_MAX_PORT, stat) + 1;
- dev_dbg(dev, "I2C master has %d ports\n", ports);
+ dev_dbg(dev, "I2C controller has %d ports\n", ports);
for (port_no = 0; port_no < ports; port_no++) {
np = fsi_i2c_find_port_of_node(dev->of_node, port_no);
@@ -712,7 +712,7 @@ static int fsi_i2c_probe(struct device *dev)
break;
}
- port->master = i2c;
+ port->ctrl = i2c;
port->port = port_no;
port->adapter.owner = THIS_MODULE;
@@ -742,7 +742,7 @@ static int fsi_i2c_probe(struct device *dev)
static int fsi_i2c_remove(struct device *dev)
{
- struct fsi_i2c_master *i2c = dev_get_drvdata(dev);
+ struct fsi_i2c_ctrl *i2c = dev_get_drvdata(dev);
struct fsi_i2c_port *port, *tmp;
list_for_each_entry_safe(port, tmp, &i2c->ports, list) {
@@ -772,5 +772,5 @@ static struct fsi_driver fsi_i2c_driver = {
module_fsi_driver(fsi_i2c_driver);
MODULE_AUTHOR("Eddie James <eajames@us.ibm.com>");
-MODULE_DESCRIPTION("FSI attached I2C master");
+MODULE_DESCRIPTION("FSI attached I2C controller");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 4f1411b1a775..e0bd218e2f14 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -216,8 +216,8 @@ static int fops_lose_arbitration_set(void *data, u64 duration)
priv->scl_irq_data = duration;
/*
- * Interrupt on falling SCL. This ensures that the master under test has
- * really started the transfer. Interrupt on falling SDA did only
+ * Interrupt on falling SCL. This ensures that the controller under test
+ * has really started the transfer. Interrupt on falling SDA did only
* exercise 'bus busy' detection on some HW but not 'arbitration lost'.
* Note that the interrupt latency may cause the first bits to be
* transmitted correctly.
@@ -245,8 +245,8 @@ static int fops_inject_panic_set(void *data, u64 duration)
priv->scl_irq_data = duration;
/*
- * Interrupt on falling SCL. This ensures that the master under test has
- * really started the transfer.
+ * Interrupt on falling SCL. This ensures that the controller under test
+ * has really started the transfer.
*/
return i2c_gpio_fi_act_on_scl_irq(priv, inject_panic_irq);
}
diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c
index 7922bc917c33..ec1ebacb9aa8 100644
--- a/drivers/i2c/busses/i2c-highlander.c
+++ b/drivers/i2c/busses/i2c-highlander.c
@@ -331,7 +331,7 @@ static int highlander_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr,
/* Ensure we're in a sane state */
highlander_i2c_done(dev);
- /* Set slave address */
+ /* Set target address */
iowrite16((addr << 1) | read_write, dev->base + SMSMADR);
highlander_i2c_command(dev, command, dev->buf_len);
diff --git a/drivers/i2c/busses/i2c-hisi.c b/drivers/i2c/busses/i2c-hisi.c
index 975c0b1c44de..4b735ad9e193 100644
--- a/drivers/i2c/busses/i2c-hisi.c
+++ b/drivers/i2c/busses/i2c-hisi.c
@@ -197,8 +197,8 @@ static void hisi_i2c_reset_xfer(struct hisi_i2c_controller *ctlr)
* wait for the transfer done. The major transfer process is performed
* in the IRQ handler.
*/
-static int hisi_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
- int num)
+static int hisi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
{
struct hisi_i2c_controller *ctlr = i2c_get_adapdata(adap);
DECLARE_COMPLETION_ONSTACK(done);
@@ -236,8 +236,8 @@ static u32 hisi_i2c_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm hisi_i2c_algo = {
- .master_xfer = hisi_i2c_master_xfer,
- .functionality = hisi_i2c_functionality,
+ .xfer = hisi_i2c_xfer,
+ .functionality = hisi_i2c_functionality,
};
static int hisi_i2c_read_rx_fifo(struct hisi_i2c_controller *ctlr)
diff --git a/drivers/i2c/busses/i2c-hix5hd2.c b/drivers/i2c/busses/i2c-hix5hd2.c
index 8e75515c3ca4..64cade6ba923 100644
--- a/drivers/i2c/busses/i2c-hix5hd2.c
+++ b/drivers/i2c/busses/i2c-hix5hd2.c
@@ -200,7 +200,7 @@ static void hix5hd2_read_handle(struct hix5hd2_i2c_priv *priv)
/* the last byte don't need send ACK */
writel_relaxed(I2C_READ | I2C_NO_ACK, priv->regs + HIX5I2C_COM);
} else if (priv->msg_len > 1) {
- /* if i2c master receive data will send ACK */
+ /* if i2c controller receive data will send ACK */
writel_relaxed(I2C_READ, priv->regs + HIX5I2C_COM);
} else {
hix5hd2_rw_handle_stop(priv);
@@ -314,7 +314,7 @@ static void hix5hd2_i2c_message_start(struct hix5hd2_i2c_priv *priv, int stop)
static int hix5hd2_i2c_xfer_msg(struct hix5hd2_i2c_priv *priv,
struct i2c_msg *msgs, int stop)
{
- unsigned long timeout;
+ unsigned long time_left;
int ret;
priv->msg = msgs;
@@ -327,9 +327,9 @@ static int hix5hd2_i2c_xfer_msg(struct hix5hd2_i2c_priv *priv,
reinit_completion(&priv->msg_complete);
hix5hd2_i2c_message_start(priv, stop);
- timeout = wait_for_completion_timeout(&priv->msg_complete,
- priv->adap.timeout);
- if (timeout == 0) {
+ time_left = wait_for_completion_timeout(&priv->msg_complete,
+ priv->adap.timeout);
+ if (time_left == 0) {
priv->state = HIX5I2C_STAT_RW_ERR;
priv->err = -ETIMEDOUT;
dev_warn(priv->dev, "%s timeout=%d\n",
@@ -384,8 +384,8 @@ static u32 hix5hd2_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm hix5hd2_i2c_algorithm = {
- .master_xfer = hix5hd2_i2c_xfer,
- .functionality = hix5hd2_i2c_func,
+ .xfer = hix5hd2_i2c_xfer,
+ .functionality = hix5hd2_i2c_func,
};
static int hix5hd2_i2c_probe(struct platform_device *pdev)
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 79870dd7a014..328c0dab6b14 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -80,6 +80,7 @@
* Meteor Lake SoC-S (SOC) 0xae22 32 hard yes yes yes
* Meteor Lake PCH-S (PCH) 0x7f23 32 hard yes yes yes
* Birch Stream (SOC) 0x5796 32 hard yes yes yes
+ * Arrow Lake-H (SOC) 0x7722 32 hard yes yes yes
*
* Features supported by this driver:
* Software PEC no
@@ -87,7 +88,7 @@
* Block buffer yes
* Block process call transaction yes
* I2C block read transaction yes (doesn't use the block buffer)
- * Slave mode no
+ * Target mode no
* SMBus Host Notify yes
* Interrupt processing yes
*
@@ -105,6 +106,7 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/i2c.h>
+#include <linux/i2c-mux.h>
#include <linux/i2c-smbus.h>
#include <linux/acpi.h>
#include <linux/io.h>
@@ -119,7 +121,7 @@
#include <linux/pm_runtime.h>
#include <linux/mutex.h>
-#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
+#ifdef CONFIG_I2C_I801_MUX
#include <linux/gpio/machine.h>
#include <linux/platform_data/i2c-mux-gpio.h>
#endif
@@ -236,6 +238,7 @@
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS 0x54a3
#define PCI_DEVICE_ID_INTEL_BIRCH_STREAM_SMBUS 0x5796
#define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4
+#define PCI_DEVICE_ID_INTEL_ARROW_LAKE_H_SMBUS 0x7722
#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
@@ -263,7 +266,6 @@ struct i801_mux_config {
char *gpio_chip;
unsigned values[3];
int n_values;
- unsigned classes[3];
unsigned gpios[2]; /* Relative to gpio_chip->base */
int n_gpios;
};
@@ -288,9 +290,10 @@ struct i801_priv {
int len;
u8 *data;
-#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
+#ifdef CONFIG_I2C_I801_MUX
struct platform_device *mux_pdev;
struct gpiod_lookup_table *lookup;
+ struct notifier_block mux_notifier_block;
#endif
struct platform_device *tco_pdev;
@@ -398,9 +401,7 @@ static int i801_check_post(struct i801_priv *priv, int status)
* If the SMBus is still busy, we give up
*/
if (unlikely(status < 0)) {
- dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
/* try to stop the current command */
- dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n");
outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv));
usleep_range(1000, 2000);
outb_p(0, SMBHSTCNT(priv));
@@ -409,7 +410,7 @@ static int i801_check_post(struct i801_priv *priv, int status)
status = inb_p(SMBHSTSTS(priv));
if ((status & SMBHSTSTS_HOST_BUSY) ||
!(status & SMBHSTSTS_FAILED))
- dev_err(&priv->pci_dev->dev,
+ dev_dbg(&priv->pci_dev->dev,
"Failed terminating the transaction\n");
return -ETIMEDOUT;
}
@@ -1053,13 +1054,14 @@ static const struct pci_device_id i801_ids[] = {
{ PCI_DEVICE_DATA(INTEL, METEOR_LAKE_SOC_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, METEOR_LAKE_PCH_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, BIRCH_STREAM_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
+ { PCI_DEVICE_DATA(INTEL, ARROW_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, i801_ids);
#if defined CONFIG_X86 && defined CONFIG_DMI
-static unsigned char apanel_addr;
+static unsigned char apanel_addr __ro_after_init;
/* Scan the system ROM for the signature "FJKEYINF" */
static __init const void __iomem *bios_signature(const void __iomem *bios)
@@ -1275,10 +1277,10 @@ static void register_dell_lis3lv02d_i2c_device(struct i801_priv *priv)
i2c_new_client_device(&priv->adapter, &info);
}
-/* Register optional slaves */
-static void i801_probe_optional_slaves(struct i801_priv *priv)
+/* Register optional targets */
+static void i801_probe_optional_targets(struct i801_priv *priv)
{
- /* Only register slaves on main SMBus channel */
+ /* Only register targets on main SMBus channel */
if (priv->features & FEATURE_IDF)
return;
@@ -1298,22 +1300,21 @@ static void i801_probe_optional_slaves(struct i801_priv *priv)
register_dell_lis3lv02d_i2c_device(priv);
/* Instantiate SPD EEPROMs unless the SMBus is multiplexed */
-#if IS_ENABLED(CONFIG_I2C_MUX_GPIO)
+#ifdef CONFIG_I2C_I801_MUX
if (!priv->mux_pdev)
#endif
i2c_register_spd(&priv->adapter);
}
#else
static void __init input_apanel_init(void) {}
-static void i801_probe_optional_slaves(struct i801_priv *priv) {}
+static void i801_probe_optional_targets(struct i801_priv *priv) {}
#endif /* CONFIG_X86 && CONFIG_DMI */
-#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
+#ifdef CONFIG_I2C_I801_MUX
static struct i801_mux_config i801_mux_config_asus_z8_d12 = {
.gpio_chip = "gpio_ich",
.values = { 0x02, 0x03 },
.n_values = 2,
- .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD },
.gpios = { 52, 53 },
.n_gpios = 2,
};
@@ -1322,7 +1323,6 @@ static struct i801_mux_config i801_mux_config_asus_z8_d18 = {
.gpio_chip = "gpio_ich",
.values = { 0x02, 0x03, 0x01 },
.n_values = 3,
- .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD },
.gpios = { 52, 53 },
.n_gpios = 2,
};
@@ -1394,6 +1394,23 @@ static const struct dmi_system_id mux_dmi_table[] = {
{ }
};
+static int i801_notifier_call(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct i801_priv *priv = container_of(nb, struct i801_priv, mux_notifier_block);
+ struct device *dev = data;
+
+ if (action != BUS_NOTIFY_ADD_DEVICE ||
+ dev->type != &i2c_adapter_type ||
+ i2c_root_adapter(dev) != &priv->adapter)
+ return NOTIFY_DONE;
+
+ /* Call i2c_register_spd for muxed child segments */
+ i2c_register_spd(to_i2c_adapter(dev));
+
+ return NOTIFY_OK;
+}
+
/* Setup multiplexing if needed */
static void i801_add_mux(struct i801_priv *priv)
{
@@ -1415,7 +1432,6 @@ static void i801_add_mux(struct i801_priv *priv)
gpio_data.parent = priv->adapter.nr;
gpio_data.values = mux_config->values;
gpio_data.n_values = mux_config->n_values;
- gpio_data.classes = mux_config->classes;
gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;
/* Register GPIO descriptor lookup table */
@@ -1430,6 +1446,9 @@ static void i801_add_mux(struct i801_priv *priv)
mux_config->gpios[i], "mux", 0);
gpiod_add_lookup_table(lookup);
+ priv->mux_notifier_block.notifier_call = i801_notifier_call;
+ if (bus_register_notifier(&i2c_bus_type, &priv->mux_notifier_block))
+ return;
/*
* Register the mux device, we use PLATFORM_DEVID_NONE here
* because since we are referring to the GPIO chip by name we are
@@ -1451,6 +1470,7 @@ static void i801_add_mux(struct i801_priv *priv)
static void i801_del_mux(struct i801_priv *priv)
{
+ bus_unregister_notifier(&i2c_bus_type, &priv->mux_notifier_block);
platform_device_unregister(priv->mux_pdev);
gpiod_remove_lookup_table(priv->lookup);
}
@@ -1757,7 +1777,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
/* We ignore errors - multiplexing is optional */
i801_add_mux(priv);
- i801_probe_optional_slaves(priv);
+ i801_probe_optional_targets(priv);
pci_set_drvdata(dev, priv);
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index 7fb87b78923e..82dedb1bb5be 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -136,11 +136,11 @@ static void iic_dev_init(struct ibm_iic_private* dev)
DBG("%d: init\n", dev->idx);
- /* Clear master address */
+ /* Clear remote target address */
out_8(&iic->lmadr, 0);
out_8(&iic->hmadr, 0);
- /* Clear slave address */
+ /* Clear local target address */
out_8(&iic->lsadr, 0);
out_8(&iic->hsadr, 0);
@@ -337,7 +337,7 @@ static irqreturn_t iic_handler(int irq, void *dev_id)
}
/*
- * Get master transfer result and clear errors if any.
+ * Get controller transfer result and clear errors if any.
* Returns the number of actually transferred bytes or error (<0)
*/
static int iic_xfer_result(struct ibm_iic_private* dev)
@@ -352,7 +352,7 @@ static int iic_xfer_result(struct ibm_iic_private* dev)
out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD |
EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA);
- /* Flush master data buffer */
+ /* Flush controller data buffer */
out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
/* Is bus free?
@@ -401,7 +401,7 @@ static void iic_abort_xfer(struct ibm_iic_private* dev)
}
/*
- * Wait for master transfer to complete.
+ * Wait for controller transfer to complete.
* It puts current process to sleep until we get interrupt or timeout expires.
* Returns the number of transferred bytes or error (<0)
*/
@@ -452,9 +452,6 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){
return ret;
}
-/*
- * Low level master transfer routine
- */
static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm,
int combined_xfer)
{
@@ -511,9 +508,7 @@ static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm,
return ret > 0 ? 0 : ret;
}
-/*
- * Set target slave address for master transfer
- */
+/* Set remote target address for transfer */
static inline void iic_address(struct ibm_iic_private* dev, struct i2c_msg* msg)
{
volatile struct iic_regs __iomem *iic = dev->vaddr;
@@ -546,7 +541,7 @@ static inline int iic_address_neq(const struct i2c_msg* p1,
}
/*
- * Generic master transfer entrypoint.
+ * Generic transfer entrypoint.
* Returns the number of processed messages or error (<0)
*/
static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
@@ -604,11 +599,11 @@ static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
}
}
else {
- /* Flush master data buffer (just in case) */
+ /* Flush controller data buffer (just in case) */
out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
}
- /* Load slave address */
+ /* Load target address */
iic_address(dev, &msgs[0]);
/* Do real transfer */
@@ -624,8 +619,8 @@ static u32 iic_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm iic_algo = {
- .master_xfer = iic_xfer,
- .functionality = iic_func
+ .xfer = iic_xfer,
+ .functionality = iic_func
};
/*
diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c
index f9d4bfef511c..e0e87185f6bb 100644
--- a/drivers/i2c/busses/i2c-img-scb.c
+++ b/drivers/i2c/busses/i2c-img-scb.c
@@ -1124,11 +1124,8 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
IMG_I2C_TIMEOUT);
del_timer_sync(&i2c->check_timer);
- if (time_left == 0) {
- dev_err(adap->dev.parent, "i2c transfer timed out\n");
+ if (time_left == 0)
i2c->msg_status = -ETIMEDOUT;
- break;
- }
if (i2c->msg_status)
break;
diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
index 6d72e4e126dd..0197786892a2 100644
--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -99,6 +99,7 @@ struct lpi2c_imx_struct {
__u8 *rx_buf;
__u8 *tx_buf;
struct completion complete;
+ unsigned long rate_per;
unsigned int msglen;
unsigned int delivered;
unsigned int block_data;
@@ -212,9 +213,7 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)
lpi2c_imx_set_mode(lpi2c_imx);
- clk_rate = clk_get_rate(lpi2c_imx->clks[0].clk);
- if (!clk_rate)
- return -EINVAL;
+ clk_rate = lpi2c_imx->rate_per;
if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST)
filt = 0;
@@ -308,11 +307,11 @@ static int lpi2c_imx_master_disable(struct lpi2c_imx_struct *lpi2c_imx)
static int lpi2c_imx_msg_complete(struct lpi2c_imx_struct *lpi2c_imx)
{
- unsigned long timeout;
+ unsigned long time_left;
- timeout = wait_for_completion_timeout(&lpi2c_imx->complete, HZ);
+ time_left = wait_for_completion_timeout(&lpi2c_imx->complete, HZ);
- return timeout ? 0 : -ETIMEDOUT;
+ return time_left ? 0 : -ETIMEDOUT;
}
static int lpi2c_imx_txfifo_empty(struct lpi2c_imx_struct *lpi2c_imx)
@@ -611,6 +610,20 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
if (ret)
return ret;
+ /*
+ * Lock the parent clock rate to avoid getting parent clock upon
+ * each transfer
+ */
+ ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clks[0].clk);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "can't lock I2C peripheral clock rate\n");
+
+ lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk);
+ if (!lpi2c_imx->rate_per)
+ return dev_err_probe(&pdev->dev, -EINVAL,
+ "can't get I2C peripheral clock rate\n");
+
pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_get_noresume(&pdev->dev);
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 2e5f0165c3d3..859c14e340e7 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -22,7 +22,7 @@
* - Make it work with IXP46x chips
* - Cleanup function names, coding style, etc
*
- * - writing to slave address causes latchup on iop331.
+ * - writing to local target address causes latchup on iop331.
* fix: driver refuses to address self.
*/
@@ -234,7 +234,7 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
int status;
int rc;
- /* avoid writing to my slave address (hangs on 80331),
+ /* avoid writing to local target address (hangs on 80331),
* forbidden in Intel developer manual
*/
if (msg->addr == MYSAR) {
@@ -349,12 +349,9 @@ iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg *pmsg)
}
}
-/*
- * master_xfer() - main read/write entry
- */
static int
-iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
- int num)
+iop3xx_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
+ int num)
{
struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
int im = 0;
@@ -384,8 +381,8 @@ iop3xx_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm iop3xx_i2c_algo = {
- .master_xfer = iop3xx_i2c_master_xfer,
- .functionality = iop3xx_i2c_func,
+ .xfer = iop3xx_i2c_xfer,
+ .functionality = iop3xx_i2c_func,
};
static void
diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c
index 416a9968ed28..33dbc19d3848 100644
--- a/drivers/i2c/busses/i2c-isch.c
+++ b/drivers/i2c/busses/i2c-isch.c
@@ -104,7 +104,7 @@ static int sch_transaction(void)
result = -EIO;
dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be "
"locked until next hard reset. (sorry!)\n");
- /* Clock stops and slave is stuck in mid-transmission */
+ /* Clock stops and target is stuck in mid-transmission */
} else if (temp & 0x02) {
result = -EIO;
dev_err(&sch_adapter.dev, "Error: no response!\n");
diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
index c74985d77b0e..655b5d851c48 100644
--- a/drivers/i2c/busses/i2c-ismt.c
+++ b/drivers/i2c/busses/i2c-ismt.c
@@ -623,7 +623,6 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
dma_unmap_single(dev, dma_addr, dma_size, dma_direction);
if (unlikely(!time_left)) {
- dev_err(dev, "completion wait timed out\n");
ret = -ETIMEDOUT;
goto out;
}
diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c
index 55035cca0ae5..4aafdfab6305 100644
--- a/drivers/i2c/busses/i2c-jz4780.c
+++ b/drivers/i2c/busses/i2c-jz4780.c
@@ -565,7 +565,7 @@ static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c,
int idx)
{
int ret = 0;
- long timeout;
+ unsigned long time_left;
int wait_time = JZ4780_I2C_TIMEOUT * (len + 5);
unsigned short tmp;
unsigned long flags;
@@ -600,10 +600,10 @@ static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c,
spin_unlock_irqrestore(&i2c->lock, flags);
- timeout = wait_for_completion_timeout(&i2c->trans_waitq,
- msecs_to_jiffies(wait_time));
+ time_left = wait_for_completion_timeout(&i2c->trans_waitq,
+ msecs_to_jiffies(wait_time));
- if (!timeout) {
+ if (!time_left) {
dev_err(&i2c->adap.dev, "irq read timeout\n");
dev_dbg(&i2c->adap.dev, "send cmd count:%d %d\n",
i2c->cmd, i2c->cmd_buf[i2c->cmd]);
@@ -627,7 +627,7 @@ static inline int jz4780_i2c_xfer_write(struct jz4780_i2c *i2c,
{
int ret = 0;
int wait_time = JZ4780_I2C_TIMEOUT * (len + 5);
- long timeout;
+ unsigned long time_left;
unsigned short tmp;
unsigned long flags;
@@ -655,14 +655,14 @@ static inline int jz4780_i2c_xfer_write(struct jz4780_i2c *i2c,
spin_unlock_irqrestore(&i2c->lock, flags);
- timeout = wait_for_completion_timeout(&i2c->trans_waitq,
- msecs_to_jiffies(wait_time));
- if (timeout && !i2c->stop_hold) {
+ time_left = wait_for_completion_timeout(&i2c->trans_waitq,
+ msecs_to_jiffies(wait_time));
+ if (time_left && !i2c->stop_hold) {
unsigned short i2c_sta;
int write_in_process;
- timeout = JZ4780_I2C_TIMEOUT * 100;
- for (; timeout > 0; timeout--) {
+ time_left = JZ4780_I2C_TIMEOUT * 100;
+ for (; time_left > 0; time_left--) {
i2c_sta = jz4780_i2c_readw(i2c, JZ4780_I2C_STA);
write_in_process = (i2c_sta & JZ4780_I2C_STA_MSTACT) ||
@@ -673,7 +673,7 @@ static inline int jz4780_i2c_xfer_write(struct jz4780_i2c *i2c,
}
}
- if (!timeout) {
+ if (!time_left) {
dev_err(&i2c->adap.dev, "write wait timeout\n");
ret = -EIO;
}
@@ -730,8 +730,8 @@ static u32 jz4780_i2c_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm jz4780_i2c_algorithm = {
- .master_xfer = jz4780_i2c_xfer,
- .functionality = jz4780_i2c_functionality,
+ .xfer = jz4780_i2c_xfer,
+ .functionality = jz4780_i2c_functionality,
};
static const struct ingenic_i2c_config jz4780_i2c_config = {
diff --git a/drivers/i2c/busses/i2c-kempld.c b/drivers/i2c/busses/i2c-kempld.c
index c3a529a73b5b..eb66942e0b7d 100644
--- a/drivers/i2c/busses/i2c-kempld.c
+++ b/drivers/i2c/busses/i2c-kempld.c
@@ -276,8 +276,8 @@ static u32 kempld_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm kempld_i2c_algorithm = {
- .master_xfer = kempld_i2c_xfer,
- .functionality = kempld_i2c_func,
+ .xfer = kempld_i2c_xfer,
+ .functionality = kempld_i2c_func,
};
static const struct i2c_adapter kempld_i2c_adapter = {
diff --git a/drivers/i2c/busses/i2c-ljca.c b/drivers/i2c/busses/i2c-ljca.c
index b4927622177c..0b70621cf9d3 100644
--- a/drivers/i2c/busses/i2c-ljca.c
+++ b/drivers/i2c/busses/i2c-ljca.c
@@ -76,7 +76,7 @@ static int ljca_i2c_init(struct ljca_i2c_dev *ljca_i2c, u8 id)
return ret < 0 ? ret : 0;
}
-static int ljca_i2c_start(struct ljca_i2c_dev *ljca_i2c, u8 slave_addr,
+static int ljca_i2c_start(struct ljca_i2c_dev *ljca_i2c, u8 target_addr,
enum ljca_xfer_type type)
{
struct ljca_i2c_rw_packet *w_packet =
@@ -88,7 +88,7 @@ static int ljca_i2c_start(struct ljca_i2c_dev *ljca_i2c, u8 slave_addr,
w_packet->id = ljca_i2c->i2c_info->id;
w_packet->len = cpu_to_le16(sizeof(*w_packet->data));
- w_packet->data[0] = (slave_addr << 1) | type;
+ w_packet->data[0] = (target_addr << 1) | type;
ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_START, (u8 *)w_packet,
struct_size(w_packet, data, 1), (u8 *)r_packet,
@@ -107,7 +107,7 @@ static int ljca_i2c_start(struct ljca_i2c_dev *ljca_i2c, u8 slave_addr,
return 0;
}
-static void ljca_i2c_stop(struct ljca_i2c_dev *ljca_i2c, u8 slave_addr)
+static void ljca_i2c_stop(struct ljca_i2c_dev *ljca_i2c, u8 target_addr)
{
struct ljca_i2c_rw_packet *w_packet =
(struct ljca_i2c_rw_packet *)ljca_i2c->obuf;
@@ -169,16 +169,16 @@ static int ljca_i2c_pure_read(struct ljca_i2c_dev *ljca_i2c, u8 *data, u8 len)
return 0;
}
-static int ljca_i2c_read(struct ljca_i2c_dev *ljca_i2c, u8 slave_addr, u8 *data,
+static int ljca_i2c_read(struct ljca_i2c_dev *ljca_i2c, u8 target_addr, u8 *data,
u8 len)
{
int ret;
- ret = ljca_i2c_start(ljca_i2c, slave_addr, LJCA_I2C_READ_XFER_TYPE);
+ ret = ljca_i2c_start(ljca_i2c, target_addr, LJCA_I2C_READ_XFER_TYPE);
if (!ret)
ret = ljca_i2c_pure_read(ljca_i2c, data, len);
- ljca_i2c_stop(ljca_i2c, slave_addr);
+ ljca_i2c_stop(ljca_i2c, target_addr);
return ret;
}
@@ -213,16 +213,16 @@ static int ljca_i2c_pure_write(struct ljca_i2c_dev *ljca_i2c, u8 *data, u8 len)
return 0;
}
-static int ljca_i2c_write(struct ljca_i2c_dev *ljca_i2c, u8 slave_addr,
+static int ljca_i2c_write(struct ljca_i2c_dev *ljca_i2c, u8 target_addr,
u8 *data, u8 len)
{
int ret;
- ret = ljca_i2c_start(ljca_i2c, slave_addr, LJCA_I2C_WRITE_XFER_TYPE);
+ ret = ljca_i2c_start(ljca_i2c, target_addr, LJCA_I2C_WRITE_XFER_TYPE);
if (!ret)
ret = ljca_i2c_pure_write(ljca_i2c, data, len);
- ljca_i2c_stop(ljca_i2c, slave_addr);
+ ljca_i2c_stop(ljca_i2c, target_addr);
return ret;
}
@@ -266,7 +266,7 @@ static const struct i2c_adapter_quirks ljca_i2c_quirks = {
};
static const struct i2c_algorithm ljca_i2c_algo = {
- .master_xfer = ljca_i2c_xfer,
+ .xfer = ljca_i2c_xfer,
.functionality = ljca_i2c_func,
};
diff --git a/drivers/i2c/busses/i2c-lpc2k.c b/drivers/i2c/busses/i2c-lpc2k.c
index e3660333e91c..9fb33cbf7419 100644
--- a/drivers/i2c/busses/i2c-lpc2k.c
+++ b/drivers/i2c/busses/i2c-lpc2k.c
@@ -50,7 +50,7 @@
/*
* 26 possible I2C status codes, but codes applicable only
- * to master are listed here and used in this driver
+ * to controller mode are listed here and used in this driver
*/
enum {
M_BUS_ERROR = 0x00,
@@ -157,7 +157,7 @@ static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)
break;
case MR_ADDR_R_ACK:
- /* Receive first byte from slave */
+ /* Receive first byte from target */
if (i2c->msg->len == 1) {
/* Last byte, return NACK */
writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONCLR);
@@ -196,7 +196,7 @@ static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)
}
/*
- * One pre-last data input, send NACK to tell the slave that
+ * One pre-last data input, send NACK to tell the target that
* this is going to be the last data byte to be transferred.
*/
if (i2c->msg_idx >= i2c->msg->len - 2) {
@@ -338,8 +338,8 @@ static u32 i2c_lpc2k_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm i2c_lpc2k_algorithm = {
- .master_xfer = i2c_lpc2k_xfer,
- .functionality = i2c_lpc2k_functionality,
+ .xfer = i2c_lpc2k_xfer,
+ .functionality = i2c_lpc2k_functionality,
};
static int i2c_lpc2k_probe(struct platform_device *pdev)
diff --git a/drivers/i2c/busses/i2c-ls2x.c b/drivers/i2c/busses/i2c-ls2x.c
index ebae6035701d..8821cac3897b 100644
--- a/drivers/i2c/busses/i2c-ls2x.c
+++ b/drivers/i2c/busses/i2c-ls2x.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Loongson-2K/Loongson LS7A I2C master mode driver
+ * Loongson-2K/Loongson LS7A I2C controller mode driver
*
* Copyright (C) 2013 Loongson Technology Corporation Limited.
* Copyright (C) 2014-2017 Lemote, Inc.
@@ -51,7 +51,7 @@
/* Control Register Bit */
#define LS2X_CTR_EN BIT(7) /* 0: I2c frequency setting 1: Normal */
#define LS2X_CTR_IEN BIT(6) /* Enable i2c interrupt */
-#define LS2X_CTR_MST BIT(5) /* 0: Slave mode 1: Master mode */
+#define LS2X_CTR_MST BIT(5) /* 0: Target mode 1: Controller mode */
#define CTR_FREQ_MASK GENMASK(7, 6)
#define CTR_READY_MASK GENMASK(7, 5)
@@ -251,8 +251,7 @@ static int ls2x_i2c_xfer_one(struct ls2x_i2c_priv *priv,
return ret;
}
-static int ls2x_i2c_master_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs, int num)
+static int ls2x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
int ret;
struct i2c_msg *msg, *emsg = msgs + num;
@@ -273,8 +272,8 @@ static unsigned int ls2x_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm ls2x_i2c_algo = {
- .master_xfer = ls2x_i2c_master_xfer,
- .functionality = ls2x_i2c_func,
+ .xfer = ls2x_i2c_xfer,
+ .functionality = ls2x_i2c_func,
};
static int ls2x_i2c_probe(struct platform_device *pdev)
diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c
index 099291a0411d..8223f6d29eb3 100644
--- a/drivers/i2c/busses/i2c-mlxcpld.c
+++ b/drivers/i2c/busses/i2c-mlxcpld.c
@@ -197,8 +197,8 @@ static int mlxcpld_i2c_check_status(struct mlxcpld_i2c_priv *priv, int *status)
if (val & MLXCPLD_LPCI2C_TRANS_END) {
if (val & MLXCPLD_LPCI2C_STATUS_NACK)
/*
- * The slave is unable to accept the data. No such
- * slave, command not understood, or unable to accept
+ * The target is unable to accept the data. No such
+ * target, command not understood, or unable to accept
* any more data.
*/
*status = MLXCPLD_LPCI2C_NACK_IND;
@@ -280,7 +280,7 @@ static int mlxcpld_i2c_wait_for_free(struct mlxcpld_i2c_priv *priv)
}
/*
- * Wait for master transfer to complete.
+ * Wait for transfer to complete.
* It puts current process to sleep until we get interrupt or timeout expires.
* Returns the number of transferred or read bytes or error (<0).
*/
@@ -315,7 +315,7 @@ static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv)
/*
* Actual read data len will be always the same as
* requested len. 0xff (line pull-up) will be returned
- * if slave has no data to return. Thus don't read
+ * if target has no data to return. Thus don't read
* MLXCPLD_LPCI2C_NUM_DAT_REG reg from CPLD. Only in case of
* SMBus block read transaction data len can be different,
* check this case.
@@ -375,7 +375,7 @@ static void mlxcpld_i2c_xfer_msg(struct mlxcpld_i2c_priv *priv)
}
/*
- * Set target slave address with command for master transfer.
+ * Set target address with command for transfer.
* It should be latest executed function before CPLD transaction.
*/
cmd = (priv->xfer.msg[0].addr << 1) | priv->xfer.cmd;
@@ -449,8 +449,8 @@ static u32 mlxcpld_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm mlxcpld_i2c_algo = {
- .master_xfer = mlxcpld_i2c_xfer,
- .functionality = mlxcpld_i2c_func
+ .xfer = mlxcpld_i2c_xfer,
+ .functionality = mlxcpld_i2c_func
};
static const struct i2c_adapter_quirks mlxcpld_i2c_quirks = {
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 8d73c0f405ed..41d6c8ed163a 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -115,7 +115,7 @@ static inline void writeccr(struct mpc_i2c *i2c, u32 x)
writeb(x, i2c->base + MPC_I2C_CR);
}
-/* Sometimes 9th clock pulse isn't generated, and slave doesn't release
+/* Sometimes 9th clock pulse isn't generated, and target doesn't release
* the bus, because it wants to send ACK.
* Following sequence of enabling/disabling and sending start/stop generates
* the 9 pulses, each with a START then ending with STOP, so it's all OK.
@@ -304,13 +304,12 @@ static void mpc_i2c_setup_512x(struct device_node *node,
struct mpc_i2c *i2c,
u32 clock)
{
- struct device_node *node_ctrl;
void __iomem *ctrl;
u32 idx;
/* Enable I2C interrupts for mpc5121 */
- node_ctrl = of_find_compatible_node(NULL, NULL,
- "fsl,mpc5121-i2c-ctrl");
+ struct device_node *node_ctrl __free(device_node) =
+ of_find_compatible_node(NULL, NULL, "fsl,mpc5121-i2c-ctrl");
if (node_ctrl) {
ctrl = of_iomap(node_ctrl, 0);
if (ctrl) {
@@ -321,7 +320,6 @@ static void mpc_i2c_setup_512x(struct device_node *node,
setbits32(ctrl, 1 << (24 + idx * 2));
iounmap(ctrl);
}
- of_node_put(node_ctrl);
}
/* The clock setup for the 52xx works also fine for the 512x */
@@ -358,11 +356,11 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
static u32 mpc_i2c_get_sec_cfg_8xxx(void)
{
- struct device_node *node;
u32 __iomem *reg;
u32 val = 0;
- node = of_find_node_by_name(NULL, "global-utilities");
+ struct device_node *node __free(device_node) =
+ of_find_node_by_name(NULL, "global-utilities");
if (node) {
const u32 *prop = of_get_property(node, "reg", NULL);
if (prop) {
@@ -383,7 +381,6 @@ static u32 mpc_i2c_get_sec_cfg_8xxx(void)
iounmap(reg);
}
}
- of_node_put(node);
return val;
}
@@ -762,7 +759,7 @@ static int fsl_i2c_bus_recovery(struct i2c_adapter *adap)
}
static const struct i2c_algorithm mpc_algo = {
- .master_xfer = mpc_xfer,
+ .xfer = mpc_xfer,
.functionality = mpc_functionality,
};
diff --git a/drivers/i2c/busses/i2c-mt7621.c b/drivers/i2c/busses/i2c-mt7621.c
index 81d46169bc1f..23d417ff5e71 100644
--- a/drivers/i2c/busses/i2c-mt7621.c
+++ b/drivers/i2c/busses/i2c-mt7621.c
@@ -117,27 +117,27 @@ static int mtk_i2c_check_ack(struct mtk_i2c *i2c, u32 expected)
return ((ack & ack_expected) == ack_expected) ? 0 : -ENXIO;
}
-static int mtk_i2c_master_start(struct mtk_i2c *i2c)
+static int mtk_i2c_start(struct mtk_i2c *i2c)
{
iowrite32(SM0CTL1_START | SM0CTL1_TRI, i2c->base + REG_SM0CTL1_REG);
return mtk_i2c_wait_idle(i2c);
}
-static int mtk_i2c_master_stop(struct mtk_i2c *i2c)
+static int mtk_i2c_stop(struct mtk_i2c *i2c)
{
iowrite32(SM0CTL1_STOP | SM0CTL1_TRI, i2c->base + REG_SM0CTL1_REG);
return mtk_i2c_wait_idle(i2c);
}
-static int mtk_i2c_master_cmd(struct mtk_i2c *i2c, u32 cmd, int page_len)
+static int mtk_i2c_cmd(struct mtk_i2c *i2c, u32 cmd, int page_len)
{
iowrite32(cmd | SM0CTL1_TRI | SM0CTL1_PGLEN(page_len),
i2c->base + REG_SM0CTL1_REG);
return mtk_i2c_wait_idle(i2c);
}
-static int mtk_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
- int num)
+static int mtk_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
{
struct mtk_i2c *i2c;
struct i2c_msg *pmsg;
@@ -157,7 +157,7 @@ static int mtk_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
goto err_timeout;
/* start sequence */
- ret = mtk_i2c_master_start(i2c);
+ ret = mtk_i2c_start(i2c);
if (ret)
goto err_timeout;
@@ -169,14 +169,14 @@ static int mtk_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
if (pmsg->flags & I2C_M_RD)
addr |= 1;
iowrite32(addr, i2c->base + REG_SM0D0_REG);
- ret = mtk_i2c_master_cmd(i2c, SM0CTL1_WRITE, 2);
+ ret = mtk_i2c_cmd(i2c, SM0CTL1_WRITE, 2);
if (ret)
goto err_timeout;
} else {
/* 7 bits address */
addr = i2c_8bit_addr_from_msg(pmsg);
iowrite32(addr, i2c->base + REG_SM0D0_REG);
- ret = mtk_i2c_master_cmd(i2c, SM0CTL1_WRITE, 1);
+ ret = mtk_i2c_cmd(i2c, SM0CTL1_WRITE, 1);
if (ret)
goto err_timeout;
}
@@ -202,7 +202,7 @@ static int mtk_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
cmd = SM0CTL1_WRITE;
}
- ret = mtk_i2c_master_cmd(i2c, cmd, page_len);
+ ret = mtk_i2c_cmd(i2c, cmd, page_len);
if (ret)
goto err_timeout;
@@ -222,7 +222,7 @@ static int mtk_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
}
}
- ret = mtk_i2c_master_stop(i2c);
+ ret = mtk_i2c_stop(i2c);
if (ret)
goto err_timeout;
@@ -230,7 +230,7 @@ static int mtk_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
return i;
err_ack:
- ret = mtk_i2c_master_stop(i2c);
+ ret = mtk_i2c_stop(i2c);
if (ret)
goto err_timeout;
return -ENXIO;
@@ -247,8 +247,8 @@ static u32 mtk_i2c_func(struct i2c_adapter *a)
}
static const struct i2c_algorithm mtk_i2c_algo = {
- .master_xfer = mtk_i2c_master_xfer,
- .functionality = mtk_i2c_func,
+ .xfer = mtk_i2c_xfer,
+ .functionality = mtk_i2c_func,
};
static const struct of_device_id i2c_mtk_dt_ids[] = {
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index dc160cbc3155..29f94efedf60 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -89,8 +89,8 @@ enum {
MV64XXX_I2C_STATE_WAITING_FOR_RESTART,
MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK,
MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
- MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK,
- MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA,
+ MV64XXX_I2C_STATE_WAITING_FOR_TARGET_ACK,
+ MV64XXX_I2C_STATE_WAITING_FOR_TARGET_DATA,
};
/* Driver actions */
@@ -279,7 +279,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
} else {
drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
drv_data->state =
- MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK;
+ MV64XXX_I2C_STATE_WAITING_FOR_TARGET_ACK;
drv_data->bytes_left--;
}
break;
@@ -307,7 +307,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
drv_data->action = MV64XXX_I2C_ACTION_RCV_DATA;
drv_data->bytes_left--;
}
- drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA;
+ drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_TARGET_DATA;
if ((drv_data->bytes_left == 1) || drv_data->aborting)
drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK;
@@ -797,8 +797,8 @@ static int mv64xxx_i2c_xfer_atomic(struct i2c_adapter *adap,
}
static const struct i2c_algorithm mv64xxx_i2c_algo = {
- .master_xfer = mv64xxx_i2c_xfer,
- .master_xfer_atomic = mv64xxx_i2c_xfer_atomic,
+ .xfer = mv64xxx_i2c_xfer,
+ .xfer_atomic = mv64xxx_i2c_xfer_atomic,
.functionality = mv64xxx_i2c_functionality,
};
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 4f41a3c7824d..ad0f02acdb12 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -542,12 +542,9 @@ static int read_i2c(struct nmk_i2c_dev *priv, u16 flags)
xfer_done = nmk_i2c_wait_xfer_done(priv);
- if (!xfer_done) {
- /* Controller timed out */
- dev_err(&priv->adev->dev, "read from slave 0x%x timed out\n",
- priv->cli.slave_adr);
+ if (!xfer_done)
status = -ETIMEDOUT;
- }
+
return status;
}
@@ -1194,7 +1191,6 @@ MODULE_DEVICE_TABLE(amba, nmk_i2c_ids);
static struct amba_driver nmk_i2c_driver = {
.drv = {
- .owner = THIS_MODULE,
.name = DRIVER_NAME,
.pm = pm_ptr(&nmk_i2c_pm),
},
diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c
index 26622d24bb1b..9bcaa29a7191 100644
--- a/drivers/i2c/busses/i2c-nvidia-gpu.c
+++ b/drivers/i2c/busses/i2c-nvidia-gpu.c
@@ -163,8 +163,7 @@ static int gpu_i2c_write(struct gpu_i2c_dev *i2cd, u8 data)
return gpu_i2c_check_status(i2cd);
}
-static int gpu_i2c_master_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs, int num)
+static int gpu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
struct gpu_i2c_dev *i2cd = i2c_get_adapdata(adap);
int status, status2;
@@ -234,8 +233,8 @@ static u32 gpu_i2c_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm gpu_i2c_algorithm = {
- .master_xfer = gpu_i2c_master_xfer,
- .functionality = gpu_i2c_functionality,
+ .xfer = gpu_i2c_xfer,
+ .functionality = gpu_i2c_functionality,
};
/*
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index e106af83cef4..482b37c8a129 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -32,7 +32,6 @@
*/
struct ocores_i2c {
void __iomem *base;
- int iobase;
u32 reg_shift;
u32 reg_io_width;
unsigned long flags;
@@ -136,16 +135,6 @@ static inline u8 oc_getreg_32be(struct ocores_i2c *i2c, int reg)
return ioread32be(i2c->base + (reg << i2c->reg_shift));
}
-static void oc_setreg_io_8(struct ocores_i2c *i2c, int reg, u8 value)
-{
- outb(value, i2c->iobase + reg);
-}
-
-static inline u8 oc_getreg_io_8(struct ocores_i2c *i2c, int reg)
-{
- return inb(i2c->iobase + reg);
-}
-
static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value)
{
i2c->setreg(i2c, reg, value);
@@ -442,8 +431,8 @@ static int ocores_init(struct device *dev, struct ocores_i2c *i2c)
oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8);
/* Init the device */
- oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN);
+ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
return 0;
}
@@ -455,8 +444,8 @@ static u32 ocores_func(struct i2c_adapter *adap)
}
static struct i2c_algorithm ocores_algorithm = {
- .master_xfer = ocores_xfer,
- .master_xfer_atomic = ocores_xfer_polling,
+ .xfer = ocores_xfer,
+ .xfer_atomic = ocores_xfer_polling,
.functionality = ocores_func,
};
@@ -618,15 +607,19 @@ static int ocores_i2c_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!res)
return -EINVAL;
- i2c->iobase = res->start;
if (!devm_request_region(&pdev->dev, res->start,
resource_size(res),
pdev->name)) {
dev_err(&pdev->dev, "Can't get I/O resource.\n");
return -EBUSY;
}
- i2c->setreg = oc_setreg_io_8;
- i2c->getreg = oc_getreg_io_8;
+ i2c->base = devm_ioport_map(&pdev->dev, res->start,
+ resource_size(res));
+ if (!i2c->base) {
+ dev_err(&pdev->dev, "Can't map I/O resource.\n");
+ return -EBUSY;
+ }
+ i2c->reg_io_width = 1;
}
pdata = dev_get_platdata(&pdev->dev);
@@ -689,13 +682,13 @@ static int ocores_i2c_probe(struct platform_device *pdev)
}
if (irq == -ENXIO) {
- ocores_algorithm.master_xfer = ocores_xfer_polling;
+ ocores_algorithm.xfer = ocores_xfer_polling;
} else {
if (irq < 0)
return irq;
}
- if (ocores_algorithm.master_xfer != ocores_xfer_polling) {
+ if (ocores_algorithm.xfer != ocores_xfer_polling) {
ret = devm_request_any_context_irq(&pdev->dev, irq,
ocores_isr, 0,
pdev->name, i2c);
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index 845eda70b8ca..16cc34a0526e 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -17,9 +17,14 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/pci.h>
#include "i2c-octeon-core.h"
+#define INITIAL_DELTA_HZ 1000000
+#define TWSI_MASTER_CLK_REG_DEF_VAL 0x18
+#define TWSI_MASTER_CLK_REG_OTX2_VAL 0x3
+
/* interrupt service routine */
irqreturn_t octeon_i2c_isr(int irq, void *dev_id)
{
@@ -80,7 +85,7 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c)
static bool octeon_i2c_hlc_test_valid(struct octeon_i2c *i2c)
{
- return (__raw_readq(i2c->twsi_base + SW_TWSI(i2c)) & SW_TWSI_V) == 0;
+ return (__raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)) & SW_TWSI_V) == 0;
}
static void octeon_i2c_hlc_int_clear(struct octeon_i2c *i2c)
@@ -177,13 +182,14 @@ static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c)
static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
{
u8 stat;
+ u64 mode;
/*
* This is ugly... in HLC mode the status is not in the status register
- * but in the lower 8 bits of SW_TWSI.
+ * but in the lower 8 bits of OCTEON_REG_SW_TWSI.
*/
if (i2c->hlc_enabled)
- stat = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ stat = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
else
stat = octeon_i2c_stat_read(i2c);
@@ -215,14 +221,14 @@ static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
case STAT_LOST_ARB_B0:
return -EAGAIN;
- /* Being addressed as slave, should back off & listen */
+ /* Being addressed as local target, should back off & listen */
case STAT_SLAVE_60:
case STAT_SLAVE_70:
case STAT_GENDATA_ACK:
case STAT_GENDATA_NAK:
return -EOPNOTSUPP;
- /* Core busy as slave */
+ /* Core busy as local target */
case STAT_SLAVE_80:
case STAT_SLAVE_88:
case STAT_SLAVE_A0:
@@ -239,6 +245,13 @@ static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
case STAT_RXADDR_NAK:
case STAT_AD2W_NAK:
return -ENXIO;
+
+ case STAT_WDOG_TOUT:
+ mode = __raw_readq(i2c->twsi_base + OCTEON_REG_MODE(i2c));
+ /* Set BUS_MON_RST to reset bus monitor */
+ mode |= BUS_MON_RST_MASK;
+ octeon_i2c_writeq_flush(mode, i2c->twsi_base + OCTEON_REG_MODE(i2c));
+ return -EIO;
default:
dev_err(i2c->dev, "unhandled state: %d\n", stat);
return -EIO;
@@ -419,12 +432,12 @@ static int octeon_i2c_hlc_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
else
cmd |= SW_TWSI_OP_7;
- octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+ octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
ret = octeon_i2c_hlc_wait(i2c);
if (ret)
goto err;
- cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
if ((cmd & SW_TWSI_R) == 0)
return octeon_i2c_check_status(i2c, false);
@@ -432,7 +445,7 @@ static int octeon_i2c_hlc_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff;
if (msgs[0].len > 4) {
- cmd = __raw_readq(i2c->twsi_base + SW_TWSI_EXT(i2c));
+ cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
for (i = 0; i < msgs[0].len - 4 && i < 4; i++, j--)
msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff;
}
@@ -469,15 +482,15 @@ static int octeon_i2c_hlc_write(struct octeon_i2c *i2c, struct i2c_msg *msgs)
for (i = 0; i < msgs[0].len - 4 && i < 4; i++, j--)
ext |= (u64)msgs[0].buf[j] << (8 * i);
- octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
+ octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
}
- octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+ octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
ret = octeon_i2c_hlc_wait(i2c);
if (ret)
goto err;
- cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
if ((cmd & SW_TWSI_R) == 0)
return octeon_i2c_check_status(i2c, false);
@@ -510,19 +523,19 @@ static int octeon_i2c_hlc_comp_read(struct octeon_i2c *i2c, struct i2c_msg *msgs
cmd |= SW_TWSI_EIA;
ext = (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
cmd |= (u64)msgs[0].buf[1] << SW_TWSI_IA_SHIFT;
- octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
+ octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
} else {
cmd |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
}
octeon_i2c_hlc_int_clear(i2c);
- octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+ octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
ret = octeon_i2c_hlc_wait(i2c);
if (ret)
goto err;
- cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
if ((cmd & SW_TWSI_R) == 0)
return octeon_i2c_check_status(i2c, false);
@@ -530,7 +543,7 @@ static int octeon_i2c_hlc_comp_read(struct octeon_i2c *i2c, struct i2c_msg *msgs
msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff;
if (msgs[1].len > 4) {
- cmd = __raw_readq(i2c->twsi_base + SW_TWSI_EXT(i2c));
+ cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
for (i = 0; i < msgs[1].len - 4 && i < 4; i++, j--)
msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff;
}
@@ -577,16 +590,16 @@ static int octeon_i2c_hlc_comp_write(struct octeon_i2c *i2c, struct i2c_msg *msg
set_ext = true;
}
if (set_ext)
- octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
+ octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c));
octeon_i2c_hlc_int_clear(i2c);
- octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
+ octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
ret = octeon_i2c_hlc_wait(i2c);
if (ret)
goto err;
- cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
if ((cmd & SW_TWSI_R) == 0)
return octeon_i2c_check_status(i2c, false);
@@ -595,7 +608,7 @@ err:
}
/**
- * octeon_i2c_xfer - The driver's master_xfer function
+ * octeon_i2c_xfer - The driver's xfer function
* @adap: Pointer to the i2c_adapter structure
* @msgs: Pointer to the messages to be processed
* @num: Length of the MSGS array
@@ -607,25 +620,27 @@ int octeon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
struct octeon_i2c *i2c = i2c_get_adapdata(adap);
int i, ret = 0;
- if (num == 1) {
- if (msgs[0].len > 0 && msgs[0].len <= 8) {
- if (msgs[0].flags & I2C_M_RD)
- ret = octeon_i2c_hlc_read(i2c, msgs);
- else
- ret = octeon_i2c_hlc_write(i2c, msgs);
- goto out;
- }
- } else if (num == 2) {
- if ((msgs[0].flags & I2C_M_RD) == 0 &&
- (msgs[1].flags & I2C_M_RECV_LEN) == 0 &&
- msgs[0].len > 0 && msgs[0].len <= 2 &&
- msgs[1].len > 0 && msgs[1].len <= 8 &&
- msgs[0].addr == msgs[1].addr) {
- if (msgs[1].flags & I2C_M_RD)
- ret = octeon_i2c_hlc_comp_read(i2c, msgs);
- else
- ret = octeon_i2c_hlc_comp_write(i2c, msgs);
- goto out;
+ if (IS_LS_FREQ(i2c->twsi_freq)) {
+ if (num == 1) {
+ if (msgs[0].len > 0 && msgs[0].len <= 8) {
+ if (msgs[0].flags & I2C_M_RD)
+ ret = octeon_i2c_hlc_read(i2c, msgs);
+ else
+ ret = octeon_i2c_hlc_write(i2c, msgs);
+ goto out;
+ }
+ } else if (num == 2) {
+ if ((msgs[0].flags & I2C_M_RD) == 0 &&
+ (msgs[1].flags & I2C_M_RECV_LEN) == 0 &&
+ msgs[0].len > 0 && msgs[0].len <= 2 &&
+ msgs[1].len > 0 && msgs[1].len <= 8 &&
+ msgs[0].addr == msgs[1].addr) {
+ if (msgs[1].flags & I2C_M_RD)
+ ret = octeon_i2c_hlc_comp_read(i2c, msgs);
+ else
+ ret = octeon_i2c_hlc_comp_write(i2c, msgs);
+ goto out;
+ }
}
}
@@ -658,31 +673,64 @@ out:
void octeon_i2c_set_clock(struct octeon_i2c *i2c)
{
int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff;
- int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000;
+ bool is_plat_otx2;
+ /*
+ * Find divisors to produce target frequency, start with large delta
+ * to cover wider range of divisors, note thp = TCLK half period and
+ * ds is OSCL output frequency divisor.
+ */
+ unsigned int thp, mdiv_min, mdiv = 2, ndiv = 0, ds = 10;
+ unsigned int delta_hz = INITIAL_DELTA_HZ;
+
+ is_plat_otx2 = octeon_i2c_is_otx2(to_pci_dev(i2c->dev));
+
+ if (is_plat_otx2) {
+ thp = TWSI_MASTER_CLK_REG_OTX2_VAL;
+ mdiv_min = 0;
+ if (!IS_LS_FREQ(i2c->twsi_freq))
+ ds = 15;
+ } else {
+ thp = TWSI_MASTER_CLK_REG_DEF_VAL;
+ mdiv_min = 2;
+ }
for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) {
/*
* An mdiv value of less than 2 seems to not work well
* with ds1337 RTCs, so we constrain it to larger values.
*/
- for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) {
+ for (mdiv_idx = 15; mdiv_idx >= mdiv_min && delta_hz != 0; mdiv_idx--) {
/*
* For given ndiv and mdiv values check the
* two closest thp values.
*/
- tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10;
+ tclk = i2c->twsi_freq * (mdiv_idx + 1) * ds;
tclk *= (1 << ndiv_idx);
- thp_base = (i2c->sys_freq / (tclk * 2)) - 1;
+ if (is_plat_otx2)
+ thp_base = (i2c->sys_freq / tclk) - 2;
+ else
+ thp_base = (i2c->sys_freq / (tclk * 2)) - 1;
for (inc = 0; inc <= 1; inc++) {
thp_idx = thp_base + inc;
if (thp_idx < 5 || thp_idx > 0xff)
continue;
- foscl = i2c->sys_freq / (2 * (thp_idx + 1));
+ if (is_plat_otx2)
+ foscl = i2c->sys_freq / (thp_idx + 2);
+ else
+ foscl = i2c->sys_freq /
+ (2 * (thp_idx + 1));
foscl = foscl / (1 << ndiv_idx);
- foscl = foscl / (mdiv_idx + 1) / 10;
+ foscl = foscl / (mdiv_idx + 1) / ds;
+ if (foscl > i2c->twsi_freq)
+ continue;
diff = abs(foscl - i2c->twsi_freq);
+ /*
+ * Diff holds difference between calculated frequency
+ * value vs desired frequency.
+ * Delta_hz is updated with last minimum diff.
+ */
if (diff < delta_hz) {
delta_hz = diff;
thp = thp_idx;
@@ -694,6 +742,17 @@ void octeon_i2c_set_clock(struct octeon_i2c *i2c)
}
octeon_i2c_reg_write(i2c, SW_TWSI_OP_TWSI_CLK, thp);
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv);
+ if (is_plat_otx2) {
+ u64 mode;
+
+ mode = __raw_readq(i2c->twsi_base + OCTEON_REG_MODE(i2c));
+ /* Set REFCLK_SRC and HS_MODE in TWSX_MODE register */
+ if (!IS_LS_FREQ(i2c->twsi_freq))
+ mode |= TWSX_MODE_HS_MASK;
+ else
+ mode &= ~TWSX_MODE_HS_MASK;
+ octeon_i2c_writeq_flush(mode, i2c->twsi_base + OCTEON_REG_MODE(i2c));
+ }
}
int octeon_i2c_init_lowlevel(struct octeon_i2c *i2c)
diff --git a/drivers/i2c/busses/i2c-octeon-core.h b/drivers/i2c/busses/i2c-octeon-core.h
index 9bb9f64fdda0..b265e21189a1 100644
--- a/drivers/i2c/busses/i2c-octeon-core.h
+++ b/drivers/i2c/busses/i2c-octeon-core.h
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/atomic.h>
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -7,6 +8,7 @@
#include <linux/i2c-smbus.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/pci.h>
/* Controller command patterns */
#define SW_TWSI_V BIT_ULL(63) /* Valid bit */
@@ -37,8 +39,8 @@
/* Controller command and status bits */
#define TWSI_CTL_CE 0x80 /* High level controller enable */
#define TWSI_CTL_ENAB 0x40 /* Bus enable */
-#define TWSI_CTL_STA 0x20 /* Master-mode start, HW clears when done */
-#define TWSI_CTL_STP 0x10 /* Master-mode stop, HW clears when done */
+#define TWSI_CTL_STA 0x20 /* Controller-mode start, HW clears when done */
+#define TWSI_CTL_STP 0x10 /* Controller-mode stop, HW clears when done */
#define TWSI_CTL_IFLG 0x08 /* HW event, SW writes 0 to ACK */
#define TWSI_CTL_AAK 0x04 /* Assert ACK */
@@ -71,6 +73,7 @@
#define STAT_SLAVE_ACK 0xC8
#define STAT_AD2W_ACK 0xD0
#define STAT_AD2W_NAK 0xD8
+#define STAT_WDOG_TOUT 0xF0
#define STAT_IDLE 0xF8
/* TWSI_INT values */
@@ -92,11 +95,21 @@ struct octeon_i2c_reg_offset {
unsigned int sw_twsi;
unsigned int twsi_int;
unsigned int sw_twsi_ext;
+ unsigned int mode;
};
-#define SW_TWSI(x) (x->roff.sw_twsi)
-#define TWSI_INT(x) (x->roff.twsi_int)
-#define SW_TWSI_EXT(x) (x->roff.sw_twsi_ext)
+#define OCTEON_REG_SW_TWSI(x) ((x)->roff.sw_twsi)
+#define OCTEON_REG_TWSI_INT(x) ((x)->roff.twsi_int)
+#define OCTEON_REG_SW_TWSI_EXT(x) ((x)->roff.sw_twsi_ext)
+#define OCTEON_REG_MODE(x) ((x)->roff.mode)
+
+/* Set REFCLK_SRC and HS_MODE in TWSX_MODE register */
+#define TWSX_MODE_REFCLK_SRC BIT(4)
+#define TWSX_MODE_HS_MODE BIT(0)
+#define TWSX_MODE_HS_MASK (TWSX_MODE_REFCLK_SRC | TWSX_MODE_HS_MODE)
+
+/* Set BUS_MON_RST to reset bus monitor */
+#define BUS_MON_RST_MASK BIT(3)
struct octeon_i2c {
wait_queue_head_t queue;
@@ -134,16 +147,16 @@ static inline void octeon_i2c_writeq_flush(u64 val, void __iomem *addr)
* @eop_reg: Register selector
* @data: Value to be written
*
- * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
+ * The I2C core registers are accessed indirectly via the OCTEON_REG_SW_TWSI CSR.
*/
static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8 data)
{
int tries = 1000;
u64 tmp;
- __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI(i2c));
+ __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
do {
- tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ tmp = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
if (--tries < 0)
return;
} while ((tmp & SW_TWSI_V) != 0);
@@ -169,9 +182,9 @@ static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
int tries = 1000;
u64 tmp;
- __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI(i2c));
+ __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
do {
- tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+ tmp = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
if (--tries < 0) {
/* signal that the returned data is invalid */
if (error)
@@ -191,24 +204,40 @@ static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT, NULL)
/**
- * octeon_i2c_read_int - read the TWSI_INT register
+ * octeon_i2c_read_int - read the OCTEON_REG_TWSI_INT register
* @i2c: The struct octeon_i2c
*
* Returns the value of the register.
*/
static inline u64 octeon_i2c_read_int(struct octeon_i2c *i2c)
{
- return __raw_readq(i2c->twsi_base + TWSI_INT(i2c));
+ return __raw_readq(i2c->twsi_base + OCTEON_REG_TWSI_INT(i2c));
}
/**
- * octeon_i2c_write_int - write the TWSI_INT register
+ * octeon_i2c_write_int - write the OCTEON_REG_TWSI_INT register
* @i2c: The struct octeon_i2c
* @data: Value to be written
*/
static inline void octeon_i2c_write_int(struct octeon_i2c *i2c, u64 data)
{
- octeon_i2c_writeq_flush(data, i2c->twsi_base + TWSI_INT(i2c));
+ octeon_i2c_writeq_flush(data, i2c->twsi_base + OCTEON_REG_TWSI_INT(i2c));
+}
+
+#define IS_LS_FREQ(twsi_freq) ((twsi_freq) <= 400000)
+#define PCI_SUBSYS_DEVID_9XXX 0xB
+#define PCI_SUBSYS_MASK GENMASK(15, 12)
+/**
+ * octeon_i2c_is_otx2 - check for chip ID
+ * @pdev: PCI dev structure
+ *
+ * Returns true if the device is an OcteonTX2, false otherwise.
+ */
+static inline bool octeon_i2c_is_otx2(struct pci_dev *pdev)
+{
+ u32 chip_id = FIELD_GET(PCI_SUBSYS_MASK, pdev->subsystem_device);
+
+ return (chip_id == PCI_SUBSYS_DEVID_9XXX);
}
/* Prototypes */
diff --git a/drivers/i2c/busses/i2c-octeon-platdrv.c b/drivers/i2c/busses/i2c-octeon-platdrv.c
index 7d54b3203f71..dc6dff95c68c 100644
--- a/drivers/i2c/busses/i2c-octeon-platdrv.c
+++ b/drivers/i2c/busses/i2c-octeon-platdrv.c
@@ -122,7 +122,7 @@ static u32 octeon_i2c_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm octeon_i2c_algo = {
- .master_xfer = octeon_i2c_xfer,
+ .xfer = octeon_i2c_xfer,
.functionality = octeon_i2c_functionality,
};
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 42165ef57946..35a3f0a64986 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -660,7 +660,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
struct i2c_msg *msg, int stop, bool polling)
{
struct omap_i2c_dev *omap = i2c_get_adapdata(adap);
- unsigned long timeout;
+ unsigned long time_left;
u16 w;
int ret;
@@ -740,19 +740,18 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
* into arbitration and we're currently unable to recover from it.
*/
if (!polling) {
- timeout = wait_for_completion_timeout(&omap->cmd_complete,
- OMAP_I2C_TIMEOUT);
+ time_left = wait_for_completion_timeout(&omap->cmd_complete,
+ OMAP_I2C_TIMEOUT);
} else {
do {
omap_i2c_wait(omap);
ret = omap_i2c_xfer_data(omap);
} while (ret == -EAGAIN);
- timeout = !ret;
+ time_left = !ret;
}
- if (timeout == 0) {
- dev_err(omap->dev, "controller timed out\n");
+ if (time_left == 0) {
omap_i2c_reset(omap);
__omap_i2c_init(omap);
return -ETIMEDOUT;
@@ -1535,7 +1534,7 @@ static void omap_i2c_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
}
-static int __maybe_unused omap_i2c_runtime_suspend(struct device *dev)
+static int omap_i2c_runtime_suspend(struct device *dev)
{
struct omap_i2c_dev *omap = dev_get_drvdata(dev);
@@ -1561,7 +1560,7 @@ static int __maybe_unused omap_i2c_runtime_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused omap_i2c_runtime_resume(struct device *dev)
+static int omap_i2c_runtime_resume(struct device *dev)
{
struct omap_i2c_dev *omap = dev_get_drvdata(dev);
@@ -1575,11 +1574,33 @@ static int __maybe_unused omap_i2c_runtime_resume(struct device *dev)
return 0;
}
+static int omap_i2c_suspend(struct device *dev)
+{
+ /*
+ * If the controller is autosuspended, there is no way to wakeup it once
+ * runtime pm is disabled (in suspend_late()).
+ * But a device may need the controller up during suspend_noirq() or
+ * resume_noirq().
+ * Wakeup the controller while runtime pm is enabled, so it is available
+ * until its suspend_noirq(), and from resume_noirq().
+ */
+ return pm_runtime_resume_and_get(dev);
+}
+
+static int omap_i2c_resume(struct device *dev)
+{
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
+
+ return 0;
+}
+
static const struct dev_pm_ops omap_i2c_pm_ops = {
- SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
- pm_runtime_force_resume)
- SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend,
- omap_i2c_runtime_resume, NULL)
+ NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SYSTEM_SLEEP_PM_OPS(omap_i2c_suspend, omap_i2c_resume)
+ RUNTIME_PM_OPS(omap_i2c_runtime_suspend,
+ omap_i2c_runtime_resume, NULL)
};
static struct platform_driver omap_i2c_driver = {
@@ -1587,7 +1608,7 @@ static struct platform_driver omap_i2c_driver = {
.remove_new = omap_i2c_remove,
.driver = {
.name = "omap_i2c",
- .pm = &omap_i2c_pm_ops,
+ .pm = pm_ptr(&omap_i2c_pm_ops),
.of_match_table = of_match_ptr(omap_i2c_of_match),
},
};
diff --git a/drivers/i2c/busses/i2c-opal.c b/drivers/i2c/busses/i2c-opal.c
index 17ef87d50f7c..d9dd71cf37fd 100644
--- a/drivers/i2c/busses/i2c-opal.c
+++ b/drivers/i2c/busses/i2c-opal.c
@@ -70,8 +70,8 @@ exit:
return rc;
}
-static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
- int num)
+static int i2c_opal_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
{
unsigned long opal_id = (unsigned long)adap->algo_data;
struct opal_i2c_request req;
@@ -179,9 +179,9 @@ static u32 i2c_opal_func(struct i2c_adapter *adapter)
}
static const struct i2c_algorithm i2c_opal_algo = {
- .master_xfer = i2c_opal_master_xfer,
- .smbus_xfer = i2c_opal_smbus_xfer,
- .functionality = i2c_opal_func,
+ .xfer = i2c_opal_xfer,
+ .smbus_xfer = i2c_opal_smbus_xfer,
+ .functionality = i2c_opal_func,
};
/*
diff --git a/drivers/i2c/busses/i2c-owl.c b/drivers/i2c/busses/i2c-owl.c
index 777f1a0278c7..84a195e35886 100644
--- a/drivers/i2c/busses/i2c-owl.c
+++ b/drivers/i2c/busses/i2c-owl.c
@@ -172,7 +172,7 @@ static void owl_i2c_xfer_data(struct owl_i2c_dev *i2c_dev)
i2c_dev->err = 0;
- /* Handle NACK from slave */
+ /* Handle NACK from target */
fifostat = readl(i2c_dev->base + OWL_I2C_REG_FIFOSTAT);
if (fifostat & OWL_I2C_FIFOSTAT_RNB) {
i2c_dev->err = -ENXIO;
@@ -302,7 +302,7 @@ static int owl_i2c_xfer_common(struct i2c_adapter *adap, struct i2c_msg *msgs,
OWL_I2C_CTL_IRQE, !atomic);
/*
- * Select: FIFO enable, Master mode, Stop enable, Data count enable,
+ * Select: FIFO enable, controller mode, Stop enable, Data count enable,
* Send start bit
*/
i2c_cmd = OWL_I2C_CMD_SECL | OWL_I2C_CMD_MSS | OWL_I2C_CMD_SE |
@@ -314,7 +314,7 @@ static int owl_i2c_xfer_common(struct i2c_adapter *adap, struct i2c_msg *msgs,
i2c_cmd |= OWL_I2C_CMD_AS(msgs[0].len + 1) |
OWL_I2C_CMD_SAS(1) | OWL_I2C_CMD_RBE;
- /* Write slave address */
+ /* Write target address */
addr = i2c_8bit_addr_from_msg(&msgs[0]);
writel(addr, i2c_dev->base + OWL_I2C_REG_TXDAT);
@@ -420,9 +420,9 @@ static int owl_i2c_xfer_atomic(struct i2c_adapter *adap,
}
static const struct i2c_algorithm owl_i2c_algorithm = {
- .master_xfer = owl_i2c_xfer,
- .master_xfer_atomic = owl_i2c_xfer_atomic,
- .functionality = owl_i2c_func,
+ .xfer = owl_i2c_xfer,
+ .xfer_atomic = owl_i2c_xfer_atomic,
+ .functionality = owl_i2c_func,
};
static const struct i2c_adapter_quirks owl_i2c_quirks = {
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 0af86a542568..3249bbd5eb43 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -400,7 +400,6 @@ static struct parport_driver i2c_parport_driver = {
.name = "i2c-parport",
.match_port = i2c_parport_attach,
.detach = i2c_parport_detach,
- .devmodel = true,
};
module_parport_driver(i2c_parport_driver);
diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
index bd8becbdeeb2..dac694a9d781 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.c
+++ b/drivers/i2c/busses/i2c-pasemi-core.c
@@ -336,9 +336,9 @@ static u32 pasemi_smb_func(struct i2c_adapter *adapter)
}
static const struct i2c_algorithm smbus_algorithm = {
- .master_xfer = pasemi_i2c_xfer,
- .smbus_xfer = pasemi_smb_xfer,
- .functionality = pasemi_smb_func,
+ .xfer = pasemi_i2c_xfer,
+ .smbus_xfer = pasemi_smb_xfer,
+ .functionality = pasemi_smb_func,
};
int pasemi_i2c_common_probe(struct pasemi_smbus *smbus)
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 6a0392172b2f..4e32d57ae0bf 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -29,6 +29,7 @@
#include <linux/stddef.h>
#include <linux/ioport.h>
#include <linux/i2c.h>
+#include <linux/i2c-smbus.h>
#include <linux/slab.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
@@ -589,7 +590,7 @@ static int piix4_transaction(struct i2c_adapter *piix4_adapter)
result = -EIO;
dev_dbg(&piix4_adapter->dev, "Bus collision! SMBus may be "
"locked until next hard reset. (sorry!)\n");
- /* Clock stops and slave is stuck in mid-transmission */
+ /* Clock stops and target is stuck in mid-transmission */
}
if (temp & 0x04) {
@@ -982,6 +983,14 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
return retval;
}
+ /*
+ * The AUX bus can not be probed as on some platforms it reports all
+ * devices present and all reads return "0".
+ * This would allow the ee1004 to be probed incorrectly.
+ */
+ if (port == 0)
+ i2c_register_spd(adap);
+
*padap = adap;
return 0;
}
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index a12525b3186b..f448505d5468 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -15,7 +15,6 @@
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/i2c.h>
-#include <linux/timer.h>
#include <linux/completion.h>
#include <linux/platform_device.h>
#include <linux/io.h>
@@ -32,7 +31,6 @@ struct i2c_pnx_mif {
int ret; /* Return value */
int mode; /* Interface mode */
struct completion complete; /* I/O completion */
- struct timer_list timer; /* Timeout */
u8 * buf; /* Data buffer */
int len; /* Length of data buffer */
int order; /* RX Bytes to order via TX */
@@ -117,24 +115,6 @@ static inline int wait_reset(struct i2c_pnx_algo_data *data)
return (timeout <= 0);
}
-static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data)
-{
- struct timer_list *timer = &alg_data->mif.timer;
- unsigned long expires = msecs_to_jiffies(alg_data->timeout);
-
- if (expires <= 1)
- expires = 2;
-
- del_timer_sync(timer);
-
- dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n",
- jiffies, expires);
-
- timer->expires = jiffies + expires;
-
- add_timer(timer);
-}
-
/**
* i2c_pnx_start - start a device
* @slave_addr: slave address
@@ -259,8 +239,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
I2C_REG_CTL(alg_data));
- del_timer_sync(&alg_data->mif.timer);
-
dev_dbg(&alg_data->adapter.dev,
"%s(): Waking up xfer routine.\n",
__func__);
@@ -276,8 +254,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
I2C_REG_CTL(alg_data));
- /* Stop timer. */
- del_timer_sync(&alg_data->mif.timer);
dev_dbg(&alg_data->adapter.dev,
"%s(): Waking up xfer routine after zero-xfer.\n",
__func__);
@@ -364,8 +340,6 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
mcntrl_drmie | mcntrl_daie);
iowrite32(ctl, I2C_REG_CTL(alg_data));
- /* Kill timer. */
- del_timer_sync(&alg_data->mif.timer);
complete(&alg_data->mif.complete);
}
}
@@ -400,8 +374,6 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
mcntrl_drmie);
iowrite32(ctl, I2C_REG_CTL(alg_data));
- /* Stop timer, to prevent timeout. */
- del_timer_sync(&alg_data->mif.timer);
complete(&alg_data->mif.complete);
} else if (stat & mstatus_nai) {
/* Slave did not acknowledge, generate a STOP */
@@ -419,8 +391,6 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
/* Our return value. */
alg_data->mif.ret = -EIO;
- /* Stop timer, to prevent timeout. */
- del_timer_sync(&alg_data->mif.timer);
complete(&alg_data->mif.complete);
} else {
/*
@@ -453,9 +423,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void i2c_pnx_timeout(struct timer_list *t)
+static void i2c_pnx_timeout(struct i2c_pnx_algo_data *alg_data)
{
- struct i2c_pnx_algo_data *alg_data = from_timer(alg_data, t, mif.timer);
u32 ctl;
dev_err(&alg_data->adapter.dev,
@@ -472,7 +441,6 @@ static void i2c_pnx_timeout(struct timer_list *t)
iowrite32(ctl, I2C_REG_CTL(alg_data));
wait_reset(alg_data);
alg_data->mif.ret = -EIO;
- complete(&alg_data->mif.complete);
}
static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)
@@ -514,6 +482,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
struct i2c_msg *pmsg;
int rc = 0, completed = 0, i;
struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+ unsigned long time_left;
u32 stat;
dev_dbg(&alg_data->adapter.dev,
@@ -548,7 +517,6 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n",
__func__, alg_data->mif.mode, alg_data->mif.len);
- i2c_pnx_arm_timer(alg_data);
/* initialize the completion var */
init_completion(&alg_data->mif.complete);
@@ -564,7 +532,10 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
break;
/* Wait for completion */
- wait_for_completion(&alg_data->mif.complete);
+ time_left = wait_for_completion_timeout(&alg_data->mif.complete,
+ alg_data->timeout);
+ if (time_left == 0)
+ i2c_pnx_timeout(alg_data);
if (!(rc = alg_data->mif.ret))
completed++;
@@ -653,7 +624,10 @@ static int i2c_pnx_probe(struct platform_device *pdev)
alg_data->adapter.algo_data = alg_data;
alg_data->adapter.nr = pdev->id;
- alg_data->timeout = I2C_PNX_TIMEOUT_DEFAULT;
+ alg_data->timeout = msecs_to_jiffies(I2C_PNX_TIMEOUT_DEFAULT);
+ if (alg_data->timeout <= 1)
+ alg_data->timeout = 2;
+
#ifdef CONFIG_OF
alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node);
if (pdev->dev.of_node) {
@@ -673,8 +647,6 @@ static int i2c_pnx_probe(struct platform_device *pdev)
if (IS_ERR(alg_data->clk))
return PTR_ERR(alg_data->clk);
- timer_setup(&alg_data->mif.timer, i2c_pnx_timeout, 0);
-
snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name),
"%s", pdev->name);
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index 8e57ebe595be..b6b03539f626 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -127,13 +127,13 @@ static s32 i2c_powermac_smbus_xfer( struct i2c_adapter* adap,
}
/*
- * Generic i2c master transfer entrypoint. This driver only support single
+ * Generic i2c transfer entrypoint. This driver only supports single
* messages (for "lame i2c" transfers). Anything else should use the smbus
* entry point
*/
-static int i2c_powermac_master_xfer( struct i2c_adapter *adap,
- struct i2c_msg *msgs,
- int num)
+static int i2c_powermac_xfer(struct i2c_adapter *adap,
+ struct i2c_msg *msgs,
+ int num)
{
struct pmac_i2c_bus *bus = i2c_get_adapdata(adap);
int rc = 0;
@@ -179,9 +179,9 @@ static u32 i2c_powermac_func(struct i2c_adapter * adapter)
/* For now, we only handle smbus */
static const struct i2c_algorithm i2c_powermac_algorithm = {
- .smbus_xfer = i2c_powermac_smbus_xfer,
- .master_xfer = i2c_powermac_master_xfer,
- .functionality = i2c_powermac_func,
+ .smbus_xfer = i2c_powermac_smbus_xfer,
+ .xfer = i2c_powermac_xfer,
+ .functionality = i2c_powermac_func,
};
static const struct i2c_adapter_quirks i2c_powermac_quirks = {
diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c
index 08b3229c443d..6b3c6a733368 100644
--- a/drivers/i2c/busses/i2c-pxa-pci.c
+++ b/drivers/i2c/busses/i2c-pxa-pci.c
@@ -4,7 +4,7 @@
* Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
*
* The CE4100's I2C device is more or less the same one as found on PXA.
- * It does not support slave mode, the register slightly moved. This PCI
+ * It does not support target mode, the register slightly moved. This PCI
* device provides three bars, every contains a single I2C controller.
*/
#include <linux/init.h>
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 888ca636f3f3..031175113dd4 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -826,7 +826,7 @@ static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c)
static int i2c_pxa_send_mastercode(struct pxa_i2c *i2c)
{
u32 icr;
- long timeout;
+ long time_left;
spin_lock_irq(&i2c->lock);
i2c->highmode_enter = true;
@@ -837,12 +837,12 @@ static int i2c_pxa_send_mastercode(struct pxa_i2c *i2c)
writel(icr, _ICR(i2c));
spin_unlock_irq(&i2c->lock);
- timeout = wait_event_timeout(i2c->wait,
- i2c->highmode_enter == false, HZ * 1);
+ time_left = wait_event_timeout(i2c->wait,
+ i2c->highmode_enter == false, HZ * 1);
i2c->highmode_enter = false;
- return (timeout == 0) ? I2C_RETRY : 0;
+ return (time_left == 0) ? I2C_RETRY : 0;
}
/*
@@ -1050,7 +1050,7 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
*/
static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
{
- long timeout;
+ long time_left;
int ret;
/*
@@ -1095,7 +1095,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
/*
* The rest of the processing occurs in the interrupt handler.
*/
- timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+ time_left = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
i2c_pxa_stop_message(i2c);
/*
@@ -1103,7 +1103,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
*/
ret = i2c->msg_idx;
- if (!timeout && i2c->msg_num) {
+ if (!time_left && i2c->msg_num) {
i2c_pxa_scream_blue_murder(i2c, "timeout with active message");
i2c_recover_bus(&i2c->adap);
ret = I2C_RETRY;
@@ -1593,6 +1593,7 @@ static void __exit i2c_adap_pxa_exit(void)
platform_driver_unregister(&i2c_pxa_driver);
}
+MODULE_DESCRIPTION("Intel PXA2XX I2C adapter");
MODULE_LICENSE("GPL");
subsys_initcall(i2c_adap_pxa_init);
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index da94df466e83..0a8b95ce35f7 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -586,7 +586,8 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
{
struct dma_slave_config config = {};
struct gpi_i2c_config peripheral = {};
- int i, ret = 0, timeout;
+ int i, ret = 0;
+ unsigned long time_left;
dma_addr_t tx_addr, rx_addr;
void *tx_buf = NULL, *rx_buf = NULL;
const struct geni_i2c_clk_fld *itr = gi2c->clk_fld;
@@ -629,12 +630,9 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i
dma_async_issue_pending(gi2c->tx_c);
- timeout = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
- if (!timeout) {
- dev_err(gi2c->se.dev, "I2C timeout gpi flags:%d addr:0x%x\n",
- gi2c->cur->flags, gi2c->cur->addr);
+ time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
+ if (!time_left)
gi2c->err = -ETIMEDOUT;
- }
if (gi2c->err) {
ret = gi2c->err;
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 598102d16677..4a2c745751a2 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -793,10 +793,8 @@ static int qup_i2c_bam_schedule_desc(struct qup_i2c_dev *qup)
dma_async_issue_pending(qup->brx.dma);
}
- if (!wait_for_completion_timeout(&qup->xfer, qup->xfer_timeout)) {
- dev_err(qup->dev, "normal trans timed out\n");
+ if (!wait_for_completion_timeout(&qup->xfer, qup->xfer_timeout))
ret = -ETIMEDOUT;
- }
if (ret || qup->bus_err || qup->qup_err) {
reinit_completion(&qup->xfer);
@@ -1987,5 +1985,6 @@ static struct platform_driver qup_i2c_driver = {
module_platform_driver(qup_i2c_driver);
+MODULE_DESCRIPTION("Qualcomm QUP based I2C controller");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:i2c_qup");
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index 828aa2ea0fe4..da4b07c0ed4c 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -191,8 +191,7 @@ static int rcar_i2c_get_scl(struct i2c_adapter *adap)
struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
return !!(rcar_i2c_read(priv, ICMCR) & FSCL);
-
-};
+}
static void rcar_i2c_set_scl(struct i2c_adapter *adap, int val)
{
@@ -204,7 +203,7 @@ static void rcar_i2c_set_scl(struct i2c_adapter *adap, int val)
priv->recovery_icmcr &= ~FSCL;
rcar_i2c_write(priv, ICMCR, priv->recovery_icmcr);
-};
+}
static void rcar_i2c_set_sda(struct i2c_adapter *adap, int val)
{
@@ -216,15 +215,14 @@ static void rcar_i2c_set_sda(struct i2c_adapter *adap, int val)
priv->recovery_icmcr &= ~FSDA;
rcar_i2c_write(priv, ICMCR, priv->recovery_icmcr);
-};
+}
static int rcar_i2c_get_bus_free(struct i2c_adapter *adap)
{
struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
return !(rcar_i2c_read(priv, ICMCR) & FSDA);
-
-};
+}
static struct i2c_bus_recovery_info rcar_i2c_bri = {
.get_scl = rcar_i2c_get_scl,
@@ -233,6 +231,7 @@ static struct i2c_bus_recovery_info rcar_i2c_bri = {
.get_bus_free = rcar_i2c_get_bus_free,
.recover_bus = i2c_generic_scl_recovery,
};
+
static void rcar_i2c_init(struct rcar_i2c_priv *priv)
{
/* reset master mode */
@@ -257,6 +256,14 @@ static void rcar_i2c_init(struct rcar_i2c_priv *priv)
}
}
+static void rcar_i2c_reset_slave(struct rcar_i2c_priv *priv)
+{
+ rcar_i2c_write(priv, ICSIER, 0);
+ rcar_i2c_write(priv, ICSSR, 0);
+ rcar_i2c_write(priv, ICSCR, SDBS);
+ rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
+}
+
static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
{
int ret;
@@ -545,7 +552,7 @@ static void rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)
u32 irqs_to_clear = MDE;
/* FIXME: sometimes, unknown interrupt happened. Do nothing */
- if (!(msr & MDE))
+ if (WARN(!(msr & MDE), "spurious irq"))
return;
if (msr & MAT)
@@ -875,6 +882,10 @@ static int rcar_i2c_do_reset(struct rcar_i2c_priv *priv)
{
int ret;
+ /* Don't reset if a slave instance is currently running */
+ if (priv->slave)
+ return -EISCONN;
+
ret = reset_control_reset(priv->rstc);
if (ret)
return ret;
@@ -903,10 +914,10 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
/* Gen3+ needs a reset. That also allows RXDMA once */
if (priv->devtype >= I2C_RCAR_GEN3) {
- priv->flags &= ~ID_P_NO_RXDMA;
ret = rcar_i2c_do_reset(priv);
if (ret)
goto out;
+ priv->flags &= ~ID_P_NO_RXDMA;
}
rcar_i2c_init(priv);
@@ -1033,11 +1044,8 @@ static int rcar_unreg_slave(struct i2c_client *slave)
/* ensure no irq is running before clearing ptr */
disable_irq(priv->irq);
- rcar_i2c_write(priv, ICSIER, 0);
- rcar_i2c_write(priv, ICSSR, 0);
+ rcar_i2c_reset_slave(priv);
enable_irq(priv->irq);
- rcar_i2c_write(priv, ICSCR, SDBS);
- rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
priv->slave = NULL;
@@ -1152,7 +1160,9 @@ static int rcar_i2c_probe(struct platform_device *pdev)
goto out_pm_disable;
}
- rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
+ /* Bring hardware to known state */
+ rcar_i2c_init(priv);
+ rcar_i2c_reset_slave(priv);
if (priv->devtype < I2C_RCAR_GEN3) {
irqflags |= IRQF_NO_THREAD;
@@ -1168,6 +1178,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
if (of_property_read_bool(dev->of_node, "smbus"))
priv->flags |= ID_P_HOST_NOTIFY;
+ /* R-Car Gen3+ needs a reset before every transfer */
if (priv->devtype >= I2C_RCAR_GEN3) {
priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(priv->rstc)) {
@@ -1178,6 +1189,9 @@ static int rcar_i2c_probe(struct platform_device *pdev)
ret = reset_control_status(priv->rstc);
if (ret < 0)
goto out_pm_put;
+
+ /* hard reset disturbs HostNotify local target, so disable it */
+ priv->flags &= ~ID_P_HOST_NOTIFY;
}
ret = platform_get_irq(pdev, 0);
diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c
index e43ff483c56e..d6f585cdb7e5 100644
--- a/drivers/i2c/busses/i2c-riic.c
+++ b/drivers/i2c/busses/i2c-riic.c
@@ -12,9 +12,9 @@
*
* 1) The main xfer routine kicks off a transmission by putting the start bit
* (or repeated start) on the bus and enabling the transmit interrupt (TIE)
- * since we need to send the slave address + RW bit in every case.
+ * since we need to send the target address + RW bit in every case.
*
- * 2) TIE sends slave address + RW bit and selects how to continue.
+ * 2) TIE sends target address + RW bit and selects how to continue.
*
* 3a) Write case: We keep utilizing TIE as long as we have data to send. If we
* are done, we switch over to the transmission done interrupt (TEIE) and mark
@@ -46,18 +46,6 @@
#include <linux/pm_runtime.h>
#include <linux/reset.h>
-#define RIIC_ICCR1 0x00
-#define RIIC_ICCR2 0x04
-#define RIIC_ICMR1 0x08
-#define RIIC_ICMR3 0x10
-#define RIIC_ICSER 0x18
-#define RIIC_ICIER 0x1c
-#define RIIC_ICSR2 0x24
-#define RIIC_ICBRL 0x34
-#define RIIC_ICBRH 0x38
-#define RIIC_ICDRT 0x3c
-#define RIIC_ICDRR 0x40
-
#define ICCR1_ICE 0x80
#define ICCR1_IICRST 0x40
#define ICCR1_SOWP 0x10
@@ -87,6 +75,25 @@
#define RIIC_INIT_MSG -1
+enum riic_reg_list {
+ RIIC_ICCR1 = 0,
+ RIIC_ICCR2,
+ RIIC_ICMR1,
+ RIIC_ICMR3,
+ RIIC_ICSER,
+ RIIC_ICIER,
+ RIIC_ICSR2,
+ RIIC_ICBRL,
+ RIIC_ICBRH,
+ RIIC_ICDRT,
+ RIIC_ICDRR,
+ RIIC_REG_END,
+};
+
+struct riic_of_data {
+ u8 regs[RIIC_REG_END];
+};
+
struct riic_dev {
void __iomem *base;
u8 *buf;
@@ -94,6 +101,7 @@ struct riic_dev {
int bytes_left;
int err;
int is_last;
+ const struct riic_of_data *info;
struct completion msg_done;
struct i2c_adapter adapter;
struct clk *clk;
@@ -105,9 +113,19 @@ struct riic_irq_desc {
char *name;
};
+static inline void riic_writeb(struct riic_dev *riic, u8 val, u8 offset)
+{
+ writeb(val, riic->base + riic->info->regs[offset]);
+}
+
+static inline u8 riic_readb(struct riic_dev *riic, u8 offset)
+{
+ return readb(riic->base + riic->info->regs[offset]);
+}
+
static inline void riic_clear_set_bit(struct riic_dev *riic, u8 clear, u8 set, u8 reg)
{
- writeb((readb(riic->base + reg) & ~clear) | set, riic->base + reg);
+ riic_writeb(riic, (riic_readb(riic, reg) & ~clear) | set, reg);
}
static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
@@ -119,7 +137,7 @@ static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
pm_runtime_get_sync(adap->dev.parent);
- if (readb(riic->base + RIIC_ICCR2) & ICCR2_BBSY) {
+ if (riic_readb(riic, RIIC_ICCR2) & ICCR2_BBSY) {
riic->err = -EBUSY;
goto out;
}
@@ -127,7 +145,7 @@ static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
reinit_completion(&riic->msg_done);
riic->err = 0;
- writeb(0, riic->base + RIIC_ICSR2);
+ riic_writeb(riic, 0, RIIC_ICSR2);
for (i = 0, start_bit = ICCR2_ST; i < num; i++) {
riic->bytes_left = RIIC_INIT_MSG;
@@ -135,9 +153,9 @@ static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
riic->msg = &msgs[i];
riic->is_last = (i == num - 1);
- writeb(ICIER_NAKIE | ICIER_TIE, riic->base + RIIC_ICIER);
+ riic_writeb(riic, ICIER_NAKIE | ICIER_TIE, RIIC_ICIER);
- writeb(start_bit, riic->base + RIIC_ICCR2);
+ riic_writeb(riic, start_bit, RIIC_ICCR2);
time_left = wait_for_completion_timeout(&riic->msg_done, riic->adapter.timeout);
if (time_left == 0)
@@ -191,7 +209,7 @@ static irqreturn_t riic_tdre_isr(int irq, void *data)
* value could be moved to the shadow shift register right away. So
* this must be after updates to ICIER (where we want to disable TIE)!
*/
- writeb(val, riic->base + RIIC_ICDRT);
+ riic_writeb(riic, val, RIIC_ICDRT);
return IRQ_HANDLED;
}
@@ -200,9 +218,9 @@ static irqreturn_t riic_tend_isr(int irq, void *data)
{
struct riic_dev *riic = data;
- if (readb(riic->base + RIIC_ICSR2) & ICSR2_NACKF) {
+ if (riic_readb(riic, RIIC_ICSR2) & ICSR2_NACKF) {
/* We got a NACKIE */
- readb(riic->base + RIIC_ICDRR); /* dummy read */
+ riic_readb(riic, RIIC_ICDRR); /* dummy read */
riic_clear_set_bit(riic, ICSR2_NACKF, 0, RIIC_ICSR2);
riic->err = -ENXIO;
} else if (riic->bytes_left) {
@@ -211,7 +229,7 @@ static irqreturn_t riic_tend_isr(int irq, void *data)
if (riic->is_last || riic->err) {
riic_clear_set_bit(riic, ICIER_TEIE, ICIER_SPIE, RIIC_ICIER);
- writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
+ riic_writeb(riic, ICCR2_SP, RIIC_ICCR2);
} else {
/* Transfer is complete, but do not send STOP */
riic_clear_set_bit(riic, ICIER_TEIE, 0, RIIC_ICIER);
@@ -230,7 +248,7 @@ static irqreturn_t riic_rdrf_isr(int irq, void *data)
if (riic->bytes_left == RIIC_INIT_MSG) {
riic->bytes_left = riic->msg->len;
- readb(riic->base + RIIC_ICDRR); /* dummy read */
+ riic_readb(riic, RIIC_ICDRR); /* dummy read */
return IRQ_HANDLED;
}
@@ -238,7 +256,7 @@ static irqreturn_t riic_rdrf_isr(int irq, void *data)
/* STOP must come before we set ACKBT! */
if (riic->is_last) {
riic_clear_set_bit(riic, 0, ICIER_SPIE, RIIC_ICIER);
- writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
+ riic_writeb(riic, ICCR2_SP, RIIC_ICCR2);
}
riic_clear_set_bit(riic, 0, ICMR3_ACKBT, RIIC_ICMR3);
@@ -248,7 +266,7 @@ static irqreturn_t riic_rdrf_isr(int irq, void *data)
}
/* Reading acks the RIE interrupt */
- *riic->buf = readb(riic->base + RIIC_ICDRR);
+ *riic->buf = riic_readb(riic, RIIC_ICDRR);
riic->buf++;
riic->bytes_left--;
@@ -260,10 +278,10 @@ static irqreturn_t riic_stop_isr(int irq, void *data)
struct riic_dev *riic = data;
/* read back registers to confirm writes have fully propagated */
- writeb(0, riic->base + RIIC_ICSR2);
- readb(riic->base + RIIC_ICSR2);
- writeb(0, riic->base + RIIC_ICIER);
- readb(riic->base + RIIC_ICIER);
+ riic_writeb(riic, 0, RIIC_ICSR2);
+ riic_readb(riic, RIIC_ICSR2);
+ riic_writeb(riic, 0, RIIC_ICIER);
+ riic_readb(riic, RIIC_ICIER);
complete(&riic->msg_done);
@@ -276,8 +294,8 @@ static u32 riic_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm riic_algo = {
- .master_xfer = riic_xfer,
- .functionality = riic_func,
+ .xfer = riic_xfer,
+ .functionality = riic_func,
};
static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t)
@@ -365,15 +383,15 @@ static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t)
t->scl_rise_ns / (1000000000 / rate), cks, brl, brh);
/* Changing the order of accessing IICRST and ICE may break things! */
- writeb(ICCR1_IICRST | ICCR1_SOWP, riic->base + RIIC_ICCR1);
+ riic_writeb(riic, ICCR1_IICRST | ICCR1_SOWP, RIIC_ICCR1);
riic_clear_set_bit(riic, 0, ICCR1_ICE, RIIC_ICCR1);
- writeb(ICMR1_CKS(cks), riic->base + RIIC_ICMR1);
- writeb(brh | ICBR_RESERVED, riic->base + RIIC_ICBRH);
- writeb(brl | ICBR_RESERVED, riic->base + RIIC_ICBRL);
+ riic_writeb(riic, ICMR1_CKS(cks), RIIC_ICMR1);
+ riic_writeb(riic, brh | ICBR_RESERVED, RIIC_ICBRH);
+ riic_writeb(riic, brl | ICBR_RESERVED, RIIC_ICBRL);
- writeb(0, riic->base + RIIC_ICSER);
- writeb(ICMR3_ACKWP | ICMR3_RDRFS, riic->base + RIIC_ICMR3);
+ riic_writeb(riic, 0, RIIC_ICSER);
+ riic_writeb(riic, ICMR3_ACKWP | ICMR3_RDRFS, RIIC_ICMR3);
riic_clear_set_bit(riic, ICCR1_IICRST, 0, RIIC_ICCR1);
@@ -443,6 +461,8 @@ static int riic_i2c_probe(struct platform_device *pdev)
}
}
+ riic->info = of_device_get_match_data(&pdev->dev);
+
adap = &riic->adapter;
i2c_set_adapdata(adap, riic);
strscpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name));
@@ -481,14 +501,47 @@ static void riic_i2c_remove(struct platform_device *pdev)
struct riic_dev *riic = platform_get_drvdata(pdev);
pm_runtime_get_sync(&pdev->dev);
- writeb(0, riic->base + RIIC_ICIER);
+ riic_writeb(riic, 0, RIIC_ICIER);
pm_runtime_put(&pdev->dev);
i2c_del_adapter(&riic->adapter);
pm_runtime_disable(&pdev->dev);
}
+static const struct riic_of_data riic_rz_a_info = {
+ .regs = {
+ [RIIC_ICCR1] = 0x00,
+ [RIIC_ICCR2] = 0x04,
+ [RIIC_ICMR1] = 0x08,
+ [RIIC_ICMR3] = 0x10,
+ [RIIC_ICSER] = 0x18,
+ [RIIC_ICIER] = 0x1c,
+ [RIIC_ICSR2] = 0x24,
+ [RIIC_ICBRL] = 0x34,
+ [RIIC_ICBRH] = 0x38,
+ [RIIC_ICDRT] = 0x3c,
+ [RIIC_ICDRR] = 0x40,
+ },
+};
+
+static const struct riic_of_data riic_rz_v2h_info = {
+ .regs = {
+ [RIIC_ICCR1] = 0x00,
+ [RIIC_ICCR2] = 0x01,
+ [RIIC_ICMR1] = 0x02,
+ [RIIC_ICMR3] = 0x04,
+ [RIIC_ICSER] = 0x06,
+ [RIIC_ICIER] = 0x07,
+ [RIIC_ICSR2] = 0x09,
+ [RIIC_ICBRL] = 0x10,
+ [RIIC_ICBRH] = 0x11,
+ [RIIC_ICDRT] = 0x12,
+ [RIIC_ICDRR] = 0x13,
+ },
+};
+
static const struct of_device_id riic_i2c_dt_ids[] = {
- { .compatible = "renesas,riic-rz", },
+ { .compatible = "renesas,riic-rz", .data = &riic_rz_a_info },
+ { .compatible = "renesas,riic-r9a09g057", .data = &riic_rz_v2h_info },
{ /* Sentinel */ },
};
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
index 086fdf262e7b..4ef9bad77b85 100644
--- a/drivers/i2c/busses/i2c-rk3x.c
+++ b/drivers/i2c/busses/i2c-rk3x.c
@@ -28,8 +28,8 @@
/* Register Map */
#define REG_CON 0x00 /* control register */
#define REG_CLKDIV 0x04 /* clock divisor register */
-#define REG_MRXADDR 0x08 /* slave address for REGISTER_TX */
-#define REG_MRXRADDR 0x0c /* slave register address for REGISTER_TX */
+#define REG_MRXADDR 0x08 /* target address for REGISTER_TX */
+#define REG_MRXRADDR 0x0c /* target register address for REGISTER_TX */
#define REG_MTXCNT 0x10 /* number of bytes to be transmitted */
#define REG_MRXCNT 0x14 /* number of bytes to be received */
#define REG_IEN 0x18 /* interrupt enable */
@@ -68,8 +68,8 @@ enum {
/* REG_IEN/REG_IPD bits */
#define REG_INT_BTF BIT(0) /* a byte was transmitted */
#define REG_INT_BRF BIT(1) /* a byte was received */
-#define REG_INT_MBTF BIT(2) /* master data transmit finished */
-#define REG_INT_MBRF BIT(3) /* master data receive finished */
+#define REG_INT_MBTF BIT(2) /* controller data transmit finished */
+#define REG_INT_MBRF BIT(3) /* controller data receive finished */
#define REG_INT_START BIT(4) /* START condition generated */
#define REG_INT_STOP BIT(5) /* STOP condition generated */
#define REG_INT_NAKRCV BIT(6) /* NACK received */
@@ -184,7 +184,7 @@ struct rk3x_i2c_soc_data {
* @wait: the waitqueue to wait for i2c transfer
* @busy: the condition for the event to wait for
* @msg: current i2c message
- * @addr: addr of i2c slave device
+ * @addr: addr of i2c target device
* @mode: mode of i2c transfer
* @is_last_msg: flag determines whether it is the last msg in this transfer
* @state: state of i2c transfer
@@ -979,7 +979,7 @@ static int rk3x_i2c_setup(struct rk3x_i2c *i2c, struct i2c_msg *msgs, int num)
/*
* The I2C adapter can issue a small (len < 4) write packet before
* reading. This speeds up SMBus-style register reads.
- * The MRXADDR/MRXRADDR hold the slave address and the slave register
+ * The MRXADDR/MRXRADDR hold the target address and the target register
* address in this case.
*/
@@ -1016,7 +1016,7 @@ static int rk3x_i2c_setup(struct rk3x_i2c *i2c, struct i2c_msg *msgs, int num)
addr |= 1; /* set read bit */
/*
- * We have to transmit the slave addr first. Use
+ * We have to transmit the target addr first. Use
* MOD_REGISTER_TX for that purpose.
*/
i2c->mode = REG_CON_MOD_REGISTER_TX;
@@ -1060,7 +1060,8 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num, bool polling)
{
struct rk3x_i2c *i2c = (struct rk3x_i2c *)adap->algo_data;
- unsigned long timeout, flags;
+ unsigned long flags;
+ long time_left;
u32 val;
int ret = 0;
int i;
@@ -1092,23 +1093,20 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
if (!polling) {
rk3x_i2c_start(i2c);
- timeout = wait_event_timeout(i2c->wait, !i2c->busy,
- msecs_to_jiffies(WAIT_TIMEOUT));
+ time_left = wait_event_timeout(i2c->wait, !i2c->busy,
+ msecs_to_jiffies(WAIT_TIMEOUT));
} else {
disable_irq(i2c->irq);
rk3x_i2c_start(i2c);
- timeout = rk3x_i2c_wait_xfer_poll(i2c);
+ time_left = rk3x_i2c_wait_xfer_poll(i2c);
enable_irq(i2c->irq);
}
spin_lock_irqsave(&i2c->lock, flags);
- if (timeout == 0) {
- dev_err(i2c->dev, "timeout, ipd: 0x%02x, state: %d\n",
- i2c_readl(i2c, REG_IPD), i2c->state);
-
+ if (time_left == 0) {
/* Force a STOP condition without interrupt */
i2c_writel(i2c, 0, REG_IEN);
val = i2c_readl(i2c, REG_CON) & REG_CON_TUNING_MASK;
@@ -1162,9 +1160,9 @@ static u32 rk3x_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm rk3x_i2c_algorithm = {
- .master_xfer = rk3x_i2c_xfer,
- .master_xfer_atomic = rk3x_i2c_xfer_polling,
- .functionality = rk3x_i2c_func,
+ .xfer = rk3x_i2c_xfer,
+ .xfer_atomic = rk3x_i2c_xfer_polling,
+ .functionality = rk3x_i2c_func,
};
static const struct rk3x_i2c_soc_data rv1108_soc_data = {
diff --git a/drivers/i2c/busses/i2c-robotfuzz-osif.c b/drivers/i2c/busses/i2c-robotfuzz-osif.c
index 66dfa211e736..80d45079b763 100644
--- a/drivers/i2c/busses/i2c-robotfuzz-osif.c
+++ b/drivers/i2c/busses/i2c-robotfuzz-osif.c
@@ -112,8 +112,8 @@ static u32 osif_func(struct i2c_adapter *adapter)
}
static const struct i2c_algorithm osif_algorithm = {
- .master_xfer = osif_xfer,
- .functionality = osif_func,
+ .xfer = osif_xfer,
+ .functionality = osif_func,
};
#define USB_OSIF_VENDOR_ID 0x1964
diff --git a/drivers/i2c/busses/i2c-rzv2m.c b/drivers/i2c/busses/i2c-rzv2m.c
index b0bfc96b9ede..8380a68538ab 100644
--- a/drivers/i2c/busses/i2c-rzv2m.c
+++ b/drivers/i2c/busses/i2c-rzv2m.c
@@ -321,8 +321,8 @@ static int rzv2m_i2c_stop_condition(struct rzv2m_i2c_priv *priv)
100, jiffies_to_usecs(priv->adap.timeout));
}
-static int rzv2m_i2c_master_xfer_msg(struct rzv2m_i2c_priv *priv,
- struct i2c_msg *msg, int stop)
+static int rzv2m_i2c_xfer_msg(struct rzv2m_i2c_priv *priv,
+ struct i2c_msg *msg, int stop)
{
unsigned int count = 0;
int ret, read = !!(msg->flags & I2C_M_RD);
@@ -351,8 +351,8 @@ static int rzv2m_i2c_master_xfer_msg(struct rzv2m_i2c_priv *priv,
return ret;
}
-static int rzv2m_i2c_master_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs, int num)
+static int rzv2m_i2c_xfer(struct i2c_adapter *adap,
+ struct i2c_msg *msgs, int num)
{
struct rzv2m_i2c_priv *priv = i2c_get_adapdata(adap);
struct device *dev = priv->adap.dev.parent;
@@ -370,7 +370,7 @@ static int rzv2m_i2c_master_xfer(struct i2c_adapter *adap,
/* I2C main transfer */
for (i = 0; i < num; i++) {
- ret = rzv2m_i2c_master_xfer_msg(priv, &msgs[i], i == (num - 1));
+ ret = rzv2m_i2c_xfer_msg(priv, &msgs[i], i == (num - 1));
if (ret < 0)
goto out;
}
@@ -408,7 +408,7 @@ static const struct i2c_adapter_quirks rzv2m_i2c_quirks = {
};
static struct i2c_algorithm rzv2m_i2c_algo = {
- .master_xfer = rzv2m_i2c_master_xfer,
+ .xfer = rzv2m_i2c_xfer,
.functionality = rzv2m_i2c_func,
};
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 275f7c42165c..01419c738cfc 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -685,7 +685,7 @@ static void s3c24xx_i2c_wait_idle(struct s3c24xx_i2c *i2c)
static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
struct i2c_msg *msgs, int num)
{
- unsigned long timeout = 0;
+ long time_left = 0;
int ret;
ret = s3c24xx_i2c_set_master(i2c);
@@ -715,7 +715,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
dev_err(i2c->dev, "deal with arbitration loss\n");
}
} else {
- timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+ time_left = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
}
ret = i2c->msg_idx;
@@ -724,7 +724,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
* Having these next two as dev_err() makes life very
* noisy when doing an i2cdetect
*/
- if (timeout == 0)
+ if (time_left == 0)
dev_dbg(i2c->dev, "timeout\n");
else if (ret != num)
dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index c65ac3d7eadc..f86c29737df1 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -688,7 +688,6 @@ static int sh_mobile_xfer(struct sh_mobile_i2c_data *pd,
}
if (!time_left) {
- dev_err(pd->dev, "Transfer request timed out\n");
if (pd->dma_direction != DMA_NONE)
sh_mobile_i2c_cleanup_dma(pd, true);
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index 32476dc10ad6..ca06fffb8f61 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -257,7 +257,7 @@ static int sis5595_transaction(struct i2c_adapter *adap)
if (temp & 0x20) {
dev_err(&adap->dev, "Bus collision! SMBus may be locked until "
"next hard reset (or not...)\n");
- /* Clock stops and slave is stuck in mid-transmission */
+ /* Clock stops and target is stuck in mid-transmission */
result = -EIO;
}
diff --git a/drivers/i2c/busses/i2c-sprd.c b/drivers/i2c/busses/i2c-sprd.c
index 28c88901d9bc..9c45e75b9187 100644
--- a/drivers/i2c/busses/i2c-sprd.c
+++ b/drivers/i2c/busses/i2c-sprd.c
@@ -283,8 +283,8 @@ static int sprd_i2c_handle_msg(struct i2c_adapter *i2c_adap,
return i2c_dev->err;
}
-static int sprd_i2c_master_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs, int num)
+static int sprd_i2c_xfer(struct i2c_adapter *i2c_adap,
+ struct i2c_msg *msgs, int num)
{
struct sprd_i2c *i2c_dev = i2c_adap->algo_data;
int im, ret;
@@ -314,7 +314,7 @@ static u32 sprd_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm sprd_i2c_algo = {
- .master_xfer = sprd_i2c_master_xfer,
+ .xfer = sprd_i2c_xfer,
.functionality = sprd_i2c_func,
};
@@ -378,12 +378,12 @@ static irqreturn_t sprd_i2c_isr_thread(int irq, void *dev_id)
i2c_tran = i2c_dev->count;
/*
- * If we got one ACK from slave when writing data, and we did not
+ * If we got one ACK from target when writing data, and we did not
* finish this transmission (i2c_tran is not zero), then we should
* continue to write data.
*
* For reading data, ack is always true, if i2c_tran is not 0 which
- * means we still need to contine to read data from slave.
+ * means we still need to contine to read data from target.
*/
if (i2c_tran && ack) {
sprd_i2c_data_transfer(i2c_dev);
@@ -393,7 +393,7 @@ static irqreturn_t sprd_i2c_isr_thread(int irq, void *dev_id)
i2c_dev->err = 0;
/*
- * If we did not get one ACK from slave when writing data, we should
+ * If we did not get one ACK from target when writing data, we should
* return -EIO to notify users.
*/
if (!ack)
@@ -422,7 +422,7 @@ static irqreturn_t sprd_i2c_isr(int irq, void *dev_id)
i2c_tran = i2c_dev->count;
/*
- * If we did not get one ACK from slave when writing data, then we
+ * If we did not get one ACK from target when writing data, then we
* should finish this transmission since we got some errors.
*
* When writing data, if i2c_tran == 0 which means we have writen
@@ -653,5 +653,5 @@ static struct platform_driver sprd_i2c_driver = {
module_platform_driver(sprd_i2c_driver);
-MODULE_DESCRIPTION("Spreadtrum I2C master controller driver");
+MODULE_DESCRIPTION("Spreadtrum I2C controller driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/i2c/busses/i2c-st.c b/drivers/i2c/busses/i2c-st.c
index ce2333408904..05b19ede65a0 100644
--- a/drivers/i2c/busses/i2c-st.c
+++ b/drivers/i2c/busses/i2c-st.c
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2013 STMicroelectronics
*
- * I2C master mode controller driver, used in STMicroelectronics devices.
+ * I2C controller driver, used in STMicroelectronics devices.
*
* Author: Maxime Coquelin <maxime.coquelin@st.com>
*/
@@ -150,7 +150,7 @@ struct st_i2c_timings {
/**
* struct st_i2c_client - client specific data
- * @addr: 8-bit slave addr, including r/w bit
+ * @addr: 8-bit target addr, including r/w bit
* @count: number of bytes to be transfered
* @xfered: number of bytes already transferred
* @buf: data buffer
@@ -647,7 +647,7 @@ static int st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg,
{
struct st_i2c_client *c = &i2c_dev->client;
u32 ctl, i2c, it;
- unsigned long timeout;
+ unsigned long time_left;
int ret;
c->addr = i2c_8bit_addr_from_msg(msg);
@@ -667,7 +667,7 @@ static int st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg,
i2c |= SSC_I2C_ACKG;
st_i2c_set_bits(i2c_dev->base + SSC_I2C, i2c);
- /* Write slave address */
+ /* Write target address */
st_i2c_write_tx_fifo(i2c_dev, c->addr);
/* Pre-fill Tx fifo with data in case of write */
@@ -685,15 +685,12 @@ static int st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg,
st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STRTG);
}
- timeout = wait_for_completion_timeout(&i2c_dev->complete,
- i2c_dev->adap.timeout);
+ time_left = wait_for_completion_timeout(&i2c_dev->complete,
+ i2c_dev->adap.timeout);
ret = c->result;
- if (!timeout) {
- dev_err(i2c_dev->dev, "Write to slave 0x%x timed out\n",
- c->addr);
+ if (!time_left)
ret = -ETIMEDOUT;
- }
i2c = SSC_I2C_STOPG | SSC_I2C_REPSTRTG;
st_i2c_clr_bits(i2c_dev->base + SSC_I2C, i2c);
@@ -769,7 +766,7 @@ static u32 st_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm st_i2c_algo = {
- .master_xfer = st_i2c_xfer,
+ .xfer = st_i2c_xfer,
.functionality = st_i2c_func,
};
diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c
index 859ac0cf7f6c..230fff0c0bf9 100644
--- a/drivers/i2c/busses/i2c-stm32f4.c
+++ b/drivers/i2c/busses/i2c-stm32f4.c
@@ -95,7 +95,7 @@
/**
* struct stm32f4_i2c_msg - client specific data
- * @addr: 8-bit slave addr, including r/w bit
+ * @addr: 8-bit target addr, including r/w bit
* @count: number of bytes to be transferred
* @buf: data buffer
* @result: result of the transfer
@@ -480,7 +480,7 @@ static void stm32f4_i2c_handle_rx_done(struct stm32f4_i2c_dev *i2c_dev)
/**
* stm32f4_i2c_handle_rx_addr() - Handle address matched interrupt in case of
- * master receiver
+ * controller receiver
* @i2c_dev: Controller's private data
*/
static void stm32f4_i2c_handle_rx_addr(struct stm32f4_i2c_dev *i2c_dev)
@@ -643,7 +643,7 @@ static irqreturn_t stm32f4_i2c_isr_error(int irq, void *data)
/*
* Acknowledge failure:
- * In master transmitter mode a Stop must be generated by software
+ * In controller transmitter mode a Stop must be generated by software
*/
if (status & STM32F4_I2C_SR1_AF) {
if (!(msg->addr & I2C_M_RD)) {
@@ -681,7 +681,7 @@ static int stm32f4_i2c_xfer_msg(struct stm32f4_i2c_dev *i2c_dev,
{
struct stm32f4_i2c_msg *f4_msg = &i2c_dev->msg;
void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR1;
- unsigned long timeout;
+ unsigned long time_left;
u32 mask;
int ret;
@@ -706,11 +706,11 @@ static int stm32f4_i2c_xfer_msg(struct stm32f4_i2c_dev *i2c_dev,
stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
}
- timeout = wait_for_completion_timeout(&i2c_dev->complete,
- i2c_dev->adap.timeout);
+ time_left = wait_for_completion_timeout(&i2c_dev->complete,
+ i2c_dev->adap.timeout);
ret = f4_msg->result;
- if (!timeout)
+ if (!time_left)
ret = -ETIMEDOUT;
return ret;
@@ -749,7 +749,7 @@ static u32 stm32f4_i2c_func(struct i2c_adapter *adap)
}
static const struct i2c_algorithm stm32f4_i2c_algo = {
- .master_xfer = stm32f4_i2c_xfer,
+ .xfer = stm32f4_i2c_xfer,
.functionality = stm32f4_i2c_func,
};
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
index 01210452216b..cfee2d9c09de 100644
--- a/drivers/i2c/busses/i2c-stm32f7.c
+++ b/drivers/i2c/busses/i2c-stm32f7.c
@@ -1789,7 +1789,7 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
struct stm32_i2c_dma *dma = i2c_dev->dma;
struct device *dev = i2c_dev->dev;
- unsigned long timeout;
+ unsigned long time_left;
int i, ret;
f7_msg->addr = addr;
@@ -1809,8 +1809,8 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
if (ret)
goto pm_free;
- timeout = wait_for_completion_timeout(&i2c_dev->complete,
- i2c_dev->adap.timeout);
+ time_left = wait_for_completion_timeout(&i2c_dev->complete,
+ i2c_dev->adap.timeout);
ret = f7_msg->result;
if (ret) {
if (i2c_dev->use_dma)
@@ -1826,7 +1826,7 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
goto pm_free;
}
- if (!timeout) {
+ if (!time_left) {
dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr);
if (i2c_dev->use_dma)
dmaengine_terminate_sync(dma->chan_using);
diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c
index 85e035e7a1d7..074eade6c4a4 100644
--- a/drivers/i2c/busses/i2c-sun6i-p2wi.c
+++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c
@@ -10,7 +10,7 @@
* The P2WI controller looks like an SMBus controller which only supports byte
* data transfers. But, it differs from standard SMBus protocol on several
* aspects:
- * - it supports only one slave device, and thus drop the address field
+ * - it supports only one target device, and thus drop the address field
* - it adds a parity bit every 8bits of data
* - only one read access is required to read a byte (instead of a write
* followed by a read access in standard SMBus protocol)
@@ -88,7 +88,7 @@ struct p2wi {
void __iomem *regs;
struct clk *clk;
struct reset_control *rstc;
- int slave_addr;
+ int target_addr;
};
static irqreturn_t p2wi_interrupt(int irq, void *dev_id)
@@ -121,7 +121,7 @@ static int p2wi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
struct p2wi *p2wi = i2c_get_adapdata(adap);
unsigned long dlen = P2WI_DLEN_DATA_LENGTH(1);
- if (p2wi->slave_addr >= 0 && addr != p2wi->slave_addr) {
+ if (p2wi->target_addr >= 0 && addr != p2wi->target_addr) {
dev_err(&adap->dev, "invalid P2WI address\n");
return -EINVAL;
}
@@ -188,7 +188,7 @@ static int p2wi_probe(struct platform_device *pdev)
unsigned long parent_clk_freq;
u32 clk_freq = I2C_MAX_STANDARD_MODE_FREQ;
struct p2wi *p2wi;
- u32 slave_addr;
+ u32 target_addr;
int clk_div;
int irq;
int ret;
@@ -207,7 +207,7 @@ static int p2wi_probe(struct platform_device *pdev)
}
if (of_get_child_count(np) > 1) {
- dev_err(dev, "P2WI only supports one slave device\n");
+ dev_err(dev, "P2WI only supports one target device\n");
return -EINVAL;
}
@@ -215,24 +215,24 @@ static int p2wi_probe(struct platform_device *pdev)
if (!p2wi)
return -ENOMEM;
- p2wi->slave_addr = -1;
+ p2wi->target_addr = -1;
/*
* Authorize a p2wi node without any children to be able to use an
* i2c-dev from userpace.
- * In this case the slave_addr is set to -1 and won't be checked when
+ * In this case the target_addr is set to -1 and won't be checked when
* launching a P2WI transfer.
*/
childnp = of_get_next_available_child(np, NULL);
if (childnp) {
- ret = of_property_read_u32(childnp, "reg", &slave_addr);
+ ret = of_property_read_u32(childnp, "reg", &target_addr);
if (ret) {
- dev_err(dev, "invalid slave address on node %pOF\n",
+ dev_err(dev, "invalid target address on node %pOF\n",
childnp);
return -EINVAL;
}
- p2wi->slave_addr = slave_addr;
+ p2wi->target_addr = target_addr;
}
p2wi->regs = devm_platform_ioremap_resource(pdev, 0);
diff --git a/drivers/i2c/busses/i2c-synquacer.c b/drivers/i2c/busses/i2c-synquacer.c
index bbea521b05dd..4eccbcd0fbfc 100644
--- a/drivers/i2c/busses/i2c-synquacer.c
+++ b/drivers/i2c/busses/i2c-synquacer.c
@@ -138,7 +138,6 @@ struct synquacer_i2c {
int irq;
struct device *dev;
void __iomem *base;
- struct clk *pclk;
u32 pclkrate;
u32 speed_khz;
u32 timeout_ms;
@@ -311,7 +310,7 @@ static int synquacer_i2c_doxfer(struct synquacer_i2c *i2c,
struct i2c_msg *msgs, int num)
{
unsigned char bsr;
- unsigned long timeout;
+ unsigned long time_left;
int ret;
synquacer_i2c_hw_init(i2c);
@@ -335,9 +334,9 @@ static int synquacer_i2c_doxfer(struct synquacer_i2c *i2c,
return ret;
}
- timeout = wait_for_completion_timeout(&i2c->completion,
- msecs_to_jiffies(i2c->timeout_ms));
- if (timeout == 0) {
+ time_left = wait_for_completion_timeout(&i2c->completion,
+ msecs_to_jiffies(i2c->timeout_ms));
+ if (time_left == 0) {
dev_dbg(i2c->dev, "timeout\n");
return -EAGAIN;
}
@@ -535,6 +534,7 @@ static const struct i2c_adapter synquacer_i2c_ops = {
static int synquacer_i2c_probe(struct platform_device *pdev)
{
struct synquacer_i2c *i2c;
+ struct clk *pclk;
u32 bus_speed;
int ret;
@@ -550,17 +550,12 @@ static int synquacer_i2c_probe(struct platform_device *pdev)
device_property_read_u32(&pdev->dev, "socionext,pclk-rate",
&i2c->pclkrate);
- i2c->pclk = devm_clk_get(&pdev->dev, "pclk");
- if (PTR_ERR(i2c->pclk) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
- if (!IS_ERR_OR_NULL(i2c->pclk)) {
- dev_dbg(&pdev->dev, "clock source %p\n", i2c->pclk);
+ pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
+ if (IS_ERR(pclk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
+ "failed to get and enable clock\n");
- ret = clk_prepare_enable(i2c->pclk);
- if (ret)
- return dev_err_probe(&pdev->dev, ret, "failed to enable clock\n");
- i2c->pclkrate = clk_get_rate(i2c->pclk);
- }
+ i2c->pclkrate = clk_get_rate(pclk);
if (i2c->pclkrate < SYNQUACER_I2C_MIN_CLK_RATE ||
i2c->pclkrate > SYNQUACER_I2C_MAX_CLK_RATE)
@@ -615,8 +610,6 @@ static void synquacer_i2c_remove(struct platform_device *pdev)
struct synquacer_i2c *i2c = platform_get_drvdata(pdev);
i2c_del_adapter(&i2c->adapter);
- if (!IS_ERR(i2c->pclk))
- clk_disable_unprepare(i2c->pclk);
};
static const struct of_device_id synquacer_i2c_dt_ids[] __maybe_unused = {
diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c
index b0f0120793e1..cb97f72291bc 100644
--- a/drivers/i2c/busses/i2c-taos-evm.c
+++ b/drivers/i2c/busses/i2c-taos-evm.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Driver for the TAOS evaluation modules
- * These devices include an I2C master which can be controlled over the
+ * These devices include an I2C controller which can be controlled over the
* serial port.
*
* Copyright (C) 2007 Jean Delvare <jdelvare@suse.de>
diff --git a/drivers/i2c/busses/i2c-tegra-bpmp.c b/drivers/i2c/busses/i2c-tegra-bpmp.c
index b0840fa0f53e..dabadbcc6d6a 100644
--- a/drivers/i2c/busses/i2c-tegra-bpmp.c
+++ b/drivers/i2c/busses/i2c-tegra-bpmp.c
@@ -275,8 +275,8 @@ static u32 tegra_bpmp_i2c_func(struct i2c_adapter *adapter)
}
static const struct i2c_algorithm tegra_bpmp_i2c_algo = {
- .master_xfer = tegra_bpmp_i2c_xfer,
- .master_xfer_atomic = tegra_bpmp_i2c_xfer_atomic,
+ .xfer = tegra_bpmp_i2c_xfer,
+ .xfer_atomic = tegra_bpmp_i2c_xfer_atomic,
.functionality = tegra_bpmp_i2c_func,
};
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 920d5a8cbf4c..85b31edc558d 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1331,7 +1331,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
dmaengine_terminate_sync(i2c_dev->dma_chan);
if (!time_left && !completion_done(&i2c_dev->dma_complete)) {
- dev_err(i2c_dev->dev, "DMA transfer timed out\n");
tegra_i2c_init(i2c_dev);
return -ETIMEDOUT;
}
@@ -1351,7 +1350,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
tegra_i2c_mask_irq(i2c_dev, int_mask);
if (time_left == 0) {
- dev_err(i2c_dev->dev, "I2C transfer timed out\n");
tegra_i2c_init(i2c_dev);
return -ETIMEDOUT;
}
diff --git a/drivers/i2c/busses/i2c-thunderx-pcidrv.c b/drivers/i2c/busses/i2c-thunderx-pcidrv.c
index a77cd86fe75e..143d012fa43e 100644
--- a/drivers/i2c/busses/i2c-thunderx-pcidrv.c
+++ b/drivers/i2c/busses/i2c-thunderx-pcidrv.c
@@ -27,7 +27,8 @@
#define PCI_DEVICE_ID_THUNDER_TWSI 0xa012
-#define SYS_FREQ_DEFAULT 700000000
+#define SYS_FREQ_DEFAULT 800000000
+#define OTX2_REF_FREQ_DEFAULT 100000000
#define TWSI_INT_ENA_W1C 0x1028
#define TWSI_INT_ENA_W1S 0x1030
@@ -71,7 +72,7 @@ static u32 thunderx_i2c_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm thunderx_i2c_algo = {
- .master_xfer = octeon_i2c_xfer,
+ .xfer = octeon_i2c_xfer,
.functionality = thunderx_i2c_functionality,
};
@@ -99,7 +100,8 @@ static void thunder_i2c_clock_enable(struct device *dev, struct octeon_i2c *i2c)
i2c->sys_freq = clk_get_rate(i2c->clk);
} else {
/* ACPI */
- device_property_read_u32(dev, "sclk", &i2c->sys_freq);
+ if (device_property_read_u32(dev, "sclk", &i2c->sys_freq))
+ device_property_read_u32(dev, "ioclk", &i2c->sys_freq);
}
skip:
@@ -165,6 +167,7 @@ static int thunder_i2c_probe_pci(struct pci_dev *pdev,
i2c->roff.sw_twsi = 0x1000;
i2c->roff.twsi_int = 0x1010;
i2c->roff.sw_twsi_ext = 0x1018;
+ i2c->roff.mode = 0x1038;
i2c->dev = dev;
pci_set_drvdata(pdev, i2c);
@@ -205,6 +208,12 @@ static int thunder_i2c_probe_pci(struct pci_dev *pdev,
if (ret)
goto error;
+ /*
+ * For OcteonTX2 chips, set reference frequency to 100MHz
+ * as refclk_src in TWSI_MODE register defaults to 100MHz.
+ */
+ if (octeon_i2c_is_otx2(pdev) && IS_LS_FREQ(i2c->twsi_freq))
+ i2c->sys_freq = OTX2_REF_FREQ_DEFAULT;
octeon_i2c_set_clock(i2c);
i2c->adap = thunderx_i2c_ops;
diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c
index 1bffe36c40ad..0f2ed181b266 100644
--- a/drivers/i2c/busses/i2c-tiny-usb.c
+++ b/drivers/i2c/busses/i2c-tiny-usb.c
@@ -54,8 +54,6 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
struct i2c_msg *pmsg;
int i, ret;
- dev_dbg(&adapter->dev, "master xfer %d messages:\n", num);
-
pstatus = kmalloc(sizeof(*pstatus), GFP_KERNEL);
if (!pstatus)
return -ENOMEM;
@@ -142,8 +140,8 @@ out:
/* This is the actual algorithm we define */
static const struct i2c_algorithm usb_algorithm = {
- .master_xfer = usb_xfer,
- .functionality = usb_func,
+ .xfer = usb_xfer,
+ .functionality = usb_func,
};
/* ----- end of i2c layer ------------------------------------------------ */
diff --git a/drivers/i2c/busses/i2c-uniphier-f.c b/drivers/i2c/busses/i2c-uniphier-f.c
index dbc91c7c3788..10a99cd08972 100644
--- a/drivers/i2c/busses/i2c-uniphier-f.c
+++ b/drivers/i2c/busses/i2c-uniphier-f.c
@@ -12,15 +12,15 @@
#include <linux/platform_device.h>
#define UNIPHIER_FI2C_CR 0x00 /* control register */
-#define UNIPHIER_FI2C_CR_MST BIT(3) /* master mode */
+#define UNIPHIER_FI2C_CR_MST BIT(3) /* controller mode */
#define UNIPHIER_FI2C_CR_STA BIT(2) /* start condition */
#define UNIPHIER_FI2C_CR_STO BIT(1) /* stop condition */
#define UNIPHIER_FI2C_CR_NACK BIT(0) /* do not return ACK */
#define UNIPHIER_FI2C_DTTX 0x04 /* TX FIFO */
-#define UNIPHIER_FI2C_DTTX_CMD BIT(8) /* send command (slave addr) */
+#define UNIPHIER_FI2C_DTTX_CMD BIT(8) /* send command (target addr) */
#define UNIPHIER_FI2C_DTTX_RD BIT(0) /* read transaction */
#define UNIPHIER_FI2C_DTRX 0x04 /* RX FIFO */
-#define UNIPHIER_FI2C_SLAD 0x0c /* slave address */
+#define UNIPHIER_FI2C_SLAD 0x0c /* target address */
#define UNIPHIER_FI2C_CYC 0x10 /* clock cycle control */
#define UNIPHIER_FI2C_LCTL 0x14 /* clock low period control */
#define UNIPHIER_FI2C_SSUT 0x18 /* restart/stop setup time control */
@@ -96,7 +96,7 @@ static void uniphier_fi2c_fill_txfifo(struct uniphier_fi2c_priv *priv,
int fifo_space = UNIPHIER_FI2C_FIFO_SIZE;
/*
- * TX-FIFO stores slave address in it for the first access.
+ * TX-FIFO stores target address in it for the first access.
* Decrement the counter.
*/
if (first)
@@ -252,7 +252,7 @@ static void uniphier_fi2c_tx_init(struct uniphier_fi2c_priv *priv, u16 addr,
/* do not use TX byte counter */
writel(0, priv->membase + UNIPHIER_FI2C_TBC);
- /* set slave address */
+ /* set target address */
writel(UNIPHIER_FI2C_DTTX_CMD | addr << 1,
priv->membase + UNIPHIER_FI2C_DTTX);
/*
@@ -288,7 +288,7 @@ static void uniphier_fi2c_rx_init(struct uniphier_fi2c_priv *priv, u16 addr)
uniphier_fi2c_set_irqs(priv);
- /* set slave address with RD bit */
+ /* set target address with RD bit */
writel(UNIPHIER_FI2C_DTTX_CMD | UNIPHIER_FI2C_DTTX_RD | addr << 1,
priv->membase + UNIPHIER_FI2C_DTTX);
}
@@ -310,9 +310,8 @@ static void uniphier_fi2c_recover(struct uniphier_fi2c_priv *priv)
i2c_recover_bus(&priv->adap);
}
-static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
- struct i2c_msg *msg, bool repeat,
- bool stop)
+static int uniphier_fi2c_xfer_one(struct i2c_adapter *adap, struct i2c_msg *msg,
+ bool repeat, bool stop)
{
struct uniphier_fi2c_priv *priv = i2c_get_adapdata(adap);
bool is_read = msg->flags & I2C_M_RD;
@@ -340,7 +339,7 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
uniphier_fi2c_tx_init(priv, msg->addr, repeat);
/*
- * For a repeated START condition, writing a slave address to the FIFO
+ * For a repeated START condition, writing a target address to the FIFO
* kicks the controller. So, the UNIPHIER_FI2C_CR register should be
* written only for a non-repeated START condition.
*/
@@ -358,7 +357,6 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
spin_unlock_irqrestore(&priv->lock, flags);
if (!time_left) {
- dev_err(&adap->dev, "transaction timeout.\n");
uniphier_fi2c_recover(priv);
return -ETIMEDOUT;
}
@@ -404,8 +402,7 @@ static int uniphier_fi2c_check_bus_busy(struct i2c_adapter *adap)
return 0;
}
-static int uniphier_fi2c_master_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs, int num)
+static int uniphier_fi2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
struct i2c_msg *msg, *emsg = msgs + num;
bool repeat = false;
@@ -419,7 +416,7 @@ static int uniphier_fi2c_master_xfer(struct i2c_adapter *adap,
/* Emit STOP if it is the last message or I2C_M_STOP is set. */
bool stop = (msg + 1 == emsg) || (msg->flags & I2C_M_STOP);
- ret = uniphier_fi2c_master_xfer_one(adap, msg, repeat, stop);
+ ret = uniphier_fi2c_xfer_one(adap, msg, repeat, stop);
if (ret)
return ret;
@@ -435,7 +432,7 @@ static u32 uniphier_fi2c_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm uniphier_fi2c_algo = {
- .master_xfer = uniphier_fi2c_master_xfer,
+ .xfer = uniphier_fi2c_xfer,
.functionality = uniphier_fi2c_functionality,
};
diff --git a/drivers/i2c/busses/i2c-uniphier.c b/drivers/i2c/busses/i2c-uniphier.c
index 854ac25b5862..ef5753307469 100644
--- a/drivers/i2c/busses/i2c-uniphier.c
+++ b/drivers/i2c/busses/i2c-uniphier.c
@@ -17,13 +17,13 @@
#define UNIPHIER_I2C_DTRM_NACK BIT(8) /* do not return ACK */
#define UNIPHIER_I2C_DTRM_RD BIT(0) /* read transaction */
#define UNIPHIER_I2C_DREC 0x04 /* RX register */
-#define UNIPHIER_I2C_DREC_MST BIT(14) /* 1 = master, 0 = slave */
+#define UNIPHIER_I2C_DREC_MST BIT(14) /* 1 = controller, 0 = target */
#define UNIPHIER_I2C_DREC_TX BIT(13) /* 1 = transmit, 0 = receive */
#define UNIPHIER_I2C_DREC_STS BIT(12) /* stop condition detected */
#define UNIPHIER_I2C_DREC_LRB BIT(11) /* no ACK */
#define UNIPHIER_I2C_DREC_LAB BIT(9) /* arbitration lost */
#define UNIPHIER_I2C_DREC_BBN BIT(8) /* bus not busy */
-#define UNIPHIER_I2C_MYAD 0x08 /* slave address */
+#define UNIPHIER_I2C_MYAD 0x08 /* local target address */
#define UNIPHIER_I2C_CLK 0x0c /* clock frequency control */
#define UNIPHIER_I2C_BRST 0x10 /* bus reset */
#define UNIPHIER_I2C_BRST_FOEN BIT(1) /* normal operation */
@@ -71,10 +71,8 @@ static int uniphier_i2c_xfer_byte(struct i2c_adapter *adap, u32 txdata,
writel(txdata, priv->membase + UNIPHIER_I2C_DTRM);
time_left = wait_for_completion_timeout(&priv->comp, adap->timeout);
- if (unlikely(!time_left)) {
- dev_err(&adap->dev, "transaction timeout\n");
+ if (unlikely(!time_left))
return -ETIMEDOUT;
- }
rxdata = readl(priv->membase + UNIPHIER_I2C_DREC);
if (rxdatap)
@@ -154,8 +152,8 @@ static int uniphier_i2c_stop(struct i2c_adapter *adap)
UNIPHIER_I2C_DTRM_NACK);
}
-static int uniphier_i2c_master_xfer_one(struct i2c_adapter *adap,
- struct i2c_msg *msg, bool stop)
+static int uniphier_i2c_xfer_one(struct i2c_adapter *adap,
+ struct i2c_msg *msg, bool stop)
{
bool is_read = msg->flags & I2C_M_RD;
bool recovery = false;
@@ -213,8 +211,7 @@ static int uniphier_i2c_check_bus_busy(struct i2c_adapter *adap)
return 0;
}
-static int uniphier_i2c_master_xfer(struct i2c_adapter *adap,
- struct i2c_msg *msgs, int num)
+static int uniphier_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
struct i2c_msg *msg, *emsg = msgs + num;
int ret;
@@ -227,7 +224,7 @@ static int uniphier_i2c_master_xfer(struct i2c_adapter *adap,
/* Emit STOP if it is the last message or I2C_M_STOP is set. */
bool stop = (msg + 1 == emsg) || (msg->flags & I2C_M_STOP);
- ret = uniphier_i2c_master_xfer_one(adap, msg, stop);
+ ret = uniphier_i2c_xfer_one(adap, msg, stop);
if (ret)
return ret;
}
@@ -241,7 +238,7 @@ static u32 uniphier_i2c_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm uniphier_i2c_algo = {
- .master_xfer = uniphier_i2c_master_xfer,
+ .xfer = uniphier_i2c_xfer,
.functionality = uniphier_i2c_functionality,
};
diff --git a/drivers/i2c/busses/i2c-viai2c-common.c b/drivers/i2c/busses/i2c-viai2c-common.c
new file mode 100644
index 000000000000..5a53ed95a59b
--- /dev/null
+++ b/drivers/i2c/busses/i2c-viai2c-common.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <linux/of_irq.h>
+#include "i2c-viai2c-common.h"
+
+int viai2c_wait_bus_not_busy(struct viai2c *i2c)
+{
+ unsigned long timeout;
+
+ timeout = jiffies + VIAI2C_TIMEOUT;
+ while (!(readw(i2c->base + VIAI2C_REG_CSR) & VIAI2C_CSR_READY_MASK)) {
+ if (time_after(jiffies, timeout)) {
+ dev_warn(i2c->dev, "timeout waiting for bus ready\n");
+ return -EBUSY;
+ }
+ msleep(20);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(viai2c_wait_bus_not_busy);
+
+static int viai2c_write(struct viai2c *i2c, struct i2c_msg *pmsg, int last)
+{
+ u16 val, tcr_val = i2c->tcr;
+
+ i2c->last = last;
+
+ if (pmsg->len == 0) {
+ /*
+ * We still need to run through the while (..) once, so
+ * start at -1 and break out early from the loop
+ */
+ i2c->xfered_len = -1;
+ writew(0, i2c->base + VIAI2C_REG_CDR);
+ } else {
+ writew(pmsg->buf[0] & 0xFF, i2c->base + VIAI2C_REG_CDR);
+ }
+
+ if (i2c->platform == VIAI2C_PLAT_WMT && !(pmsg->flags & I2C_M_NOSTART)) {
+ val = readw(i2c->base + VIAI2C_REG_CR);
+ val &= ~VIAI2C_CR_TX_END;
+ val |= VIAI2C_CR_CPU_RDY;
+ writew(val, i2c->base + VIAI2C_REG_CR);
+ }
+
+ reinit_completion(&i2c->complete);
+
+ tcr_val |= pmsg->addr & VIAI2C_TCR_ADDR_MASK;
+
+ writew(tcr_val, i2c->base + VIAI2C_REG_TCR);
+
+ if (i2c->platform == VIAI2C_PLAT_WMT && pmsg->flags & I2C_M_NOSTART) {
+ val = readw(i2c->base + VIAI2C_REG_CR);
+ val |= VIAI2C_CR_CPU_RDY;
+ writew(val, i2c->base + VIAI2C_REG_CR);
+ }
+
+ if (!wait_for_completion_timeout(&i2c->complete, VIAI2C_TIMEOUT))
+ return -ETIMEDOUT;
+
+ return i2c->ret;
+}
+
+static int viai2c_read(struct viai2c *i2c, struct i2c_msg *pmsg, bool first)
+{
+ u16 val, tcr_val = i2c->tcr;
+
+ val = readw(i2c->base + VIAI2C_REG_CR);
+ val &= ~(VIAI2C_CR_TX_END | VIAI2C_CR_RX_END);
+
+ if (i2c->platform == VIAI2C_PLAT_WMT && !(pmsg->flags & I2C_M_NOSTART))
+ val |= VIAI2C_CR_CPU_RDY;
+
+ if (pmsg->len == 1)
+ val |= VIAI2C_CR_RX_END;
+
+ writew(val, i2c->base + VIAI2C_REG_CR);
+
+ reinit_completion(&i2c->complete);
+
+ tcr_val |= VIAI2C_TCR_READ | (pmsg->addr & VIAI2C_TCR_ADDR_MASK);
+
+ writew(tcr_val, i2c->base + VIAI2C_REG_TCR);
+
+ if ((i2c->platform == VIAI2C_PLAT_WMT && (pmsg->flags & I2C_M_NOSTART)) ||
+ (i2c->platform == VIAI2C_PLAT_ZHAOXIN && !first)) {
+ val = readw(i2c->base + VIAI2C_REG_CR);
+ val |= VIAI2C_CR_CPU_RDY;
+ writew(val, i2c->base + VIAI2C_REG_CR);
+ }
+
+ if (!wait_for_completion_timeout(&i2c->complete, VIAI2C_TIMEOUT))
+ return -ETIMEDOUT;
+
+ return i2c->ret;
+}
+
+int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+ struct i2c_msg *pmsg;
+ int i;
+ int ret = 0;
+ struct viai2c *i2c = i2c_get_adapdata(adap);
+
+ i2c->mode = VIAI2C_BYTE_MODE;
+ for (i = 0; ret >= 0 && i < num; i++) {
+ pmsg = &msgs[i];
+ if (i2c->platform == VIAI2C_PLAT_WMT && !(pmsg->flags & I2C_M_NOSTART)) {
+ ret = viai2c_wait_bus_not_busy(i2c);
+ if (ret < 0)
+ return ret;
+ }
+
+ i2c->msg = pmsg;
+ i2c->xfered_len = 0;
+
+ if (pmsg->flags & I2C_M_RD)
+ ret = viai2c_read(i2c, pmsg, i == 0);
+ else
+ ret = viai2c_write(i2c, pmsg, (i + 1) == num);
+ }
+
+ return (ret < 0) ? ret : i;
+}
+EXPORT_SYMBOL_GPL(viai2c_xfer);
+
+/*
+ * Main process of the byte mode xfer
+ *
+ * Return value indicates whether the transfer is complete
+ * 1: all the data has been successfully transferred
+ * 0: there is still data that needs to be transferred
+ * -EIO: error occurred
+ */
+int viai2c_irq_xfer(struct viai2c *i2c)
+{
+ u16 val;
+ struct i2c_msg *msg = i2c->msg;
+ u8 read = msg->flags & I2C_M_RD;
+ void __iomem *base = i2c->base;
+
+ if (read) {
+ msg->buf[i2c->xfered_len] = readw(base + VIAI2C_REG_CDR) >> 8;
+
+ val = readw(base + VIAI2C_REG_CR) | VIAI2C_CR_CPU_RDY;
+ if (i2c->xfered_len == msg->len - 2)
+ val |= VIAI2C_CR_RX_END;
+ writew(val, base + VIAI2C_REG_CR);
+ } else {
+ val = readw(base + VIAI2C_REG_CSR);
+ if (val & VIAI2C_CSR_RCV_NOT_ACK)
+ return -EIO;
+
+ /* I2C_SMBUS_QUICK */
+ if (msg->len == 0) {
+ val = VIAI2C_CR_TX_END | VIAI2C_CR_CPU_RDY | VIAI2C_CR_ENABLE;
+ writew(val, base + VIAI2C_REG_CR);
+ return 1;
+ }
+
+ if ((i2c->xfered_len + 1) == msg->len) {
+ if (i2c->platform == VIAI2C_PLAT_WMT && !i2c->last)
+ writew(VIAI2C_CR_ENABLE, base + VIAI2C_REG_CR);
+ else if (i2c->platform == VIAI2C_PLAT_ZHAOXIN && i2c->last)
+ writeb(VIAI2C_CR_TX_END, base + VIAI2C_REG_CR);
+ } else {
+ writew(msg->buf[i2c->xfered_len + 1] & 0xFF, base + VIAI2C_REG_CDR);
+ writew(VIAI2C_CR_CPU_RDY | VIAI2C_CR_ENABLE, base + VIAI2C_REG_CR);
+ }
+ }
+
+ i2c->xfered_len++;
+
+ return i2c->xfered_len == msg->len;
+}
+EXPORT_SYMBOL_GPL(viai2c_irq_xfer);
+
+int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat)
+{
+ struct viai2c *i2c;
+
+ i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
+ if (!i2c)
+ return -ENOMEM;
+
+ i2c->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+ if (IS_ERR(i2c->base))
+ return PTR_ERR(i2c->base);
+
+ i2c->platform = plat;
+
+ i2c->dev = &pdev->dev;
+ init_completion(&i2c->complete);
+ platform_set_drvdata(pdev, i2c);
+
+ *pi2c = i2c;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(viai2c_init);
+
+MODULE_DESCRIPTION("Via/Wondermedia/Zhaoxin I2C controller core");
+MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-viai2c-common.h b/drivers/i2c/busses/i2c-viai2c-common.h
new file mode 100644
index 000000000000..00f17733223c
--- /dev/null
+++ b/drivers/i2c/busses/i2c-viai2c-common.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef __I2C_VIAI2C_COMMON_H_
+#define __I2C_VIAI2C_COMMON_H_
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+/* REG_CR Bit fields */
+#define VIAI2C_REG_CR 0x00
+#define VIAI2C_CR_ENABLE BIT(0)
+#define VIAI2C_CR_RX_END BIT(1)
+#define VIAI2C_CR_TX_END BIT(2)
+#define VIAI2C_CR_CPU_RDY BIT(3)
+#define VIAI2C_CR_END_MASK GENMASK(2, 1)
+
+/* REG_TCR Bit fields */
+#define VIAI2C_REG_TCR 0x02
+#define VIAI2C_TCR_HS_MODE BIT(13)
+#define VIAI2C_TCR_READ BIT(14)
+#define VIAI2C_TCR_FAST BIT(15)
+#define VIAI2C_TCR_ADDR_MASK GENMASK(6, 0)
+
+/* REG_CSR Bit fields */
+#define VIAI2C_REG_CSR 0x04
+#define VIAI2C_CSR_RCV_NOT_ACK BIT(0)
+#define VIAI2C_CSR_RCV_ACK_MASK BIT(0)
+#define VIAI2C_CSR_READY_MASK BIT(1)
+
+/* REG_ISR Bit fields */
+#define VIAI2C_REG_ISR 0x06
+#define VIAI2C_ISR_NACK_ADDR BIT(0)
+#define VIAI2C_ISR_BYTE_END BIT(1)
+#define VIAI2C_ISR_SCL_TIMEOUT BIT(2)
+#define VIAI2C_ISR_MASK_ALL GENMASK(2, 0)
+
+/* REG_IMR Bit fields */
+#define VIAI2C_REG_IMR 0x08
+#define VIAI2C_IMR_BYTE BIT(1)
+#define VIAI2C_IMR_ENABLE_ALL GENMASK(2, 0)
+
+#define VIAI2C_REG_CDR 0x0A
+#define VIAI2C_REG_TR 0x0C
+#define VIAI2C_REG_MCR 0x0E
+
+#define VIAI2C_TIMEOUT (msecs_to_jiffies(1000))
+
+enum {
+ VIAI2C_PLAT_WMT,
+ VIAI2C_PLAT_ZHAOXIN
+};
+
+enum {
+ VIAI2C_BYTE_MODE,
+ VIAI2C_FIFO_MODE
+};
+
+struct viai2c {
+ struct i2c_adapter adapter;
+ struct completion complete;
+ struct device *dev;
+ void __iomem *base;
+ struct clk *clk;
+ u16 tcr;
+ int irq;
+ u16 xfered_len;
+ struct i2c_msg *msg;
+ int ret;
+ bool last;
+ unsigned int mode;
+ unsigned int platform;
+ void *pltfm_priv;
+};
+
+int viai2c_wait_bus_not_busy(struct viai2c *i2c);
+int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num);
+int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat);
+int viai2c_irq_xfer(struct viai2c *i2c);
+
+#endif
diff --git a/drivers/i2c/busses/i2c-viai2c-wmt.c b/drivers/i2c/busses/i2c-viai2c-wmt.c
new file mode 100644
index 000000000000..3415683dab91
--- /dev/null
+++ b/drivers/i2c/busses/i2c-viai2c-wmt.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Wondermedia I2C Controller Driver
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Derived from GPLv2+ licensed source:
+ * - Copyright (C) 2008 WonderMedia Technologies, Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include "i2c-viai2c-common.h"
+
+#define REG_SLAVE_CR 0x10
+#define REG_SLAVE_SR 0x12
+#define REG_SLAVE_ISR 0x14
+#define REG_SLAVE_IMR 0x16
+#define REG_SLAVE_DR 0x18
+#define REG_SLAVE_TR 0x1A
+
+/* REG_TR */
+#define SCL_TIMEOUT(x) (((x) & 0xFF) << 8)
+#define TR_STD 0x0064
+#define TR_HS 0x0019
+
+/* REG_MCR */
+#define MCR_APB_96M 7
+#define MCR_APB_166M 12
+
+static u32 wmt_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART;
+}
+
+static const struct i2c_algorithm wmt_i2c_algo = {
+ .xfer = viai2c_xfer,
+ .functionality = wmt_i2c_func,
+};
+
+static int wmt_i2c_reset_hardware(struct viai2c *i2c)
+{
+ int err;
+
+ err = clk_prepare_enable(i2c->clk);
+ if (err) {
+ dev_err(i2c->dev, "failed to enable clock\n");
+ return err;
+ }
+
+ err = clk_set_rate(i2c->clk, 20000000);
+ if (err) {
+ dev_err(i2c->dev, "failed to set clock = 20Mhz\n");
+ clk_disable_unprepare(i2c->clk);
+ return err;
+ }
+
+ writew(0, i2c->base + VIAI2C_REG_CR);
+ writew(MCR_APB_166M, i2c->base + VIAI2C_REG_MCR);
+ writew(VIAI2C_ISR_MASK_ALL, i2c->base + VIAI2C_REG_ISR);
+ writew(VIAI2C_IMR_ENABLE_ALL, i2c->base + VIAI2C_REG_IMR);
+ writew(VIAI2C_CR_ENABLE, i2c->base + VIAI2C_REG_CR);
+ readw(i2c->base + VIAI2C_REG_CSR); /* read clear */
+ writew(VIAI2C_ISR_MASK_ALL, i2c->base + VIAI2C_REG_ISR);
+
+ if (i2c->tcr == VIAI2C_TCR_FAST)
+ writew(SCL_TIMEOUT(128) | TR_HS, i2c->base + VIAI2C_REG_TR);
+ else
+ writew(SCL_TIMEOUT(128) | TR_STD, i2c->base + VIAI2C_REG_TR);
+
+ return 0;
+}
+
+static irqreturn_t wmt_i2c_isr(int irq, void *data)
+{
+ struct viai2c *i2c = data;
+ u8 status;
+
+ /* save the status and write-clear it */
+ status = readw(i2c->base + VIAI2C_REG_ISR);
+ writew(status, i2c->base + VIAI2C_REG_ISR);
+
+ i2c->ret = 0;
+ if (status & VIAI2C_ISR_NACK_ADDR)
+ i2c->ret = -EIO;
+
+ if (status & VIAI2C_ISR_SCL_TIMEOUT)
+ i2c->ret = -ETIMEDOUT;
+
+ if (!i2c->ret)
+ i2c->ret = viai2c_irq_xfer(i2c);
+
+ /* All the data has been successfully transferred or error occurred */
+ if (i2c->ret)
+ complete(&i2c->complete);
+
+ return IRQ_HANDLED;
+}
+
+static int wmt_i2c_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct viai2c *i2c;
+ struct i2c_adapter *adap;
+ int err;
+ u32 clk_rate;
+
+ err = viai2c_init(pdev, &i2c, VIAI2C_PLAT_WMT);
+ if (err)
+ return err;
+
+ i2c->irq = platform_get_irq(pdev, 0);
+ if (i2c->irq < 0)
+ return i2c->irq;
+
+ err = devm_request_irq(&pdev->dev, i2c->irq, wmt_i2c_isr,
+ 0, pdev->name, i2c);
+ if (err)
+ return dev_err_probe(&pdev->dev, err,
+ "failed to request irq %i\n", i2c->irq);
+
+ i2c->clk = of_clk_get(np, 0);
+ if (IS_ERR(i2c->clk)) {
+ dev_err(&pdev->dev, "unable to request clock\n");
+ return PTR_ERR(i2c->clk);
+ }
+
+ err = of_property_read_u32(np, "clock-frequency", &clk_rate);
+ if (!err && clk_rate == I2C_MAX_FAST_MODE_FREQ)
+ i2c->tcr = VIAI2C_TCR_FAST;
+
+ adap = &i2c->adapter;
+ i2c_set_adapdata(adap, i2c);
+ strscpy(adap->name, "WMT I2C adapter", sizeof(adap->name));
+ adap->owner = THIS_MODULE;
+ adap->algo = &wmt_i2c_algo;
+ adap->dev.parent = &pdev->dev;
+ adap->dev.of_node = pdev->dev.of_node;
+
+ err = wmt_i2c_reset_hardware(i2c);
+ if (err) {
+ dev_err(&pdev->dev, "error initializing hardware\n");
+ return err;
+ }
+
+ err = i2c_add_adapter(adap);
+ if (err)
+ /* wmt_i2c_reset_hardware() enables i2c_dev->clk */
+ clk_disable_unprepare(i2c->clk);
+
+ return err;
+}
+
+static void wmt_i2c_remove(struct platform_device *pdev)
+{
+ struct viai2c *i2c = platform_get_drvdata(pdev);
+
+ /* Disable interrupts, clock and delete adapter */
+ writew(0, i2c->base + VIAI2C_REG_IMR);
+ clk_disable_unprepare(i2c->clk);
+ i2c_del_adapter(&i2c->adapter);
+}
+
+static const struct of_device_id wmt_i2c_dt_ids[] = {
+ { .compatible = "wm,wm8505-i2c" },
+ { /* Sentinel */ },
+};
+
+static struct platform_driver wmt_i2c_driver = {
+ .probe = wmt_i2c_probe,
+ .remove_new = wmt_i2c_remove,
+ .driver = {
+ .name = "wmt-i2c",
+ .of_match_table = wmt_i2c_dt_ids,
+ },
+};
+
+module_platform_driver(wmt_i2c_driver);
+
+MODULE_DESCRIPTION("Wondermedia I2C controller driver");
+MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(of, wmt_i2c_dt_ids);
diff --git a/drivers/i2c/busses/i2c-viai2c-zhaoxin.c b/drivers/i2c/busses/i2c-viai2c-zhaoxin.c
new file mode 100644
index 000000000000..95dc64902b7c
--- /dev/null
+++ b/drivers/i2c/busses/i2c-viai2c-zhaoxin.c
@@ -0,0 +1,367 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright(c) 2024 Shanghai Zhaoxin Semiconductor Corporation.
+ * All rights reserved.
+ */
+
+#include <linux/acpi.h>
+#include "i2c-viai2c-common.h"
+
+/*
+ * registers
+ */
+/* Zhaoxin specific register bit fields */
+/* REG_CR Bit fields */
+#define ZXI2C_CR_MST_RST BIT(7)
+#define ZXI2C_CR_FIFO_MODE BIT(14)
+/* REG_ISR/IMR Bit fields */
+#define ZXI2C_IRQ_FIFONACK BIT(4)
+#define ZXI2C_IRQ_FIFOEND BIT(3)
+#define ZXI2C_IRQ_MASK (VIAI2C_ISR_MASK_ALL \
+ | ZXI2C_IRQ_FIFOEND \
+ | ZXI2C_IRQ_FIFONACK)
+/* Zhaoxin specific registers */
+#define ZXI2C_REG_CLK 0x10
+#define ZXI2C_CLK_50M BIT(0)
+#define ZXI2C_REG_REV 0x11
+#define ZXI2C_REG_HCR 0x12
+#define ZXI2C_HCR_RST_FIFO GENMASK(1, 0)
+#define ZXI2C_REG_HTDR 0x13
+#define ZXI2C_REG_HRDR 0x14
+#define ZXI2C_REG_HTLR 0x15
+#define ZXI2C_REG_HRLR 0x16
+#define ZXI2C_REG_HWCNTR 0x18
+#define ZXI2C_REG_HRCNTR 0x19
+
+/* parameters Constants */
+#define ZXI2C_GOLD_FSTP_100K 0xF3
+#define ZXI2C_GOLD_FSTP_400K 0x38
+#define ZXI2C_GOLD_FSTP_1M 0x13
+#define ZXI2C_GOLD_FSTP_3400K 0x37
+#define ZXI2C_HS_CTRL_CODE (0x08 << 8)
+
+#define ZXI2C_FIFO_SIZE 32
+
+struct viai2c_zhaoxin {
+ u8 hrv;
+ u16 tr;
+ u16 mcr;
+ u16 xfer_len;
+};
+
+static int viai2c_fifo_xfer(struct viai2c *i2c)
+{
+ u16 i;
+ u8 tmp;
+ struct i2c_msg *msg = i2c->msg;
+ void __iomem *base = i2c->base;
+ bool read = !!(msg->flags & I2C_M_RD);
+ struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
+
+ /* reset fifo buffer */
+ tmp = ioread8(base + ZXI2C_REG_HCR);
+ iowrite8(tmp | ZXI2C_HCR_RST_FIFO, base + ZXI2C_REG_HCR);
+
+ /* set xfer len */
+ priv->xfer_len = min_t(u16, msg->len - i2c->xfered_len, ZXI2C_FIFO_SIZE);
+ if (read) {
+ iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HRLR);
+ } else {
+ iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HTLR);
+ /* set write data */
+ for (i = 0; i < priv->xfer_len; i++)
+ iowrite8(msg->buf[i2c->xfered_len + i], base + ZXI2C_REG_HTDR);
+ }
+
+ /* prepare to stop transmission */
+ if (priv->hrv && msg->len == (i2c->xfered_len + priv->xfer_len)) {
+ tmp = ioread8(base + VIAI2C_REG_CR);
+ tmp |= read ? VIAI2C_CR_RX_END : VIAI2C_CR_TX_END;
+ iowrite8(tmp, base + VIAI2C_REG_CR);
+ }
+
+ u16 tcr_val = i2c->tcr;
+
+ /* start transmission */
+ tcr_val |= read ? VIAI2C_TCR_READ : 0;
+ writew(tcr_val | msg->addr, base + VIAI2C_REG_TCR);
+
+ return 0;
+}
+
+static int viai2c_fifo_irq_xfer(struct viai2c *i2c)
+{
+ u16 i;
+ u8 tmp;
+ struct i2c_msg *msg = i2c->msg;
+ void __iomem *base = i2c->base;
+ bool read = !!(msg->flags & I2C_M_RD);
+ struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
+
+ /* get the received data */
+ if (read)
+ for (i = 0; i < priv->xfer_len; i++)
+ msg->buf[i2c->xfered_len + i] = ioread8(base + ZXI2C_REG_HRDR);
+
+ i2c->xfered_len += priv->xfer_len;
+ if (i2c->xfered_len == msg->len)
+ return 1;
+
+ /* reset fifo buffer */
+ tmp = ioread8(base + ZXI2C_REG_HCR);
+ iowrite8(tmp | ZXI2C_HCR_RST_FIFO, base + ZXI2C_REG_HCR);
+
+ /* set xfer len */
+ priv->xfer_len = min_t(u16, msg->len - i2c->xfered_len, ZXI2C_FIFO_SIZE);
+ if (read) {
+ iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HRLR);
+ } else {
+ iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HTLR);
+ /* set write data */
+ for (i = 0; i < priv->xfer_len; i++)
+ iowrite8(msg->buf[i2c->xfered_len + i], base + ZXI2C_REG_HTDR);
+ }
+
+ /* prepare to stop transmission */
+ if (priv->hrv && msg->len == (i2c->xfered_len + priv->xfer_len)) {
+ tmp = ioread8(base + VIAI2C_REG_CR);
+ tmp |= read ? VIAI2C_CR_RX_END : VIAI2C_CR_TX_END;
+ iowrite8(tmp, base + VIAI2C_REG_CR);
+ }
+
+ /* continue transmission */
+ tmp = ioread8(base + VIAI2C_REG_CR);
+ iowrite8(tmp |= VIAI2C_CR_CPU_RDY, base + VIAI2C_REG_CR);
+
+ return 0;
+}
+
+static int zxi2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+ u8 tmp;
+ int ret;
+ struct viai2c *i2c = (struct viai2c *)i2c_get_adapdata(adap);
+ struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
+ void __iomem *base = i2c->base;
+
+ ret = viai2c_wait_bus_not_busy(i2c);
+ if (ret)
+ return ret;
+
+ tmp = ioread8(base + VIAI2C_REG_CR);
+ tmp &= ~(VIAI2C_CR_RX_END | VIAI2C_CR_TX_END);
+
+ if (num == 1 && msgs->len >= 2 && (priv->hrv || msgs->len <= ZXI2C_FIFO_SIZE)) {
+ /* enable fifo mode */
+ iowrite16(ZXI2C_CR_FIFO_MODE | tmp, base + VIAI2C_REG_CR);
+ /* clear irq status */
+ iowrite8(ZXI2C_IRQ_MASK, base + VIAI2C_REG_ISR);
+ /* enable fifo irq */
+ iowrite8(VIAI2C_ISR_NACK_ADDR | ZXI2C_IRQ_FIFOEND, base + VIAI2C_REG_IMR);
+
+ i2c->msg = msgs;
+ i2c->mode = VIAI2C_FIFO_MODE;
+ priv->xfer_len = 0;
+ i2c->xfered_len = 0;
+
+ viai2c_fifo_xfer(i2c);
+
+ if (!wait_for_completion_timeout(&i2c->complete, VIAI2C_TIMEOUT))
+ return -ETIMEDOUT;
+
+ ret = i2c->ret;
+ } else {
+ /* enable byte mode */
+ iowrite16(tmp, base + VIAI2C_REG_CR);
+ /* clear irq status */
+ iowrite8(ZXI2C_IRQ_MASK, base + VIAI2C_REG_ISR);
+ /* enable byte irq */
+ iowrite8(VIAI2C_ISR_NACK_ADDR | VIAI2C_IMR_BYTE, base + VIAI2C_REG_IMR);
+
+ ret = viai2c_xfer(adap, msgs, num);
+ if (ret == -ETIMEDOUT)
+ iowrite16(tmp | VIAI2C_CR_END_MASK, base + VIAI2C_REG_CR);
+ }
+ /* dis interrupt */
+ iowrite8(0, base + VIAI2C_REG_IMR);
+
+ return ret;
+}
+
+static u32 zxi2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm zxi2c_algorithm = {
+ .xfer = zxi2c_xfer,
+ .functionality = zxi2c_func,
+};
+
+static const struct i2c_adapter_quirks zxi2c_quirks = {
+ .flags = I2C_AQ_NO_ZERO_LEN | I2C_AQ_COMB_WRITE_THEN_READ,
+};
+
+static const u32 zxi2c_speed_params_table[][3] = {
+ /* speed, ZXI2C_TCR, ZXI2C_FSTP */
+ { I2C_MAX_STANDARD_MODE_FREQ, 0, ZXI2C_GOLD_FSTP_100K },
+ { I2C_MAX_FAST_MODE_FREQ, VIAI2C_TCR_FAST, ZXI2C_GOLD_FSTP_400K },
+ { I2C_MAX_FAST_MODE_PLUS_FREQ, VIAI2C_TCR_FAST, ZXI2C_GOLD_FSTP_1M },
+ { I2C_MAX_HIGH_SPEED_MODE_FREQ, VIAI2C_TCR_HS_MODE | VIAI2C_TCR_FAST,
+ ZXI2C_GOLD_FSTP_3400K },
+};
+
+static void zxi2c_set_bus_speed(struct viai2c *i2c)
+{
+ struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
+
+ iowrite16(priv->tr, i2c->base + VIAI2C_REG_TR);
+ iowrite8(ZXI2C_CLK_50M, i2c->base + ZXI2C_REG_CLK);
+ iowrite16(priv->mcr, i2c->base + VIAI2C_REG_MCR);
+}
+
+static void zxi2c_get_bus_speed(struct viai2c *i2c)
+{
+ u8 i, count;
+ u8 fstp;
+ const u32 *params;
+ struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
+ u32 acpi_speed = i2c_acpi_find_bus_speed(i2c->dev);
+
+ count = ARRAY_SIZE(zxi2c_speed_params_table);
+ for (i = 0; i < count; i++)
+ if (acpi_speed == zxi2c_speed_params_table[i][0])
+ break;
+ /* if not found, use 400k as default */
+ i = i < count ? i : 1;
+
+ params = zxi2c_speed_params_table[i];
+ fstp = ioread8(i2c->base + VIAI2C_REG_TR);
+ if (abs(fstp - params[2]) > 0x10) {
+ /*
+ * if BIOS setting value far from golden value,
+ * use golden value and warn user
+ */
+ dev_warn(i2c->dev, "FW FSTP[%x] might cause wrong timings, dropped\n", fstp);
+ priv->tr = params[2] | 0xff00;
+ } else {
+ priv->tr = fstp | 0xff00;
+ }
+
+ i2c->tcr = params[1];
+ priv->mcr = ioread16(i2c->base + VIAI2C_REG_MCR);
+ /* for Hs-mode, use 0x80 as controller code */
+ if (params[0] == I2C_MAX_HIGH_SPEED_MODE_FREQ)
+ priv->mcr |= ZXI2C_HS_CTRL_CODE;
+
+ dev_info(i2c->dev, "speed mode is %s\n", i2c_freq_mode_string(params[0]));
+}
+
+static irqreturn_t zxi2c_isr(int irq, void *data)
+{
+ struct viai2c *i2c = data;
+ u8 status;
+
+ /* save the status and write-clear it */
+ status = readw(i2c->base + VIAI2C_REG_ISR);
+ if (!status)
+ return IRQ_NONE;
+
+ writew(status, i2c->base + VIAI2C_REG_ISR);
+
+ i2c->ret = 0;
+ if (status & VIAI2C_ISR_NACK_ADDR)
+ i2c->ret = -EIO;
+
+ if (!i2c->ret) {
+ if (i2c->mode == VIAI2C_BYTE_MODE)
+ i2c->ret = viai2c_irq_xfer(i2c);
+ else
+ i2c->ret = viai2c_fifo_irq_xfer(i2c);
+ }
+
+ /* All the data has been successfully transferred or error occurred */
+ if (i2c->ret)
+ complete(&i2c->complete);
+
+ return IRQ_HANDLED;
+}
+
+static int zxi2c_probe(struct platform_device *pdev)
+{
+ int error;
+ struct viai2c *i2c;
+ struct i2c_adapter *adap;
+ struct viai2c_zhaoxin *priv;
+
+ error = viai2c_init(pdev, &i2c, VIAI2C_PLAT_ZHAOXIN);
+ if (error)
+ return error;
+
+ i2c->irq = platform_get_irq(pdev, 0);
+ if (i2c->irq < 0)
+ return i2c->irq;
+
+ error = devm_request_irq(&pdev->dev, i2c->irq, zxi2c_isr,
+ IRQF_SHARED, pdev->name, i2c);
+ if (error)
+ return dev_err_probe(&pdev->dev, error,
+ "failed to request irq %i\n", i2c->irq);
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ i2c->pltfm_priv = priv;
+
+ zxi2c_get_bus_speed(i2c);
+ zxi2c_set_bus_speed(i2c);
+
+ priv->hrv = ioread8(i2c->base + ZXI2C_REG_REV);
+
+ adap = &i2c->adapter;
+ adap->owner = THIS_MODULE;
+ adap->algo = &zxi2c_algorithm;
+ adap->quirks = &zxi2c_quirks;
+ adap->dev.parent = &pdev->dev;
+ ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev));
+ snprintf(adap->name, sizeof(adap->name), "zhaoxin-%s-%s",
+ dev_name(pdev->dev.parent), dev_name(i2c->dev));
+ i2c_set_adapdata(adap, i2c);
+
+ return devm_i2c_add_adapter(&pdev->dev, adap);
+}
+
+static int __maybe_unused zxi2c_resume(struct device *dev)
+{
+ struct viai2c *i2c = dev_get_drvdata(dev);
+
+ iowrite8(ZXI2C_CR_MST_RST, i2c->base + VIAI2C_REG_CR);
+ zxi2c_set_bus_speed(i2c);
+
+ return 0;
+}
+
+static const struct dev_pm_ops zxi2c_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(NULL, zxi2c_resume)
+};
+
+static const struct acpi_device_id zxi2c_acpi_match[] = {
+ {"IIC1D17", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, zxi2c_acpi_match);
+
+static struct platform_driver zxi2c_driver = {
+ .probe = zxi2c_probe,
+ .driver = {
+ .name = "i2c_zhaoxin",
+ .acpi_match_table = zxi2c_acpi_match,
+ .pm = &zxi2c_pm,
+ },
+};
+
+module_platform_driver(zxi2c_driver);
+
+MODULE_AUTHOR("HansHu@zhaoxin.com");
+MODULE_DESCRIPTION("Shanghai Zhaoxin IIC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-viperboard.c b/drivers/i2c/busses/i2c-viperboard.c
index 9e153b5b0e8e..2ed4130c0339 100644
--- a/drivers/i2c/busses/i2c-viperboard.c
+++ b/drivers/i2c/busses/i2c-viperboard.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Nano River Technologies viperboard i2c master driver
+ * Nano River Technologies viperboard i2c controller driver
*
* (C) 2012 by Lemonage GmbH
* Author: Lars Poeschel <poeschel@lemonage.de>
@@ -273,8 +273,6 @@ static int vprbrd_i2c_xfer(struct i2c_adapter *i2c, struct i2c_msg *msgs,
(struct vprbrd_i2c_addr_msg *)vb->buf;
struct vprbrd_i2c_status *smsg = (struct vprbrd_i2c_status *)vb->buf;
- dev_dbg(&i2c->dev, "master xfer %d messages:\n", num);
-
for (i = 0 ; i < num ; i++) {
pmsg = &msgs[i];
@@ -345,8 +343,8 @@ static u32 vprbrd_i2c_func(struct i2c_adapter *i2c)
/* This is the actual algorithm we define */
static const struct i2c_algorithm vprbrd_algorithm = {
- .master_xfer = vprbrd_i2c_xfer,
- .functionality = vprbrd_i2c_func,
+ .xfer = vprbrd_i2c_xfer,
+ .functionality = vprbrd_i2c_func,
};
static const struct i2c_adapter_quirks vprbrd_quirks = {
@@ -416,7 +414,6 @@ static void vprbrd_i2c_remove(struct platform_device *pdev)
static struct platform_driver vprbrd_i2c_driver = {
.driver.name = "viperboard-i2c",
- .driver.owner = THIS_MODULE,
.probe = vprbrd_i2c_probe,
.remove_new = vprbrd_i2c_remove,
};
@@ -461,6 +458,6 @@ static void __exit vprbrd_i2c_exit(void)
module_exit(vprbrd_i2c_exit);
MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>");
-MODULE_DESCRIPTION("I2C master driver for Nano River Techs Viperboard");
+MODULE_DESCRIPTION("I2C controller driver for Nano River Techs Viperboard");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:viperboard-i2c");
diff --git a/drivers/i2c/busses/i2c-virtio.c b/drivers/i2c/busses/i2c-virtio.c
index c60ae531ba57..52ba1e0845ca 100644
--- a/drivers/i2c/busses/i2c-virtio.c
+++ b/drivers/i2c/busses/i2c-virtio.c
@@ -183,7 +183,7 @@ static u32 virtio_i2c_func(struct i2c_adapter *adap)
}
static struct i2c_algorithm virtio_algorithm = {
- .master_xfer = virtio_i2c_xfer,
+ .xfer = virtio_i2c_xfer,
.functionality = virtio_i2c_func,
};
diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c
deleted file mode 100644
index 198afee5233c..000000000000
--- a/drivers/i2c/busses/i2c-wmt.c
+++ /dev/null
@@ -1,421 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Wondermedia I2C Master Mode Driver
- *
- * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
- *
- * Derived from GPLv2+ licensed source:
- * - Copyright (C) 2008 WonderMedia Technologies, Inc.
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/platform_device.h>
-
-#define REG_CR 0x00
-#define REG_TCR 0x02
-#define REG_CSR 0x04
-#define REG_ISR 0x06
-#define REG_IMR 0x08
-#define REG_CDR 0x0A
-#define REG_TR 0x0C
-#define REG_MCR 0x0E
-#define REG_SLAVE_CR 0x10
-#define REG_SLAVE_SR 0x12
-#define REG_SLAVE_ISR 0x14
-#define REG_SLAVE_IMR 0x16
-#define REG_SLAVE_DR 0x18
-#define REG_SLAVE_TR 0x1A
-
-/* REG_CR Bit fields */
-#define CR_TX_NEXT_ACK 0x0000
-#define CR_ENABLE 0x0001
-#define CR_TX_NEXT_NO_ACK 0x0002
-#define CR_TX_END 0x0004
-#define CR_CPU_RDY 0x0008
-#define SLAV_MODE_SEL 0x8000
-
-/* REG_TCR Bit fields */
-#define TCR_STANDARD_MODE 0x0000
-#define TCR_MASTER_WRITE 0x0000
-#define TCR_HS_MODE 0x2000
-#define TCR_MASTER_READ 0x4000
-#define TCR_FAST_MODE 0x8000
-#define TCR_SLAVE_ADDR_MASK 0x007F
-
-/* REG_ISR Bit fields */
-#define ISR_NACK_ADDR 0x0001
-#define ISR_BYTE_END 0x0002
-#define ISR_SCL_TIMEOUT 0x0004
-#define ISR_WRITE_ALL 0x0007
-
-/* REG_IMR Bit fields */
-#define IMR_ENABLE_ALL 0x0007
-
-/* REG_CSR Bit fields */
-#define CSR_RCV_NOT_ACK 0x0001
-#define CSR_RCV_ACK_MASK 0x0001
-#define CSR_READY_MASK 0x0002
-
-/* REG_TR */
-#define SCL_TIMEOUT(x) (((x) & 0xFF) << 8)
-#define TR_STD 0x0064
-#define TR_HS 0x0019
-
-/* REG_MCR */
-#define MCR_APB_96M 7
-#define MCR_APB_166M 12
-
-#define WMT_I2C_TIMEOUT (msecs_to_jiffies(1000))
-
-struct wmt_i2c_dev {
- struct i2c_adapter adapter;
- struct completion complete;
- struct device *dev;
- void __iomem *base;
- struct clk *clk;
- u16 tcr;
- int irq;
- u16 cmd_status;
-};
-
-static int wmt_i2c_wait_bus_not_busy(struct wmt_i2c_dev *i2c_dev)
-{
- unsigned long timeout;
-
- timeout = jiffies + WMT_I2C_TIMEOUT;
- while (!(readw(i2c_dev->base + REG_CSR) & CSR_READY_MASK)) {
- if (time_after(jiffies, timeout)) {
- dev_warn(i2c_dev->dev, "timeout waiting for bus ready\n");
- return -EBUSY;
- }
- msleep(20);
- }
-
- return 0;
-}
-
-static int wmt_check_status(struct wmt_i2c_dev *i2c_dev)
-{
- int ret = 0;
- unsigned long wait_result;
-
- wait_result = wait_for_completion_timeout(&i2c_dev->complete,
- msecs_to_jiffies(500));
- if (!wait_result)
- return -ETIMEDOUT;
-
- if (i2c_dev->cmd_status & ISR_NACK_ADDR)
- ret = -EIO;
-
- if (i2c_dev->cmd_status & ISR_SCL_TIMEOUT)
- ret = -ETIMEDOUT;
-
- return ret;
-}
-
-static int wmt_i2c_write(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg,
- int last)
-{
- u16 val, tcr_val = i2c_dev->tcr;
- int ret;
- int xfer_len = 0;
-
- if (pmsg->len == 0) {
- /*
- * We still need to run through the while (..) once, so
- * start at -1 and break out early from the loop
- */
- xfer_len = -1;
- writew(0, i2c_dev->base + REG_CDR);
- } else {
- writew(pmsg->buf[0] & 0xFF, i2c_dev->base + REG_CDR);
- }
-
- if (!(pmsg->flags & I2C_M_NOSTART)) {
- val = readw(i2c_dev->base + REG_CR);
- val &= ~CR_TX_END;
- val |= CR_CPU_RDY;
- writew(val, i2c_dev->base + REG_CR);
- }
-
- reinit_completion(&i2c_dev->complete);
-
- tcr_val |= (TCR_MASTER_WRITE | (pmsg->addr & TCR_SLAVE_ADDR_MASK));
-
- writew(tcr_val, i2c_dev->base + REG_TCR);
-
- if (pmsg->flags & I2C_M_NOSTART) {
- val = readw(i2c_dev->base + REG_CR);
- val |= CR_CPU_RDY;
- writew(val, i2c_dev->base + REG_CR);
- }
-
- while (xfer_len < pmsg->len) {
- ret = wmt_check_status(i2c_dev);
- if (ret)
- return ret;
-
- xfer_len++;
-
- val = readw(i2c_dev->base + REG_CSR);
- if ((val & CSR_RCV_ACK_MASK) == CSR_RCV_NOT_ACK) {
- dev_dbg(i2c_dev->dev, "write RCV NACK error\n");
- return -EIO;
- }
-
- if (pmsg->len == 0) {
- val = CR_TX_END | CR_CPU_RDY | CR_ENABLE;
- writew(val, i2c_dev->base + REG_CR);
- break;
- }
-
- if (xfer_len == pmsg->len) {
- if (last != 1)
- writew(CR_ENABLE, i2c_dev->base + REG_CR);
- } else {
- writew(pmsg->buf[xfer_len] & 0xFF, i2c_dev->base +
- REG_CDR);
- writew(CR_CPU_RDY | CR_ENABLE, i2c_dev->base + REG_CR);
- }
- }
-
- return 0;
-}
-
-static int wmt_i2c_read(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg)
-{
- u16 val, tcr_val = i2c_dev->tcr;
- int ret;
- u32 xfer_len = 0;
-
- val = readw(i2c_dev->base + REG_CR);
- val &= ~(CR_TX_END | CR_TX_NEXT_NO_ACK);
-
- if (!(pmsg->flags & I2C_M_NOSTART))
- val |= CR_CPU_RDY;
-
- if (pmsg->len == 1)
- val |= CR_TX_NEXT_NO_ACK;
-
- writew(val, i2c_dev->base + REG_CR);
-
- reinit_completion(&i2c_dev->complete);
-
- tcr_val |= TCR_MASTER_READ | (pmsg->addr & TCR_SLAVE_ADDR_MASK);
-
- writew(tcr_val, i2c_dev->base + REG_TCR);
-
- if (pmsg->flags & I2C_M_NOSTART) {
- val = readw(i2c_dev->base + REG_CR);
- val |= CR_CPU_RDY;
- writew(val, i2c_dev->base + REG_CR);
- }
-
- while (xfer_len < pmsg->len) {
- ret = wmt_check_status(i2c_dev);
- if (ret)
- return ret;
-
- pmsg->buf[xfer_len] = readw(i2c_dev->base + REG_CDR) >> 8;
- xfer_len++;
-
- val = readw(i2c_dev->base + REG_CR) | CR_CPU_RDY;
- if (xfer_len == pmsg->len - 1)
- val |= CR_TX_NEXT_NO_ACK;
- writew(val, i2c_dev->base + REG_CR);
- }
-
- return 0;
-}
-
-static int wmt_i2c_xfer(struct i2c_adapter *adap,
- struct i2c_msg msgs[],
- int num)
-{
- struct i2c_msg *pmsg;
- int i;
- int ret = 0;
- struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
-
- for (i = 0; ret >= 0 && i < num; i++) {
- pmsg = &msgs[i];
- if (!(pmsg->flags & I2C_M_NOSTART)) {
- ret = wmt_i2c_wait_bus_not_busy(i2c_dev);
- if (ret < 0)
- return ret;
- }
-
- if (pmsg->flags & I2C_M_RD)
- ret = wmt_i2c_read(i2c_dev, pmsg);
- else
- ret = wmt_i2c_write(i2c_dev, pmsg, (i + 1) == num);
- }
-
- return (ret < 0) ? ret : i;
-}
-
-static u32 wmt_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART;
-}
-
-static const struct i2c_algorithm wmt_i2c_algo = {
- .master_xfer = wmt_i2c_xfer,
- .functionality = wmt_i2c_func,
-};
-
-static irqreturn_t wmt_i2c_isr(int irq, void *data)
-{
- struct wmt_i2c_dev *i2c_dev = data;
-
- /* save the status and write-clear it */
- i2c_dev->cmd_status = readw(i2c_dev->base + REG_ISR);
- writew(i2c_dev->cmd_status, i2c_dev->base + REG_ISR);
-
- complete(&i2c_dev->complete);
-
- return IRQ_HANDLED;
-}
-
-static int wmt_i2c_reset_hardware(struct wmt_i2c_dev *i2c_dev)
-{
- int err;
-
- err = clk_prepare_enable(i2c_dev->clk);
- if (err) {
- dev_err(i2c_dev->dev, "failed to enable clock\n");
- return err;
- }
-
- err = clk_set_rate(i2c_dev->clk, 20000000);
- if (err) {
- dev_err(i2c_dev->dev, "failed to set clock = 20Mhz\n");
- clk_disable_unprepare(i2c_dev->clk);
- return err;
- }
-
- writew(0, i2c_dev->base + REG_CR);
- writew(MCR_APB_166M, i2c_dev->base + REG_MCR);
- writew(ISR_WRITE_ALL, i2c_dev->base + REG_ISR);
- writew(IMR_ENABLE_ALL, i2c_dev->base + REG_IMR);
- writew(CR_ENABLE, i2c_dev->base + REG_CR);
- readw(i2c_dev->base + REG_CSR); /* read clear */
- writew(ISR_WRITE_ALL, i2c_dev->base + REG_ISR);
-
- if (i2c_dev->tcr == TCR_FAST_MODE)
- writew(SCL_TIMEOUT(128) | TR_HS, i2c_dev->base + REG_TR);
- else
- writew(SCL_TIMEOUT(128) | TR_STD, i2c_dev->base + REG_TR);
-
- return 0;
-}
-
-static int wmt_i2c_probe(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- struct wmt_i2c_dev *i2c_dev;
- struct i2c_adapter *adap;
- int err;
- u32 clk_rate;
-
- i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
- if (!i2c_dev)
- return -ENOMEM;
-
- i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
- if (IS_ERR(i2c_dev->base))
- return PTR_ERR(i2c_dev->base);
-
- i2c_dev->irq = irq_of_parse_and_map(np, 0);
- if (!i2c_dev->irq) {
- dev_err(&pdev->dev, "irq missing or invalid\n");
- return -EINVAL;
- }
-
- i2c_dev->clk = of_clk_get(np, 0);
- if (IS_ERR(i2c_dev->clk)) {
- dev_err(&pdev->dev, "unable to request clock\n");
- return PTR_ERR(i2c_dev->clk);
- }
-
- err = of_property_read_u32(np, "clock-frequency", &clk_rate);
- if (!err && (clk_rate == I2C_MAX_FAST_MODE_FREQ))
- i2c_dev->tcr = TCR_FAST_MODE;
-
- i2c_dev->dev = &pdev->dev;
-
- err = devm_request_irq(&pdev->dev, i2c_dev->irq, wmt_i2c_isr, 0,
- "i2c", i2c_dev);
- if (err) {
- dev_err(&pdev->dev, "failed to request irq %i\n", i2c_dev->irq);
- return err;
- }
-
- adap = &i2c_dev->adapter;
- i2c_set_adapdata(adap, i2c_dev);
- strscpy(adap->name, "WMT I2C adapter", sizeof(adap->name));
- adap->owner = THIS_MODULE;
- adap->algo = &wmt_i2c_algo;
- adap->dev.parent = &pdev->dev;
- adap->dev.of_node = pdev->dev.of_node;
-
- init_completion(&i2c_dev->complete);
-
- err = wmt_i2c_reset_hardware(i2c_dev);
- if (err) {
- dev_err(&pdev->dev, "error initializing hardware\n");
- return err;
- }
-
- err = i2c_add_adapter(adap);
- if (err)
- goto err_disable_clk;
-
- platform_set_drvdata(pdev, i2c_dev);
-
- return 0;
-
-err_disable_clk:
- clk_disable_unprepare(i2c_dev->clk);
- return err;
-}
-
-static void wmt_i2c_remove(struct platform_device *pdev)
-{
- struct wmt_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
-
- /* Disable interrupts, clock and delete adapter */
- writew(0, i2c_dev->base + REG_IMR);
- clk_disable_unprepare(i2c_dev->clk);
- i2c_del_adapter(&i2c_dev->adapter);
-}
-
-static const struct of_device_id wmt_i2c_dt_ids[] = {
- { .compatible = "wm,wm8505-i2c" },
- { /* Sentinel */ },
-};
-
-static struct platform_driver wmt_i2c_driver = {
- .probe = wmt_i2c_probe,
- .remove_new = wmt_i2c_remove,
- .driver = {
- .name = "wmt-i2c",
- .of_match_table = wmt_i2c_dt_ids,
- },
-};
-
-module_platform_driver(wmt_i2c_driver);
-
-MODULE_DESCRIPTION("Wondermedia I2C master-mode bus adapter");
-MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(of, wmt_i2c_dt_ids);
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index 71391b590ada..19468565120e 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -1105,8 +1105,11 @@ static int xiic_start_xfer(struct xiic_i2c *i2c, struct i2c_msg *msgs, int num)
mutex_lock(&i2c->lock);
ret = xiic_busy(i2c);
- if (ret)
+ if (ret) {
+ dev_err(i2c->adap.dev.parent,
+ "cannot start a transfer while busy\n");
goto out;
+ }
i2c->tx_msg = msgs;
i2c->rx_msg = NULL;
@@ -1164,10 +1167,8 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
return err;
err = xiic_start_xfer(i2c, msgs, num);
- if (err < 0) {
- dev_err(adap->dev.parent, "Error xiic_start_xfer\n");
+ if (err < 0)
goto out;
- }
err = wait_for_completion_timeout(&i2c->completion, XIIC_XFER_TIMEOUT);
mutex_lock(&i2c->lock);
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index d6037a328669..14ae0cfc325e 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -445,6 +445,11 @@ static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
return i2c_find_device_by_fwnode(acpi_fwnode_handle(adev));
}
+static struct i2c_adapter *i2c_acpi_find_adapter_by_adev(struct acpi_device *adev)
+{
+ return i2c_find_adapter_by_fwnode(acpi_fwnode_handle(adev));
+}
+
static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
void *arg)
{
@@ -471,11 +476,17 @@ static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
break;
client = i2c_acpi_find_client_by_adev(adev);
- if (!client)
- break;
+ if (client) {
+ i2c_unregister_device(client);
+ put_device(&client->dev);
+ }
+
+ adapter = i2c_acpi_find_adapter_by_adev(adev);
+ if (adapter) {
+ acpi_unbind_one(&adapter->dev);
+ put_device(&adapter->dev);
+ }
- i2c_unregister_device(client);
- put_device(&client->dev);
break;
}
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index db0d1ac82910..f76b7f4fafc1 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1066,7 +1066,8 @@ EXPORT_SYMBOL(i2c_find_device_by_fwnode);
static const struct i2c_device_id dummy_id[] = {
- { "dummy", 0 },
+ { "dummy", },
+ { "smbus_host_notify", },
{ },
};
@@ -1468,6 +1469,8 @@ int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr)
if (!adap)
return -EINVAL;
+ dev_dbg(&adap->dev, "Detected HostNotify from address 0x%02x", addr);
+
irq = irq_find_mapping(adap->host_notify_domain, addr);
if (irq <= 0)
return -ENXIO;
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 8b7e599f1674..f4fb212b7f39 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -139,6 +139,10 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,
struct i2c_client *client = file->private_data;
+ /* Adapter must support I2C transfers */
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -EOPNOTSUPP;
+
if (count > 8192)
count = 8192;
@@ -163,6 +167,10 @@ static ssize_t i2cdev_write(struct file *file, const char __user *buf,
char *tmp;
struct i2c_client *client = file->private_data;
+ /* Adapter must support I2C transfers */
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -EOPNOTSUPP;
+
if (count > 8192)
count = 8192;
@@ -238,6 +246,10 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
u8 __user **data_ptrs;
int i, res;
+ /* Adapter must support I2C transfers */
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -EOPNOTSUPP;
+
data_ptrs = kmalloc_array(nmsgs, sizeof(u8 __user *), GFP_KERNEL);
if (data_ptrs == NULL) {
kfree(msgs);
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 57ff09f18c37..fda72e8be885 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -127,19 +127,6 @@ static u32 i2c_mux_functionality(struct i2c_adapter *adap)
return parent->algo->functionality(parent);
}
-/* Return all parent classes, merged */
-static unsigned int i2c_mux_parent_classes(struct i2c_adapter *parent)
-{
- unsigned int class = 0;
-
- do {
- class |= parent->class;
- parent = i2c_parent_is_i2c_adapter(parent);
- } while (parent);
-
- return class;
-}
-
static void i2c_mux_lock_bus(struct i2c_adapter *adapter, unsigned int flags)
{
struct i2c_mux_priv *priv = adapter->algo_data;
@@ -281,8 +268,7 @@ static const struct i2c_lock_operations i2c_parent_lock_ops = {
};
int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
- u32 force_nr, u32 chan_id,
- unsigned int class)
+ u32 force_nr, u32 chan_id)
{
struct i2c_adapter *parent = muxc->parent;
struct i2c_mux_priv *priv;
@@ -340,14 +326,6 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
else
priv->adap.lock_ops = &i2c_parent_lock_ops;
- /* Sanity check on class */
- if (i2c_mux_parent_classes(parent) & class & ~I2C_CLASS_DEPRECATED)
- dev_err(&parent->dev,
- "Segment %d behind mux can't share classes with ancestors\n",
- chan_id);
- else
- priv->adap.class = class;
-
/*
* Try to populate the mux adapter's of_node, expands to
* nothing if !CONFIG_OF.
diff --git a/drivers/i2c/i2c-slave-testunit.c b/drivers/i2c/i2c-slave-testunit.c
index a49642bbae4b..4e03b75f9ad7 100644
--- a/drivers/i2c/i2c-slave-testunit.c
+++ b/drivers/i2c/i2c-slave-testunit.c
@@ -118,9 +118,19 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client,
queue_delayed_work(system_long_wq, &tu->worker,
msecs_to_jiffies(10 * tu->regs[TU_REG_DELAY]));
}
- fallthrough;
+
+ /*
+ * Reset reg_idx to avoid that work gets queued again in case of
+ * STOP after a following read message. But do not clear TU regs
+ * here because we still need them in the workqueue!
+ */
+ tu->reg_idx = 0;
+ break;
case I2C_SLAVE_WRITE_REQUESTED:
+ if (test_bit(TU_FLAG_IN_PROCESS, &tu->flags))
+ return -EBUSY;
+
memset(tu->regs, 0, TU_NUM_REGS);
tu->reg_idx = 0;
break;
@@ -162,7 +172,7 @@ static void i2c_slave_testunit_remove(struct i2c_client *client)
}
static const struct i2c_device_id i2c_slave_testunit_id[] = {
- { "slave-testunit", 0 },
+ { "slave-testunit" },
{ }
};
MODULE_DEVICE_TABLE(i2c, i2c_slave_testunit_id);
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
index 97f338b123b1..7e4203df83ed 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
@@ -160,7 +160,7 @@ static void smbalert_remove(struct i2c_client *ara)
}
static const struct i2c_device_id smbalert_ids[] = {
- { "smbus_alert", 0 },
+ { "smbus_alert" },
{ /* LIST END */ }
};
MODULE_DEVICE_TABLE(i2c, smbalert_ids);
@@ -308,7 +308,7 @@ EXPORT_SYMBOL_GPL(i2c_free_slave_host_notify_device);
* target systems are the same.
* Restrictions to automatic SPD instantiation:
* - Only works if all filled slots have the same memory type
- * - Only works for DDR, DDR2, DDR3 and DDR4 for now
+ * - Only works for (LP)DDR memory types up to DDR5
* - Only works on systems with 1 to 8 memory slots
*/
#if IS_ENABLED(CONFIG_DMI)
@@ -352,18 +352,11 @@ void i2c_register_spd(struct i2c_adapter *adap)
return;
/*
- * If we're a child adapter on a muxed segment, then limit slots to 8,
- * as this is the max number of SPD EEPROMs that can be addressed per bus.
+ * The max number of SPD EEPROMs that can be addressed per bus is 8.
+ * If more slots are present either muxed or multiple busses are
+ * necessary or the additional slots are ignored.
*/
- if (i2c_parent_is_i2c_adapter(adap)) {
- slot_count = 8;
- } else {
- if (slot_count > 8) {
- dev_warn(&adap->dev,
- "More than 8 memory slots on a single bus, contact i801 maintainer to add missing mux config\n");
- return;
- }
- }
+ slot_count = min(slot_count, 8);
/*
* Memory types could be found at section 7.18.2 (Memory Device — Type), table 78
@@ -382,6 +375,10 @@ void i2c_register_spd(struct i2c_adapter *adap)
case 0x1E: /* LPDDR4 */
name = "ee1004";
break;
+ case 0x22: /* DDR5 */
+ case 0x23: /* LPDDR5 */
+ name = "spd5118";
+ break;
default:
dev_info(&adap->dev,
"Memory type 0x%02x not supported yet, not instantiating SPD\n",
diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
index 24168e9f7df4..7aa6e795d833 100644
--- a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
+++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
@@ -167,7 +167,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
}
/* Actually add the mux adapter */
- ret = i2c_mux_add_adapter(muxc, 0, 0, 0);
+ ret = i2c_mux_add_adapter(muxc, 0, 0);
if (ret)
i2c_put_adapter(muxc->parent);
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index 6b979a0a6ab8..944577bb09c1 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -5,16 +5,17 @@
* Peter Korsgaard <peter.korsgaard@barco.com>
*/
+#include <linux/bits.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
+#include <linux/module.h>
#include <linux/overflow.h>
#include <linux/platform_data/i2c-mux-gpio.h>
#include <linux/platform_device.h>
-#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/bits.h>
-#include <linux/gpio/consumer.h>
-#include <linux/gpio/driver.h>
struct gpiomux {
struct i2c_mux_gpio_platform_data data;
@@ -37,6 +38,9 @@ static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan)
i2c_mux_gpio_set(mux, chan);
+ if (mux->data.settle_time)
+ fsleep(mux->data.settle_time);
+
return 0;
}
@@ -116,6 +120,8 @@ static int i2c_mux_gpio_probe_fw(struct gpiomux *mux,
if (device_property_read_u32(dev, "idle-state", &mux->data.idle))
mux->data.idle = I2C_MUX_GPIO_NO_IDLE;
+ device_property_read_u32(dev, "settle-time-us", &mux->data.settle_time);
+
return 0;
}
@@ -206,9 +212,8 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
for (i = 0; i < mux->data.n_values; i++) {
u32 nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0;
- unsigned int class = mux->data.classes ? mux->data.classes[i] : 0;
- ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], class);
+ ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i]);
if (ret)
goto add_adapter_failed;
}
diff --git a/drivers/i2c/muxes/i2c-mux-gpmux.c b/drivers/i2c/muxes/i2c-mux-gpmux.c
index 8305661e1253..10d63307b14d 100644
--- a/drivers/i2c/muxes/i2c-mux-gpmux.c
+++ b/drivers/i2c/muxes/i2c-mux-gpmux.c
@@ -124,7 +124,7 @@ static int i2c_mux_probe(struct platform_device *pdev)
goto err_children;
}
- ret = i2c_mux_add_adapter(muxc, 0, chan, 0);
+ ret = i2c_mux_add_adapter(muxc, 0, chan);
if (ret)
goto err_children;
}
diff --git a/drivers/i2c/muxes/i2c-mux-ltc4306.c b/drivers/i2c/muxes/i2c-mux-ltc4306.c
index 23766d853e76..19a7c370946d 100644
--- a/drivers/i2c/muxes/i2c-mux-ltc4306.c
+++ b/drivers/i2c/muxes/i2c-mux-ltc4306.c
@@ -279,7 +279,7 @@ static int ltc4306_probe(struct i2c_client *client)
/* Now create an adapter for each channel */
for (num = 0; num < chip->nchans; num++) {
- ret = i2c_mux_add_adapter(muxc, 0, num, 0);
+ ret = i2c_mux_add_adapter(muxc, 0, num);
if (ret) {
i2c_mux_del_adapters(muxc);
return ret;
diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c
index 4c6ed1d58c79..3f06aa3331a7 100644
--- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c
+++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c
@@ -154,7 +154,7 @@ static int mlxcpld_mux_probe(struct platform_device *pdev)
/* Create an adapter for each channel. */
for (num = 0; num < pdata->num_adaps; num++) {
- err = i2c_mux_add_adapter(muxc, 0, pdata->chan_ids[num], 0);
+ err = i2c_mux_add_adapter(muxc, 0, pdata->chan_ids[num]);
if (err)
goto virt_reg_failed;
}
diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c
index ce0fb69249a8..8663c8a7c269 100644
--- a/drivers/i2c/muxes/i2c-mux-pca9541.c
+++ b/drivers/i2c/muxes/i2c-mux-pca9541.c
@@ -78,7 +78,7 @@ struct pca9541 {
};
static const struct i2c_device_id pca9541_id[] = {
- {"pca9541", 0},
+ { "pca9541" },
{}
};
@@ -314,7 +314,7 @@ static int pca9541_probe(struct i2c_client *client)
i2c_set_clientdata(client, muxc);
- ret = i2c_mux_add_adapter(muxc, 0, 0, 0);
+ ret = i2c_mux_add_adapter(muxc, 0, 0);
if (ret)
return ret;
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index c3f4ff08ac38..6f84018258c4 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -644,7 +644,7 @@ static int pca954x_probe(struct i2c_client *client)
/* Now create an adapter for each channel */
for (num = 0; num < data->chip->nchans; num++) {
- ret = i2c_mux_add_adapter(muxc, 0, num, 0);
+ ret = i2c_mux_add_adapter(muxc, 0, num);
if (ret)
goto fail_cleanup;
}
diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
index 6ebca7bfd8a2..02aaf0781e9c 100644
--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
@@ -151,7 +151,7 @@ static int i2c_mux_pinctrl_probe(struct platform_device *pdev)
/* Do not add any adapter for the idle state (if it's there at all). */
for (i = 0; i < num_names - !!muxc->deselect; i++) {
- ret = i2c_mux_add_adapter(muxc, 0, i, 0);
+ ret = i2c_mux_add_adapter(muxc, 0, i);
if (ret)
goto err_del_adapter;
}
diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-reg.c
index 8489971babd3..ef765fcd33f5 100644
--- a/drivers/i2c/muxes/i2c-mux-reg.c
+++ b/drivers/i2c/muxes/i2c-mux-reg.c
@@ -213,7 +213,7 @@ static int i2c_mux_reg_probe(struct platform_device *pdev)
for (i = 0; i < mux->data.n_values; i++) {
nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0;
- ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], 0);
+ ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i]);
if (ret)
goto err_del_mux_adapters;
}