For the case that msg->len is 0(I2C_SMBUS_QUICK), when the interrupt occurs, it means that the access has completed, viai2c_irq_xfer() should return 1. v1->v2: Added some code comments; The commit log is adjusted. Link: https://lore.kernel.org/all/20240311032600.56244-2-hanshu-oc@xxxxxxxxxxx/ Signed-off-by: Hans Hu <hanshu-oc@xxxxxxxxxxx> --- drivers/i2c/busses/i2c-viai2c-common.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-viai2c-common.c b/drivers/i2c/busses/i2c-viai2c-common.c index 4c208b3a509e..fbb76d7ea3b0 100644 --- a/drivers/i2c/busses/i2c-viai2c-common.c +++ b/drivers/i2c/busses/i2c-viai2c-common.c @@ -123,6 +123,14 @@ int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) return (ret < 0) ? ret : i; } +/* + * Main process of the byte mode xfer + * + * Return value indicates whether the transfer is complete + * 1: all the data has been successfully transferred + * 0: there is still data that needs to be transferred + * -EIO: error occurred + */ static int viai2c_irq_xfer(struct viai2c *i2c) { u16 val; @@ -142,10 +150,11 @@ static int viai2c_irq_xfer(struct viai2c *i2c) if (val & VIAI2C_CSR_RCV_NOT_ACK) return -EIO; + /* I2C_SMBUS_QUICK */ if (msg->len == 0) { val = VIAI2C_CR_TX_END | VIAI2C_CR_CPU_RDY | VIAI2C_CR_ENABLE; writew(val, base + VIAI2C_REG_CR); - return 0; + return 1; } if ((i2c->xfered_len + 1) == msg->len) { @@ -195,6 +204,7 @@ static irqreturn_t viai2c_isr(int irq, void *data) i2c->ret = viai2c_fifo_irq_xfer(i2c, true); } + /* All the data has been successfully transferred or error occurred */ if (i2c->ret) complete(&i2c->complete); -- 2.34.1