diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2025-12-10 07:48:05 +0900 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-12-10 07:48:05 +0900 |
| commit | c9b47175e9131118e6f221cc8fb81397d62e7c91 (patch) | |
| tree | ec9cf60ad95a2e8e13e73706287825ffe9ac20f6 | |
| parent | 9d588a1140b9ae211581a7a154d0b806d8cd8238 (diff) | |
| parent | d202341d9b0c5b5965787061ba0d10daafb9d6c5 (diff) | |
| download | tip-c9b47175e9131118e6f221cc8fb81397d62e7c91.tar.gz | |
Merge tag 'i2c-for-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
- general cleanups in bcm2835, designware, pcf8584, and stm32
- amd-mp2: fix device refcount
- designware: avoid interrupt storms caused by bad firmware
- spacemit: fix device detection failures
- new devices: Intel Diamond Rapids, Rockchip RK3506, Qualcomm
Kaanapali and MSM8953
- minor fixes to i801, core documentation, elektor Kconfig dependencies
- at24 updates: add new compatible for Belling BL24S64
* tag 'i2c-for-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (21 commits)
i2c: qcom-cci: Add msm8953 compatible
i2c: spacemit: fix detect issue
i2c: amd-mp2: fix reference leak in MP2 PCI device
i2c: i2c.h: fix a bad kernel-doc line
i2c: i2c-elektor: Allow building on SMP kernels
dt-bindings: i2c: qcom-cci: Document Kaanapali compatible
dt-bindings: i2c: qcom-cci: Document msm8953 compatible
dt-bindings: eeprom: at24: Add compatible for Belling BL24S64
i2c: i801: Fix the Intel Diamond Rapids features
i2c: pcf8584: Change pcf_doAdress() to pcf_send_address()
i2c: pcf8584: Make pcf_doAddress() function void
i2c: pcf8584: Move 'ret' variable inside for loop, goto out if ret < 0.
i2c: designware: Disable SMBus interrupts to prevent storms from mis-configured firmware
dt-bindings: i2c: i2c-rk3x: Add compatible string for RK3506
i2c: i801: Add support for Intel Diamond Rapids
i2c: stm32: Omit two variable reassignments in stm32_i2c_dma_request()
i2c: designware: Omit a variable reassignment in dw_i2c_plat_probe()
i2c: pcf8584: Fix do not use assignment inside if conditional
i2c: pcf8584: Remove debug macros from i2c-algo-pcf.c
i2c: busses: bcm2835: convert from round_rate() to determine_rate()
...
| -rw-r--r-- | Documentation/devicetree/bindings/eeprom/at24.yaml | 1 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml | 1 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml | 4 | ||||
| -rw-r--r-- | Documentation/i2c/busses/i2c-i801.rst | 1 | ||||
| -rw-r--r-- | drivers/i2c/algos/i2c-algo-pcf.c | 105 | ||||
| -rw-r--r-- | drivers/i2c/busses/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-amd-mp2-pci.c | 5 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-bcm2835.c | 12 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-designware-core.h | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-designware-master.c | 7 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-designware-platdrv.c | 13 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 3 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-k1.c | 19 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-qcom-cci.c | 46 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-stm32.c | 7 | ||||
| -rw-r--r-- | include/uapi/linux/i2c.h | 2 |
16 files changed, 120 insertions, 111 deletions
diff --git a/Documentation/devicetree/bindings/eeprom/at24.yaml b/Documentation/devicetree/bindings/eeprom/at24.yaml index 50af7ccf6e21ab..c212826347803e 100644 --- a/Documentation/devicetree/bindings/eeprom/at24.yaml +++ b/Documentation/devicetree/bindings/eeprom/at24.yaml @@ -131,6 +131,7 @@ properties: - const: atmel,24c32 - items: - enum: + - belling,bl24s64 - onnn,n24s64b - puya,p24c64f - const: atmel,24c64 diff --git a/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml b/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml index 4ac5a40a3886f4..91805fe8f3936e 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml +++ b/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml @@ -37,6 +37,7 @@ properties: - rockchip,px30-i2c - rockchip,rk3308-i2c - rockchip,rk3328-i2c + - rockchip,rk3506-i2c - rockchip,rk3528-i2c - rockchip,rk3562-i2c - rockchip,rk3568-i2c diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml index 9bc99d736343f1..33852a5ffca8fe 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml @@ -15,6 +15,7 @@ properties: oneOf: - enum: - qcom,msm8226-cci + - qcom,msm8953-cci - qcom,msm8974-cci - qcom,msm8996-cci @@ -25,6 +26,7 @@ properties: - items: - enum: + - qcom,kaanapali-cci - qcom,qcm2290-cci - qcom,sa8775p-cci - qcom,sc7280-cci @@ -128,6 +130,7 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-cci - qcom,qcm2290-cci then: properties: @@ -146,6 +149,7 @@ allOf: - contains: enum: - qcom,msm8916-cci + - qcom,msm8953-cci - const: qcom,msm8996-cci then: diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst index 36c563ad3f068f..c939a5bfc8d008 100644 --- a/Documentation/i2c/busses/i2c-i801.rst +++ b/Documentation/i2c/busses/i2c-i801.rst @@ -51,6 +51,7 @@ Supported adapters: * Intel Arrow Lake (SOC) * Intel Panther Lake (SOC) * Intel Wildcat Lake (SOC) + * Intel Diamond Rapids (SOC) Datasheets: Publicly available at the Intel website diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index fd563e845d4b70..a87ecea7f51001 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -23,17 +23,8 @@ #include "i2c-algo-pcf.h" -#define DEB2(x) if (i2c_debug >= 2) x -#define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */ -#define DEBPROTO(x) if (i2c_debug >= 9) x; - /* debug the protocol by showing transferred bits */ #define DEF_TIMEOUT 16 -/* - * module parameters: - */ -static int i2c_debug; - /* setting states on the bus with the right timing: */ #define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val) @@ -47,27 +38,21 @@ static int i2c_debug; static void i2c_start(struct i2c_algo_pcf_data *adap) { - DEBPROTO(printk(KERN_DEBUG "S ")); set_pcf(adap, 1, I2C_PCF_START); } static void i2c_repstart(struct i2c_algo_pcf_data *adap) { - DEBPROTO(printk(" Sr ")); set_pcf(adap, 1, I2C_PCF_REPSTART); } static void i2c_stop(struct i2c_algo_pcf_data *adap) { - DEBPROTO(printk("P\n")); set_pcf(adap, 1, I2C_PCF_STOP); } static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) { - DEB2(printk(KERN_INFO - "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n", - *status)); /* * Cleanup from LAB -- reset and enable ESO. * This resets the PCF8584; since we've lost the bus, no @@ -88,9 +73,6 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) if (adap->lab_mdelay) mdelay(adap->lab_mdelay); - DEB2(printk(KERN_INFO - "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n", - get_pcf(adap, 1))); } static int wait_for_bb(struct i2c_algo_pcf_data *adap) @@ -147,56 +129,48 @@ static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) * * vdovikin: added detect code for PCF8584 */ -static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) +static int pcf_init_8584(struct i2c_algo_pcf_data *adap) { unsigned char temp; - DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", - get_pcf(adap, 1))); - /* S1=0x80: S0 selected, serial interface off */ set_pcf(adap, 1, I2C_PCF_PIN); /* * check to see S1 now used as R/W ctrl - * PCF8584 does that when ESO is zero */ - if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { - DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); + temp = get_pcf(adap, 1); + if ((temp & 0x7f) != 0) return -ENXIO; /* definitely not PCF8584 */ - } /* load own address in S0, effective address is (own << 1) */ i2c_outb(adap, get_own(adap)); /* check it's really written */ - if ((temp = i2c_inb(adap)) != get_own(adap)) { - DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp)); + temp = i2c_inb(adap); + if (temp != get_own(adap)) return -ENXIO; - } /* S1=0xA0, next byte in S2 */ set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); /* check to see S2 now selected */ - if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) { - DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp)); + temp = get_pcf(adap, 1); + if ((temp & 0x7f) != I2C_PCF_ES1) return -ENXIO; - } /* load clock register S2 */ i2c_outb(adap, get_clock(adap)); /* check it's really written, the only 5 lowest bits does matter */ - if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { - DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp)); + temp = i2c_inb(adap); + if ((temp & 0x1f) != get_clock(adap)) return -ENXIO; - } /* Enable serial interface, idle, S0 selected */ set_pcf(adap, 1, I2C_PCF_IDLE); /* check to see PCF is really idled and we can access status register */ - if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) { - DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); + temp = get_pcf(adap, 1); + if (temp != (I2C_PCF_PIN | I2C_PCF_BB)) return -ENXIO; - } printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n"); @@ -209,9 +183,7 @@ static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; int wrcount, status, timeout; - for (wrcount=0; wrcount<count; ++wrcount) { - DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n", - buf[wrcount] & 0xff)); + for (wrcount = 0; wrcount < count; ++wrcount) { i2c_outb(adap, buf[wrcount]); timeout = wait_for_pin(adap, &status); if (timeout) { @@ -246,7 +218,8 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, /* increment number of bytes to read by one -- read dummy byte */ for (i = 0; i <= count; i++) { - if ((wfp = wait_for_pin(adap, &status))) { + wfp = wait_for_pin(adap, &status); + if (wfp) { if (wfp == -EINTR) return -EINTR; /* arbitration lost */ @@ -280,7 +253,7 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, } -static int pcf_doAddress(struct i2c_algo_pcf_data *adap, +static void pcf_send_address(struct i2c_algo_pcf_data *adap, struct i2c_msg *msg) { unsigned char addr = i2c_8bit_addr_from_msg(msg); @@ -288,8 +261,6 @@ static int pcf_doAddress(struct i2c_algo_pcf_data *adap, if (msg->flags & I2C_M_REV_DIR_ADDR) addr ^= 1; i2c_outb(adap, addr); - - return 0; } static int pcf_xfer(struct i2c_adapter *i2c_adap, @@ -299,7 +270,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; struct i2c_msg *pmsg; int i; - int ret=0, timeout, status; + int timeout, status; if (adap->xfer_begin) adap->xfer_begin(adap->data); @@ -307,20 +278,15 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, /* Check for bus busy */ timeout = wait_for_bb(adap); if (timeout) { - DEB2(printk(KERN_ERR "i2c-algo-pcf.o: " - "Timeout waiting for BB in pcf_xfer\n");) i = -EIO; goto out; } - for (i = 0;ret >= 0 && i < num; i++) { - pmsg = &msgs[i]; - - DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", - str_read_write(pmsg->flags & I2C_M_RD), - pmsg->len, pmsg->addr, i + 1, num);) + for (i = 0; i < num; i++) { + int ret; - ret = pcf_doAddress(adap, pmsg); + pmsg = &msgs[i]; + pcf_send_address(adap, pmsg); /* Send START */ if (i == 0) @@ -335,8 +301,6 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, goto out; } i2c_stop(adap); - DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting " - "for PIN(1) in pcf_xfer\n");) i = -EREMOTEIO; goto out; } @@ -344,35 +308,21 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, /* Check LRB (last rcvd bit - slave ack) */ if (status & I2C_PCF_LRB) { i2c_stop(adap); - DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");) i = -EREMOTEIO; goto out; } - DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", - i, msgs[i].addr, msgs[i].flags, msgs[i].len);) if (pmsg->flags & I2C_M_RD) { ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len, (i + 1 == num)); - - if (ret != pmsg->len) { - DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " - "only read %d bytes.\n",ret)); - } else { - DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret)); - } } else { ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len, (i + 1 == num)); - - if (ret != pmsg->len) { - DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " - "only wrote %d bytes.\n",ret)); - } else { - DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: wrote %d bytes.\n",ret)); - } } + + if (ret < 0) + goto out; } out: @@ -401,12 +351,11 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap) struct i2c_algo_pcf_data *pcf_adap = adap->algo_data; int rval; - DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); - /* register new adapter to i2c module... */ adap->algo = &pcf_algo; - if ((rval = pcf_init_8584(pcf_adap))) + rval = pcf_init_8584(pcf_adap); + if (rval) return rval; rval = i2c_add_adapter(adap); @@ -418,7 +367,3 @@ EXPORT_SYMBOL(i2c_pcf_add_bus); MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>"); MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm"); MODULE_LICENSE("GPL"); - -module_param(i2c_debug, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(i2c_debug, - "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol"); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index fd81e49638aaa1..cea87fcb4a1a94 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -166,6 +166,7 @@ config I2C_I801 Arrow Lake (SOC) Panther Lake (SOC) Wildcat Lake (SOC) + Diamond Rapids (SOC) This driver can also be built as a module. If so, the module will be called i2c-i801. @@ -1474,7 +1475,7 @@ config I2C_ACORN config I2C_ELEKTOR tristate "Elektor ISA card" - depends on ISA && HAS_IOPORT_MAP && BROKEN_ON_SMP + depends on ISA && HAS_IOPORT_MAP select I2C_ALGOPCF help This supports the PCF8584 ISA bus I2C adapter. Say Y if you own diff --git a/drivers/i2c/busses/i2c-amd-mp2-pci.c b/drivers/i2c/busses/i2c-amd-mp2-pci.c index ef7370d3dbea31..60edbabc2986be 100644 --- a/drivers/i2c/busses/i2c-amd-mp2-pci.c +++ b/drivers/i2c/busses/i2c-amd-mp2-pci.c @@ -458,13 +458,16 @@ struct amd_mp2_dev *amd_mp2_find_device(void) { struct device *dev; struct pci_dev *pci_dev; + struct amd_mp2_dev *mp2_dev; dev = driver_find_next_device(&amd_mp2_pci_driver.driver, NULL); if (!dev) return NULL; pci_dev = to_pci_dev(dev); - return (struct amd_mp2_dev *)pci_get_drvdata(pci_dev); + mp2_dev = (struct amd_mp2_dev *)pci_get_drvdata(pci_dev); + put_device(dev); + return mp2_dev; } EXPORT_SYMBOL_GPL(amd_mp2_find_device); diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c index 8554e790f8e36c..0d7e2654a534e9 100644 --- a/drivers/i2c/busses/i2c-bcm2835.c +++ b/drivers/i2c/busses/i2c-bcm2835.c @@ -137,12 +137,14 @@ static int clk_bcm2835_i2c_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static long clk_bcm2835_i2c_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_bcm2835_i2c_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - u32 divider = clk_bcm2835_i2c_calc_divider(rate, *parent_rate); + u32 divider = clk_bcm2835_i2c_calc_divider(req->rate, req->best_parent_rate); - return DIV_ROUND_UP(*parent_rate, divider); + req->rate = DIV_ROUND_UP(req->best_parent_rate, divider); + + return 0; } static unsigned long clk_bcm2835_i2c_recalc_rate(struct clk_hw *hw, @@ -156,7 +158,7 @@ static unsigned long clk_bcm2835_i2c_recalc_rate(struct clk_hw *hw, static const struct clk_ops clk_bcm2835_i2c_ops = { .set_rate = clk_bcm2835_i2c_set_rate, - .round_rate = clk_bcm2835_i2c_round_rate, + .determine_rate = clk_bcm2835_i2c_determine_rate, .recalc_rate = clk_bcm2835_i2c_recalc_rate, }; diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 347843b4f5dd7a..bb5ce0a382f928 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -78,6 +78,7 @@ #define DW_IC_TX_ABRT_SOURCE 0x80 #define DW_IC_ENABLE_STATUS 0x9c #define DW_IC_CLR_RESTART_DET 0xa8 +#define DW_IC_SMBUS_INTR_MASK 0xcc #define DW_IC_COMP_PARAM_1 0xf4 #define DW_IC_COMP_VERSION 0xf8 #define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A /* "111*" == v1.11* */ @@ -330,7 +331,6 @@ struct dw_i2c_dev { struct i2c_dw_semaphore_callbacks { int (*probe)(struct dw_i2c_dev *dev); - void (*remove)(struct dw_i2c_dev *dev); }; int i2c_dw_init_regmap(struct dw_i2c_dev *dev); diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 41e9b5ecad2013..45bfca05bb300f 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -220,6 +220,13 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev) /* Disable the adapter */ __i2c_dw_disable(dev); + /* + * Mask SMBus interrupts to block storms from broken + * firmware that leaves IC_SMBUS=1; the handler never + * services them. + */ + regmap_write(dev->map, DW_IC_SMBUS_INTR_MASK, 0); + /* Write standard speed timing parameters */ regmap_write(dev->map, DW_IC_SS_SCL_HCNT, dev->ss_hcnt); regmap_write(dev->map, DW_IC_SS_SCL_LCNT, dev->ss_lcnt); diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 34d881572351cc..7be99656a67db4 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -197,15 +197,6 @@ static int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) return 0; } -static void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev) -{ - if (dev->semaphore_idx < 0) - return; - - if (i2c_dw_semaphore_cb_table[dev->semaphore_idx].remove) - i2c_dw_semaphore_cb_table[dev->semaphore_idx].remove(dev); -} - static int dw_i2c_plat_probe(struct platform_device *pdev) { u32 flags = (uintptr_t)device_get_match_data(&pdev->dev); @@ -248,7 +239,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) ret = i2c_dw_probe_lock_support(dev); if (ret) { - ret = dev_err_probe(device, ret, "failed to probe lock support\n"); + dev_err_probe(device, ret, "failed to probe lock support\n"); goto exit_reset; } @@ -339,8 +330,6 @@ static void dw_i2c_plat_remove(struct platform_device *pdev) i2c_dw_prepare_clk(dev, false); - i2c_dw_remove_lock_support(dev); - reset_control_assert(dev->rst); } diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 57fbec1259beab..81e6e2d7ad3dcc 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -84,6 +84,7 @@ * Panther Lake-H (SOC) 0xe322 32 hard yes yes yes * Panther Lake-P (SOC) 0xe422 32 hard yes yes yes * Wildcat Lake-U (SOC) 0x4d22 32 hard yes yes yes + * Diamond Rapids (SOC) 0x5827 32 hard yes yes yes * * Features supported by this driver: * Software PEC no @@ -242,6 +243,7 @@ #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_P_SMBUS 0x51a3 #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS 0x54a3 #define PCI_DEVICE_ID_INTEL_BIRCH_STREAM_SMBUS 0x5796 +#define PCI_DEVICE_ID_INTEL_DIAMOND_RAPIDS_SMBUS 0x5827 #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 @@ -1054,6 +1056,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) }, + { PCI_DEVICE_DATA(INTEL, DIAMOND_RAPIDS_SMBUS, FEATURES_ICH5) }, { PCI_DEVICE_DATA(INTEL, ARROW_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, { PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, { PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, diff --git a/drivers/i2c/busses/i2c-k1.c b/drivers/i2c/busses/i2c-k1.c index 6b918770e612e0..d42c03ef5db598 100644 --- a/drivers/i2c/busses/i2c-k1.c +++ b/drivers/i2c/busses/i2c-k1.c @@ -158,11 +158,16 @@ static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c) { dev_dbg(i2c->dev, "i2c error status: 0x%08x\n", i2c->status); - if (i2c->status & (SPACEMIT_SR_BED | SPACEMIT_SR_ALD)) { + /* Arbitration Loss Detected */ + if (i2c->status & SPACEMIT_SR_ALD) { spacemit_i2c_reset(i2c); return -EAGAIN; } + /* Bus Error No ACK/NAK */ + if (i2c->status & SPACEMIT_SR_BED) + spacemit_i2c_reset(i2c); + return i2c->status & SPACEMIT_SR_ACKNAK ? -ENXIO : -EIO; } @@ -224,6 +229,12 @@ static void spacemit_i2c_check_bus_release(struct spacemit_i2c_dev *i2c) } } +static inline void +spacemit_i2c_clear_int_status(struct spacemit_i2c_dev *i2c, u32 mask) +{ + writel(mask & SPACEMIT_I2C_INT_STATUS_MASK, i2c->base + SPACEMIT_ISR); +} + static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c) { u32 val; @@ -267,12 +278,8 @@ static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c) val = readl(i2c->base + SPACEMIT_IRCR); val |= SPACEMIT_RCR_SDA_GLITCH_NOFIX; writel(val, i2c->base + SPACEMIT_IRCR); -} -static inline void -spacemit_i2c_clear_int_status(struct spacemit_i2c_dev *i2c, u32 mask) -{ - writel(mask & SPACEMIT_I2C_INT_STATUS_MASK, i2c->base + SPACEMIT_ISR); + spacemit_i2c_clear_int_status(i2c, SPACEMIT_I2C_INT_STATUS_MASK); } static void spacemit_i2c_start(struct spacemit_i2c_dev *i2c) diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c index e631d79baf1405..884055df1560fd 100644 --- a/drivers/i2c/busses/i2c-qcom-cci.c +++ b/drivers/i2c/busses/i2c-qcom-cci.c @@ -783,8 +783,54 @@ static const struct cci_data cci_v2_data = { }, }; +static const struct cci_data cci_msm8953_data = { + .num_masters = 2, + .queue_size = { 64, 16 }, + .quirks = { + .max_write_len = 11, + .max_read_len = 12, + }, + .params[I2C_MODE_STANDARD] = { + .thigh = 78, + .tlow = 114, + .tsu_sto = 28, + .tsu_sta = 28, + .thd_dat = 10, + .thd_sta = 77, + .tbuf = 118, + .scl_stretch_en = 0, + .trdhld = 6, + .tsp = 1 + }, + .params[I2C_MODE_FAST] = { + .thigh = 20, + .tlow = 28, + .tsu_sto = 21, + .tsu_sta = 21, + .thd_dat = 13, + .thd_sta = 18, + .tbuf = 32, + .scl_stretch_en = 0, + .trdhld = 6, + .tsp = 3 + }, + .params[I2C_MODE_FAST_PLUS] = { + .thigh = 16, + .tlow = 22, + .tsu_sto = 17, + .tsu_sta = 18, + .thd_dat = 16, + .thd_sta = 15, + .tbuf = 19, + .scl_stretch_en = 1, + .trdhld = 3, + .tsp = 3 + }, +}; + static const struct of_device_id cci_dt_match[] = { { .compatible = "qcom,msm8226-cci", .data = &cci_v1_data}, + { .compatible = "qcom,msm8953-cci", .data = &cci_msm8953_data}, { .compatible = "qcom,msm8974-cci", .data = &cci_v1_5_data}, { .compatible = "qcom,msm8996-cci", .data = &cci_v2_data}, diff --git a/drivers/i2c/busses/i2c-stm32.c b/drivers/i2c/busses/i2c-stm32.c index f84ec056e36dfe..becf8977979f73 100644 --- a/drivers/i2c/busses/i2c-stm32.c +++ b/drivers/i2c/busses/i2c-stm32.c @@ -27,8 +27,8 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev, if (IS_ERR(dma->chan_tx)) { ret = PTR_ERR(dma->chan_tx); if (ret != -ENODEV) - ret = dev_err_probe(dev, ret, - "can't request DMA tx channel\n"); + dev_err_probe(dev, ret, "can't request DMA tx channel\n"); + goto fail_al; } @@ -48,8 +48,7 @@ struct stm32_i2c_dma *stm32_i2c_dma_request(struct device *dev, if (IS_ERR(dma->chan_rx)) { ret = PTR_ERR(dma->chan_rx); if (ret != -ENODEV) - ret = dev_err_probe(dev, ret, - "can't request DMA rx channel\n"); + dev_err_probe(dev, ret, "can't request DMA rx channel\n"); goto fail_tx; } diff --git a/include/uapi/linux/i2c.h b/include/uapi/linux/i2c.h index a2db2a56c8b01e..2a226657d9f823 100644 --- a/include/uapi/linux/i2c.h +++ b/include/uapi/linux/i2c.h @@ -36,7 +36,7 @@ * * Only if I2C_FUNC_NOSTART is set: * %I2C_M_NOSTART: skip repeated start sequence - + * * Only if I2C_FUNC_PROTOCOL_MANGLING is set: * %I2C_M_NO_RD_ACK: in a read message, master ACK/NACK bit is skipped * %I2C_M_IGNORE_NAK: treat NACK from client as ACK |
