summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-05-05 19:07:17 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-05-05 19:07:17 -0700
commita5e219005aeaf52cb10f9999a61c07a140db7097 (patch)
tree5d574c4472b9ceef372c54315eb28a2a30efef69 /drivers
parentc12753d5fa3eab636b5ced91d6a2155173c11527 (diff)
parent1bd922877a084c1c6c1d0cb1bb9c3700fa0f6c61 (diff)
downloadlwn-a5e219005aeaf52cb10f9999a61c07a140db7097.tar.gz
lwn-a5e219005aeaf52cb10f9999a61c07a140db7097.zip
Merge tag 'i2c-for-6.4-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull more i2c updates from Wolfram Sang: "Some more driver bugfixes and a DT binding conversion" * tag 'i2c-for-6.4-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: dt-bindings: i2c: brcm,kona-i2c: convert to YAML i2c: gxp: fix build failure without CONFIG_I2C_SLAVE i2c: imx-lpi2c: avoid taking clk_prepare mutex in PM callbacks i2c: omap: Fix standard mode false ACK readings i2c: tegra: Fix PEC support for SMBUS block read
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/busses/i2c-gxp.c2
-rw-r--r--drivers/i2c/busses/i2c-imx-lpi2c.c4
-rw-r--r--drivers/i2c/busses/i2c-omap.c2
-rw-r--r--drivers/i2c/busses/i2c-tegra.c40
4 files changed, 30 insertions, 18 deletions
diff --git a/drivers/i2c/busses/i2c-gxp.c b/drivers/i2c/busses/i2c-gxp.c
index d4b55d989a26..8ea3fb5e4c7f 100644
--- a/drivers/i2c/busses/i2c-gxp.c
+++ b/drivers/i2c/busses/i2c-gxp.c
@@ -353,7 +353,6 @@ static void gxp_i2c_chk_data_ack(struct gxp_i2c_drvdata *drvdata)
writew(value, drvdata->base + GXP_I2CMCMD);
}
-#if IS_ENABLED(CONFIG_I2C_SLAVE)
static bool gxp_i2c_slave_irq_handler(struct gxp_i2c_drvdata *drvdata)
{
u8 value;
@@ -437,7 +436,6 @@ static bool gxp_i2c_slave_irq_handler(struct gxp_i2c_drvdata *drvdata)
return true;
}
-#endif
static irqreturn_t gxp_i2c_irq_handler(int irq, void *_drvdata)
{
diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
index a49b14d52a98..1af0a637d7f1 100644
--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -639,7 +639,7 @@ static int __maybe_unused lpi2c_runtime_suspend(struct device *dev)
{
struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev);
- clk_bulk_disable_unprepare(lpi2c_imx->num_clks, lpi2c_imx->clks);
+ clk_bulk_disable(lpi2c_imx->num_clks, lpi2c_imx->clks);
pinctrl_pm_select_sleep_state(dev);
return 0;
@@ -651,7 +651,7 @@ static int __maybe_unused lpi2c_runtime_resume(struct device *dev)
int ret;
pinctrl_pm_select_default_state(dev);
- ret = clk_bulk_prepare_enable(lpi2c_imx->num_clks, lpi2c_imx->clks);
+ ret = clk_bulk_enable(lpi2c_imx->num_clks, lpi2c_imx->clks);
if (ret) {
dev_err(dev, "failed to enable I2C clock, ret=%d\n", ret);
return ret;
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 2b4e2be51318..4199f57a6bf2 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1058,7 +1058,7 @@ omap_i2c_isr(int irq, void *dev_id)
u16 stat;
stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG);
- mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG);
+ mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG) & ~OMAP_I2C_STAT_NACK;
if (stat & mask)
ret = IRQ_WAKE_THREAD;
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 6aab84c8d22b..157066f06a32 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -242,9 +242,10 @@ struct tegra_i2c_hw_feature {
* @is_dvc: identifies the DVC I2C controller, has a different register layout
* @is_vi: identifies the VI I2C controller, has a different register layout
* @msg_complete: transfer completion notifier
+ * @msg_buf_remaining: size of unsent data in the message buffer
+ * @msg_len: length of message in current transfer
* @msg_err: error code for completed message
* @msg_buf: pointer to current message data
- * @msg_buf_remaining: size of unsent data in the message buffer
* @msg_read: indicates that the transfer is a read access
* @timings: i2c timings information like bus frequency
* @multimaster_mode: indicates that I2C controller is in multi-master mode
@@ -277,6 +278,7 @@ struct tegra_i2c_dev {
struct completion msg_complete;
size_t msg_buf_remaining;
+ unsigned int msg_len;
int msg_err;
u8 *msg_buf;
@@ -1169,7 +1171,7 @@ static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
else
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
- packet_header = msg->len - 1;
+ packet_header = i2c_dev->msg_len - 1;
if (i2c_dev->dma_mode && !i2c_dev->msg_read)
*dma_buf++ = packet_header;
@@ -1242,20 +1244,32 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
return err;
i2c_dev->msg_buf = msg->buf;
+ i2c_dev->msg_len = msg->len;
- /* The condition true implies smbus block read and len is already read */
- if (msg->flags & I2C_M_RECV_LEN && end_state != MSG_END_CONTINUE)
- i2c_dev->msg_buf = msg->buf + 1;
-
- i2c_dev->msg_buf_remaining = msg->len;
i2c_dev->msg_err = I2C_ERR_NONE;
i2c_dev->msg_read = !!(msg->flags & I2C_M_RD);
reinit_completion(&i2c_dev->msg_complete);
+ /*
+ * For SMBUS block read command, read only 1 byte in the first transfer.
+ * Adjust that 1 byte for the next transfer in the msg buffer and msg
+ * length.
+ */
+ if (msg->flags & I2C_M_RECV_LEN) {
+ if (end_state == MSG_END_CONTINUE) {
+ i2c_dev->msg_len = 1;
+ } else {
+ i2c_dev->msg_buf += 1;
+ i2c_dev->msg_len -= 1;
+ }
+ }
+
+ i2c_dev->msg_buf_remaining = i2c_dev->msg_len;
+
if (i2c_dev->msg_read)
- xfer_size = msg->len;
+ xfer_size = i2c_dev->msg_len;
else
- xfer_size = msg->len + I2C_PACKET_HEADER_SIZE;
+ xfer_size = i2c_dev->msg_len + I2C_PACKET_HEADER_SIZE;
xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD);
@@ -1295,7 +1309,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
if (!i2c_dev->msg_read) {
if (i2c_dev->dma_mode) {
memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
- msg->buf, msg->len);
+ msg->buf, i2c_dev->msg_len);
dma_sync_single_for_device(i2c_dev->dma_dev,
i2c_dev->dma_phys,
@@ -1352,7 +1366,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
i2c_dev->dma_phys,
xfer_size, DMA_FROM_DEVICE);
- memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, msg->len);
+ memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, i2c_dev->msg_len);
}
}
@@ -1408,8 +1422,8 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE);
if (ret)
break;
- /* Set the read byte as msg len */
- msgs[i].len = msgs[i].buf[0];
+ /* Set the msg length from first byte */
+ msgs[i].len += msgs[i].buf[0];
dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len);
}
ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], end_type);