|
@@ -173,8 +173,6 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id)
|
|
|
"interrupt: enabled_irqs=%04x, irq_status=%04x\n",
|
|
|
priv->enabled_irqs, irq_status);
|
|
|
|
|
|
- uniphier_fi2c_clear_irqs(priv, irq_status);
|
|
|
-
|
|
|
if (irq_status & UNIPHIER_FI2C_INT_STOP)
|
|
|
goto complete;
|
|
|
|
|
@@ -214,7 +212,13 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id)
|
|
|
|
|
|
if (irq_status & (UNIPHIER_FI2C_INT_RF | UNIPHIER_FI2C_INT_RB)) {
|
|
|
uniphier_fi2c_drain_rxfifo(priv);
|
|
|
- if (!priv->len)
|
|
|
+ /*
|
|
|
+ * If the number of bytes to read is multiple of the FIFO size
|
|
|
+ * (msg->len == 8, 16, 24, ...), the INT_RF bit is set a little
|
|
|
+ * earlier than INT_RB. We wait for INT_RB to confirm the
|
|
|
+ * completion of the current message.
|
|
|
+ */
|
|
|
+ if (!priv->len && (irq_status & UNIPHIER_FI2C_INT_RB))
|
|
|
goto data_done;
|
|
|
|
|
|
if (unlikely(priv->flags & UNIPHIER_FI2C_MANUAL_NACK)) {
|
|
@@ -253,6 +257,13 @@ complete:
|
|
|
}
|
|
|
|
|
|
handled:
|
|
|
+ /*
|
|
|
+ * This controller makes a pause while any bit of the IRQ status is
|
|
|
+ * asserted. Clear the asserted bit to kick the controller just before
|
|
|
+ * exiting the handler.
|
|
|
+ */
|
|
|
+ uniphier_fi2c_clear_irqs(priv, irq_status);
|
|
|
+
|
|
|
spin_unlock(&priv->lock);
|
|
|
|
|
|
return IRQ_HANDLED;
|