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