diff options
Diffstat (limited to 'drivers/i2c')
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; } |