Re: [PATCH v2] i2c: iproc: reset bus after timeout if START_BUSY is stuck

Mukesh Savaliya <[email protected]>
Newsgroups org.kernel.vger.linux-i2c,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>

On 7/17/2026 2:25 PM, Jonas Gorski wrote:
> If a transaction times out, the START_BUSY signal can stay up, and
What's exactly START_BUSY signal
> subsequent transactaction attempts will fail as the bus is still
transactaction => transaction
> considered busy.
> 
> 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,
> 
what's here after it is, ? wanted to end the statement ?
> This is also done by the original non-upstream iproc-smbus driver
> 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.
isn't there a max retry count ?
> 
[...]
>   	if (!time_left && !iproc_i2c->xfer_is_done) {
> +		/*
> +		 * The controller may fail to clear START_BUSY after a timeout,
> +		 * reset the controller to recover in that case.
> +		 */
Make it simple ?
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);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.