[PATCH] i2c: rk3x: Do not dispatch stale pending bits after a NAK
From: Alexey Charkov
Date: Thu Sep 17 2026 - 08:42:01 EST
A read that gets NAKed raises NAKRCV alongside the spurious START flag
which the controller sets on every read. The NAK branch acks NAKRCV and
calls rk3x_i2c_stop(), moving the state to STATE_STOP, but the leftover
START bit survives the REG_INT_ALL mask, so the state machine below runs
once more and dispatches it into rk3x_i2c_handle_stop().
That path finds no STOP bit, reports a bogus "unexpected irq in STOP",
replaces -ENXIO with -EIO and calls rk3x_i2c_clean_ipd(), which clears
the pending bit of the STOP that rk3x_i2c_stop() has just started. The
completion interrupt is lost, so the transfer only ends when the 1s
timeout expires, holding the adapter lock and stalling every other client
on the bus.
Return from the handler once the NAK has been acted upon.
Fixes: c41aa3ce938b ("i2c: rk3x: add driver for Rockchip RK3xxx SoC I2C adapter")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Alexey Charkov <alchark@xxxxxxxxxxx>
---
drivers/i2c/busses/i2c-rk3x.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
index fcede9f6ed54..7629ea7b6ac2 100644
--- a/drivers/i2c/busses/i2c-rk3x.c
+++ b/drivers/i2c/busses/i2c-rk3x.c
@@ -507,8 +507,18 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id)
ipd &= ~REG_INT_NAKRCV;
- if (!(i2c->msg->flags & I2C_M_IGNORE_NAK))
+ /*
+ * rk3x_i2c_stop() moves us to STATE_STOP and arms the STOP
+ * interrupt. The remaining pending bits belong to the state we
+ * just left, so stop processing them here: dispatching them
+ * into rk3x_i2c_handle_stop() would report a bogus "unexpected
+ * irq in STOP", replace -ENXIO with -EIO and clear the pending
+ * bits of the STOP we are waiting for.
+ */
+ if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
rk3x_i2c_stop(i2c, -ENXIO);
+ goto out;
+ }
}
/* is there anything left to handle? */
---
base-commit: 0d9d0dbf2fddcff5859d623e90ca73c4054276e1
change-id: 20260917-rk-i2c-stop-ff0e17be017d
Best regards,
--
Alexey Charkov <alchark@xxxxxxxxxxx>