From: Anders Berg <anders.b...@lsi.com>

Changed the order in which the interrupt conditions are checked in the
interrupt handler. Need to check for transfer-complete before timeout-error,
otherwise a delayed interrupt may report a false timeout error (since the
timeout may expire after the transfer was completed).

Signed-off-by: Anders Berg <anders.b...@lsi.com>
---
 drivers/i2c/busses/i2c-axxia.c |   50 ++++++++++++++++++----------------------
 1 file changed, 23 insertions(+), 27 deletions(-)

diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c
index e58292b..43b433b 100644
--- a/drivers/i2c/busses/i2c-axxia.c
+++ b/drivers/i2c/busses/i2c-axxia.c
@@ -334,33 +334,6 @@ axxia_i2c_isr(int irq, void *_dev)
        /* Clear interrupt */
        writel(0x01, &idev->regs->interrupt_status);
 
-       if (unlikely(status & MST_STATUS_ERR)) {
-               idev->msg_err = status & MST_STATUS_ERR;
-               i2c_int_disable(idev, ~0);
-               dev_err(idev->dev, "error %s, rx=%u/%u tx=%u/%u\n",
-                       status_str(idev->msg_err),
-                       readl(&idev->regs->mst_rx_bytes_xfrd),
-                       readl(&idev->regs->mst_rx_xfer),
-                       readl(&idev->regs->mst_tx_bytes_xfrd),
-                       readl(&idev->regs->mst_tx_xfer));
-               complete(&idev->msg_complete);
-               return IRQ_HANDLED;
-       }
-
-       /* Stop completed? */
-       if (status & MST_STATUS_SCC) {
-               i2c_int_disable(idev, ~0);
-               complete(&idev->msg_complete);
-       }
-
-       /* Transfer done? */
-       if (status & (MST_STATUS_SNS | MST_STATUS_SS)) {
-               if (i2c_m_rd(idev->msg) && idev->msg_xfrd < idev->msg->len)
-                       axxia_i2c_empty_rx_fifo(idev);
-               i2c_int_disable(idev, ~0);
-               complete(&idev->msg_complete);
-       }
-
        /* RX FIFO needs service? */
        if (i2c_m_rd(idev->msg) && (status & MST_STATUS_RFL))
                axxia_i2c_empty_rx_fifo(idev);
@@ -373,6 +346,29 @@ axxia_i2c_isr(int irq, void *_dev)
                        i2c_int_disable(idev, MST_STATUS_TFL);
        }
 
+       if (status & MST_STATUS_SCC) {
+               /* Stop completed? */
+               i2c_int_disable(idev, ~0);
+               complete(&idev->msg_complete);
+       } else if (status & (MST_STATUS_SNS | MST_STATUS_SS)) {
+               /* Transfer done? */
+               if (i2c_m_rd(idev->msg) && idev->msg_xfrd < idev->msg->len)
+                       axxia_i2c_empty_rx_fifo(idev);
+               i2c_int_disable(idev, ~0);
+               complete(&idev->msg_complete);
+       } else if (unlikely(status & MST_STATUS_ERR)) {
+               /* Transfer error? */
+               idev->msg_err = status & MST_STATUS_ERR;
+               i2c_int_disable(idev, ~0);
+               dev_err(idev->dev, "error %s, rx=%u/%u tx=%u/%u\n",
+                       status_str(status),
+                       readl(&idev->regs->mst_rx_bytes_xfrd),
+                       readl(&idev->regs->mst_rx_xfer),
+                       readl(&idev->regs->mst_tx_bytes_xfrd),
+                       readl(&idev->regs->mst_tx_xfer));
+               complete(&idev->msg_complete);
+       }
+
        return IRQ_HANDLED;
 }
 
-- 
1.7.9.5

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to