Skip to content

Commit f4fcf7f

Browse files
committed
i2c: imx: fix emulated smbus block read
JIRA: https://issues.redhat.com/browse/RHEL-116101 commit a5d0b9e Author: Lukasz Kucharczyk <lukasz.kucharczyk@leica-geosystems.com> Date: Tue May 20 14:22:52 2025 +0200 i2c: imx: fix emulated smbus block read Acknowledge the byte count submitted by the target. When I2C_SMBUS_BLOCK_DATA read operation is executed by i2c_smbus_xfer_emulated(), the length of the second (read) message is set to 1. Length of the block is supposed to be obtained from the target by the underlying bus driver. The i2c_imx_isr_read() function should emit the acknowledge on i2c bus after reading the first byte (i.e., byte count) while processing such message (as defined in Section 6.5.7 of System Management Bus Specification [1]). Without this acknowledge, the target does not submit subsequent bytes and the controller only reads 0xff's. In addition, store the length of block data obtained from the target in the buffer provided by i2c_smbus_xfer_emulated() - otherwise the first byte of actual data is erroneously interpreted as length of the data block. [1] https://smbus.org/specs/SMBus_3_3_20240512.pdf Fixes: 5f5c2d4 ("i2c: imx: prevent rescheduling in non dma mode") Signed-off-by: Lukasz Kucharczyk <lukasz.kucharczyk@leica-geosystems.com> Cc: <stable@vger.kernel.org> # v6.13+ Acked-by: Oleksij Rempel <o.rempel@pengutronix.de> Reviewed-by: Stefan Eichenberger <eichest@gmail.com> Reviewed-by: Carlos Song <carlos.song@nxp.com> Signed-off-by: Andi Shyti <andi.shyti@kernel.org> Link: https://lore.kernel.org/r/20250520122252.1475403-1-lukasz.kucharczyk@leica-geosystems.com Signed-off-by: Jared Kangas <jkangas@redhat.com>
1 parent 1154568 commit f4fcf7f

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

drivers/i2c/busses/i2c-imx.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,7 @@ static inline int i2c_imx_isr_read(struct imx_i2c_struct *i2c_imx)
10081008
/* setup bus to read data */
10091009
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
10101010
temp &= ~I2CR_MTX;
1011-
if (i2c_imx->msg->len - 1)
1011+
if ((i2c_imx->msg->len - 1) || (i2c_imx->msg->flags & I2C_M_RECV_LEN))
10121012
temp &= ~I2CR_TXAK;
10131013

10141014
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
@@ -1063,6 +1063,7 @@ static inline void i2c_imx_isr_read_block_data_len(struct imx_i2c_struct *i2c_im
10631063
wake_up(&i2c_imx->queue);
10641064
}
10651065
i2c_imx->msg->len += len;
1066+
i2c_imx->msg->buf[i2c_imx->msg_buf_idx++] = len;
10661067
}
10671068

10681069
static irqreturn_t i2c_imx_master_isr(struct imx_i2c_struct *i2c_imx, unsigned int status)

0 commit comments

Comments
 (0)