Re: [PATCH v2] i2c: iproc: reset bus after timeout if START_BUSY is stuck
From: Mukesh Savaliya
Date: Fri Jul 17 2026 - 05:54:15 EST
On 7/17/2026 2:25 PM, Jonas Gorski wrote:
If a transaction times out, the START_BUSY signal can stay up, andWhat's exactly START_BUSY signal
subsequent transactaction attempts will fail as the bus is stilltransactaction => transaction
considered busy.what's here after it is, ? wanted to end the statement ?
I can easily trigger this by attempting to read from an address with no
device, e.g. when running i2cdetect. After the first read times out, all
subsequent read attempts return busy.
To get to a working state again, the controller needs to be reset to
clear the START_BUSY signal. So check for START_BUSY still asserted on a
timeout, and do reset in case it is,
This is also done by the original non-upstream iproc-smbus driverisn't there a max retry count ?
implementation [1].
Works around situations like:
bcm-iproc-2c 1803b000.i2c: transaction timed out
bcm-iproc-2c 1803b000.i2c: bus is busy
bcm-iproc-2c 1803b000.i2c: bus is busy
bcm-iproc-2c 1803b000.i2c: bus is busy
bcm-iproc-2c 1803b000.i2c: bus is busy
bcm-iproc-2c 1803b000.i2c: bus is busy
...
where the bus never recovers after a timeout.
[...]
if (!time_left && !iproc_i2c->xfer_is_done) {Make it simple ?
+ /*
+ * The controller may fail to clear START_BUSY after a timeout,
+ * reset the controller to recover in that case.
+ */
Recover controller if START_BUSY signal is high after timeout
+ if (!!(iproc_i2c_rd_reg(iproc_i2c, M_CMD_OFFSET) &
+ BIT(M_CMD_START_BUSY_SHIFT))) {
+ bcm_iproc_i2c_enable_disable(iproc_i2c, false);
+ bcm_iproc_i2c_init(iproc_i2c);
+ bcm_iproc_i2c_enable_disable(iproc_i2c, true);
+ }
+
/* flush both TX/RX FIFOs */
val = BIT(M_FIFO_RX_FLUSH_SHIFT) | BIT(M_FIFO_TX_FLUSH_SHIFT);
iproc_i2c_wr_reg(iproc_i2c, M_FIFO_CTRL_OFFSET, val);