5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tommy Huang tommy_huang@aspeedtech.com
commit fee465150b458351b6d9b9f66084f3cc3022b88b upstream.
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: stable@vger.kernel.org # v5.1+ Signed-off-by: Tommy Huang tommy_huang@aspeedtech.com Reviewed-by: Andi Shyti andi.shyti@kernel.org Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/i2c/busses/i2c-aspeed.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -693,13 +693,16 @@ static int aspeed_i2c_master_xfer(struct
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