Commit 4bca93ab authored by Raviteja Narayanam's avatar Raviteja Narayanam Committed by Wolfram Sang
Browse files

i2c: xiic: Fix Tx Interrupt path for grouped messages



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: default avatarRaviteja Narayanam <raviteja.narayanam@xilinx.com>
Signed-off-by: default avatarShubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
Acked-by: default avatarMichal Simek <michal.simek@xilinx.com>
Signed-off-by: default avatarWolfram Sang <wsa@kernel.org>
parent b822039b
Loading
Loading
Loading
Loading
+20 −18
Original line number Diff line number Diff line
@@ -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);