Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull i2c fixes from Wolfram Sang:

- designware: fix resume-probe race causing NULL-deref in amdisp

- imx: fix timeout on repeated reads and extra clock at end

- MAINTAINERS: drop outdated I2C website

* tag 'i2c-for-7.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
MAINTAINERS: drop outdated I2C website
i2c: designware: amdisp: Fix resume-probe race condition issue
i2c: imx: ensure no clock is generated after last read
i2c: imx: fix i2c issue when reading multiple messages

+37 -27
-2
MAINTAINERS
··· 12020 12020 M: Wolfram Sang <wsa+renesas@sang-engineering.com> 12021 12021 L: linux-i2c@vger.kernel.org 12022 12022 S: Maintained 12023 - W: https://i2c.wiki.kernel.org/ 12024 12023 Q: https://patchwork.ozlabs.org/project/linux-i2c/list/ 12025 12024 T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git 12026 12025 F: Documentation/i2c/ ··· 12045 12046 M: Andi Shyti <andi.shyti@kernel.org> 12046 12047 L: linux-i2c@vger.kernel.org 12047 12048 S: Maintained 12048 - W: https://i2c.wiki.kernel.org/ 12049 12049 Q: https://patchwork.ozlabs.org/project/linux-i2c/list/ 12050 12050 T: git git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git 12051 12051 F: Documentation/devicetree/bindings/i2c/
+5 -6
drivers/i2c/busses/i2c-designware-amdisp.c
··· 7 7 8 8 #include <linux/module.h> 9 9 #include <linux/platform_device.h> 10 + #include <linux/pm_domain.h> 10 11 #include <linux/pm_runtime.h> 11 12 #include <linux/soc/amd/isp4_misc.h> 12 13 ··· 77 76 78 77 device_enable_async_suspend(&pdev->dev); 79 78 80 - pm_runtime_enable(&pdev->dev); 81 - pm_runtime_get_sync(&pdev->dev); 82 - 79 + dev_pm_genpd_resume(&pdev->dev); 83 80 ret = i2c_dw_probe(isp_i2c_dev); 84 81 if (ret) { 85 82 dev_err_probe(&pdev->dev, ret, "i2c_dw_probe failed\n"); 86 83 goto error_release_rpm; 87 84 } 88 - 89 - pm_runtime_put_sync(&pdev->dev); 85 + dev_pm_genpd_suspend(&pdev->dev); 86 + pm_runtime_set_suspended(&pdev->dev); 87 + pm_runtime_enable(&pdev->dev); 90 88 91 89 return 0; 92 90 93 91 error_release_rpm: 94 92 amd_isp_dw_i2c_plat_pm_cleanup(isp_i2c_dev); 95 - pm_runtime_put_sync(&pdev->dev); 96 93 return ret; 97 94 } 98 95
+32 -19
drivers/i2c/busses/i2c-imx.c
··· 1018 1018 return 0; 1019 1019 } 1020 1020 1021 - static inline void i2c_imx_isr_read_continue(struct imx_i2c_struct *i2c_imx) 1021 + static inline enum imx_i2c_state i2c_imx_isr_read_continue(struct imx_i2c_struct *i2c_imx) 1022 1022 { 1023 + enum imx_i2c_state next_state = IMX_I2C_STATE_READ_CONTINUE; 1023 1024 unsigned int temp; 1024 1025 1025 1026 if ((i2c_imx->msg->len - 1) == i2c_imx->msg_buf_idx) { ··· 1034 1033 i2c_imx->stopped = 1; 1035 1034 temp &= ~(I2CR_MSTA | I2CR_MTX); 1036 1035 imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); 1037 - } else { 1038 - /* 1039 - * For i2c master receiver repeat restart operation like: 1040 - * read -> repeat MSTA -> read/write 1041 - * The controller must set MTX before read the last byte in 1042 - * the first read operation, otherwise the first read cost 1043 - * one extra clock cycle. 1044 - */ 1045 - temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); 1046 - temp |= I2CR_MTX; 1047 - imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); 1036 + 1037 + return IMX_I2C_STATE_DONE; 1048 1038 } 1039 + /* 1040 + * For i2c master receiver repeat restart operation like: 1041 + * read -> repeat MSTA -> read/write 1042 + * The controller must set MTX before read the last byte in 1043 + * the first read operation, otherwise the first read cost 1044 + * one extra clock cycle. 1045 + */ 1046 + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); 1047 + temp |= I2CR_MTX; 1048 + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); 1049 + next_state = IMX_I2C_STATE_DONE; 1049 1050 } else if (i2c_imx->msg_buf_idx == (i2c_imx->msg->len - 2)) { 1050 1051 temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); 1051 1052 temp |= I2CR_TXAK; ··· 1055 1052 } 1056 1053 1057 1054 i2c_imx->msg->buf[i2c_imx->msg_buf_idx++] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); 1055 + return next_state; 1058 1056 } 1059 1057 1060 1058 static inline void i2c_imx_isr_read_block_data_len(struct imx_i2c_struct *i2c_imx) ··· 1092 1088 break; 1093 1089 1094 1090 case IMX_I2C_STATE_READ_CONTINUE: 1095 - i2c_imx_isr_read_continue(i2c_imx); 1096 - if (i2c_imx->msg_buf_idx == i2c_imx->msg->len) { 1097 - i2c_imx->state = IMX_I2C_STATE_DONE; 1091 + i2c_imx->state = i2c_imx_isr_read_continue(i2c_imx); 1092 + if (i2c_imx->state == IMX_I2C_STATE_DONE) 1098 1093 wake_up(&i2c_imx->queue); 1099 - } 1100 1094 break; 1101 1095 1102 1096 case IMX_I2C_STATE_READ_BLOCK_DATA: ··· 1492 1490 bool is_lastmsg) 1493 1491 { 1494 1492 int block_data = msgs->flags & I2C_M_RECV_LEN; 1493 + int ret = 0; 1495 1494 1496 1495 dev_dbg(&i2c_imx->adapter.dev, 1497 1496 "<%s> write slave address: addr=0x%x\n", ··· 1525 1522 dev_err(&i2c_imx->adapter.dev, "<%s> read timedout\n", __func__); 1526 1523 return -ETIMEDOUT; 1527 1524 } 1528 - if (!i2c_imx->stopped) 1529 - return i2c_imx_bus_busy(i2c_imx, 0, false); 1525 + if (i2c_imx->is_lastmsg) { 1526 + if (!i2c_imx->stopped) 1527 + ret = i2c_imx_bus_busy(i2c_imx, 0, false); 1528 + /* 1529 + * Only read the last byte of the last message after the bus is 1530 + * not busy. Else the controller generates another clock which 1531 + * might confuse devices. 1532 + */ 1533 + if (!ret) 1534 + i2c_imx->msg->buf[i2c_imx->msg_buf_idx++] = imx_i2c_read_reg(i2c_imx, 1535 + IMX_I2C_I2DR); 1536 + } 1530 1537 1531 - return 0; 1538 + return ret; 1532 1539 } 1533 1540 1534 1541 static int i2c_imx_xfer_common(struct i2c_adapter *adapter,