public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] i2c: imx: fix emulated smbus block read
@ 2025-05-20 12:22 Lukasz Kucharczyk
  2025-05-27 10:45 ` Carlos Song
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Lukasz Kucharczyk @ 2025-05-20 12:22 UTC (permalink / raw)
  To: Oleksij Rempel, stefan.eichenberger, Pengutronix Kernel Team,
	Andi Shyti, Shawn Guo, Sascha Hauer, Fabio Estevam
  Cc: open list:FREESCALE IMX I2C DRIVER,
	open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	open list, bsp-development.geo, customers.leicageo,
	Lukasz Kucharczyk

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>
---
 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 ee0d25b498cb..4bf550a3b98d 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.34.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-06-25 22:40 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-20 12:22 [PATCH] i2c: imx: fix emulated smbus block read Lukasz Kucharczyk
2025-05-27 10:45 ` Carlos Song
2025-05-27 12:02   ` KUCHARCZYK Lukasz
2025-05-28  1:50     ` Carlos Song
2025-05-28  7:13 ` Stefan Eichenberger
2025-05-30  5:13 ` Oleksij Rempel
2025-06-25 20:43 ` Andi Shyti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox