diff mbox series

[2/2] i2c: hisi: Add clearing tx aempty interrupt operation

Message ID 20240123080222.1512009-3-liudingyuan@huawei.com
State Superseded
Headers show
Series [1/2] i2c: hisi: Optimized the value setting of maxwrite limit to fifo depth - 1 | expand

Commit Message

Devyn Liu Jan. 23, 2024, 8:02 a.m. UTC
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@huawei.com>
---
 drivers/i2c/busses/i2c-hisi.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

Comments

Yicong Yang Feb. 1, 2024, 2:06 a.m. UTC | #1
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@huawei.com>

Reviewed-by: Yicong Yang <yangyicong@hisilicon.com>

> ---
>  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);
>  	}
>  
>
diff mbox series

Patch

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);
 	}