Message ID | 20230906004910.4157305-1-tommy_huang@aspeedtech.com |
---|---|
State | Accepted |
Headers | show |
Series | [v3] i2c: aspeed: Reset the i2c controller when timeout occurs | expand |
On Wed, Sep 06, 2023 at 08:49:10AM +0800, Tommy Huang wrote: > Reset the i2c controller when an i2c transfer timeout occurs. > The remaining interrupts and device should be reset to avoid > unpredictable controller behavior. > > Fixes: 2e57b7cebb98 ("i2c: aspeed: Add multi-master use case support") > Cc: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> > Cc: <stable@vger.kernel.org> # v5.1+ > Signed-off-by: Tommy Huang <tommy_huang@aspeedtech.com> > Reviewed-by: Andi Shyti <andi.shyti@kernel.org> Applied to for-current, thanks!
diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index 2e5acfeb76c8..5a416b39b818 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -698,13 +698,16 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap, if (time_left == 0) { /* - * If timed out and bus is still busy in a multi master - * environment, attempt recovery at here. + * In a multi-master setup, if a timeout occurs, attempt + * recovery. But if the bus is idle, we still need to reset the + * i2c controller to clear the remaining interrupts. */ if (bus->multi_master && (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS)) aspeed_i2c_recover_bus(bus); + else + aspeed_i2c_reset(bus); /* * If timed out and the state is still pending, drop the pending