[linux-yocto] [PATCH 01/15] i2c-axxia: Avoid timeout when interrupt delayed
Charlie Paul
cpaul.windriver at gmail.com
Mon Apr 28 17:13:36 PDT 2014
From: Anders Berg <anders.berg at 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.berg at 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 86fc695..cd68166 100644
--- a/drivers/i2c/busses/i2c-axxia.c
+++ b/drivers/i2c/busses/i2c-axxia.c
@@ -332,33 +332,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_dbg(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);
@@ -371,6 +344,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_dbg(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;
}
--
1.7.9.5
More information about the linux-yocto
mailing list