From: Baolin Wang <baolin.wang@linux.alibaba.com>
To: Huangzheng Lai <Huangzheng.Lai@unisoc.com>,
Andi Shyti <andi.shyti@kernel.org>
Cc: Orson Zhai <orsonzhai@gmail.com>,
Chunyan Zhang <zhang.lyra@gmail.com>,
linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org,
huangzheng lai <laihuangzheng@gmail.com>,
Xiongpeng Wu <xiongpeng.wu@unisoc.com>
Subject: Re: [PATCH V2 3/7] i2c: sprd: Use global variables to record I2C ack/nack status instead of local variables
Date: Mon, 23 Oct 2023 19:32:17 +0800 [thread overview]
Message-ID: <27d2f363-e24a-736a-9c4e-cff79ff958e0@linux.alibaba.com> (raw)
In-Reply-To: <20231023081158.10654-4-Huangzheng.Lai@unisoc.com>
On 10/23/2023 4:11 PM, Huangzheng Lai wrote:
> We found that when the interrupt bit of the I2C controller is cleared,
> the ack/nack bit is also cleared at the same time. After clearing the
> interrupt bit in sprd_i2c_isr(), incorrect ack/nack information will be
> obtained in sprd_i2c_isr_thread(), resulting in incorrect communication
> when nack cannot be recognized. To solve this problem, we used a global
This is a hardware bug?
> variable to record ack/nack information before clearing the interrupt
> bit instead of a local variable.
>
> Fixes: 8b9ec0719834 ("i2c: Add Spreadtrum I2C controller driver")
> Cc: <stable@vger.kernel.org> # v4.14+
> Signed-off-by: Huangzheng Lai <Huangzheng.Lai@unisoc.com>
> ---
> drivers/i2c/busses/i2c-sprd.c | 11 ++++++-----
> 1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-sprd.c b/drivers/i2c/busses/i2c-sprd.c
> index aa602958d4fd..dec627ef408c 100644
> --- a/drivers/i2c/busses/i2c-sprd.c
> +++ b/drivers/i2c/busses/i2c-sprd.c
> @@ -85,6 +85,7 @@ struct sprd_i2c {
> struct clk *clk;
> u32 src_clk;
> u32 bus_freq;
> + bool ack_flag;
> struct completion complete;
> struct reset_control *rst;
> u8 *buf;
> @@ -119,6 +120,7 @@ static void sprd_i2c_clear_ack(struct sprd_i2c *i2c_dev)
> {
> u32 tmp = readl(i2c_dev->base + I2C_STATUS);
>
> + i2c_dev->ack_flag = 0;
> writel(tmp & ~I2C_RX_ACK, i2c_dev->base + I2C_STATUS);
> }
>
> @@ -393,7 +395,6 @@ static irqreturn_t sprd_i2c_isr_thread(int irq, void *dev_id)
> {
> struct sprd_i2c *i2c_dev = dev_id;
> struct i2c_msg *msg = i2c_dev->msg;
> - bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
Before this patch, we will re-read the ack bit form the register, but
now we just read it in sprd_i2c_isr(). Is it possible that we will miss
the ack bit?
> u32 i2c_tran;
>
> if (msg->flags & I2C_M_RD)
> @@ -409,7 +410,7 @@ static irqreturn_t sprd_i2c_isr_thread(int irq, void *dev_id)
> * For reading data, ack is always true, if i2c_tran is not 0 which
> * means we still need to contine to read data from slave.
> */
> - if (i2c_tran && ack) {
> + if (i2c_tran && i2c_dev->ack_flag) {
> sprd_i2c_data_transfer(i2c_dev);
> return IRQ_HANDLED;
> }
> @@ -420,7 +421,7 @@ static irqreturn_t sprd_i2c_isr_thread(int irq, void *dev_id)
> * If we did not get one ACK from slave when writing data, we should
> * return -EIO to notify users.
> */
> - if (!ack)
> + if (!i2c_dev->ack_flag)
> i2c_dev->err = -EIO;
> else if (msg->flags & I2C_M_RD && i2c_dev->count)
> sprd_i2c_read_bytes(i2c_dev, i2c_dev->buf, i2c_dev->count);
> @@ -437,7 +438,6 @@ static irqreturn_t sprd_i2c_isr(int irq, void *dev_id)
> {
> struct sprd_i2c *i2c_dev = dev_id;
> struct i2c_msg *msg = i2c_dev->msg;
> - bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
> u32 i2c_tran;
>
> if (msg->flags & I2C_M_RD)
> @@ -456,7 +456,8 @@ static irqreturn_t sprd_i2c_isr(int irq, void *dev_id)
> * means we can read all data in one time, then we can finish this
> * transmission too.
> */
> - if (!i2c_tran || !ack) {
> + i2c_dev->ack_flag = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
> + if (!i2c_tran || !i2c_dev->ack_flag) {
> sprd_i2c_clear_start(i2c_dev);
> sprd_i2c_clear_irq(i2c_dev);
> }
next prev parent reply other threads:[~2023-10-23 11:32 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-23 8:11 [PATCH V2 0/7] i2c: sprd: Modification of UNISOC Platform I2C Driver Huangzheng Lai
2023-10-23 8:11 ` [PATCH V2 1/7] i2c: sprd: Add configurations that support 1Mhz and 3.4Mhz frequencies Huangzheng Lai
2023-10-23 11:19 ` Baolin Wang
2023-10-24 20:45 ` Andi Shyti
2023-10-23 8:11 ` [PATCH V2 2/7] i2c: sprd: Add I2C driver to use 'reset framework' function Huangzheng Lai
2023-10-23 11:27 ` Baolin Wang
2023-11-03 11:59 ` Krzysztof Kozlowski
2023-10-23 8:11 ` [PATCH V2 3/7] i2c: sprd: Use global variables to record I2C ack/nack status instead of local variables Huangzheng Lai
2023-10-23 11:32 ` Baolin Wang [this message]
2023-11-06 3:01 ` huangzheng lai
2023-10-24 21:20 ` Andi Shyti
2023-11-06 9:02 ` huangzheng lai
2023-11-03 11:59 ` Krzysztof Kozlowski
2023-10-23 8:11 ` [PATCH V2 4/7] i2c: sprd: Add I2C controller driver to support dynamic switching of 400K/1M/3.4M frequency Huangzheng Lai
2023-10-23 11:37 ` Baolin Wang
2023-10-24 21:28 ` Andi Shyti
2023-10-23 8:11 ` [PATCH V2 5/7] i2c: sprd: Configure the enable bit of the I2C controller before each transmission initiation Huangzheng Lai
2023-10-24 21:35 ` Andi Shyti
2023-10-23 8:11 ` [PATCH V2 6/7] i2c: sprd: Increase the waiting time for I2C transmission to avoid system crash issues Huangzheng Lai
2023-10-23 11:39 ` Baolin Wang
2023-10-24 21:38 ` Andi Shyti
2023-10-23 8:11 ` [PATCH V2 7/7] i2c: sprd: Add I2C_NACK_EN and I2C_TRANS_EN control bits Huangzheng Lai
2023-10-23 11:43 ` Baolin Wang
2023-10-23 11:44 ` [PATCH V2 0/7] i2c: sprd: Modification of UNISOC Platform I2C Driver Baolin Wang
2023-10-24 21:40 ` Andi Shyti
-- strict thread matches above, loose matches on Subject: below --
2023-09-21 8:54 Huangzheng Lai
2023-09-21 8:54 ` [PATCH V2 3/7] i2c: sprd: Use global variables to record I2C ack/nack status instead of local variables Huangzheng Lai
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=27d2f363-e24a-736a-9c4e-cff79ff958e0@linux.alibaba.com \
--to=baolin.wang@linux.alibaba.com \
--cc=Huangzheng.Lai@unisoc.com \
--cc=andi.shyti@kernel.org \
--cc=laihuangzheng@gmail.com \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=orsonzhai@gmail.com \
--cc=xiongpeng.wu@unisoc.com \
--cc=zhang.lyra@gmail.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.