On 2024/1/23 16:02, Devyn Liu wrote: > The driver receives the tx fifo almost empty(aempty) interrupt and > reads the tx_aempty_int_mstat to start a round of data transfer. > The operation of clearing the TX aempty interrupt after completing > a write cycle is added to ensure that the FIFO is truly at almost > empty status when an aempty interrupt is received. > The threshold for fifo almost empty interrupt is defined as 1. > > Signed-off-by: Devyn Liu <liudingyuan@xxxxxxxxxx> Reviewed-by: Yicong Yang <yangyicong@xxxxxxxxxxxxx> > --- > drivers/i2c/busses/i2c-hisi.c | 11 +++++++++++ > 1 file changed, 11 insertions(+) > > diff --git a/drivers/i2c/busses/i2c-hisi.c b/drivers/i2c/busses/i2c-hisi.c > index 82a0c739aae4..08f6f97722a8 100644 > --- a/drivers/i2c/busses/i2c-hisi.c > +++ b/drivers/i2c/busses/i2c-hisi.c > @@ -57,6 +57,8 @@ > #define HISI_I2C_FS_SPK_LEN_CNT GENMASK(7, 0) > #define HISI_I2C_HS_SPK_LEN 0x003c > #define HISI_I2C_HS_SPK_LEN_CNT GENMASK(7, 0) > +#define HISI_I2C_TX_INT_CLR 0x0040 > +#define HISI_I2C_TX_AEMPTY_INT BIT(0) > #define HISI_I2C_INT_MSTAT 0x0044 > #define HISI_I2C_INT_CLR 0x0048 > #define HISI_I2C_INT_MASK 0x004C > @@ -124,6 +126,11 @@ static void hisi_i2c_clear_int(struct hisi_i2c_controller *ctlr, u32 mask) > writel_relaxed(mask, ctlr->iobase + HISI_I2C_INT_CLR); > } > > +static void hisi_i2c_clear_tx_int(struct hisi_i2c_controller *ctlr, u32 mask) > +{ > + writel_relaxed(mask, ctlr->iobase + HISI_I2C_TX_INT_CLR); > +} > + > static void hisi_i2c_handle_errors(struct hisi_i2c_controller *ctlr) > { > u32 int_err = ctlr->xfer_err, reg; > @@ -168,6 +175,7 @@ static int hisi_i2c_start_xfer(struct hisi_i2c_controller *ctlr) > writel(reg, ctlr->iobase + HISI_I2C_FIFO_CTRL); > > hisi_i2c_clear_int(ctlr, HISI_I2C_INT_ALL); > + hisi_i2c_clear_tx_int(ctlr, HISI_I2C_TX_AEMPTY_INT); > hisi_i2c_enable_int(ctlr, HISI_I2C_INT_ALL); > > return 0; > @@ -323,6 +331,8 @@ static void hisi_i2c_xfer_msg(struct hisi_i2c_controller *ctlr) > */ > if (ctlr->msg_tx_idx == ctlr->msg_num) > hisi_i2c_disable_int(ctlr, HISI_I2C_INT_TX_EMPTY); > + > + hisi_i2c_clear_tx_int(ctlr, HISI_I2C_TX_AEMPTY_INT); > } > > static irqreturn_t hisi_i2c_irq(int irq, void *context) > @@ -363,6 +373,7 @@ static irqreturn_t hisi_i2c_irq(int irq, void *context) > if (int_stat & HISI_I2C_INT_TRANS_CPLT) { > hisi_i2c_disable_int(ctlr, HISI_I2C_INT_ALL); > hisi_i2c_clear_int(ctlr, HISI_I2C_INT_ALL); > + hisi_i2c_clear_tx_int(ctlr, HISI_I2C_TX_AEMPTY_INT); > complete(ctlr->completion); > } > >