From: Marek Vasut <marex@denx.de>
To: linux-i2c@vger.kernel.org
Cc: Marek Vasut <marex@denx.de>,
Michal Simek <michal.simek@xilinx.com>,
Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>,
Wolfram Sang <wsa@kernel.org>
Subject: [PATCH 3/5] i2c: xiic: Defer xiic_wakeup() and __xiic_start_xfer() in xiic_process()
Date: Sat, 13 Jun 2020 17:07:49 +0200 [thread overview]
Message-ID: <20200613150751.114595-3-marex@denx.de> (raw)
In-Reply-To: <20200613150751.114595-1-marex@denx.de>
The __xiic_start_xfer() manipulates the interrupt flags, xiic_wakeup()
may result in return from xiic_xfer() early. Defer both to the end of
the xiic_process() interrupt thread, so that they are executed after
all the other interrupt bits handling completed and once it completely
safe to perform changes to the interrupt bits in the hardware.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
Cc: Wolfram Sang <wsa@kernel.org>
---
drivers/i2c/busses/i2c-xiic.c | 37 ++++++++++++++++++++++++-----------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index 6db71c0fb6583..87eca9d46afd9 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -373,6 +373,9 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
struct xiic_i2c *i2c = dev_id;
u32 pend, isr, ier;
u32 clr = 0;
+ int xfer_more = 0;
+ int wakeup_req = 0;
+ int wakeup_code = 0;
/* Get the interrupt Status from the IPIF. There is no clearing of
* interrupts in the IPIF. Interrupts must be cleared at the source.
@@ -409,10 +412,14 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
*/
xiic_reinit(i2c);
- if (i2c->rx_msg)
- xiic_wakeup(i2c, STATE_ERROR);
- if (i2c->tx_msg)
- xiic_wakeup(i2c, STATE_ERROR);
+ if (i2c->rx_msg) {
+ wakeup_req = 1;
+ wakeup_code = STATE_ERROR;
+ }
+ if (i2c->tx_msg) {
+ wakeup_req = 1;
+ wakeup_code = STATE_ERROR;
+ }
}
if (pend & XIIC_INTR_RX_FULL_MASK) {
/* Receive register/FIFO is full */
@@ -446,8 +453,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
i2c->tx_msg++;
dev_dbg(i2c->adap.dev.parent,
"%s will start next...\n", __func__);
-
- __xiic_start_xfer(i2c);
+ xfer_more = 1;
}
}
}
@@ -461,11 +467,13 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
if (!i2c->tx_msg)
goto out;
- if ((i2c->nmsgs == 1) && !i2c->rx_msg &&
- xiic_tx_space(i2c) == 0)
- xiic_wakeup(i2c, STATE_DONE);
+ wakeup_req = 1;
+
+ if (i2c->nmsgs == 1 && !i2c->rx_msg &&
+ xiic_tx_space(i2c) == 0)
+ wakeup_code = STATE_DONE;
else
- xiic_wakeup(i2c, STATE_ERROR);
+ wakeup_code = STATE_ERROR;
}
if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
/* Transmit register/FIFO is empty or ½ empty */
@@ -489,7 +497,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
if (i2c->nmsgs > 1) {
i2c->nmsgs--;
i2c->tx_msg++;
- __xiic_start_xfer(i2c);
+ xfer_more = 1;
} else {
xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
@@ -507,6 +515,13 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr);
+ if (xfer_more)
+ __xiic_start_xfer(i2c);
+ if (wakeup_req)
+ xiic_wakeup(i2c, wakeup_code);
+
+ WARN_ON(xfer_more && wakeup_req);
+
mutex_unlock(&i2c->lock);
return IRQ_HANDLED;
}
--
2.26.2
next prev parent reply other threads:[~2020-06-13 15:08 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-13 15:07 [PATCH 1/5] i2c: xiic: Fix broken locking on tx_msg Marek Vasut
2020-06-13 15:07 ` [PATCH 2/5] i2c: xiic: Drop broken interrupt handler Marek Vasut
2020-06-17 12:25 ` Shubhrajyoti Datta
2020-06-17 12:31 ` Marek Vasut
2020-06-26 12:13 ` Raviteja Narayanam
2020-06-28 23:41 ` Marek Vasut
2020-06-29 12:52 ` Raviteja Narayanam
2020-06-29 21:50 ` Marek Vasut
2020-07-08 15:23 ` Raviteja Narayanam
2020-08-19 17:42 ` Marek Vasut
2020-08-24 8:27 ` Raviteja Narayanam
2020-08-24 11:58 ` Marek Vasut
2020-08-25 9:44 ` Raviteja Narayanam
2020-08-25 20:50 ` Marek Vasut
2020-09-07 8:51 ` Raviteja Narayanam
2020-09-08 14:04 ` Marek Vasut
2020-09-11 10:28 ` Michal Simek
2020-06-13 15:07 ` Marek Vasut [this message]
2020-06-26 12:13 ` [PATCH 3/5] i2c: xiic: Defer xiic_wakeup() and __xiic_start_xfer() in xiic_process() Raviteja Narayanam
2020-07-08 15:23 ` Raviteja Narayanam
2020-06-13 15:07 ` [PATCH 4/5] i2c: xiic: Switch from waitqueue to completion Marek Vasut
2020-06-26 12:13 ` Raviteja Narayanam
2020-06-28 23:41 ` Marek Vasut
2020-06-29 12:53 ` Raviteja Narayanam
2020-06-29 21:52 ` Marek Vasut
2020-06-13 15:07 ` [PATCH 5/5] i2c: xiic: Only ever transfer single message Marek Vasut
2020-06-13 19:33 ` Wolfram Sang
2020-06-13 19:37 ` Marek Vasut
2020-06-13 19:42 ` Wolfram Sang
2020-07-13 8:37 ` Michal Simek
2020-06-26 12:14 ` Raviteja Narayanam
2020-06-26 12:11 ` [PATCH 1/5] i2c: xiic: Fix broken locking on tx_msg Raviteja Narayanam
2020-06-28 23:18 ` Marek Vasut
2020-06-29 12:52 ` Raviteja Narayanam
2020-07-08 15:23 ` Raviteja Narayanam
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200613150751.114595-3-marex@denx.de \
--to=marex@denx.de \
--cc=linux-i2c@vger.kernel.org \
--cc=michal.simek@xilinx.com \
--cc=shubhrajyoti.datta@xilinx.com \
--cc=wsa@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).