From: George Cherian <george.cherian@cavium.com>
To: linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: wsa@the-dreams.de, jglauber@cavium.com,
kamlakant.patel@cavium.com, mchehab+samsung@kernel.org,
davem@davemloft.net, gregkh@linuxfoundation.org,
akpm@linux-foundation.org, linus.walleij@linaro.org,
rdunlap@infradead.org, george.cherian@cavium.com,
Jayachandran C <jnair@caviumnetworks.com>
Subject: [PATCH 2/4] i2c: xlp9xx: Fix issue seen when updating receive length
Date: Wed, 16 May 2018 00:00:17 -0700 [thread overview]
Message-ID: <1526454019-32714-3-git-send-email-george.cherian@cavium.com> (raw)
In-Reply-To: <1526454019-32714-1-git-send-email-george.cherian@cavium.com>
The hardware does not handle updates to the length register gracefully
if the new value is less than the number of bytes received so far. If
this happens, the i2c controller will not stop the receive transaction
properly.
Fix this by ensuring that the updated length is ok. This is done by
making sure that the new length written to hardware is at least few
bytes more than the bytes received so far.
While at that refactor the length updation to a new function.
Signed-off-by: Jayachandran C <jnair@caviumnetworks.com>
Signed-off-by: George Cherian <george.cherian@cavium.com>
---
drivers/i2c/busses/i2c-xlp9xx.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/busses/i2c-xlp9xx.c b/drivers/i2c/busses/i2c-xlp9xx.c
index fe54512..c268fde 100644
--- a/drivers/i2c/busses/i2c-xlp9xx.c
+++ b/drivers/i2c/busses/i2c-xlp9xx.c
@@ -158,9 +158,28 @@ static void xlp9xx_i2c_fill_tx_fifo(struct xlp9xx_i2c_dev *priv)
priv->msg_buf += len;
}
+static void xlp9xx_i2c_update_rlen(struct xlp9xx_i2c_dev *priv)
+{
+ u32 val, len;
+
+ /*
+ * Update receive length. Re-read len to get the latest value,
+ * and then add 4 to have a minimum value that can be safely
+ * written. This is to account for the byte read above, the
+ * transfer in progress and any delays in the register I/O
+ */
+ val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL);
+ len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) &
+ XLP9XX_I2C_FIFO_WCNT_MASK;
+ len = max_t(u32, priv->msg_len, len + 4);
+ val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
+ (len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
+ xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val);
+}
+
static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv)
{
- u32 len, i, val;
+ u32 len, i;
u8 rlen, *buf = priv->msg_buf;
len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) &
@@ -171,20 +190,13 @@ static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv)
/* read length byte */
rlen = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);
*buf++ = rlen;
- len--;
-
if (priv->client_pec)
++rlen;
/* update remaining bytes and message length */
priv->msg_buf_remaining = rlen;
priv->msg_len = rlen + 1;
priv->len_recv = false;
-
- /* Update transfer length to read only actual data */
- val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL);
- val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
- ((rlen + 1) << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
- xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val);
+ xlp9xx_i2c_update_rlen(priv);
} else {
len = min(priv->msg_buf_remaining, len);
for (i = 0; i < len; i++, buf++)
--
1.8.3.1
next prev parent reply other threads:[~2018-05-16 7:00 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-16 7:00 [PATCH 0/4] i2c-xlp9xx Add support for SMBAlert and minor fixes George Cherian
2018-05-16 7:00 ` [PATCH 1/4] i2c: xlp9xx: Add support for SMBAlert George Cherian
2018-05-22 12:08 ` Wolfram Sang
2018-05-16 7:00 ` George Cherian [this message]
2018-05-22 12:08 ` [PATCH 2/4] i2c: xlp9xx: Fix issue seen when updating receive length Wolfram Sang
2018-05-16 7:00 ` [PATCH 3/4] i2c: xlp9xx: Make sure the transfer size is not more than I2C_SMBUS_BLOCK_SIZE George Cherian
2018-05-22 12:08 ` Wolfram Sang
2018-05-16 7:00 ` [PATCH 4/4] i2c: xlp9xx: Add MAINTAINERS entry George Cherian
2018-05-22 11:54 ` Wolfram Sang
2018-05-22 11:57 ` Jan Glauber
2018-05-22 12:09 ` Wolfram Sang
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=1526454019-32714-3-git-send-email-george.cherian@cavium.com \
--to=george.cherian@cavium.com \
--cc=akpm@linux-foundation.org \
--cc=davem@davemloft.net \
--cc=gregkh@linuxfoundation.org \
--cc=jglauber@cavium.com \
--cc=jnair@caviumnetworks.com \
--cc=kamlakant.patel@cavium.com \
--cc=linus.walleij@linaro.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mchehab+samsung@kernel.org \
--cc=rdunlap@infradead.org \
--cc=wsa@the-dreams.de \
/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).