diff options
Diffstat (limited to 'drivers/i2c')
106 files changed, 2022 insertions, 952 deletions
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 44710267d669..c232054fddd6 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -40,14 +40,6 @@ config I2C_BOARDINFO bool default y -config I2C_COMPAT - bool "Enable compatibility bits for old user-space" - default y - help - Say Y here if you intend to run lm-sensors 3.1.1 or older, or any - other user-space package which expects i2c adapters to be class - devices. If you don't know, say Y. - config I2C_CHARDEV tristate "I2C device interface" help diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index fe6e8a1bb607..6b3ba7e5723a 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -159,6 +159,7 @@ 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. @@ -195,6 +196,7 @@ config I2C_ISMT config I2C_PIIX4 tristate "Intel PIIX4 and compatible (ATI/AMD/Serverworks/Broadcom/SMSC)" 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 @@ -557,28 +559,33 @@ config I2C_DAVINCI For details please see http://www.ti.com/davinci config I2C_DESIGNWARE_CORE - tristate + tristate "Synopsys DesignWare I2C adapter" select REGMAP + help + This option enables support for the Synopsys DesignWare I2C adapter. + This driver includes support for the I2C host on the Synopsys + Designware I2C adapter. + + To compile the driver as a module, choose M here: the module will be + called i2c-designware-core. + +if I2C_DESIGNWARE_CORE config I2C_DESIGNWARE_SLAVE bool "Synopsys DesignWare Slave" - depends on I2C_DESIGNWARE_CORE select I2C_SLAVE help If you say yes to this option, support will be included for the Synopsys DesignWare I2C slave adapter. - This is not a standalone module, this module compiles together with - i2c-designware-core. - config I2C_DESIGNWARE_PLATFORM - tristate "Synopsys DesignWare Platform" + tristate "Synopsys DesignWare Platform driver" depends on (ACPI && COMMON_CLK) || !ACPI - select I2C_DESIGNWARE_CORE select MFD_SYSCON if MIPS_BAIKAL_T1 + default I2C_DESIGNWARE_CORE help If you say yes to this option, support will be included for the - Synopsys DesignWare I2C adapter. + Synopsys DesignWare I2C adapters on the platform bus. This driver can also be built as a module. If so, the module will be called i2c-designware-platform. @@ -611,17 +618,19 @@ config I2C_DESIGNWARE_BAYTRAIL a BayTrail system using the AXP288. config I2C_DESIGNWARE_PCI - tristate "Synopsys DesignWare PCI" + tristate "Synopsys DesignWare PCI driver" depends on PCI - select I2C_DESIGNWARE_CORE select I2C_CCGX_UCSI help If you say yes to this option, support will be included for the - Synopsys DesignWare I2C adapter. Only master mode is supported. + Synopsys DesignWare I2C adapters on the PCI bus. Only master mode is + supported. This driver can also be built as a module. If so, the module will be called i2c-designware-pci. +endif + config I2C_DIGICOLOR tristate "Conexant Digicolor I2C driver" depends on ARCH_DIGICOLOR || COMPILE_TEST @@ -770,6 +779,18 @@ config I2C_JZ4780 If you don't know what to do here, say N. +config I2C_KEBA + tristate "KEBA I2C controller support" + depends on HAS_IOMEM + depends on KEBA_CP500 || COMPILE_TEST + select AUXILIARY_BUS + help + This driver supports the I2C controller found in KEBA system FPGA + devices. + + This driver can also be built as a module. If so, the module + will be called i2c-keba. + config I2C_KEMPLD tristate "Kontron COM I2C Controller" depends on MFD_KEMPLD @@ -857,7 +878,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. diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 78d0561339e5..ecc07c50f2a0 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_I2C_IMX) += i2c-imx.o obj-$(CONFIG_I2C_IMX_LPI2C) += i2c-imx-lpi2c.o obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o +obj-$(CONFIG_I2C_KEBA) += i2c-keba.o obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o obj-$(CONFIG_I2C_LPC2K) += i2c-lpc2k.o obj-$(CONFIG_I2C_LS2X) += i2c-ls2x.o diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 9d7b4efe26ad..544c94e86b89 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -479,9 +479,8 @@ static struct i2c_adapter ali1535_adapter = { static const struct pci_device_id ali1535_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) }, - { }, + { } }; - MODULE_DEVICE_TABLE(pci, ali1535_ids); static int ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 63897a89bb35..ee4fd66dedb0 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -438,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 956e5020d71e..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. */ 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 d3ac1c77a509..6f0ef587e76d 100644 --- a/drivers/i2c/busses/i2c-amd-mp2-plat.c +++ b/drivers/i2c/busses/i2c-amd-mp2-plat.c @@ -340,7 +340,7 @@ static void i2c_amd_remove(struct platform_device *pdev) static const struct acpi_device_id i2c_amd_acpi_match[] = { { "AMDI0011" }, - { }, + { } }; MODULE_DEVICE_TABLE(acpi, i2c_amd_acpi_match); diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index ce8c4846b7fa..cc5a26637fd5 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -170,6 +170,13 @@ struct aspeed_i2c_bus { static int aspeed_i2c_reset(struct aspeed_i2c_bus *bus); +/* precondition: bus.lock has been acquired. */ +static void aspeed_i2c_do_stop(struct aspeed_i2c_bus *bus) +{ + bus->master_state = ASPEED_I2C_MASTER_STOP; + writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG); +} + static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus) { unsigned long time_left, flags; @@ -187,7 +194,7 @@ static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus) command); reinit_completion(&bus->cmd_complete); - writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG); + aspeed_i2c_do_stop(bus); spin_unlock_irqrestore(&bus->lock, flags); time_left = wait_for_completion_timeout( @@ -391,13 +398,6 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) } /* precondition: bus.lock has been acquired. */ -static void aspeed_i2c_do_stop(struct aspeed_i2c_bus *bus) -{ - bus->master_state = ASPEED_I2C_MASTER_STOP; - writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG); -} - -/* precondition: bus.lock has been acquired. */ static void aspeed_i2c_next_msg_or_stop(struct aspeed_i2c_bus *bus) { if (bus->msgs_index + 1 < bus->msgs_count) { @@ -991,7 +991,7 @@ static const struct of_device_id aspeed_i2c_bus_of_table[] = { .compatible = "aspeed,ast2600-i2c-bus", .data = aspeed_i2c_25xx_get_clk_reg_val, }, - { }, + { } }; MODULE_DEVICE_TABLE(of, aspeed_i2c_bus_of_table); 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-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 3045ba82380d..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 @@ -390,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-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 7ae611120cfa..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)) @@ -687,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: @@ -744,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-common.c b/drivers/i2c/busses/i2c-designware-common.c index e8a688d04aee..9d88b4fa03e4 100644 --- a/drivers/i2c/busses/i2c-designware-common.c +++ b/drivers/i2c/busses/i2c-designware-common.c @@ -20,12 +20,17 @@ #include <linux/io.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/of.h> +#include <linux/pm.h> #include <linux/pm_runtime.h> +#include <linux/property.h> #include <linux/regmap.h> #include <linux/swab.h> #include <linux/types.h> #include <linux/units.h> +#define DEFAULT_SYMBOL_NAMESPACE I2C_DW_COMMON + #include "i2c-designware-core.h" static char *abort_sources[] = { @@ -188,7 +193,7 @@ static const u32 supported_speeds[] = { I2C_MAX_STANDARD_MODE_FREQ, }; -int i2c_dw_validate_speed(struct dw_i2c_dev *dev) +static int i2c_dw_validate_speed(struct dw_i2c_dev *dev) { struct i2c_timings *t = &dev->timings; unsigned int i; @@ -208,7 +213,44 @@ int i2c_dw_validate_speed(struct dw_i2c_dev *dev) return -EINVAL; } -EXPORT_SYMBOL_GPL(i2c_dw_validate_speed); + +#ifdef CONFIG_OF + +#include <linux/platform_device.h> + +#define MSCC_ICPU_CFG_TWI_DELAY 0x0 +#define MSCC_ICPU_CFG_TWI_DELAY_ENABLE BIT(0) +#define MSCC_ICPU_CFG_TWI_SPIKE_FILTER 0x4 + +static int mscc_twi_set_sda_hold_time(struct dw_i2c_dev *dev) +{ + writel((dev->sda_hold_time << 1) | MSCC_ICPU_CFG_TWI_DELAY_ENABLE, + dev->ext + MSCC_ICPU_CFG_TWI_DELAY); + + return 0; +} + +static void i2c_dw_of_configure(struct device *device) +{ + struct platform_device *pdev = to_platform_device(device); + struct dw_i2c_dev *dev = dev_get_drvdata(device); + + switch (dev->flags & MODEL_MASK) { + case MODEL_MSCC_OCELOT: + dev->ext = devm_platform_ioremap_resource(pdev, 1); + if (!IS_ERR(dev->ext)) + dev->set_sda_hold_time = mscc_twi_set_sda_hold_time; + break; + default: + break; + } +} + +#else /* CONFIG_OF */ + +static inline void i2c_dw_of_configure(struct device *device) { } + +#endif /* CONFIG_OF */ #ifdef CONFIG_ACPI @@ -255,7 +297,7 @@ static void i2c_dw_acpi_params(struct device *device, char method[], kfree(buf.pointer); } -int i2c_dw_acpi_configure(struct device *device) +static void i2c_dw_acpi_configure(struct device *device) { struct dw_i2c_dev *dev = dev_get_drvdata(device); struct i2c_timings *t = &dev->timings; @@ -285,10 +327,7 @@ int i2c_dw_acpi_configure(struct device *device) dev->sda_hold_time = fs_ht; break; } - - return 0; } -EXPORT_SYMBOL_GPL(i2c_dw_acpi_configure); static u32 i2c_dw_acpi_round_bus_speed(struct device *device) { @@ -310,11 +349,13 @@ static u32 i2c_dw_acpi_round_bus_speed(struct device *device) #else /* CONFIG_ACPI */ +static inline void i2c_dw_acpi_configure(struct device *device) { } + static inline u32 i2c_dw_acpi_round_bus_speed(struct device *device) { return 0; } #endif /* CONFIG_ACPI */ -void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev) +static void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev) { u32 acpi_speed = i2c_dw_acpi_round_bus_speed(dev->dev); struct i2c_timings *t = &dev->timings; @@ -330,10 +371,47 @@ void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev) else t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ; } -EXPORT_SYMBOL_GPL(i2c_dw_adjust_bus_speed); -u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) +int i2c_dw_fw_parse_and_configure(struct dw_i2c_dev *dev) +{ + struct i2c_timings *t = &dev->timings; + struct device *device = dev->dev; + struct fwnode_handle *fwnode = dev_fwnode(device); + + i2c_parse_fw_timings(device, t, false); + + i2c_dw_adjust_bus_speed(dev); + + if (is_of_node(fwnode)) + i2c_dw_of_configure(device); + else if (is_acpi_node(fwnode)) + i2c_dw_acpi_configure(device); + + return i2c_dw_validate_speed(dev); +} +EXPORT_SYMBOL_GPL(i2c_dw_fw_parse_and_configure); + +static u32 i2c_dw_read_scl_reg(struct dw_i2c_dev *dev, u32 reg) { + u32 val; + int ret; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return 0; + + ret = regmap_read(dev->map, reg, &val); + i2c_dw_release_lock(dev); + + return ret ? 0 : val; +} + +u32 i2c_dw_scl_hcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, + u32 tSYMBOL, u32 tf, int cond, int offset) +{ + if (!ic_clk) + return i2c_dw_read_scl_reg(dev, reg); + /* * DesignWare I2C core doesn't seem to have solid strategy to meet * the tHD;STA timing spec. Configuring _HCNT based on tHIGH spec @@ -372,8 +450,12 @@ u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) 3 + offset; } -u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) +u32 i2c_dw_scl_lcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, + u32 tLOW, u32 tf, int offset) { + if (!ic_clk) + return i2c_dw_read_scl_reg(dev, reg); + /* * Conditional expression: * @@ -441,7 +523,8 @@ err_release_lock: void __i2c_dw_disable(struct dw_i2c_dev *dev) { - unsigned int raw_intr_stats; + struct i2c_timings *t = &dev->timings; + unsigned int raw_intr_stats, ic_stats; unsigned int enable; int timeout = 100; bool abort_needed; @@ -449,10 +532,25 @@ void __i2c_dw_disable(struct dw_i2c_dev *dev) int ret; regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_intr_stats); + regmap_read(dev->map, DW_IC_STATUS, &ic_stats); regmap_read(dev->map, DW_IC_ENABLE, &enable); - abort_needed = raw_intr_stats & DW_IC_INTR_MST_ON_HOLD; + abort_needed = (raw_intr_stats & DW_IC_INTR_MST_ON_HOLD) || + (ic_stats & DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY); if (abort_needed) { + if (!(enable & DW_IC_ENABLE_ENABLE)) { + regmap_write(dev->map, DW_IC_ENABLE, DW_IC_ENABLE_ENABLE); + /* + * Wait 10 times the signaling period of the highest I2C + * transfer supported by the driver (for 400KHz this is + * 25us) to ensure the I2C ENABLE bit is already set + * as described in the DesignWare I2C databook. + */ + fsleep(DIV_ROUND_CLOSEST_ULL(10 * MICRO, t->bus_freq_hz)); + /* Set ENABLE bit before setting ABORT */ + enable |= DW_IC_ENABLE_ENABLE; + } + regmap_write(dev->map, DW_IC_ENABLE, enable | DW_IC_ENABLE_ABORT); ret = regmap_read_poll_timeout(dev->map, DW_IC_ENABLE, enable, !(enable & DW_IC_ENABLE_ABORT), 10, @@ -653,6 +751,84 @@ void i2c_dw_disable(struct dw_i2c_dev *dev) i2c_dw_release_lock(dev); } +EXPORT_SYMBOL_GPL(i2c_dw_disable); + +int i2c_dw_probe(struct dw_i2c_dev *dev) +{ + device_set_node(&dev->adapter.dev, dev_fwnode(dev->dev)); + + switch (dev->mode) { + case DW_IC_SLAVE: + return i2c_dw_probe_slave(dev); + case DW_IC_MASTER: + return i2c_dw_probe_master(dev); + default: + dev_err(dev->dev, "Wrong operation mode: %d\n", dev->mode); + return -EINVAL; + } +} +EXPORT_SYMBOL_GPL(i2c_dw_probe); + +static int i2c_dw_prepare(struct device *device) +{ + /* + * If the ACPI companion device object is present for this device, + * it may be accessed during suspend and resume of other devices via + * I2C operation regions, so tell the PM core and middle layers to + * avoid skipping system suspend/resume callbacks for it in that case. + */ + return !has_acpi_companion(device); +} + +static int i2c_dw_runtime_suspend(struct device *device) +{ + struct dw_i2c_dev *dev = dev_get_drvdata(device); + + if (dev->shared_with_punit) + return 0; + + i2c_dw_disable(dev); + i2c_dw_prepare_clk(dev, false); + + return 0; +} + +static int i2c_dw_suspend(struct device *device) +{ + struct dw_i2c_dev *dev = dev_get_drvdata(device); + + i2c_mark_adapter_suspended(&dev->adapter); + + return i2c_dw_runtime_suspend(device); +} + +static int i2c_dw_runtime_resume(struct device *device) +{ + struct dw_i2c_dev *dev = dev_get_drvdata(device); + + if (!dev->shared_with_punit) + i2c_dw_prepare_clk(dev, true); + + dev->init(dev); + + return 0; +} + +static int i2c_dw_resume(struct device *device) +{ + struct dw_i2c_dev *dev = dev_get_drvdata(device); + + i2c_dw_runtime_resume(device); + i2c_mark_adapter_resumed(&dev->adapter); + + return 0; +} + +EXPORT_GPL_DEV_PM_OPS(i2c_dw_dev_pm_ops) = { + .prepare = pm_sleep_ptr(i2c_dw_prepare), + LATE_SYSTEM_SLEEP_PM_OPS(i2c_dw_suspend, i2c_dw_resume) + RUNTIME_PM_OPS(i2c_dw_runtime_suspend, i2c_dw_runtime_resume, NULL) +}; MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core"); MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index e9606c00b8d1..2d32896d0673 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -10,11 +10,10 @@ */ #include <linux/bits.h> -#include <linux/compiler_types.h> #include <linux/completion.h> -#include <linux/dev_printk.h> #include <linux/errno.h> #include <linux/i2c.h> +#include <linux/pm.h> #include <linux/regmap.h> #include <linux/types.h> @@ -109,6 +108,7 @@ DW_IC_INTR_RX_UNDER | \ DW_IC_INTR_RD_REQ) +#define DW_IC_ENABLE_ENABLE BIT(0) #define DW_IC_ENABLE_ABORT BIT(1) #define DW_IC_STATUS_ACTIVITY BIT(0) @@ -116,6 +116,7 @@ #define DW_IC_STATUS_RFNE BIT(3) #define DW_IC_STATUS_MASTER_ACTIVITY BIT(5) #define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6) +#define DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY BIT(7) #define DW_IC_SDA_HOLD_RX_SHIFT 16 #define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, 16) @@ -237,7 +238,6 @@ struct reset_control; * @semaphore_idx: Index of table with semaphore type attached to the bus. It's * -1 if there is no semaphore. * @shared_with_punit: true if this bus is shared with the SoCs PUNIT - * @disable: function to disable the controller * @init: function to initialize the I2C hardware * @set_sda_hold_time: callback to retrieve IP specific SDA hold timing * @mode: operation mode - DW_IC_MASTER or DW_IC_SLAVE @@ -295,7 +295,6 @@ struct dw_i2c_dev { void (*release_lock)(void); int semaphore_idx; bool shared_with_punit; - void (*disable)(struct dw_i2c_dev *dev); int (*init)(struct dw_i2c_dev *dev); int (*set_sda_hold_time)(struct dw_i2c_dev *dev); int mode; @@ -329,8 +328,10 @@ struct i2c_dw_semaphore_callbacks { }; int i2c_dw_init_regmap(struct dw_i2c_dev *dev); -u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset); -u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset); +u32 i2c_dw_scl_hcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, + u32 tSYMBOL, u32 tf, int cond, int offset); +u32 i2c_dw_scl_lcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, + u32 tLOW, u32 tf, int offset); int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev); u32 i2c_dw_clk_rate(struct dw_i2c_dev *dev); int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare); @@ -340,7 +341,8 @@ int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev); int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev); int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev); u32 i2c_dw_func(struct i2c_adapter *adap); -void i2c_dw_disable(struct dw_i2c_dev *dev); + +extern const struct dev_pm_ops i2c_dw_dev_pm_ops; static inline void __i2c_dw_enable(struct dw_i2c_dev *dev) { @@ -373,6 +375,7 @@ static inline void __i2c_dw_read_intr_mask(struct dw_i2c_dev *dev, } void __i2c_dw_disable(struct dw_i2c_dev *dev); +void i2c_dw_disable(struct dw_i2c_dev *dev); extern void i2c_dw_configure_master(struct dw_i2c_dev *dev); extern int i2c_dw_probe_master(struct dw_i2c_dev *dev); @@ -385,19 +388,6 @@ static inline void i2c_dw_configure_slave(struct dw_i2c_dev *dev) { } static inline int i2c_dw_probe_slave(struct dw_i2c_dev *dev) { return -EINVAL; } #endif -static inline int i2c_dw_probe(struct dw_i2c_dev *dev) -{ - switch (dev->mode) { - case DW_IC_SLAVE: - return i2c_dw_probe_slave(dev); - case DW_IC_MASTER: - return i2c_dw_probe_master(dev); - default: - dev_err(dev->dev, "Wrong operation mode: %d\n", dev->mode); - return -EINVAL; - } -} - static inline void i2c_dw_configure(struct dw_i2c_dev *dev) { if (i2c_detect_slave_mode(dev->dev)) @@ -406,6 +396,8 @@ static inline void i2c_dw_configure(struct dw_i2c_dev *dev) i2c_dw_configure_master(dev); } +int i2c_dw_probe(struct dw_i2c_dev *dev); + #if IS_ENABLED(CONFIG_I2C_DESIGNWARE_BAYTRAIL) int i2c_dw_baytrail_probe_lock_support(struct dw_i2c_dev *dev); #endif @@ -414,11 +406,4 @@ int i2c_dw_baytrail_probe_lock_support(struct dw_i2c_dev *dev); int i2c_dw_amdpsp_probe_lock_support(struct dw_i2c_dev *dev); #endif -int i2c_dw_validate_speed(struct dw_i2c_dev *dev); -void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev); - -#if IS_ENABLED(CONFIG_ACPI) -int i2c_dw_acpi_configure(struct device *device); -#else -static inline int i2c_dw_acpi_configure(struct device *device) { return -ENODEV; } -#endif +int i2c_dw_fw_parse_and_configure(struct dw_i2c_dev *dev); diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index c7e56002809a..e8ac9a7bf0b3 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -22,6 +22,8 @@ #include <linux/regmap.h> #include <linux/reset.h> +#define DEFAULT_SYMBOL_NAMESPACE I2C_DW + #include "i2c-designware-core.h" #define AMD_TIMEOUT_MIN_US 25 @@ -64,13 +66,17 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev) if (!dev->ss_hcnt || !dev->ss_lcnt) { ic_clk = i2c_dw_clk_rate(dev); dev->ss_hcnt = - i2c_dw_scl_hcnt(ic_clk, + i2c_dw_scl_hcnt(dev, + DW_IC_SS_SCL_HCNT, + ic_clk, 4000, /* tHD;STA = tHIGH = 4.0 us */ sda_falling_time, 0, /* 0: DW default, 1: Ideal */ 0); /* No offset */ dev->ss_lcnt = - i2c_dw_scl_lcnt(ic_clk, + i2c_dw_scl_lcnt(dev, + DW_IC_SS_SCL_LCNT, + ic_clk, 4700, /* tLOW = 4.7 us */ scl_falling_time, 0); /* No offset */ @@ -94,13 +100,17 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev) } else { ic_clk = i2c_dw_clk_rate(dev); dev->fs_hcnt = - i2c_dw_scl_hcnt(ic_clk, + i2c_dw_scl_hcnt(dev, + DW_IC_FS_SCL_HCNT, + ic_clk, 260, /* tHIGH = 260 ns */ sda_falling_time, 0, /* DW default */ 0); /* No offset */ dev->fs_lcnt = - i2c_dw_scl_lcnt(ic_clk, + i2c_dw_scl_lcnt(dev, + DW_IC_FS_SCL_LCNT, + ic_clk, 500, /* tLOW = 500 ns */ scl_falling_time, 0); /* No offset */ @@ -114,13 +124,17 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev) if (!dev->fs_hcnt || !dev->fs_lcnt) { ic_clk = i2c_dw_clk_rate(dev); dev->fs_hcnt = - i2c_dw_scl_hcnt(ic_clk, + i2c_dw_scl_hcnt(dev, + DW_IC_FS_SCL_HCNT, + ic_clk, 600, /* tHD;STA = tHIGH = 0.6 us */ sda_falling_time, 0, /* 0: DW default, 1: Ideal */ 0); /* No offset */ dev->fs_lcnt = - i2c_dw_scl_lcnt(ic_clk, + i2c_dw_scl_lcnt(dev, + DW_IC_FS_SCL_LCNT, + ic_clk, 1300, /* tLOW = 1.3 us */ scl_falling_time, 0); /* No offset */ @@ -142,13 +156,17 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev) } else if (!dev->hs_hcnt || !dev->hs_lcnt) { ic_clk = i2c_dw_clk_rate(dev); dev->hs_hcnt = - i2c_dw_scl_hcnt(ic_clk, + i2c_dw_scl_hcnt(dev, + DW_IC_HS_SCL_HCNT, + ic_clk, 160, /* tHIGH = 160 ns */ sda_falling_time, 0, /* DW default */ 0); /* No offset */ dev->hs_lcnt = - i2c_dw_scl_lcnt(ic_clk, + i2c_dw_scl_lcnt(dev, + DW_IC_HS_SCL_LCNT, + ic_clk, 320, /* tLOW = 320 ns */ scl_falling_time, 0); /* No offset */ @@ -253,6 +271,34 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) __i2c_dw_write_intr_mask(dev, DW_IC_INTR_MASTER_MASK); } +/* + * This function waits for the controller to be idle before disabling I2C + * When the controller is not in the IDLE state, the MST_ACTIVITY bit + * (IC_STATUS[5]) is set. + * + * Values: + * 0x1 (ACTIVE): Controller not idle + * 0x0 (IDLE): Controller is idle + * + * The function is called after completing the current transfer. + * + * Returns: + * False when the controller is in the IDLE state. + * True when the controller is in the ACTIVE state. + */ +static bool i2c_dw_is_controller_active(struct dw_i2c_dev *dev) +{ + u32 status; + + regmap_read(dev->map, DW_IC_STATUS, &status); + if (!(status & DW_IC_STATUS_MASTER_ACTIVITY)) + return false; + + return regmap_read_poll_timeout(dev->map, DW_IC_STATUS, status, + !(status & DW_IC_STATUS_MASTER_ACTIVITY), + 1100, 20000) != 0; +} + static int i2c_dw_check_stopbit(struct dw_i2c_dev *dev) { u32 val; @@ -789,6 +835,16 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) } /* + * This happens rarely (~1:500) and is hard to reproduce. Debug trace + * showed that IC_STATUS had value of 0x23 when STOP_DET occurred, + * if disable IC_ENABLE.ENABLE immediately that can result in + * IC_RAW_INTR_STAT.MASTER_ON_HOLD holding SCL low. Check if + * controller is still ACTIVE before disabling I2C. + */ + if (i2c_dw_is_controller_active(dev)) + dev_err(dev->dev, "controller active\n"); + + /* * We must disable the adapter before returning and signaling the end * of the current transfer. Otherwise the hardware might continue * generating interrupts which in turn causes a race condition with @@ -931,7 +987,6 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) init_completion(&dev->cmd_complete); dev->init = i2c_dw_init_master; - dev->disable = i2c_dw_disable; ret = i2c_dw_init_regmap(dev); if (ret) @@ -1021,3 +1076,4 @@ EXPORT_SYMBOL_GPL(i2c_dw_probe_master); MODULE_DESCRIPTION("Synopsys DesignWare I2C bus master adapter"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(I2C_DW_COMMON); diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index a1b379a1e904..7b2c5d71a7fc 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -9,7 +9,6 @@ * Copyright (C) 2009 Provigent Ltd. * Copyright (C) 2011, 2015, 2016 Intel Corporation. */ -#include <linux/acpi.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/errno.h> @@ -19,6 +18,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/pm.h> #include <linux/pm_runtime.h> #include <linux/power_supply.h> #include <linux/sched.h> @@ -102,7 +102,7 @@ static u32 mfld_get_clk_rate_khz(struct dw_i2c_dev *dev) static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c) { - struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev); + struct dw_i2c_dev *dev = pci_get_drvdata(pdev); switch (pdev->device) { case 0x0817: @@ -152,7 +152,7 @@ static u32 navi_amd_get_clk_rate_khz(struct dw_i2c_dev *dev) static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c) { - struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev); + struct dw_i2c_dev *dev = pci_get_drvdata(pdev); dev->flags |= MODEL_AMD_NAVI_GPU | ACCESS_POLLING; dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ; @@ -194,47 +194,6 @@ static struct dw_pci_controller dw_pci_controllers[] = { }, }; -static int __maybe_unused i2c_dw_pci_runtime_suspend(struct device *dev) -{ - struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - - i_dev->disable(i_dev); - return 0; -} - -static int __maybe_unused i2c_dw_pci_suspend(struct device *dev) -{ - struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - - i2c_mark_adapter_suspended(&i_dev->adapter); - - return i2c_dw_pci_runtime_suspend(dev); -} - -static int __maybe_unused i2c_dw_pci_runtime_resume(struct device *dev) -{ - struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - - return i_dev->init(i_dev); -} - -static int __maybe_unused i2c_dw_pci_resume(struct device *dev) -{ - struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - int ret; - - ret = i2c_dw_pci_runtime_resume(dev); - - i2c_mark_adapter_resumed(&i_dev->adapter); - - return ret; -} - -static const struct dev_pm_ops i2c_dw_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(i2c_dw_pci_suspend, i2c_dw_pci_resume) - SET_RUNTIME_PM_OPS(i2c_dw_pci_runtime_suspend, i2c_dw_pci_runtime_resume, NULL) -}; - static const struct property_entry dgpu_properties[] = { /* USB-C doesn't power the system */ PROPERTY_ENTRY_U8("scope", POWER_SUPPLY_SCOPE_DEVICE), @@ -253,7 +212,6 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, int r; struct dw_pci_controller *controller; struct dw_scl_sda_cfg *cfg; - struct i2c_timings *t; if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) return dev_err_probe(&pdev->dev, -EINVAL, @@ -288,29 +246,17 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, dev->irq = pci_irq_vector(pdev, 0); dev->flags |= controller->flags; - t = &dev->timings; - i2c_parse_fw_timings(&pdev->dev, t, false); - pci_set_drvdata(pdev, dev); if (controller->setup) { r = controller->setup(pdev, controller); - if (r) { - pci_free_irq_vectors(pdev); + if (r) return r; - } } - i2c_dw_adjust_bus_speed(dev); - - if (has_acpi_companion(&pdev->dev)) - i2c_dw_acpi_configure(&pdev->dev); - - r = i2c_dw_validate_speed(dev); - if (r) { - pci_free_irq_vectors(pdev); + r = i2c_dw_fw_parse_and_configure(dev); + if (r) return r; - } i2c_dw_configure(dev); @@ -326,14 +272,11 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, adap = &dev->adapter; adap->owner = THIS_MODULE; adap->class = 0; - ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev)); adap->nr = controller->bus_num; r = i2c_dw_probe(dev); - if (r) { - pci_free_irq_vectors(pdev); + if (r) return r; - } if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) { dev->slave = i2c_new_ccgx_ucsi(&dev->adapter, dev->irq, &dgpu_node); @@ -354,16 +297,15 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev) { struct dw_i2c_dev *dev = pci_get_drvdata(pdev); - dev->disable(dev); + i2c_dw_disable(dev); + pm_runtime_forbid(&pdev->dev); pm_runtime_get_noresume(&pdev->dev); i2c_del_adapter(&dev->adapter); - devm_free_irq(&pdev->dev, dev->irq, dev); - pci_free_irq_vectors(pdev); } -static const struct pci_device_id i2_designware_pci_ids[] = { +static const struct pci_device_id i2c_designware_pci_ids[] = { /* Medfield */ { PCI_VDEVICE(INTEL, 0x0817), medfield }, { PCI_VDEVICE(INTEL, 0x0818), medfield }, @@ -409,21 +351,23 @@ static const struct pci_device_id i2_designware_pci_ids[] = { { PCI_VDEVICE(ATI, 0x73c4), navi_amd }, { PCI_VDEVICE(ATI, 0x7444), navi_amd }, { PCI_VDEVICE(ATI, 0x7464), navi_amd }, - { 0,} + {} }; -MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids); +MODULE_DEVICE_TABLE(pci, i2c_designware_pci_ids); static struct pci_driver dw_i2c_driver = { .name = DRIVER_NAME, - .id_table = i2_designware_pci_ids, .probe = i2c_dw_pci_probe, .remove = i2c_dw_pci_remove, .driver = { - .pm = &i2c_dw_pm_ops, + .pm = pm_ptr(&i2c_dw_dev_pm_ops), }, + .id_table = i2c_designware_pci_ids, }; module_pci_driver(dw_i2c_driver); MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); MODULE_DESCRIPTION("Synopsys DesignWare PCI I2C bus adapter"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(I2C_DW); +MODULE_IMPORT_NS(I2C_DW_COMMON); diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 29aac9c87368..2d0c7348e491 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -8,7 +8,6 @@ * Copyright (C) 2007 MontaVista Software Inc. * Copyright (C) 2009 Provigent Ltd. */ -#include <linux/acpi.h> #include <linux/clk-provider.h> #include <linux/clk.h> #include <linux/delay.h> @@ -21,7 +20,6 @@ #include <linux/kernel.h> #include <linux/mfd/syscon.h> #include <linux/module.h> -#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm.h> #include <linux/pm_runtime.h> @@ -30,7 +28,6 @@ #include <linux/reset.h> #include <linux/sched.h> #include <linux/slab.h> -#include <linux/suspend.h> #include <linux/units.h> #include "i2c-designware-core.h" @@ -40,29 +37,6 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) return clk_get_rate(dev->clk) / KILO; } -#ifdef CONFIG_ACPI -static const struct acpi_device_id dw_i2c_acpi_match[] = { - { "INT33C2", 0 }, - { "INT33C3", 0 }, - { "INT3432", 0 }, - { "INT3433", 0 }, - { "INTC10EF", 0 }, - { "80860F41", ACCESS_NO_IRQ_SUSPEND }, - { "808622C1", ACCESS_NO_IRQ_SUSPEND }, - { "AMD0010", ACCESS_INTR_MASK }, - { "AMDI0010", ACCESS_INTR_MASK }, - { "AMDI0019", ACCESS_INTR_MASK | ARBITRATION_SEMAPHORE }, - { "AMDI0510", 0 }, - { "APMC0D0F", 0 }, - { "HISI02A1", 0 }, - { "HISI02A2", 0 }, - { "HISI02A3", 0 }, - { "HYGO0010", ACCESS_INTR_MASK }, - { } -}; -MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); -#endif - #ifdef CONFIG_OF #define BT1_I2C_CTL 0x100 #define BT1_I2C_CTL_ADDR_MASK GENMASK(7, 0) @@ -101,7 +75,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, @@ -120,53 +94,11 @@ static int bt1_i2c_request_regs(struct dw_i2c_dev *dev) dev->map = devm_regmap_init(dev->dev, NULL, dev, &bt1_i2c_cfg); return PTR_ERR_OR_ZERO(dev->map); } - -#define MSCC_ICPU_CFG_TWI_DELAY 0x0 -#define MSCC_ICPU_CFG_TWI_DELAY_ENABLE BIT(0) -#define MSCC_ICPU_CFG_TWI_SPIKE_FILTER 0x4 - -static int mscc_twi_set_sda_hold_time(struct dw_i2c_dev *dev) -{ - writel((dev->sda_hold_time << 1) | MSCC_ICPU_CFG_TWI_DELAY_ENABLE, - dev->ext + MSCC_ICPU_CFG_TWI_DELAY); - - return 0; -} - -static int dw_i2c_of_configure(struct platform_device *pdev) -{ - struct dw_i2c_dev *dev = platform_get_drvdata(pdev); - - switch (dev->flags & MODEL_MASK) { - case MODEL_MSCC_OCELOT: - dev->ext = devm_platform_ioremap_resource(pdev, 1); - if (!IS_ERR(dev->ext)) - dev->set_sda_hold_time = mscc_twi_set_sda_hold_time; - break; - default: - break; - } - - return 0; -} - -static const struct of_device_id dw_i2c_of_match[] = { - { .compatible = "snps,designware-i2c", }, - { .compatible = "mscc,ocelot-i2c", .data = (void *)MODEL_MSCC_OCELOT }, - { .compatible = "baikal,bt1-sys-i2c", .data = (void *)MODEL_BAIKAL_BT1 }, - {}, -}; -MODULE_DEVICE_TABLE(of, dw_i2c_of_match); #else static int bt1_i2c_request_regs(struct dw_i2c_dev *dev) { return -ENODEV; } - -static inline int dw_i2c_of_configure(struct platform_device *pdev) -{ - return -ENODEV; -} #endif static int txgbe_i2c_request_regs(struct dw_i2c_dev *dev) @@ -238,11 +170,9 @@ static int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) int i = 0; int ret; - ptr = i2c_dw_semaphore_cb_table; - dev->semaphore_idx = -1; - while (ptr->probe) { + for (ptr = i2c_dw_semaphore_cb_table; ptr->probe; ptr++) { ret = ptr->probe(dev); if (ret) { /* @@ -254,7 +184,6 @@ static int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) return ret; i++; - ptr++; continue; } @@ -278,7 +207,6 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) { struct i2c_adapter *adap; struct dw_i2c_dev *dev; - struct i2c_timings *t; int irq, ret; irq = platform_get_irq(pdev, 0); @@ -307,18 +235,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) reset_control_deassert(dev->rst); - t = &dev->timings; - i2c_parse_fw_timings(&pdev->dev, t, false); - - i2c_dw_adjust_bus_speed(dev); - - if (pdev->dev.of_node) - dw_i2c_of_configure(pdev); - - if (has_acpi_companion(&pdev->dev)) - i2c_dw_acpi_configure(&pdev->dev); - - ret = i2c_dw_validate_speed(dev); + ret = i2c_dw_fw_parse_and_configure(dev); if (ret) goto exit_reset; @@ -346,6 +263,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) goto exit_reset; if (dev->clk) { + struct i2c_timings *t = &dev->timings; u64 clk_khz; dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; @@ -360,8 +278,6 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) adap->owner = THIS_MODULE; adap->class = dmi_check_system(dw_i2c_hwmon_class_dmi) ? I2C_CLASS_HWMON : I2C_CLASS_DEPRECATED; - ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev)); - adap->dev.of_node = pdev->dev.of_node; adap->nr = -1; if (dev->flags & ACCESS_NO_IRQ_SUSPEND) { @@ -408,7 +324,7 @@ static void dw_i2c_plat_remove(struct platform_device *pdev) i2c_del_adapter(&dev->adapter); - dev->disable(dev); + i2c_dw_disable(dev); pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_put_sync(&pdev->dev); @@ -419,66 +335,34 @@ static void dw_i2c_plat_remove(struct platform_device *pdev) reset_control_assert(dev->rst); } -static int dw_i2c_plat_prepare(struct device *dev) -{ - /* - * If the ACPI companion device object is present for this device, it - * may be accessed during suspend and resume of other devices via I2C - * operation regions, so tell the PM core and middle layers to avoid - * skipping system suspend/resume callbacks for it in that case. - */ - return !has_acpi_companion(dev); -} - -static int dw_i2c_plat_runtime_suspend(struct device *dev) -{ - struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - - if (i_dev->shared_with_punit) - return 0; - - i_dev->disable(i_dev); - i2c_dw_prepare_clk(i_dev, false); - - return 0; -} - -static int dw_i2c_plat_suspend(struct device *dev) -{ - struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - - i2c_mark_adapter_suspended(&i_dev->adapter); - - return dw_i2c_plat_runtime_suspend(dev); -} - -static int dw_i2c_plat_runtime_resume(struct device *dev) -{ - struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - - if (!i_dev->shared_with_punit) - i2c_dw_prepare_clk(i_dev, true); - - i_dev->init(i_dev); - - return 0; -} - -static int dw_i2c_plat_resume(struct device *dev) -{ - struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - - dw_i2c_plat_runtime_resume(dev); - i2c_mark_adapter_resumed(&i_dev->adapter); - - return 0; -} +static const struct of_device_id dw_i2c_of_match[] = { + { .compatible = "snps,designware-i2c", }, + { .compatible = "mscc,ocelot-i2c", .data = (void *)MODEL_MSCC_OCELOT }, + { .compatible = "baikal,bt1-sys-i2c", .data = (void *)MODEL_BAIKAL_BT1 }, + {} +}; +MODULE_DEVICE_TABLE(of, dw_i2c_of_match); -static const struct dev_pm_ops dw_i2c_dev_pm_ops = { - .prepare = pm_sleep_ptr(dw_i2c_plat_prepare), - LATE_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume) - RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend, dw_i2c_plat_runtime_resume, NULL) +static const struct acpi_device_id dw_i2c_acpi_match[] = { + { "80860F41", ACCESS_NO_IRQ_SUSPEND }, + { "808622C1", ACCESS_NO_IRQ_SUSPEND }, + { "AMD0010", ACCESS_INTR_MASK }, + { "AMDI0010", ACCESS_INTR_MASK }, + { "AMDI0019", ACCESS_INTR_MASK | ARBITRATION_SEMAPHORE }, + { "AMDI0510", 0 }, + { "APMC0D0F", 0 }, + { "HISI02A1", 0 }, + { "HISI02A2", 0 }, + { "HISI02A3", 0 }, + { "HYGO0010", ACCESS_INTR_MASK }, + { "INT33C2", 0 }, + { "INT33C3", 0 }, + { "INT3432", 0 }, + { "INT3433", 0 }, + { "INTC10EF", 0 }, + {} }; +MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); static const struct platform_device_id dw_i2c_platform_ids[] = { { "i2c_designware" }, @@ -491,9 +375,9 @@ static struct platform_driver dw_i2c_driver = { .remove_new = dw_i2c_plat_remove, .driver = { .name = "i2c_designware", - .of_match_table = of_match_ptr(dw_i2c_of_match), - .acpi_match_table = ACPI_PTR(dw_i2c_acpi_match), - .pm = pm_ptr(&dw_i2c_dev_pm_ops), + .of_match_table = dw_i2c_of_match, + .acpi_match_table = dw_i2c_acpi_match, + .pm = pm_ptr(&i2c_dw_dev_pm_ops), }, .id_table = dw_i2c_platform_ids, }; @@ -513,3 +397,5 @@ module_exit(dw_i2c_exit_driver); MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(I2C_DW); +MODULE_IMPORT_NS(I2C_DW_COMMON); diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index 78e2c47e3d7d..7035296aa24c 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -16,6 +16,8 @@ #include <linux/pm_runtime.h> #include <linux/regmap.h> +#define DEFAULT_SYMBOL_NAMESPACE I2C_DW + #include "i2c-designware-core.h" static void i2c_dw_configure_fifo_slave(struct dw_i2c_dev *dev) @@ -88,7 +90,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave) struct dw_i2c_dev *dev = i2c_get_adapdata(slave->adapter); regmap_write(dev->map, DW_IC_INTR_MASK, 0); - dev->disable(dev); + i2c_dw_disable(dev); synchronize_irq(dev->irq); dev->slave = NULL; pm_runtime_put(dev->dev); @@ -235,7 +237,6 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev) int ret; dev->init = i2c_dw_init_slave; - dev->disable = i2c_dw_disable; ret = i2c_dw_init_regmap(dev); if (ret) @@ -279,3 +280,4 @@ EXPORT_SYMBOL_GPL(i2c_dw_probe_slave); MODULE_AUTHOR("Luis Oliveira <lolivei@synopsys.com>"); MODULE_DESCRIPTION("Synopsys DesignWare I2C bus slave adapter"); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(I2C_DW_COMMON); diff --git a/drivers/i2c/busses/i2c-digicolor.c b/drivers/i2c/busses/i2c-digicolor.c index 737604ae11fc..3dc5a46698fc 100644 --- a/drivers/i2c/busses/i2c-digicolor.c +++ b/drivers/i2c/busses/i2c-digicolor.c @@ -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) @@ -357,7 +357,7 @@ static void dc_i2c_remove(struct platform_device *pdev) static const struct of_device_id dc_i2c_match[] = { { .compatible = "cnxt,cx92755-i2c" }, - { }, + { } }; MODULE_DEVICE_TABLE(of, dc_i2c_match); @@ -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-emev2.c b/drivers/i2c/busses/i2c-emev2.c index 557409410445..d08be3f3cede 100644 --- a/drivers/i2c/busses/i2c-emev2.c +++ b/drivers/i2c/busses/i2c-emev2.c @@ -67,7 +67,6 @@ struct em_i2c_device { void __iomem *base; struct i2c_adapter adap; struct completion msg_done; - struct clk *sclk; struct i2c_client *slave; int irq; }; @@ -361,6 +360,7 @@ static const struct i2c_algorithm em_i2c_algo = { static int em_i2c_probe(struct platform_device *pdev) { struct em_i2c_device *priv; + struct clk *sclk; int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -373,13 +373,9 @@ static int em_i2c_probe(struct platform_device *pdev) strscpy(priv->adap.name, "EMEV2 I2C", sizeof(priv->adap.name)); - priv->sclk = devm_clk_get(&pdev->dev, "sclk"); - if (IS_ERR(priv->sclk)) - return PTR_ERR(priv->sclk); - - ret = clk_prepare_enable(priv->sclk); - if (ret) - return ret; + sclk = devm_clk_get_enabled(&pdev->dev, "sclk"); + if (IS_ERR(sclk)) + return PTR_ERR(sclk); priv->adap.timeout = msecs_to_jiffies(100); priv->adap.retries = 5; @@ -397,26 +393,22 @@ static int em_i2c_probe(struct platform_device *pdev) ret = platform_get_irq(pdev, 0); if (ret < 0) - goto err_clk; + return ret; priv->irq = ret; + ret = devm_request_irq(&pdev->dev, priv->irq, em_i2c_irq_handler, 0, "em_i2c", priv); if (ret) - goto err_clk; + return ret; ret = i2c_add_adapter(&priv->adap); - if (ret) - goto err_clk; + return ret; dev_info(&pdev->dev, "Added i2c controller %d, irq %d\n", priv->adap.nr, priv->irq); return 0; - -err_clk: - clk_disable_unprepare(priv->sclk); - return ret; } static void em_i2c_remove(struct platform_device *dev) @@ -424,7 +416,6 @@ static void em_i2c_remove(struct platform_device *dev) struct em_i2c_device *priv = platform_get_drvdata(dev); i2c_del_adapter(&priv->adap); - clk_disable_unprepare(priv->sclk); } static const struct of_device_id em_i2c_ids[] = { 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 a47b9939fa2c..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); @@ -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 d2d2a6dbe29f..299fe9d3afab 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 * @@ -237,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 @@ -1052,6 +1054,7 @@ 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, } }; @@ -1274,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; @@ -1304,7 +1307,7 @@ static void i801_probe_optional_slaves(struct i801_priv *priv) } #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 */ #ifdef CONFIG_I2C_I801_MUX @@ -1760,8 +1763,15 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) i801_add_tco(priv); + /* + * adapter.name is used by platform code to find the main I801 adapter + * to instantiante i2c_clients, do not change. + */ snprintf(priv->adapter.name, sizeof(priv->adapter.name), - "SMBus I801 adapter at %04lx", priv->smba); + "SMBus %s adapter at %04lx", + (priv->features & FEATURE_IDF) ? "I801 IDF" : "I801", + priv->smba); + err = i2c_add_adapter(&priv->adapter); if (err) { platform_device_unregister(priv->tco_pdev); @@ -1774,7 +1784,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-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 0197786892a2..976d43f73f38 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -559,7 +559,7 @@ static const struct i2c_algorithm lpi2c_imx_algo = { static const struct of_device_id lpi2c_imx_of_match[] = { { .compatible = "fsl,imx7ulp-lpi2c" }, - { }, + { } }; MODULE_DEVICE_TABLE(of, lpi2c_imx_of_match); diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 3842e527116b..98539313cbc9 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -687,7 +687,7 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx, bool atomic) i2c_imx_bus_busy(i2c_imx, 0, atomic); /* Disable I2C controller */ - temp = i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN, + temp = i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN; imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); } @@ -1549,7 +1549,7 @@ static void i2c_imx_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused i2c_imx_runtime_suspend(struct device *dev) +static int i2c_imx_runtime_suspend(struct device *dev) { struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev); @@ -1558,7 +1558,7 @@ static int __maybe_unused i2c_imx_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused i2c_imx_runtime_resume(struct device *dev) +static int i2c_imx_runtime_resume(struct device *dev) { struct imx_i2c_struct *i2c_imx = dev_get_drvdata(dev); int ret; @@ -1571,8 +1571,7 @@ static int __maybe_unused i2c_imx_runtime_resume(struct device *dev) } static const struct dev_pm_ops i2c_imx_pm_ops = { - SET_RUNTIME_PM_OPS(i2c_imx_runtime_suspend, - i2c_imx_runtime_resume, NULL) + RUNTIME_PM_OPS(i2c_imx_runtime_suspend, i2c_imx_runtime_resume, NULL) }; static struct platform_driver i2c_imx_driver = { @@ -1580,7 +1579,7 @@ static struct platform_driver i2c_imx_driver = { .remove_new = i2c_imx_remove, .driver = { .name = DRIVER_NAME, - .pm = &i2c_imx_pm_ops, + .pm = pm_ptr(&i2c_imx_pm_ops), .of_match_table = i2c_imx_dt_ids, .acpi_match_table = i2c_imx_acpi_ids, }, 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..f59158489ad9 100644 --- a/drivers/i2c/busses/i2c-isch.c +++ b/drivers/i2c/busses/i2c-isch.c @@ -99,12 +99,11 @@ static int sch_transaction(void) if (retries > MAX_RETRIES) { dev_err(&sch_adapter.dev, "SMBus Timeout!\n"); result = -ETIMEDOUT; - } - if (temp & 0x04) { + } else if (temp & 0x04) { 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 655b5d851c48..c93c02aa6ac8 100644 --- a/drivers/i2c/busses/i2c-ismt.c +++ b/drivers/i2c/busses/i2c-ismt.c @@ -382,6 +382,15 @@ static int ismt_process_desc(const struct ismt_desc *desc, } /** + * ismt_kill_transaction() - kill current transaction + * @priv: iSMT private data + */ +static void ismt_kill_transaction(struct ismt_priv *priv) +{ + writel(ISMT_GCTRL_KILL, priv->smba + ISMT_GR_GCTRL); +} + +/** * ismt_access() - process an SMBus command * @adap: the i2c host adapter * @addr: address of the i2c/SMBus target @@ -623,6 +632,7 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr, dma_unmap_single(dev, dma_addr, dma_size, dma_direction); if (unlikely(!time_left)) { + ismt_kill_transaction(priv); ret = -ETIMEDOUT; goto out; } diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c index 7951891d6b97..92cc5b091137 100644 --- a/drivers/i2c/busses/i2c-jz4780.c +++ b/drivers/i2c/busses/i2c-jz4780.c @@ -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 = { @@ -792,26 +792,22 @@ static int jz4780_i2c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, i2c); - i2c->clk = devm_clk_get(&pdev->dev, NULL); + i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(i2c->clk)) return PTR_ERR(i2c->clk); - ret = clk_prepare_enable(i2c->clk); - if (ret) - return ret; - ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", &clk_freq); if (ret) { dev_err(&pdev->dev, "clock-frequency not specified in DT\n"); - goto err; + return ret; } i2c->speed = clk_freq / 1000; if (i2c->speed == 0) { ret = -EINVAL; dev_err(&pdev->dev, "clock-frequency minimum is 1000\n"); - goto err; + return ret; } jz4780_i2c_set_speed(i2c); @@ -827,29 +823,25 @@ static int jz4780_i2c_probe(struct platform_device *pdev) ret = platform_get_irq(pdev, 0); if (ret < 0) - goto err; + return ret; i2c->irq = ret; + ret = devm_request_irq(&pdev->dev, i2c->irq, jz4780_i2c_irq, 0, dev_name(&pdev->dev), i2c); if (ret) - goto err; + return ret; ret = i2c_add_adapter(&i2c->adap); if (ret < 0) - goto err; + return ret; return 0; - -err: - clk_disable_unprepare(i2c->clk); - return ret; } static void jz4780_i2c_remove(struct platform_device *pdev) { struct jz4780_i2c *i2c = platform_get_drvdata(pdev); - clk_disable_unprepare(i2c->clk); i2c_del_adapter(&i2c->adap); } diff --git a/drivers/i2c/busses/i2c-keba.c b/drivers/i2c/busses/i2c-keba.c new file mode 100644 index 000000000000..759732a07ef0 --- /dev/null +++ b/drivers/i2c/busses/i2c-keba.c @@ -0,0 +1,598 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) KEBA Industrial Automation Gmbh 2024 + * + * Driver for KEBA I2C controller FPGA IP core + */ + +#include <linux/i2c.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/module.h> +#include <linux/misc/keba.h> + +#define KI2C "i2c-keba" + +#define KI2C_CAPABILITY_REG 0x02 +#define KI2C_CAPABILITY_CRYPTO 0x01 +#define KI2C_CAPABILITY_DC 0x02 + +#define KI2C_CONTROL_REG 0x04 +#define KI2C_CONTROL_MEN 0x01 +#define KI2C_CONTROL_MSTA 0x02 +#define KI2C_CONTROL_RSTA 0x04 +#define KI2C_CONTROL_MTX 0x08 +#define KI2C_CONTROL_TXAK 0x10 +#define KI2C_CONTROL_DISABLE 0x00 + +#define KI2C_CONTROL_DC_REG 0x05 +#define KI2C_CONTROL_DC_SDA 0x01 +#define KI2C_CONTROL_DC_SCL 0x02 + +#define KI2C_STATUS_REG 0x08 +#define KI2C_STATUS_IN_USE 0x01 +#define KI2C_STATUS_ACK_CYC 0x02 +#define KI2C_STATUS_RXAK 0x04 +#define KI2C_STATUS_MCF 0x08 + +#define KI2C_STATUS_DC_REG 0x09 +#define KI2C_STATUS_DC_SDA 0x01 +#define KI2C_STATUS_DC_SCL 0x02 + +#define KI2C_DATA_REG 0x0c + +#define KI2C_INUSE_SLEEP_US (2 * USEC_PER_MSEC) +#define KI2C_INUSE_TIMEOUT_US (10 * USEC_PER_SEC) + +#define KI2C_POLL_DELAY_US 5 + +struct ki2c { + struct keba_i2c_auxdev *auxdev; + void __iomem *base; + struct i2c_adapter adapter; + + struct i2c_client **client; + int client_size; +}; + +static int ki2c_inuse_lock(struct ki2c *ki2c) +{ + u8 sts; + int ret; + + /* + * The I2C controller has an IN_USE bit for locking access to the + * controller. This enables the use of I2C controller by other none + * Linux processors. + * + * If the I2C controller is free, then the first read returns + * IN_USE == 0. After that the I2C controller is locked and further + * reads of IN_USE return 1. + * + * The I2C controller is unlocked by writing 1 into IN_USE. + * + * The IN_USE bit acts as a hardware semaphore for the I2C controller. + * Poll for semaphore, but sleep while polling to free the CPU. + */ + ret = readb_poll_timeout(ki2c->base + KI2C_STATUS_REG, + sts, (sts & KI2C_STATUS_IN_USE) == 0, + KI2C_INUSE_SLEEP_US, KI2C_INUSE_TIMEOUT_US); + if (ret) + dev_err(&ki2c->auxdev->auxdev.dev, "%s err!\n", __func__); + + return ret; +} + +static void ki2c_inuse_unlock(struct ki2c *ki2c) +{ + /* unlock the controller by writing 1 into IN_USE */ + iowrite8(KI2C_STATUS_IN_USE, ki2c->base + KI2C_STATUS_REG); +} + +static int ki2c_wait_for_bit(void __iomem *addr, u8 mask, unsigned long timeout) +{ + u8 val; + + return readb_poll_timeout(addr, val, (val & mask), KI2C_POLL_DELAY_US, + jiffies_to_usecs(timeout)); +} + +static int ki2c_wait_for_mcf(struct ki2c *ki2c) +{ + return ki2c_wait_for_bit(ki2c->base + KI2C_STATUS_REG, KI2C_STATUS_MCF, + ki2c->adapter.timeout); +} + +static int ki2c_wait_for_data(struct ki2c *ki2c) +{ + int ret; + + ret = ki2c_wait_for_mcf(ki2c); + if (ret < 0) + return ret; + + return ki2c_wait_for_bit(ki2c->base + KI2C_STATUS_REG, + KI2C_STATUS_ACK_CYC, + ki2c->adapter.timeout); +} + +static int ki2c_wait_for_data_ack(struct ki2c *ki2c) +{ + unsigned int reg; + int ret; + + ret = ki2c_wait_for_data(ki2c); + if (ret < 0) + return ret; + + /* RXAK == 0 means ACK reveived */ + reg = ioread8(ki2c->base + KI2C_STATUS_REG); + if (reg & KI2C_STATUS_RXAK) + return -EIO; + + return 0; +} + +static int ki2c_has_capability(struct ki2c *ki2c, unsigned int cap) +{ + unsigned int reg = ioread8(ki2c->base + KI2C_CAPABILITY_REG); + + return (reg & cap) != 0; +} + +static int ki2c_get_scl(struct ki2c *ki2c) +{ + unsigned int reg = ioread8(ki2c->base + KI2C_STATUS_DC_REG); + + /* capability KI2C_CAPABILITY_DC required */ + return (reg & KI2C_STATUS_DC_SCL) != 0; +} + +static int ki2c_get_sda(struct ki2c *ki2c) +{ + unsigned int reg = ioread8(ki2c->base + KI2C_STATUS_DC_REG); + + /* capability KI2C_CAPABILITY_DC required */ + return (reg & KI2C_STATUS_DC_SDA) != 0; +} + +static void ki2c_set_scl(struct ki2c *ki2c, int val) +{ + u8 control_dc; + + /* capability KI2C_CAPABILITY_DC and KI2C_CONTROL_MEN = 0 reqired */ + control_dc = ioread8(ki2c->base + KI2C_CONTROL_DC_REG); + if (val) + control_dc |= KI2C_CONTROL_DC_SCL; + else + control_dc &= ~KI2C_CONTROL_DC_SCL; + iowrite8(control_dc, ki2c->base + KI2C_CONTROL_DC_REG); +} + +/* + * Resetting bus bitwise is done by checking SDA and applying clock cycles as + * long as SDA is low. 9 clock cycles are applied at most. + * + * Clock cycles are generated and udelay() determines the duration of clock + * cycles. Generated clock rate is 100 KHz and so duration of both clock levels + * is: delay in ns = (10^6 / 100) / 2 + */ +#define KI2C_RECOVERY_CLK_CNT (9 * 2) +#define KI2C_RECOVERY_UDELAY 5 +static int ki2c_reset_bus_bitwise(struct ki2c *ki2c) +{ + int val = 1; + int ret = 0; + int i; + + /* disable I2C controller (MEN = 0) to get direct access to SCL/SDA */ + iowrite8(0, ki2c->base + KI2C_CONTROL_REG); + + /* generate clock cycles */ + ki2c_set_scl(ki2c, val); + udelay(KI2C_RECOVERY_UDELAY); + for (i = 0; i < KI2C_RECOVERY_CLK_CNT; i++) { + if (val) { + /* SCL shouldn't be low here */ + if (!ki2c_get_scl(ki2c)) { + dev_err(&ki2c->auxdev->auxdev.dev, + "SCL is stuck low!\n"); + ret = -EBUSY; + break; + } + + /* break if SDA is high */ + if (ki2c_get_sda(ki2c)) + break; + } + + val = !val; + ki2c_set_scl(ki2c, val); + udelay(KI2C_RECOVERY_UDELAY); + } + + if (!ki2c_get_sda(ki2c)) { + dev_err(&ki2c->auxdev->auxdev.dev, "SDA is still low!\n"); + ret = -EBUSY; + } + + /* reenable controller */ + iowrite8(KI2C_CONTROL_MEN, ki2c->base + KI2C_CONTROL_REG); + + return ret; +} + +/* + * Resetting bus bytewise is done by writing start bit, 9 data bits and stop + * bit. + * + * This is not 100% safe. If target is an EEPROM and a write access was + * interrupted during the ACK cycle, this approach might not be able to recover + * the bus. The reason is, that after the 9 clock cycles the EEPROM will be in + * ACK cycle again and will hold SDA low like it did before the start of the + * routine. Furthermore the EEPROM might get written one additional byte with + * 0xff into it. Thus, use bitwise approach whenever possible, especially when + * EEPROMs are on the bus. + */ +static int ki2c_reset_bus_bytewise(struct ki2c *ki2c) +{ + int ret; + + /* hold data line high for 9 clock cycles */ + iowrite8(0xFF, ki2c->base + KI2C_DATA_REG); + + /* create start condition */ + iowrite8(KI2C_CONTROL_MEN | KI2C_CONTROL_MTX | KI2C_CONTROL_MSTA | KI2C_CONTROL_TXAK, + ki2c->base + KI2C_CONTROL_REG); + ret = ki2c_wait_for_mcf(ki2c); + if (ret < 0) { + dev_err(&ki2c->auxdev->auxdev.dev, "Start condition failed\n"); + + return ret; + } + + /* create stop condition */ + iowrite8(KI2C_CONTROL_MEN | KI2C_CONTROL_MTX | KI2C_CONTROL_TXAK, + ki2c->base + KI2C_CONTROL_REG); + ret = ki2c_wait_for_mcf(ki2c); + if (ret < 0) + dev_err(&ki2c->auxdev->auxdev.dev, "Stop condition failed\n"); + + return ret; +} + +static int ki2c_reset_bus(struct ki2c *ki2c) +{ + int ret; + + ret = ki2c_inuse_lock(ki2c); + if (ret < 0) + return ret; + + /* + * If the I2C controller is capable of direct control of SCL/SDA, then a + * bitwise reset is used. Otherwise fall back to bytewise reset. + */ + if (ki2c_has_capability(ki2c, KI2C_CAPABILITY_DC)) + ret = ki2c_reset_bus_bitwise(ki2c); + else + ret = ki2c_reset_bus_bytewise(ki2c); + + ki2c_inuse_unlock(ki2c); + + return ret; +} + +static void ki2c_write_target_addr(struct ki2c *ki2c, struct i2c_msg *m) +{ + u8 addr; + + addr = m->addr << 1; + /* Bit 0 signals RD/WR */ + if (m->flags & I2C_M_RD) + addr |= 0x01; + + iowrite8(addr, ki2c->base + KI2C_DATA_REG); +} + +static int ki2c_start_addr(struct ki2c *ki2c, struct i2c_msg *m) +{ + int ret; + + /* + * Store target address byte in the controller. This has to be done + * before sending START condition. + */ + ki2c_write_target_addr(ki2c, m); + + /* enable controller for TX */ + iowrite8(KI2C_CONTROL_MEN | KI2C_CONTROL_MTX, + ki2c->base + KI2C_CONTROL_REG); + + /* send START condition and target address byte */ + iowrite8(KI2C_CONTROL_MEN | KI2C_CONTROL_MTX | KI2C_CONTROL_MSTA, + ki2c->base + KI2C_CONTROL_REG); + + ret = ki2c_wait_for_data_ack(ki2c); + if (ret < 0) + /* + * For EEPROMs this is normal behavior during internal write + * operation. + */ + dev_dbg(&ki2c->auxdev->auxdev.dev, + "%s wait for ACK err at 0x%02x!\n", __func__, m->addr); + + return ret; +} + +static int ki2c_repstart_addr(struct ki2c *ki2c, struct i2c_msg *m) +{ + int ret; + + /* repeated start and write is not supported */ + if ((m->flags & I2C_M_RD) == 0) { + dev_err(&ki2c->auxdev->auxdev.dev, + "Repeated start not supported for writes\n"); + return -EINVAL; + } + + /* send repeated start */ + iowrite8(KI2C_CONTROL_MEN | KI2C_CONTROL_MSTA | KI2C_CONTROL_RSTA, + ki2c->base + KI2C_CONTROL_REG); + + ret = ki2c_wait_for_mcf(ki2c); + if (ret < 0) { + dev_err(&ki2c->auxdev->auxdev.dev, + "%s wait for MCF err at 0x%02x!\n", __func__, m->addr); + return ret; + } + + /* write target-address byte */ + ki2c_write_target_addr(ki2c, m); + + ret = ki2c_wait_for_data_ack(ki2c); + if (ret < 0) + dev_err(&ki2c->auxdev->auxdev.dev, + "%s wait for ACK err at 0x%02x!\n", __func__, m->addr); + + return ret; +} + +static void ki2c_stop(struct ki2c *ki2c) +{ + iowrite8(KI2C_CONTROL_MEN, ki2c->base + KI2C_CONTROL_REG); + ki2c_wait_for_mcf(ki2c); +} + +static int ki2c_write(struct ki2c *ki2c, const u8 *data, int len) +{ + int ret; + int i; + + for (i = 0; i < len; i++) { + /* write data byte */ + iowrite8(data[i], ki2c->base + KI2C_DATA_REG); + + ret = ki2c_wait_for_data_ack(ki2c); + if (ret < 0) + return ret; + } + + return 0; +} + +static int ki2c_read(struct ki2c *ki2c, u8 *data, int len) +{ + u8 control; + int ret; + int i; + + if (len == 0) + return 0; /* nothing to do */ + + control = KI2C_CONTROL_MEN | KI2C_CONTROL_MSTA; + + /* if just one byte => send tx-nack after transfer */ + if (len == 1) + control |= KI2C_CONTROL_TXAK; + + iowrite8(control, ki2c->base + KI2C_CONTROL_REG); + + /* dummy read to start transfer on bus */ + ioread8(ki2c->base + KI2C_DATA_REG); + + for (i = 0; i < len; i++) { + ret = ki2c_wait_for_data(ki2c); + if (ret < 0) + return ret; + + if (i == len - 2) + /* send tx-nack after transfer of last byte */ + iowrite8(KI2C_CONTROL_MEN | KI2C_CONTROL_MSTA | KI2C_CONTROL_TXAK, + ki2c->base + KI2C_CONTROL_REG); + else if (i == len - 1) + /* + * switch to TX on last byte, so that reading DATA + * register does not trigger another read transfer + */ + iowrite8(KI2C_CONTROL_MEN | KI2C_CONTROL_MSTA | KI2C_CONTROL_MTX, + ki2c->base + KI2C_CONTROL_REG); + + /* read byte and start next transfer (if not last byte) */ + data[i] = ioread8(ki2c->base + KI2C_DATA_REG); + } + + return len; +} + +static int ki2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) +{ + struct ki2c *ki2c = i2c_get_adapdata(adap); + int ret; + int i; + + ret = ki2c_inuse_lock(ki2c); + if (ret < 0) + return ret; + + for (i = 0; i < num; i++) { + struct i2c_msg *m = &msgs[i]; + + if (i == 0) + ret = ki2c_start_addr(ki2c, m); + else + ret = ki2c_repstart_addr(ki2c, m); + if (ret < 0) + break; + + if (m->flags & I2C_M_RD) + ret = ki2c_read(ki2c, m->buf, m->len); + else + ret = ki2c_write(ki2c, m->buf, m->len); + if (ret < 0) + break; + } + + ki2c_stop(ki2c); + + ki2c_inuse_unlock(ki2c); + + return ret < 0 ? ret : num; +} + +static void ki2c_unregister_devices(struct ki2c *ki2c) +{ + int i; + + for (i = 0; i < ki2c->client_size; i++) { + struct i2c_client *client = ki2c->client[i]; + + if (client) + i2c_unregister_device(client); + } +} + +static int ki2c_register_devices(struct ki2c *ki2c) +{ + struct i2c_board_info *info = ki2c->auxdev->info; + int i; + + /* register all known I2C devices */ + for (i = 0; i < ki2c->client_size; i++) { + struct i2c_client *client; + unsigned short const addr_list[2] = { info[i].addr, + I2C_CLIENT_END }; + + client = i2c_new_scanned_device(&ki2c->adapter, &info[i], + addr_list, NULL); + if (!IS_ERR(client)) { + ki2c->client[i] = client; + } else if (PTR_ERR(client) != -ENODEV) { + ki2c->client_size = i; + ki2c_unregister_devices(ki2c); + + return PTR_ERR(client); + } + } + + return 0; +} + +static u32 ki2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm ki2c_algo = { + .master_xfer = ki2c_xfer, + .functionality = ki2c_func, +}; + +static int ki2c_probe(struct auxiliary_device *auxdev, + const struct auxiliary_device_id *id) +{ + struct device *dev = &auxdev->dev; + struct i2c_adapter *adap; + struct ki2c *ki2c; + int ret; + + ki2c = devm_kzalloc(dev, sizeof(*ki2c), GFP_KERNEL); + if (!ki2c) + return -ENOMEM; + ki2c->auxdev = container_of(auxdev, struct keba_i2c_auxdev, auxdev); + ki2c->client = devm_kcalloc(dev, ki2c->auxdev->info_size, + sizeof(*ki2c->client), GFP_KERNEL); + if (!ki2c->client) + return -ENOMEM; + ki2c->client_size = ki2c->auxdev->info_size; + auxiliary_set_drvdata(auxdev, ki2c); + + ki2c->base = devm_ioremap_resource(dev, &ki2c->auxdev->io); + if (IS_ERR(ki2c->base)) + return PTR_ERR(ki2c->base); + + adap = &ki2c->adapter; + strscpy(adap->name, "KEBA I2C adapter", sizeof(adap->name)); + adap->owner = THIS_MODULE; + adap->class = I2C_CLASS_HWMON; + adap->algo = &ki2c_algo; + adap->dev.parent = dev; + + i2c_set_adapdata(adap, ki2c); + + /* enable controller */ + iowrite8(KI2C_CONTROL_MEN, ki2c->base + KI2C_CONTROL_REG); + + /* reset bus before probing I2C devices */ + ret = ki2c_reset_bus(ki2c); + if (ret) + goto out; + + ret = devm_i2c_add_adapter(dev, adap); + if (ret) { + dev_err(dev, "Failed to add adapter (%d)!\n", ret); + goto out; + } + + ret = ki2c_register_devices(ki2c); + if (ret) { + dev_err(dev, "Failed to register devices (%d)!\n", ret); + goto out; + } + + return 0; + +out: + iowrite8(KI2C_CONTROL_DISABLE, ki2c->base + KI2C_CONTROL_REG); + return ret; +} + +static void ki2c_remove(struct auxiliary_device *auxdev) +{ + struct ki2c *ki2c = auxiliary_get_drvdata(auxdev); + + ki2c_unregister_devices(ki2c); + + /* disable controller */ + iowrite8(KI2C_CONTROL_DISABLE, ki2c->base + KI2C_CONTROL_REG); + + auxiliary_set_drvdata(auxdev, NULL); +} + +static const struct auxiliary_device_id ki2c_devtype_aux[] = { + { .name = "keba.i2c" }, + { } +}; +MODULE_DEVICE_TABLE(auxiliary, ki2c_devtype_aux); + +static struct auxiliary_driver ki2c_driver_aux = { + .name = KI2C, + .id_table = ki2c_devtype_aux, + .probe = ki2c_probe, + .remove = ki2c_remove, +}; +module_auxiliary_driver(ki2c_driver_aux); + +MODULE_AUTHOR("Gerhard Engleder <eg@keba.com>"); +MODULE_DESCRIPTION("KEBA I2C bus controller driver"); +MODULE_LICENSE("GPL"); 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..1dc516ef0fdd 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) { 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); 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); 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 c4223556b3b8..236d6b8ba867 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -88,7 +88,6 @@ struct mpc_i2c { int irq; u32 real_clk; u8 fdr, dfsrr; - struct clk *clk_per; u32 cntl_bits; enum mpc_i2c_action action; struct i2c_msg *msgs; @@ -115,7 +114,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. @@ -759,7 +758,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, }; @@ -779,7 +778,6 @@ static int fsl_i2c_probe(struct platform_device *op) struct clk *clk; int result; u32 clock; - int err; i2c = devm_kzalloc(&op->dev, sizeof(*i2c), GFP_KERNEL); if (!i2c) @@ -809,18 +807,12 @@ static int fsl_i2c_probe(struct platform_device *op) * enable clock for the I2C peripheral (non fatal), * keep a reference upon successful allocation */ - clk = devm_clk_get_optional(&op->dev, NULL); - if (IS_ERR(clk)) - return PTR_ERR(clk); - - err = clk_prepare_enable(clk); - if (err) { + clk = devm_clk_get_optional_enabled(&op->dev, NULL); + if (IS_ERR(clk)) { dev_err(&op->dev, "failed to enable clock\n"); - return err; + return PTR_ERR(clk); } - i2c->clk_per = clk; - if (of_property_read_bool(op->dev.of_node, "fsl,preserve-clocking")) { clock = MPC_I2C_CLOCK_PRESERVE; } else { @@ -876,14 +868,9 @@ static int fsl_i2c_probe(struct platform_device *op) result = i2c_add_numbered_adapter(&i2c->adap); if (result) - goto fail_add; + return result; return 0; - - fail_add: - clk_disable_unprepare(i2c->clk_per); - - return result; }; static void fsl_i2c_remove(struct platform_device *op) @@ -891,8 +878,6 @@ static void fsl_i2c_remove(struct platform_device *op) struct mpc_i2c *i2c = platform_get_drvdata(op); i2c_del_adapter(&i2c->adap); - - clk_disable_unprepare(i2c->clk_per); }; static int __maybe_unused mpc_i2c_suspend(struct device *dev) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index a8b5719c3372..e0ba653dec2d 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -1306,12 +1306,9 @@ err_exit: static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id) { struct mtk_i2c *i2c = dev_id; - u16 restart_flag = 0; + u16 restart_flag = i2c->auto_restart ? I2C_RS_TRANSFER : 0; u16 intr_stat; - if (i2c->auto_restart) - restart_flag = I2C_RS_TRANSFER; - intr_stat = mtk_i2c_readw(i2c, OFFSET_INTR_STAT); mtk_i2c_writew(i2c, intr_stat, OFFSET_INTR_STAT); 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-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index 2fe68615942e..bbcb4d6668ce 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -136,11 +136,13 @@ enum i2c_addr { * Since the addr regs are sprinkled all over the address space, * use this array to get the address or each register. */ -#define I2C_NUM_OWN_ADDR 2 +#define I2C_NUM_OWN_ADDR 10 #define I2C_NUM_OWN_ADDR_SUPPORTED 2 static const int npcm_i2caddr[I2C_NUM_OWN_ADDR] = { - NPCM_I2CADDR1, NPCM_I2CADDR2, + NPCM_I2CADDR1, NPCM_I2CADDR2, NPCM_I2CADDR3, NPCM_I2CADDR4, + NPCM_I2CADDR5, NPCM_I2CADDR6, NPCM_I2CADDR7, NPCM_I2CADDR8, + NPCM_I2CADDR9, NPCM_I2CADDR10, }; #endif diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c index 26622d24bb1b..541d808d62d0 100644 --- a/drivers/i2c/busses/i2c-nvidia-gpu.c +++ b/drivers/i2c/busses/i2c-nvidia-gpu.c @@ -16,7 +16,7 @@ #include <linux/pm_runtime.h> #include <linux/power_supply.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "i2c-ccgx-ucsi.h" @@ -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 4ad670a80a63..482b37c8a129 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -444,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, }; @@ -682,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 5b7b942141e7..16cc34a0526e 100644 --- a/drivers/i2c/busses/i2c-octeon-core.c +++ b/drivers/i2c/busses/i2c-octeon-core.c @@ -221,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: @@ -608,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 diff --git a/drivers/i2c/busses/i2c-octeon-core.h b/drivers/i2c/busses/i2c-octeon-core.h index 7af01864da75..b265e21189a1 100644 --- a/drivers/i2c/busses/i2c-octeon-core.h +++ b/drivers/i2c/busses/i2c-octeon-core.h @@ -39,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 */ 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 30a5ea282a8b..1d9ad25c89ae 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1261,7 +1261,7 @@ static const struct of_device_id omap_i2c_of_match[] = { .compatible = "ti,omap2420-i2c", .data = &omap2420_pdata, }, - { }, + { } }; MODULE_DEVICE_TABLE(of, omap_i2c_of_match); #endif @@ -1534,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); @@ -1560,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); @@ -1574,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 = { @@ -1586,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..febbd9950d8f 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> @@ -145,7 +146,7 @@ static const struct dmi_system_id piix4_dmi_ibm[] = { .ident = "IBM", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, }, - { }, + { } }; /* @@ -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 f448505d5468..1dafadda73af 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -721,7 +721,7 @@ static void i2c_pnx_remove(struct platform_device *pdev) #ifdef CONFIG_OF static const struct of_device_id i2c_pnx_of_match[] = { { .compatible = "nxp,pnx-i2c" }, - { }, + { } }; MODULE_DEVICE_TABLE(of, i2c_pnx_of_match); #endif 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..af2094720a4d 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> @@ -135,7 +135,7 @@ err_dev_add: static const struct pci_device_id ce4100_i2c_devices[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)}, - { }, + { } }; static struct pci_driver ce4100_i2c_driver = { diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index f495560bd99c..4d76e71cdd4b 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -218,7 +218,7 @@ static const struct platform_device_id i2c_pxa_id_table[] = { { "ce4100-i2c", REGS_CE4100 }, { "pxa910-i2c", REGS_PXA910 }, { "armada-3700-i2c", REGS_A3700 }, - { }, + { } }; MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table); @@ -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 0a8b95ce35f7..212336f724a6 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -721,7 +721,7 @@ static const struct i2c_algorithm geni_i2c_algo = { static const struct acpi_device_id geni_i2c_acpi_match[] = { { "QCOM0220"}, { "QCOM0411" }, - { }, + { } }; MODULE_DEVICE_TABLE(acpi, geni_i2c_acpi_match); #endif @@ -818,15 +818,13 @@ static int geni_i2c_probe(struct platform_device *pdev) init_completion(&gi2c->done); spin_lock_init(&gi2c->lock); platform_set_drvdata(pdev, gi2c); - ret = devm_request_irq(dev, gi2c->irq, geni_i2c_irq, 0, + ret = devm_request_irq(dev, gi2c->irq, geni_i2c_irq, IRQF_NO_AUTOEN, dev_name(dev), gi2c); if (ret) { dev_err(dev, "Request_irq failed:%d: err:%d\n", gi2c->irq, ret); return ret; } - /* Disable the interrupt so that the system can enter low-power mode */ - disable_irq(gi2c->irq); i2c_set_adapdata(&gi2c->adap, gi2c); gi2c->adap.dev.parent = dev; gi2c->adap.dev.of_node = dev->of_node; @@ -987,15 +985,23 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev) ret = clk_prepare_enable(gi2c->core_clk); if (ret) - return ret; + goto out_icc_disable; ret = geni_se_resources_on(&gi2c->se); if (ret) - return ret; + goto out_clk_disable; enable_irq(gi2c->irq); gi2c->suspended = 0; + return 0; + +out_clk_disable: + clk_disable_unprepare(gi2c->core_clk); +out_icc_disable: + geni_icc_disable(&gi2c->se); + + return ret; } static int __maybe_unused geni_i2c_suspend_noirq(struct device *dev) diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index c9b43a3c4bd3..d480162a4d39 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -1648,7 +1648,7 @@ static void qup_i2c_disable_clocks(struct qup_i2c_dev *qup) static const struct acpi_device_id qup_i2c_acpi_match[] = { { "QCOM8010"}, - { }, + { } }; MODULE_DEVICE_TABLE(acpi, qup_i2c_acpi_match); @@ -1985,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 185a5d60f101..9267df38c2d0 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 */ @@ -553,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) @@ -1165,11 +1164,6 @@ static int rcar_i2c_probe(struct platform_device *pdev) rcar_i2c_init(priv); rcar_i2c_reset_slave(priv); - if (priv->devtype < I2C_RCAR_GEN3) { - irqflags |= IRQF_NO_THREAD; - irqhandler = rcar_i2c_gen2_irq; - } - /* Stay always active when multi-master to keep arbitration working */ if (of_property_read_bool(dev->of_node, "multi-master")) priv->flags |= ID_P_PM_BLOCKED; @@ -1179,8 +1173,11 @@ 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) { + if (priv->devtype < I2C_RCAR_GEN3) { + irqflags |= IRQF_NO_THREAD; + irqhandler = rcar_i2c_gen2_irq; + } else { + /* R-Car Gen3+ needs a reset before every transfer */ priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(priv->rstc)) { ret = PTR_ERR(priv->rstc); diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c index f608b1838cad..c7f3a4c02470 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 @@ -63,6 +63,8 @@ #define ICMR3_ACKWP 0x10 #define ICMR3_ACKBT 0x08 +#define ICFER_FMPE 0x80 + #define ICIER_TIE 0x80 #define ICIER_TEIE 0x40 #define ICIER_RIE 0x20 @@ -80,6 +82,7 @@ enum riic_reg_list { RIIC_ICCR2, RIIC_ICMR1, RIIC_ICMR3, + RIIC_ICFER, RIIC_ICSER, RIIC_ICIER, RIIC_ICSR2, @@ -91,7 +94,8 @@ enum riic_reg_list { }; struct riic_of_data { - u8 regs[RIIC_REG_END]; + const u8 *regs; + bool fast_mode_plus; }; struct riic_dev { @@ -105,6 +109,8 @@ struct riic_dev { struct completion msg_done; struct i2c_adapter adapter; struct clk *clk; + struct reset_control *rstc; + struct i2c_timings i2c_t; }; struct riic_irq_desc { @@ -131,11 +137,14 @@ static inline void riic_clear_set_bit(struct riic_dev *riic, u8 clear, u8 set, u static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct riic_dev *riic = i2c_get_adapdata(adap); + struct device *dev = adap->dev.parent; unsigned long time_left; - int i; + int i, ret; u8 start_bit; - pm_runtime_get_sync(adap->dev.parent); + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; if (riic_readb(riic, RIIC_ICCR2) & ICCR2_BBSY) { riic->err = -EBUSY; @@ -168,7 +177,8 @@ static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) } out: - pm_runtime_put(adap->dev.parent); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); return riic->err ?: num; } @@ -294,25 +304,25 @@ 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) +static int riic_init_hw(struct riic_dev *riic) { - int ret = 0; + int ret; unsigned long rate; int total_ticks, cks, brl, brh; + struct i2c_timings *t = &riic->i2c_t; + struct device *dev = riic->adapter.dev.parent; + bool fast_mode_plus = riic->info->fast_mode_plus; + u32 max_freq = fast_mode_plus ? I2C_MAX_FAST_MODE_PLUS_FREQ + : I2C_MAX_FAST_MODE_FREQ; - pm_runtime_get_sync(riic->adapter.dev.parent); - - if (t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ) { - dev_err(&riic->adapter.dev, - "unsupported bus speed (%dHz). %d max\n", - t->bus_freq_hz, I2C_MAX_FAST_MODE_FREQ); - ret = -EINVAL; - goto out; - } + if (t->bus_freq_hz > max_freq) + return dev_err_probe(&riic->adapter.dev, -EINVAL, + "unsupported bus speed %uHz (%u max)\n", + t->bus_freq_hz, max_freq); rate = clk_get_rate(riic->clk); @@ -349,8 +359,7 @@ static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t) if (brl > (0x1F + 3)) { dev_err(&riic->adapter.dev, "invalid speed (%lu). Too slow.\n", (unsigned long)t->bus_freq_hz); - ret = -EINVAL; - goto out; + return -EINVAL; } brh = total_ticks - brl; @@ -382,6 +391,10 @@ static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t) t->scl_fall_ns / (1000000000 / rate), t->scl_rise_ns / (1000000000 / rate), cks, brl, brh); + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; + /* Changing the order of accessing IICRST and ICE may break things! */ riic_writeb(riic, ICCR1_IICRST | ICCR1_SOWP, RIIC_ICCR1); riic_clear_set_bit(riic, 0, ICCR1_ICE, RIIC_ICCR1); @@ -393,11 +406,14 @@ static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t) riic_writeb(riic, 0, RIIC_ICSER); riic_writeb(riic, ICMR3_ACKWP | ICMR3_RDRFS, RIIC_ICMR3); + if (fast_mode_plus && t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ) + riic_clear_set_bit(riic, 0, ICFER_FMPE, RIIC_ICFER); + riic_clear_set_bit(riic, ICCR1_IICRST, 0, RIIC_ICCR1); -out: - pm_runtime_put(riic->adapter.dev.parent); - return ret; + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return 0; } static struct riic_irq_desc riic_irqs[] = { @@ -415,13 +431,12 @@ static void riic_reset_control_assert(void *data) static int riic_i2c_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct riic_dev *riic; struct i2c_adapter *adap; - struct i2c_timings i2c_t; - struct reset_control *rstc; int i, ret; - riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL); + riic = devm_kzalloc(dev, sizeof(*riic), GFP_KERNEL); if (!riic) return -ENOMEM; @@ -429,22 +444,22 @@ static int riic_i2c_probe(struct platform_device *pdev) if (IS_ERR(riic->base)) return PTR_ERR(riic->base); - riic->clk = devm_clk_get(&pdev->dev, NULL); + riic->clk = devm_clk_get(dev, NULL); if (IS_ERR(riic->clk)) { - dev_err(&pdev->dev, "missing controller clock"); + dev_err(dev, "missing controller clock"); return PTR_ERR(riic->clk); } - rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); - if (IS_ERR(rstc)) - return dev_err_probe(&pdev->dev, PTR_ERR(rstc), + riic->rstc = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(riic->rstc)) + return dev_err_probe(dev, PTR_ERR(riic->rstc), "Error: missing reset ctrl\n"); - ret = reset_control_deassert(rstc); + ret = reset_control_deassert(riic->rstc); if (ret) return ret; - ret = devm_add_action_or_reset(&pdev->dev, riic_reset_control_assert, rstc); + ret = devm_add_action_or_reset(dev, riic_reset_control_assert, riic->rstc); if (ret) return ret; @@ -453,31 +468,34 @@ static int riic_i2c_probe(struct platform_device *pdev) if (ret < 0) return ret; - ret = devm_request_irq(&pdev->dev, ret, riic_irqs[i].isr, + ret = devm_request_irq(dev, ret, riic_irqs[i].isr, 0, riic_irqs[i].name, riic); if (ret) { - dev_err(&pdev->dev, "failed to request irq %s\n", riic_irqs[i].name); + dev_err(dev, "failed to request irq %s\n", riic_irqs[i].name); return ret; } } - riic->info = of_device_get_match_data(&pdev->dev); + riic->info = of_device_get_match_data(dev); adap = &riic->adapter; i2c_set_adapdata(adap, riic); strscpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name)); adap->owner = THIS_MODULE; adap->algo = &riic_algo; - adap->dev.parent = &pdev->dev; - adap->dev.of_node = pdev->dev.of_node; + adap->dev.parent = dev; + adap->dev.of_node = dev->of_node; init_completion(&riic->msg_done); - i2c_parse_fw_timings(&pdev->dev, &i2c_t, true); + i2c_parse_fw_timings(dev, &riic->i2c_t, true); - pm_runtime_enable(&pdev->dev); + /* Default 0 to save power. Can be overridden via sysfs for lower latency. */ + pm_runtime_set_autosuspend_delay(dev, 0); + pm_runtime_use_autosuspend(dev); + pm_runtime_enable(dev); - ret = riic_init_hw(riic, &i2c_t); + ret = riic_init_hw(riic); if (ret) goto out; @@ -487,60 +505,127 @@ static int riic_i2c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, riic); - dev_info(&pdev->dev, "registered with %dHz bus speed\n", - i2c_t.bus_freq_hz); + dev_info(dev, "registered with %dHz bus speed\n", riic->i2c_t.bus_freq_hz); return 0; out: - pm_runtime_disable(&pdev->dev); + pm_runtime_disable(dev); + pm_runtime_dont_use_autosuspend(dev); return ret; } static void riic_i2c_remove(struct platform_device *pdev) { struct riic_dev *riic = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + int ret; - pm_runtime_get_sync(&pdev->dev); - riic_writeb(riic, 0, RIIC_ICIER); - pm_runtime_put(&pdev->dev); + ret = pm_runtime_resume_and_get(dev); + if (!ret) { + riic_writeb(riic, 0, RIIC_ICIER); + pm_runtime_put(dev); + } i2c_del_adapter(&riic->adapter); - pm_runtime_disable(&pdev->dev); + pm_runtime_disable(dev); + pm_runtime_dont_use_autosuspend(dev); } +static const u8 riic_rz_a_regs[RIIC_REG_END] = { + [RIIC_ICCR1] = 0x00, + [RIIC_ICCR2] = 0x04, + [RIIC_ICMR1] = 0x08, + [RIIC_ICMR3] = 0x10, + [RIIC_ICFER] = 0x14, + [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_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, - }, + .regs = riic_rz_a_regs, + .fast_mode_plus = true, +}; + +static const struct riic_of_data riic_rz_a1h_info = { + .regs = riic_rz_a_regs, +}; + +static const u8 riic_rz_v2h_regs[RIIC_REG_END] = { + [RIIC_ICCR1] = 0x00, + [RIIC_ICCR2] = 0x01, + [RIIC_ICMR1] = 0x02, + [RIIC_ICMR3] = 0x04, + [RIIC_ICFER] = 0x05, + [RIIC_ICSER] = 0x06, + [RIIC_ICIER] = 0x07, + [RIIC_ICSR2] = 0x09, + [RIIC_ICBRL] = 0x10, + [RIIC_ICBRH] = 0x11, + [RIIC_ICDRT] = 0x12, + [RIIC_ICDRR] = 0x13, }; 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, - }, + .regs = riic_rz_v2h_regs, + .fast_mode_plus = true, +}; + +static int riic_i2c_suspend(struct device *dev) +{ + struct riic_dev *riic = dev_get_drvdata(dev); + int ret; + + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; + + i2c_mark_adapter_suspended(&riic->adapter); + + /* Disable output on SDA, SCL pins. */ + riic_clear_set_bit(riic, ICCR1_ICE, 0, RIIC_ICCR1); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_sync(dev); + + return reset_control_assert(riic->rstc); +} + +static int riic_i2c_resume(struct device *dev) +{ + struct riic_dev *riic = dev_get_drvdata(dev); + int ret; + + ret = reset_control_deassert(riic->rstc); + if (ret) + return ret; + + ret = riic_init_hw(riic); + if (ret) { + /* + * In case this happens there is no way to recover from this + * state. The driver will remain loaded. We want to avoid + * keeping the reset line de-asserted for no reason. + */ + reset_control_assert(riic->rstc); + return ret; + } + + i2c_mark_adapter_resumed(&riic->adapter); + + return 0; +} + +static const struct dev_pm_ops riic_i2c_pm_ops = { + SYSTEM_SLEEP_PM_OPS(riic_i2c_suspend, riic_i2c_resume) }; static const struct of_device_id riic_i2c_dt_ids[] = { { .compatible = "renesas,riic-rz", .data = &riic_rz_a_info }, + { .compatible = "renesas,riic-r7s72100", .data = &riic_rz_a1h_info, }, { .compatible = "renesas,riic-r9a09g057", .data = &riic_rz_v2h_info }, { /* Sentinel */ }, }; @@ -551,6 +636,7 @@ static struct platform_driver riic_i2c_driver = { .driver = { .name = "i2c-riic", .of_match_table = riic_i2c_dt_ids, + .pm = pm_ptr(&riic_i2c_pm_ops), }, }; diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c index beca61700c89..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; @@ -1160,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 01419c738cfc..7698d9d59744 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -130,7 +130,7 @@ static const struct platform_device_id s3c24xx_driver_ids[] = { }, { .name = "s3c2440-hdmiphy-i2c", .driver_data = QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO, - }, { }, + }, { } }; MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids); 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 5e01fe3dbb63..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 @@ -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 */ @@ -766,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 f8b12be6ef55..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)) { @@ -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 cfee2d9c09de..0174ead99de6 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -2395,7 +2395,7 @@ static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev) struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); if (!stm32f7_i2c_is_slave_registered(i2c_dev)) - clk_disable_unprepare(i2c_dev->clk); + clk_disable(i2c_dev->clk); return 0; } @@ -2406,9 +2406,9 @@ static int __maybe_unused stm32f7_i2c_runtime_resume(struct device *dev) int ret; if (!stm32f7_i2c_is_slave_registered(i2c_dev)) { - ret = clk_prepare_enable(i2c_dev->clk); + ret = clk_enable(i2c_dev->clk); if (ret) { - dev_err(dev, "failed to prepare_enable clock\n"); + dev_err(dev, "failed to enable clock\n"); return ret; } } 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 4eccbcd0fbfc..bbb9062669e4 100644 --- a/drivers/i2c/busses/i2c-synquacer.c +++ b/drivers/i2c/busses/i2c-synquacer.c @@ -550,12 +550,13 @@ static int synquacer_i2c_probe(struct platform_device *pdev) device_property_read_u32(&pdev->dev, "socionext,pclk-rate", &i2c->pclkrate); - pclk = devm_clk_get_enabled(&pdev->dev, "pclk"); + pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk"); if (IS_ERR(pclk)) return dev_err_probe(&pdev->dev, PTR_ERR(pclk), "failed to get and enable clock\n"); - i2c->pclkrate = clk_get_rate(pclk); + if (pclk) + i2c->pclkrate = clk_get_rate(pclk); if (i2c->pclkrate < SYNQUACER_I2C_MIN_CLK_RATE || i2c->pclkrate > SYNQUACER_I2C_MAX_CLK_RATE) 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 85b31edc558d..1df5b4204142 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -1802,9 +1802,9 @@ static int tegra_i2c_probe(struct platform_device *pdev) * domain. * * VI I2C device shouldn't be marked as IRQ-safe because VI I2C won't - * be used for atomic transfers. + * be used for atomic transfers. ACPI device is not IRQ safe also. */ - if (!IS_VI(i2c_dev)) + if (!IS_VI(i2c_dev) && !has_acpi_companion(i2c_dev->dev)) pm_runtime_irq_safe(i2c_dev->dev); pm_runtime_enable(i2c_dev->dev); diff --git a/drivers/i2c/busses/i2c-thunderx-pcidrv.c b/drivers/i2c/busses/i2c-thunderx-pcidrv.c index 32d0e3930b67..143d012fa43e 100644 --- a/drivers/i2c/busses/i2c-thunderx-pcidrv.c +++ b/drivers/i2c/busses/i2c-thunderx-pcidrv.c @@ -72,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, }; 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 6c3dac2cf568..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. */ @@ -403,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; @@ -418,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; @@ -434,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 e1b4c80e0285..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 */ @@ -152,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; @@ -211,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; @@ -225,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; } @@ -239,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 index 162b31306cba..5a53ed95a59b 100644 --- a/drivers/i2c/busses/i2c-viai2c-common.c +++ b/drivers/i2c/busses/i2c-viai2c-common.c @@ -198,6 +198,6 @@ int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat) } EXPORT_SYMBOL_GPL(viai2c_init); -MODULE_DESCRIPTION("Via/Wondermedia/Zhaoxin I2C master-mode bus adapter"); +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-wmt.c b/drivers/i2c/busses/i2c-viai2c-wmt.c index 420fd10fe3aa..3415683dab91 100644 --- a/drivers/i2c/busses/i2c-viai2c-wmt.c +++ b/drivers/i2c/busses/i2c-viai2c-wmt.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * Wondermedia I2C Master Mode Driver + * Wondermedia I2C Controller Driver * * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> * @@ -35,8 +35,8 @@ static u32 wmt_i2c_func(struct i2c_adapter *adap) } static const struct i2c_algorithm wmt_i2c_algo = { - .master_xfer = viai2c_xfer, - .functionality = wmt_i2c_func, + .xfer = viai2c_xfer, + .functionality = wmt_i2c_func, }; static int wmt_i2c_reset_hardware(struct viai2c *i2c) @@ -178,7 +178,7 @@ static struct platform_driver wmt_i2c_driver = { module_platform_driver(wmt_i2c_driver); -MODULE_DESCRIPTION("Wondermedia I2C master-mode bus adapter"); +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 index ab3e44e147e9..95dc64902b7c 100644 --- a/drivers/i2c/busses/i2c-viai2c-zhaoxin.c +++ b/drivers/i2c/busses/i2c-viai2c-zhaoxin.c @@ -38,7 +38,7 @@ #define ZXI2C_GOLD_FSTP_400K 0x38 #define ZXI2C_GOLD_FSTP_1M 0x13 #define ZXI2C_GOLD_FSTP_3400K 0x37 -#define ZXI2C_HS_MASTER_CODE (0x08 << 8) +#define ZXI2C_HS_CTRL_CODE (0x08 << 8) #define ZXI2C_FIFO_SIZE 32 @@ -136,7 +136,7 @@ static int viai2c_fifo_irq_xfer(struct viai2c *i2c) return 0; } -static int zxi2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +static int zxi2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { u8 tmp; int ret; @@ -194,8 +194,8 @@ static u32 zxi2c_func(struct i2c_adapter *adap) } static const struct i2c_algorithm zxi2c_algorithm = { - .master_xfer = zxi2c_master_xfer, - .functionality = zxi2c_func, + .xfer = zxi2c_xfer, + .functionality = zxi2c_func, }; static const struct i2c_adapter_quirks zxi2c_quirks = { @@ -250,9 +250,9 @@ static void zxi2c_get_bus_speed(struct viai2c *i2c) i2c->tcr = params[1]; priv->mcr = ioread16(i2c->base + VIAI2C_REG_MCR); - /* for Hs-mode, use 0x80 as master code */ + /* for Hs-mode, use 0x80 as controller code */ if (params[0] == I2C_MAX_HIGH_SPEED_MODE_FREQ) - priv->mcr |= ZXI2C_HS_MASTER_CODE; + priv->mcr |= ZXI2C_HS_CTRL_CODE; dev_info(i2c->dev, "speed mode is %s\n", i2c_freq_mode_string(params[0])); } diff --git a/drivers/i2c/busses/i2c-viperboard.c b/drivers/i2c/busses/i2c-viperboard.c index 3784b07f5371..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 = { @@ -460,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..2a351f961b89 100644 --- a/drivers/i2c/busses/i2c-virtio.c +++ b/drivers/i2c/busses/i2c-virtio.c @@ -182,8 +182,8 @@ static u32 virtio_i2c_func(struct i2c_adapter *adap) return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } -static struct i2c_algorithm virtio_algorithm = { - .master_xfer = virtio_i2c_xfer, +static const struct i2c_algorithm virtio_algorithm = { + .xfer = virtio_i2c_xfer, .functionality = virtio_i2c_func, }; @@ -237,7 +237,7 @@ static void virtio_i2c_remove(struct virtio_device *vdev) virtio_i2c_del_vqs(vdev); } -static struct virtio_device_id id_table[] = { +static const struct virtio_device_id id_table[] = { { VIRTIO_ID_I2C_ADAPTER, VIRTIO_DEV_ANY_ID }, {} }; diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 71391b590ada..1d68177241a6 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -772,14 +772,17 @@ static irqreturn_t xiic_process(int irq, void *dev_id) goto out; } - xiic_fill_tx_fifo(i2c); - - /* current message sent and there is space in the fifo */ - if (!xiic_tx_space(i2c) && xiic_tx_fifo_space(i2c) >= 2) { + if (xiic_tx_space(i2c)) { + xiic_fill_tx_fifo(i2c); + } else { + /* current message fully written */ dev_dbg(i2c->adap.dev.parent, "%s end of message sent, nmsgs: %d\n", __func__, i2c->nmsgs); - if (i2c->nmsgs > 1) { + /* Don't move onto the next message until the TX FIFO empties, + * to ensure that a NAK is not missed. + */ + if (i2c->nmsgs > 1 && (pend & XIIC_INTR_TX_EMPTY_MASK)) { i2c->nmsgs--; i2c->tx_msg++; xfer_more = 1; @@ -790,11 +793,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) "%s Got TX IRQ but no more to do...\n", __func__); } - } else if (!xiic_tx_space(i2c) && (i2c->nmsgs == 1)) - /* current frame is sent and is last, - * make sure to disable tx half - */ - xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK); + } } if (pend & XIIC_INTR_BNB_MASK) { @@ -844,23 +843,11 @@ static int xiic_bus_busy(struct xiic_i2c *i2c) return (sr & XIIC_SR_BUS_BUSY_MASK) ? -EBUSY : 0; } -static int xiic_busy(struct xiic_i2c *i2c) +static int xiic_wait_not_busy(struct xiic_i2c *i2c) { int tries = 3; int err; - if (i2c->tx_msg || i2c->rx_msg) - return -EBUSY; - - /* In single master mode bus can only be busy, when in use by this - * driver. If the register indicates bus being busy for some reason we - * should ignore it, since bus will never be released and i2c will be - * stuck forever. - */ - if (i2c->singlemaster) { - return 0; - } - /* for instance if previous transfer was terminated due to TX error * it might be that the bus is on it's way to become available * give it at most 3 ms to wake @@ -1104,9 +1091,35 @@ 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 (i2c->tx_msg || i2c->rx_msg) { + dev_err(i2c->adap.dev.parent, + "cannot start a transfer while busy\n"); + ret = -EBUSY; goto out; + } + + /* In single master mode bus can only be busy, when in use by this + * driver. If the register indicates bus being busy for some reason we + * should ignore it, since bus will never be released and i2c will be + * stuck forever. + */ + if (!i2c->singlemaster) { + ret = xiic_wait_not_busy(i2c); + if (ret) { + /* If the bus is stuck in a busy state, such as due to spurious low + * pulses on the bus causing a false start condition to be detected, + * then try to recover by re-initializing the controller and check + * again if the bus is still busy. + */ + dev_warn(i2c->adap.dev.parent, "I2C bus busy timeout, reinitializing\n"); + ret = xiic_reinit(i2c); + if (ret) + goto out; + ret = xiic_wait_not_busy(i2c); + if (ret) + goto out; + } + } i2c->tx_msg = msgs; i2c->rx_msg = NULL; @@ -1164,10 +1177,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); @@ -1326,8 +1337,8 @@ static int xiic_i2c_probe(struct platform_device *pdev) return 0; err_pm_disable: - pm_runtime_set_suspended(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); return ret; } diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 7e7b15440832..7c810893bfa3 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -136,10 +136,10 @@ const void *i2c_get_match_data(const struct i2c_client *client) } EXPORT_SYMBOL(i2c_get_match_data); -static int i2c_device_match(struct device *dev, struct device_driver *drv) +static int i2c_device_match(struct device *dev, const struct device_driver *drv) { struct i2c_client *client = i2c_verify_client(dev); - struct i2c_driver *driver; + const struct i2c_driver *driver; /* Attempt an OF style match */ @@ -915,6 +915,27 @@ int i2c_dev_irq_from_resources(const struct resource *resources, return 0; } +/* + * Serialize device instantiation in case it can be instantiated explicitly + * and by auto-detection + */ +static int i2c_lock_addr(struct i2c_adapter *adap, unsigned short addr, + unsigned short flags) +{ + if (!(flags & I2C_CLIENT_TEN) && + test_and_set_bit(addr, adap->addrs_in_instantiation)) + return -EBUSY; + + return 0; +} + +static void i2c_unlock_addr(struct i2c_adapter *adap, unsigned short addr, + unsigned short flags) +{ + if (!(flags & I2C_CLIENT_TEN)) + clear_bit(addr, adap->addrs_in_instantiation); +} + /** * i2c_new_client_device - instantiate an i2c device * @adap: the adapter managing the device @@ -962,6 +983,10 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf goto out_err_silent; } + status = i2c_lock_addr(adap, client->addr, client->flags); + if (status) + goto out_err_silent; + /* Check for address business */ status = i2c_check_addr_busy(adap, i2c_encode_flags_to_addr(client)); if (status) @@ -993,6 +1018,8 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n", client->name, dev_name(&client->dev)); + i2c_unlock_addr(adap, client->addr, client->flags); + return client; out_remove_swnode: @@ -1004,6 +1031,7 @@ out_err: dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x (%d)\n", client->name, client->addr, status); + i2c_unlock_addr(adap, client->addr, client->flags); out_err_silent: if (need_put) put_device(&client->dev); @@ -1066,9 +1094,9 @@ EXPORT_SYMBOL(i2c_find_device_by_fwnode); static const struct i2c_device_id dummy_id[] = { - { "dummy", 0 }, - { "smbus_host_notify", 0 }, - { }, + { "dummy", }, + { "smbus_host_notify", }, + { } }; static int dummy_probe(struct i2c_client *client) @@ -1367,10 +1395,6 @@ struct i2c_adapter *i2c_verify_adapter(struct device *dev) } EXPORT_SYMBOL(i2c_verify_adapter); -#ifdef CONFIG_I2C_COMPAT -static struct class_compat *i2c_adapter_compat_class; -#endif - static void i2c_scan_static_board_info(struct i2c_adapter *adapter) { struct i2c_devinfo *devinfo; @@ -1469,6 +1493,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; @@ -1522,7 +1548,18 @@ static int i2c_register_adapter(struct i2c_adapter *adap) dev_set_name(&adap->dev, "i2c-%d", adap->nr); adap->dev.bus = &i2c_bus_type; adap->dev.type = &i2c_adapter_type; - res = device_register(&adap->dev); + device_initialize(&adap->dev); + + /* + * This adapter can be used as a parent immediately after device_add(), + * setup runtime-pm (especially ignore-children) before hand. + */ + device_enable_async_suspend(&adap->dev); + pm_runtime_no_callbacks(&adap->dev); + pm_suspend_ignore_children(&adap->dev, true); + pm_runtime_enable(&adap->dev); + + res = device_add(&adap->dev); if (res) { pr_err("adapter '%s': can't register device (%d)\n", adap->name, res); goto out_list; @@ -1534,25 +1571,12 @@ static int i2c_register_adapter(struct i2c_adapter *adap) if (res) goto out_reg; - device_enable_async_suspend(&adap->dev); - pm_runtime_no_callbacks(&adap->dev); - pm_suspend_ignore_children(&adap->dev, true); - pm_runtime_enable(&adap->dev); - res = i2c_init_recovery(adap); if (res == -EPROBE_DEFER) goto out_reg; dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); -#ifdef CONFIG_I2C_COMPAT - res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev, - adap->dev.parent); - if (res) - dev_warn(&adap->dev, - "Failed to create compatibility class link\n"); -#endif - /* create pre-declared device nodes */ of_i2c_register_devices(adap); i2c_acpi_install_space_handler(adap); @@ -1759,11 +1783,6 @@ void i2c_del_adapter(struct i2c_adapter *adap) device_for_each_child(&adap->dev, NULL, __unregister_client); device_for_each_child(&adap->dev, NULL, __unregister_dummy); -#ifdef CONFIG_I2C_COMPAT - class_compat_remove_link(i2c_adapter_compat_class, &adap->dev, - adap->dev.parent); -#endif - /* device name is gone after device_unregister */ dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); @@ -2072,13 +2091,6 @@ static int __init i2c_init(void) i2c_debugfs_root = debugfs_create_dir("i2c", NULL); -#ifdef CONFIG_I2C_COMPAT - i2c_adapter_compat_class = class_compat_register("i2c-adapter"); - if (!i2c_adapter_compat_class) { - retval = -ENOMEM; - goto bus_err; - } -#endif retval = i2c_add_driver(&dummy_driver); if (retval) goto class_err; @@ -2091,10 +2103,6 @@ static int __init i2c_init(void) return 0; class_err: -#ifdef CONFIG_I2C_COMPAT - class_compat_unregister(i2c_adapter_compat_class); -bus_err: -#endif is_registered = false; bus_unregister(&i2c_bus_type); return retval; @@ -2107,9 +2115,6 @@ static void __exit i2c_exit(void) if (IS_ENABLED(CONFIG_OF_DYNAMIC)) WARN_ON(of_reconfig_notifier_unregister(&i2c_of_notifier)); i2c_del_driver(&dummy_driver); -#ifdef CONFIG_I2C_COMPAT - class_compat_unregister(i2c_adapter_compat_class); -#endif debugfs_remove_recursive(i2c_debugfs_root); bus_unregister(&i2c_bus_type); tracepoint_synchronize_unregister(); diff --git a/drivers/i2c/i2c-core-slave.c b/drivers/i2c/i2c-core-slave.c index e3765e12f93b..faefe1dfa8e5 100644 --- a/drivers/i2c/i2c-core-slave.c +++ b/drivers/i2c/i2c-core-slave.c @@ -109,15 +109,12 @@ EXPORT_SYMBOL_GPL(i2c_slave_event); bool i2c_detect_slave_mode(struct device *dev) { if (IS_BUILTIN(CONFIG_OF) && dev->of_node) { - struct device_node *child; u32 reg; - for_each_child_of_node(dev->of_node, child) { + for_each_child_of_node_scoped(dev->of_node, child) { of_property_read_u32(child, "reg", ®); - if (reg & I2C_OWN_SLAVE_ADDRESS) { - of_node_put(child); + if (reg & I2C_OWN_SLAVE_ADDRESS) return true; - } } } else if (IS_BUILTIN(CONFIG_ACPI) && ACPI_HANDLE(dev)) { dev_dbg(dev, "ACPI slave is not supported yet\n"); diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 8b7e599f1674..61f7c4003d2f 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); @@ -625,7 +637,6 @@ static int i2cdev_release(struct inode *inode, struct file *file) static const struct file_operations i2cdev_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = i2cdev_read, .write = i2cdev_write, .unlocked_ioctl = i2cdev_ioctl, diff --git a/drivers/i2c/i2c-slave-testunit.c b/drivers/i2c/i2c-slave-testunit.c index 23a11e4e9256..9fe3150378e8 100644 --- a/drivers/i2c/i2c-slave-testunit.c +++ b/drivers/i2c/i2c-slave-testunit.c @@ -6,7 +6,10 @@ * Copyright (C) 2020 by Renesas Electronics Corporation */ +#include <generated/utsrelease.h> #include <linux/bitops.h> +#include <linux/completion.h> +#include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/init.h> #include <linux/module.h> @@ -14,12 +17,14 @@ #include <linux/slab.h> #include <linux/workqueue.h> /* FIXME: is system_long_wq the best choice? */ -#define TU_CUR_VERSION 0x01 +#define TU_VERSION_MAX_LENGTH 128 enum testunit_cmds { TU_CMD_READ_BYTES = 1, /* save 0 for ABORT, RESET or similar */ - TU_CMD_HOST_NOTIFY, + TU_CMD_SMBUS_HOST_NOTIFY, TU_CMD_SMBUS_BLOCK_PROC_CALL, + TU_CMD_GET_VERSION_WITH_REP_START, + TU_CMD_SMBUS_ALERT_REQUEST, TU_NUM_CMDS }; @@ -39,50 +44,38 @@ struct testunit_data { unsigned long flags; u8 regs[TU_NUM_REGS]; u8 reg_idx; + u8 read_idx; struct i2c_client *client; struct delayed_work worker; + struct gpio_desc *gpio; + struct completion alert_done; }; -static void i2c_slave_testunit_work(struct work_struct *work) -{ - struct testunit_data *tu = container_of(work, struct testunit_data, worker.work); - struct i2c_msg msg; - u8 msgbuf[256]; - int ret = 0; +static char tu_version_info[] = "v" UTS_RELEASE "\n\0"; - msg.addr = I2C_CLIENT_END; - msg.buf = msgbuf; - - switch (tu->regs[TU_REG_CMD]) { - case TU_CMD_READ_BYTES: - msg.addr = tu->regs[TU_REG_DATAL]; - msg.flags = I2C_M_RD; - msg.len = tu->regs[TU_REG_DATAH]; - break; +static int i2c_slave_testunit_smbalert_cb(struct i2c_client *client, + enum i2c_slave_event event, u8 *val) +{ + struct testunit_data *tu = i2c_get_clientdata(client); - case TU_CMD_HOST_NOTIFY: - msg.addr = 0x08; - msg.flags = 0; - msg.len = 3; - msgbuf[0] = tu->client->addr; - msgbuf[1] = tu->regs[TU_REG_DATAL]; - msgbuf[2] = tu->regs[TU_REG_DATAH]; + switch (event) { + case I2C_SLAVE_READ_PROCESSED: + gpiod_set_value(tu->gpio, 0); + fallthrough; + case I2C_SLAVE_READ_REQUESTED: + *val = tu->regs[TU_REG_DATAL]; break; - default: + case I2C_SLAVE_STOP: + complete(&tu->alert_done); break; - } - if (msg.addr != I2C_CLIENT_END) { - ret = i2c_transfer(tu->client->adapter, &msg, 1); - /* convert '0 msgs transferred' to errno */ - ret = (ret == 0) ? -EIO : ret; + case I2C_SLAVE_WRITE_REQUESTED: + case I2C_SLAVE_WRITE_RECEIVED: + return -EOPNOTSUPP; } - if (ret < 0) - dev_err(&tu->client->dev, "CMD%02X failed (%d)\n", tu->regs[TU_REG_CMD], ret); - - clear_bit(TU_FLAG_IN_PROCESS, &tu->flags); + return 0; } static int i2c_slave_testunit_slave_cb(struct i2c_client *client, @@ -91,9 +84,20 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client, struct testunit_data *tu = i2c_get_clientdata(client); bool is_proc_call = tu->reg_idx == 3 && tu->regs[TU_REG_DATAL] == 1 && tu->regs[TU_REG_CMD] == TU_CMD_SMBUS_BLOCK_PROC_CALL; + bool is_get_version = tu->reg_idx == 3 && + tu->regs[TU_REG_CMD] == TU_CMD_GET_VERSION_WITH_REP_START; int ret = 0; switch (event) { + 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; + tu->read_idx = 0; + break; + case I2C_SLAVE_WRITE_RECEIVED: if (test_bit(TU_FLAG_IN_PROCESS, &tu->flags)) return -EBUSY; @@ -127,27 +131,93 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client, 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; - case I2C_SLAVE_READ_PROCESSED: - if (is_proc_call && tu->regs[TU_REG_DATAH]) + /* Advance until we reach the NUL character */ + if (is_get_version && tu_version_info[tu->read_idx] != 0) + tu->read_idx++; + else if (is_proc_call && tu->regs[TU_REG_DATAH]) tu->regs[TU_REG_DATAH]--; + fallthrough; case I2C_SLAVE_READ_REQUESTED: - *val = is_proc_call ? tu->regs[TU_REG_DATAH] : TU_CUR_VERSION; + if (is_get_version) + *val = tu_version_info[tu->read_idx]; + else if (is_proc_call) + *val = tu->regs[TU_REG_DATAH]; + else + *val = test_bit(TU_FLAG_IN_PROCESS, &tu->flags) ? + tu->regs[TU_REG_CMD] : 0; break; } return ret; } +static void i2c_slave_testunit_work(struct work_struct *work) +{ + struct testunit_data *tu = container_of(work, struct testunit_data, worker.work); + unsigned long time_left; + struct i2c_msg msg; + u8 msgbuf[256]; + u16 orig_addr; + int ret = 0; + + msg.addr = I2C_CLIENT_END; + msg.buf = msgbuf; + + switch (tu->regs[TU_REG_CMD]) { + case TU_CMD_READ_BYTES: + msg.addr = tu->regs[TU_REG_DATAL]; + msg.flags = I2C_M_RD; + msg.len = tu->regs[TU_REG_DATAH]; + break; + + case TU_CMD_SMBUS_HOST_NOTIFY: + msg.addr = 0x08; + msg.flags = 0; + msg.len = 3; + msgbuf[0] = tu->client->addr; + msgbuf[1] = tu->regs[TU_REG_DATAL]; + msgbuf[2] = tu->regs[TU_REG_DATAH]; + break; + + case TU_CMD_SMBUS_ALERT_REQUEST: + i2c_slave_unregister(tu->client); + orig_addr = tu->client->addr; + tu->client->addr = 0x0c; + ret = i2c_slave_register(tu->client, i2c_slave_testunit_smbalert_cb); + if (ret) + goto out_smbalert; + + reinit_completion(&tu->alert_done); + gpiod_set_value(tu->gpio, 1); + time_left = wait_for_completion_timeout(&tu->alert_done, HZ); + if (!time_left) + ret = -ETIMEDOUT; + + i2c_slave_unregister(tu->client); +out_smbalert: + tu->client->addr = orig_addr; + i2c_slave_register(tu->client, i2c_slave_testunit_slave_cb); + break; + + default: + break; + } + + if (msg.addr != I2C_CLIENT_END) { + ret = i2c_transfer(tu->client->adapter, &msg, 1); + /* convert '0 msgs transferred' to errno */ + ret = (ret == 0) ? -EIO : ret; + } + + if (ret < 0) + dev_err(&tu->client->dev, "CMD%02X failed (%d)\n", tu->regs[TU_REG_CMD], ret); + + clear_bit(TU_FLAG_IN_PROCESS, &tu->flags); +} + static int i2c_slave_testunit_probe(struct i2c_client *client) { struct testunit_data *tu; @@ -158,8 +228,18 @@ static int i2c_slave_testunit_probe(struct i2c_client *client) tu->client = client; i2c_set_clientdata(client, tu); + init_completion(&tu->alert_done); INIT_DELAYED_WORK(&tu->worker, i2c_slave_testunit_work); + tu->gpio = devm_gpiod_get_index_optional(&client->dev, NULL, 0, GPIOD_OUT_LOW); + if (gpiod_cansleep(tu->gpio)) { + dev_err(&client->dev, "GPIO access which may sleep is not allowed\n"); + return -EDEADLK; + } + + if (sizeof(tu_version_info) > TU_VERSION_MAX_LENGTH) + tu_version_info[TU_VERSION_MAX_LENGTH - 1] = 0; + return i2c_slave_register(client, i2c_slave_testunit_slave_cb); }; @@ -172,7 +252,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..8256f7aed0cf 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -34,6 +34,7 @@ static int smbus_do_alert(struct device *dev, void *addrp) struct i2c_client *client = i2c_verify_client(dev); struct alert_data *data = addrp; struct i2c_driver *driver; + int ret; if (!client || client->addr != data->addr) return 0; @@ -47,16 +48,47 @@ static int smbus_do_alert(struct device *dev, void *addrp) device_lock(dev); if (client->dev.driver) { driver = to_i2c_driver(client->dev.driver); - if (driver->alert) + if (driver->alert) { + /* Stop iterating after we find the device */ driver->alert(client, data->type, data->data); - else + ret = -EBUSY; + } else { dev_warn(&client->dev, "no driver alert()!\n"); - } else + ret = -EOPNOTSUPP; + } + } else { dev_dbg(&client->dev, "alert with no driver\n"); + ret = -ENODEV; + } + device_unlock(dev); + + return ret; +} + +/* Same as above, but call back all drivers with alert handler */ + +static int smbus_do_alert_force(struct device *dev, void *addrp) +{ + struct i2c_client *client = i2c_verify_client(dev); + struct alert_data *data = addrp; + struct i2c_driver *driver; + + if (!client || (client->flags & I2C_CLIENT_TEN)) + return 0; + + /* + * Drivers should either disable alerts, or provide at least + * a minimal handler. Lock so the driver won't change. + */ + device_lock(dev); + if (client->dev.driver) { + driver = to_i2c_driver(client->dev.driver); + if (driver->alert) + driver->alert(client, data->type, data->data); + } device_unlock(dev); - /* Stop iterating after we find the device */ - return -EBUSY; + return 0; } /* @@ -67,6 +99,7 @@ static irqreturn_t smbus_alert(int irq, void *d) { struct i2c_smbus_alert *alert = d; struct i2c_client *ara; + unsigned short prev_addr = I2C_CLIENT_END; /* Not a valid address */ ara = alert->ara; @@ -94,8 +127,25 @@ static irqreturn_t smbus_alert(int irq, void *d) data.addr, data.data); /* Notify driver for the device which issued the alert */ - device_for_each_child(&ara->adapter->dev, &data, - smbus_do_alert); + status = device_for_each_child(&ara->adapter->dev, &data, + smbus_do_alert); + /* + * If we read the same address more than once, and the alert + * was not handled by a driver, it won't do any good to repeat + * the loop because it will never terminate. Try again, this + * time calling the alert handlers of all devices connected to + * the bus, and abort the loop afterwards. If this helps, we + * are all set. If it doesn't, there is nothing else we can do, + * so we might as well abort the loop. + * Note: This assumes that a driver with alert handler handles + * the alert properly and clears it if necessary. + */ + if (data.addr == prev_addr && status != -EBUSY) { + device_for_each_child(&ara->adapter->dev, &data, + smbus_do_alert_force); + break; + } + prev_addr = data.addr; } return IRQ_HANDLED; @@ -160,7 +210,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 +358,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 +402,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 +425,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/Kconfig b/drivers/i2c/muxes/Kconfig index db1b9057612a..6d2f66810cdc 100644 --- a/drivers/i2c/muxes/Kconfig +++ b/drivers/i2c/muxes/Kconfig @@ -119,4 +119,20 @@ config I2C_MUX_MLXCPLD This driver can also be built as a module. If so, the module will be called i2c-mux-mlxcpld. +config I2C_MUX_MULE + tristate "Theobroma Systems Mule I2C device multiplexer" + depends on OF && SENSORS_AMC6821 + help + Mule is an MCU that emulates a set of I2C devices, among which + devices that are reachable through an I2C-mux. The devices on the mux + can be selected by writing the appropriate device number to an I2C + configuration register. + + If you say yes to this option, support will be included for a + Theobroma Systems Mule I2C multiplexer. This driver provides access to + I2C devices connected on this mux. + + This driver can also be built as a module. If so, the module + will be called i2c-mux-mule. + endmenu diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile index 6d9d865e8518..4b24f49515a7 100644 --- a/drivers/i2c/muxes/Makefile +++ b/drivers/i2c/muxes/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_I2C_MUX_GPIO) += i2c-mux-gpio.o obj-$(CONFIG_I2C_MUX_GPMUX) += i2c-mux-gpmux.o obj-$(CONFIG_I2C_MUX_LTC4306) += i2c-mux-ltc4306.o obj-$(CONFIG_I2C_MUX_MLXCPLD) += i2c-mux-mlxcpld.o +obj-$(CONFIG_I2C_MUX_MULE) += i2c-mux-mule.o obj-$(CONFIG_I2C_MUX_PCA9541) += i2c-mux-pca9541.o obj-$(CONFIG_I2C_MUX_PCA954x) += i2c-mux-pca954x.o obj-$(CONFIG_I2C_MUX_PINCTRL) += i2c-mux-pinctrl.o diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c index d6bbb8b68333..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; } diff --git a/drivers/i2c/muxes/i2c-mux-mule.c b/drivers/i2c/muxes/i2c-mux-mule.c new file mode 100644 index 000000000000..284ff4afeeac --- /dev/null +++ b/drivers/i2c/muxes/i2c-mux-mule.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Theobroma Systems Mule I2C device multiplexer + * + * Copyright (C) 2024 Theobroma Systems Design und Consulting GmbH + */ + +#include <linux/i2c-mux.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/property.h> +#include <linux/regmap.h> + +#define MULE_I2C_MUX_CONFIG_REG 0xff +#define MULE_I2C_MUX_DEFAULT_DEV 0x0 + +struct mule_i2c_reg_mux { + struct regmap *regmap; +}; + +static int mule_i2c_mux_select(struct i2c_mux_core *muxc, u32 dev) +{ + struct mule_i2c_reg_mux *mux = muxc->priv; + + return regmap_write(mux->regmap, MULE_I2C_MUX_CONFIG_REG, dev); +} + +static int mule_i2c_mux_deselect(struct i2c_mux_core *muxc, u32 dev) +{ + return mule_i2c_mux_select(muxc, MULE_I2C_MUX_DEFAULT_DEV); +} + +static void mule_i2c_mux_remove(void *data) +{ + struct i2c_mux_core *muxc = data; + + i2c_mux_del_adapters(muxc); + + mule_i2c_mux_deselect(muxc, MULE_I2C_MUX_DEFAULT_DEV); +} + +static int mule_i2c_mux_probe(struct platform_device *pdev) +{ + struct device *mux_dev = &pdev->dev; + struct mule_i2c_reg_mux *priv; + struct i2c_client *client; + struct i2c_mux_core *muxc; + struct device_node *dev; + unsigned int readback; + int ndev, ret; + bool old_fw; + + /* Count devices on the mux */ + ndev = of_get_child_count(mux_dev->of_node); + dev_dbg(mux_dev, "%d devices on the mux\n", ndev); + + client = to_i2c_client(mux_dev->parent); + + muxc = i2c_mux_alloc(client->adapter, mux_dev, ndev, sizeof(*priv), + I2C_MUX_LOCKED, mule_i2c_mux_select, mule_i2c_mux_deselect); + if (!muxc) + return -ENOMEM; + + priv = i2c_mux_priv(muxc); + + priv->regmap = dev_get_regmap(mux_dev->parent, NULL); + if (!priv->regmap) + return dev_err_probe(mux_dev, -ENODEV, + "No parent i2c register map\n"); + + platform_set_drvdata(pdev, muxc); + + /* + * MULE_I2C_MUX_DEFAULT_DEV is guaranteed to exist on all old and new + * mule fw. Mule fw without mux support will accept write ops to the + * config register, but readback returns 0xff (register not updated). + */ + ret = mule_i2c_mux_select(muxc, MULE_I2C_MUX_DEFAULT_DEV); + if (ret) + return dev_err_probe(mux_dev, ret, + "Failed to write config register\n"); + + ret = regmap_read(priv->regmap, MULE_I2C_MUX_CONFIG_REG, &readback); + if (ret) + return dev_err_probe(mux_dev, ret, + "Failed to read config register\n"); + + old_fw = (readback != MULE_I2C_MUX_DEFAULT_DEV); + + ret = devm_add_action_or_reset(mux_dev, mule_i2c_mux_remove, muxc); + if (ret) + return dev_err_probe(mux_dev, ret, + "Failed to register mux remove\n"); + + /* Create device adapters */ + for_each_child_of_node(mux_dev->of_node, dev) { + u32 reg; + + ret = of_property_read_u32(dev, "reg", ®); + if (ret) + return dev_err_probe(mux_dev, ret, + "No reg property found for %s\n", + of_node_full_name(dev)); + + if (old_fw && reg != 0) { + dev_warn(mux_dev, + "Mux is not supported, please update Mule FW\n"); + continue; + } + + ret = mule_i2c_mux_select(muxc, reg); + if (ret) { + dev_warn(mux_dev, + "Device %d not supported, please update Mule FW\n", reg); + continue; + } + + ret = i2c_mux_add_adapter(muxc, 0, reg); + if (ret) + return ret; + } + + mule_i2c_mux_deselect(muxc, MULE_I2C_MUX_DEFAULT_DEV); + + return 0; +} + +static const struct of_device_id mule_i2c_mux_of_match[] = { + { .compatible = "tsd,mule-i2c-mux", }, + {}, +}; +MODULE_DEVICE_TABLE(of, mule_i2c_mux_of_match); + +static struct platform_driver mule_i2c_mux_driver = { + .driver = { + .name = "mule-i2c-mux", + .of_match_table = mule_i2c_mux_of_match, + }, + .probe = mule_i2c_mux_probe, +}; + +module_platform_driver(mule_i2c_mux_driver); + +MODULE_AUTHOR("Farouk Bouabid <farouk.bouabid@cherry.de>"); +MODULE_DESCRIPTION("I2C mux driver for Theobroma Systems Mule"); +MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c index e28694d991fb..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" }, {} }; |