Re: [PATCH 4/4] i2c: xiic: Fix Tx Interrupt path for grouped messages

Michal Simek
2022-04-21T08:52:03Z

On 4/20/22 09:59, Shubhrajyoti Datta wrote:
> From: Raviteja Narayanam <raviteja.narayanam@xilinx.com>
>
> When a group of messages are sent from user space as a set, if
> the last message has less than Tx FIFO DEPTH number of bytes
> to transfer, Tx half empty interrupt is triggered continuously
> from the hardware. It is due to Bus not busy interrupt coming
> along with Tx half empty and tx empty.
>
> Hence, service the Tx interrupts before Bus not busy interrupt
> to update the i2c message status correctly.
>
> Signed-off-by: Raviteja Narayanam <raviteja.narayanam@xilinx.com>
> Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
> ---
> drivers/i2c/busses/i2c-xiic.c | 38 ++++++++++++++++++-----------------
> 1 file changed, 20 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
> index eb4d34e7c0fe..953f7cffe0d8 100644
> --- a/drivers/i2c/busses/i2c-xiic.c
> +++ b/drivers/i2c/busses/i2c-xiic.c
> @@ -468,24 +468,6 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
> }
> }
> }
> - if (pend & XIIC_INTR_BNB_MASK) {
> - /* IIC bus has transitioned to not busy */
> - clr |= XIIC_INTR_BNB_MASK;
> -
> - /* The bus is not busy, disable BusNotBusy interrupt */
> - xiic_irq_dis(i2c, XIIC_INTR_BNB_MASK);
> -
> - if (!i2c->tx_msg)
> - goto out;
> -
> - wakeup_req = 1;
> -
> - if (i2c->nmsgs == 1 && !i2c->rx_msg &&
> - xiic_tx_space(i2c) == 0)
> - wakeup_code = STATE_DONE;
> - else
> - wakeup_code = STATE_ERROR;
> - }
> if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
> /* Transmit register/FIFO is empty or ½ empty */
>
> @@ -522,6 +504,26 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
> */
> xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
> }
> +
> + if (pend & XIIC_INTR_BNB_MASK) {
> + /* IIC bus has transitioned to not busy */
> + clr |= XIIC_INTR_BNB_MASK;
> +
> + /* The bus is not busy, disable BusNotBusy interrupt */
> + xiic_irq_dis(i2c, XIIC_INTR_BNB_MASK);
> +
> + if (!i2c->tx_msg)
> + goto out;
> +
> + wakeup_req = 1;
> +
> + if (i2c->nmsgs == 1 && !i2c->rx_msg &&
> + xiic_tx_space(i2c) == 0)
> + wakeup_code = STATE_DONE;
> + else
> + wakeup_code = STATE_ERROR;
> + }
> +
> out:
> dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
>

Acked-by: Michal Simek <michal.simek@xilinx.com>

Thanks,
Michal