diff options
Diffstat (limited to 'queue-6.15/i2c-imx-fix-emulated-smbus-block-read.patch')
-rw-r--r-- | queue-6.15/i2c-imx-fix-emulated-smbus-block-read.patch | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/queue-6.15/i2c-imx-fix-emulated-smbus-block-read.patch b/queue-6.15/i2c-imx-fix-emulated-smbus-block-read.patch new file mode 100644 index 0000000000..87ecc1fdef --- /dev/null +++ b/queue-6.15/i2c-imx-fix-emulated-smbus-block-read.patch @@ -0,0 +1,64 @@ +From a5d0b9e32745277644cda8d7d334e7080bd339bf Mon Sep 17 00:00:00 2001 +From: Lukasz Kucharczyk <lukasz.kucharczyk@leica-geosystems.com> +Date: Tue, 20 May 2025 14:22:52 +0200 +Subject: i2c: imx: fix emulated smbus block read + +From: Lukasz Kucharczyk <lukasz.kucharczyk@leica-geosystems.com> + +commit a5d0b9e32745277644cda8d7d334e7080bd339bf upstream. + +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: 5f5c2d4579ca ("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: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/i2c/busses/i2c-imx.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c +index e5732b0557fb..205cc132fdec 100644 +--- a/drivers/i2c/busses/i2c-imx.c ++++ b/drivers/i2c/busses/i2c-imx.c +@@ -1008,7 +1008,7 @@ static inline int i2c_imx_isr_read(struct imx_i2c_struct *i2c_imx) + /* setup bus to read data */ + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); + temp &= ~I2CR_MTX; +- if (i2c_imx->msg->len - 1) ++ if ((i2c_imx->msg->len - 1) || (i2c_imx->msg->flags & I2C_M_RECV_LEN)) + temp &= ~I2CR_TXAK; + + 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 + wake_up(&i2c_imx->queue); + } + i2c_imx->msg->len += len; ++ i2c_imx->msg->buf[i2c_imx->msg_buf_idx++] = len; + } + + static irqreturn_t i2c_imx_master_isr(struct imx_i2c_struct *i2c_imx, unsigned int status) +-- +2.50.0 + |