Skip to content

Commit 4d6d5f1

Browse files
Russell KingWolfram Sang
authored andcommitted
i2c: designware: fix rx fifo depth tracking
When loading the TX fifo to receive bytes on the I2C bus, we incorrectly count the number of bytes: rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR); while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { if (rx_limit - dev->rx_outstanding <= 0) break; rx_limit--; dev->rx_outstanding++; } DW_IC_RXFLR indicates how many bytes are available to be read in the FIFO, dev->rx_fifo_depth is the FIFO size, and dev->rx_outstanding is the number of bytes that we've requested to be read so far, but which have not been read. Firstly, increasing dev->rx_outstanding and decreasing rx_limit and then comparing them results in each byte consuming "two" bytes in this tracking, so this is obviously wrong. Secondly, the number of bytes that _could_ be received into the FIFO at any time is the number of bytes we have so far requested but not yet read from the FIFO - in other words dev->rx_outstanding. So, in order to request enough bytes to fill the RX FIFO, we need to request dev->rx_fifo_depth - dev->rx_outstanding bytes. Modifying the code thusly results in us reaching the maximum number of bytes outstanding each time we queue more "receive" operations, provided the transfer allows that to happen. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
1 parent 2bf413d commit 4d6d5f1

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

drivers/i2c/busses/i2c-designware-core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
611611
if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
612612

613613
/* avoid rx buffer overrun */
614-
if (rx_limit - dev->rx_outstanding <= 0)
614+
if (dev->rx_outstanding >= dev->rx_fifo_depth)
615615
break;
616616

617617
dw_writel(dev, cmd | 0x100, DW_IC_DATA_CMD);

0 commit comments

Comments
 (0)