2020-10-07 08:49:01

by Christian Eggers

[permalink] [raw]
Subject: [PATCH v5 0/3] i2c: imx: Fix handling of arbitration loss

Changes in v2:
---------------
- Don't accidently clear additional status flags on Vybrid
(reported by Uwe Kleine-Koenig)

Changes in v3:
---------------
- dedicated function for clearing an irq

Changes in v4:
---------------
- Extend comment (W1C vs. W0C)

Changes in v5:
---------------
- Added missing "Tested-By" tags.

Best regards
Christian



2020-10-07 08:50:02

by Christian Eggers

[permalink] [raw]
Subject: [PATCH v5 2/3] i2c: imx: Check for I2SR_IAL after every byte

Arbitration Lost (IAL) can happen after every single byte transfer. If
arbitration is lost, the I2C hardware will autonomously switch from
master mode to slave. If a transfer is not aborted in this state,
consecutive transfers will not be executed by the hardware and will
timeout.

Signed-off-by: Christian Eggers <[email protected]>
Tested (not extensively) on Vybrid VF500 (Toradex VF50):
Tested-by: Krzysztof Kozlowski <[email protected]>
Cc: [email protected]
---
drivers/i2c/busses/i2c-imx.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index cbdcab73a055..63575af41c09 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -490,6 +490,16 @@ static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx, bool atomic)
dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__);
return -ETIMEDOUT;
}
+
+ /* check for arbitration lost */
+ if (i2c_imx->i2csr & I2SR_IAL) {
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> Arbitration lost\n", __func__);
+ i2c_imx_clear_irq(i2c_imx, I2SR_IAL);
+
+ i2c_imx->i2csr = 0;
+ return -EAGAIN;
+ }
+
dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__);
i2c_imx->i2csr = 0;
return 0;
--
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler

2020-10-07 08:52:03

by Christian Eggers

[permalink] [raw]
Subject: [PATCH v5 3/3] i2c: imx: Don't generate STOP condition if arbitration has been lost

If arbitration is lost, the master automatically changes to slave mode.
I2SR_IBB may or may not be reset by hardware. Raising a STOP condition
by resetting I2CR_MSTA has no effect and will not clear I2SR_IBB.

So calling i2c_imx_bus_busy() is not required and would busy-wait until
timeout.

Signed-off-by: Christian Eggers <[email protected]>
Tested (not extensively) on Vybrid VF500 (Toradex VF50):
Tested-by: Krzysztof Kozlowski <[email protected]>
Cc: [email protected] # Requires trivial backporting, simple remove
# the 3rd argument from the calls to
# i2c_imx_bus_busy().
---
drivers/i2c/busses/i2c-imx.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 63575af41c09..5d8a79319b2b 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -615,6 +615,8 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx, bool atomic)
/* Stop I2C transaction */
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+ if (!(temp & I2CR_MSTA))
+ i2c_imx->stopped = 1;
temp &= ~(I2CR_MSTA | I2CR_MTX);
if (i2c_imx->dma)
temp &= ~I2CR_DMAEN;
@@ -778,9 +780,12 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
*/
dev_dbg(dev, "<%s> clear MSTA\n", __func__);
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+ if (!(temp & I2CR_MSTA))
+ i2c_imx->stopped = 1;
temp &= ~(I2CR_MSTA | I2CR_MTX);
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
- i2c_imx_bus_busy(i2c_imx, 0, false);
+ if (!i2c_imx->stopped)
+ i2c_imx_bus_busy(i2c_imx, 0, false);
} else {
/*
* For i2c master receiver repeat restart operation like:
@@ -905,9 +910,12 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs,
dev_dbg(&i2c_imx->adapter.dev,
"<%s> clear MSTA\n", __func__);
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+ if (!(temp & I2CR_MSTA))
+ i2c_imx->stopped = 1;
temp &= ~(I2CR_MSTA | I2CR_MTX);
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
- i2c_imx_bus_busy(i2c_imx, 0, atomic);
+ if (!i2c_imx->stopped)
+ i2c_imx_bus_busy(i2c_imx, 0, atomic);
} else {
/*
* For i2c master receiver repeat restart operation like:
--
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler

2020-10-07 15:26:19

by Christian Eggers

[permalink] [raw]
Subject: [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag

According to the "VFxxx Controller Reference Manual" (and the comment
block starting at line 97), Vybrid requires writing a one for clearing
an interrupt flag. Syncing the method for clearing I2SR_IIF in
i2c_imx_isr().

Signed-off-by: Christian Eggers <[email protected]>
Fixes: 4b775022f6fd ("i2c: imx: add struct to hold more configurable quirks")
Reviewed-by: Uwe Kleine-König <[email protected]>
Cc: [email protected]
---
drivers/i2c/busses/i2c-imx.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 0ab5381aa012..cbdcab73a055 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -412,6 +412,19 @@ static void i2c_imx_dma_free(struct imx_i2c_struct *i2c_imx)
dma->chan_using = NULL;
}

+static void i2c_imx_clear_irq(struct imx_i2c_struct *i2c_imx, unsigned int bits)
+{
+ unsigned int temp;
+
+ /*
+ * i2sr_clr_opcode is the value to clear all interrupts. Here we want to
+ * clear only <bits>, so we write ~i2sr_clr_opcode with just <bits>
+ * toggled. This is required because i.MX needs W1C and Vybrid uses W0C.
+ */
+ temp = ~i2c_imx->hwdata->i2sr_clr_opcode ^ bits;
+ imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
+}
+
static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool atomic)
{
unsigned long orig_jiffies = jiffies;
@@ -424,8 +437,7 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool a

/* check for arbitration lost */
if (temp & I2SR_IAL) {
- temp &= ~I2SR_IAL;
- imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
+ i2c_imx_clear_irq(i2c_imx, I2SR_IAL);
return -EAGAIN;
}

@@ -623,9 +635,7 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
if (temp & I2SR_IIF) {
/* save status register */
i2c_imx->i2csr = temp;
- temp &= ~I2SR_IIF;
- temp |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF);
- imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
+ i2c_imx_clear_irq(i2c_imx, I2SR_IIF);
wake_up(&i2c_imx->queue);
return IRQ_HANDLED;
}
--
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler

2020-10-08 10:00:36

by Wolfram Sang

[permalink] [raw]
Subject: Re: [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag

On Wed, Oct 07, 2020 at 10:45:22AM +0200, Christian Eggers wrote:
> According to the "VFxxx Controller Reference Manual" (and the comment
> block starting at line 97), Vybrid requires writing a one for clearing
> an interrupt flag. Syncing the method for clearing I2SR_IIF in
> i2c_imx_isr().
>
> Signed-off-by: Christian Eggers <[email protected]>
> Fixes: 4b775022f6fd ("i2c: imx: add struct to hold more configurable quirks")
> Reviewed-by: Uwe Kleine-König <[email protected]>
> Cc: [email protected]

Applied to for-current, thanks!

Waiting for review tags for patches 2 & 3.


Attachments:
(No filename) (616.00 B)
signature.asc (849.00 B)
Download all attachments

2020-10-09 07:14:25

by Oleksij Rempel

[permalink] [raw]
Subject: Re: [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag

Hi Christian,

On Wed, Oct 07, 2020 at 10:45:22AM +0200, Christian Eggers wrote:
> According to the "VFxxx Controller Reference Manual" (and the comment
> block starting at line 97), Vybrid requires writing a one for clearing
> an interrupt flag. Syncing the method for clearing I2SR_IIF in
> i2c_imx_isr().
>
> Signed-off-by: Christian Eggers <[email protected]>
> Fixes: 4b775022f6fd ("i2c: imx: add struct to hold more configurable quirks")
> Reviewed-by: Uwe Kleine-König <[email protected]>
> Cc: [email protected]
> ---
> drivers/i2c/busses/i2c-imx.c | 20 +++++++++++++++-----
> 1 file changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index 0ab5381aa012..cbdcab73a055 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -412,6 +412,19 @@ static void i2c_imx_dma_free(struct imx_i2c_struct *i2c_imx)
> dma->chan_using = NULL;
> }
>
> +static void i2c_imx_clear_irq(struct imx_i2c_struct *i2c_imx, unsigned int bits)
> +{
> + unsigned int temp;
> +
> + /*
> + * i2sr_clr_opcode is the value to clear all interrupts. Here we want to
> + * clear only <bits>, so we write ~i2sr_clr_opcode with just <bits>
> + * toggled. This is required because i.MX needs W1C and Vybrid uses W0C.
> + */

This comment need correction. The i.MX needs W0C and Vybrid uses W1C

> + temp = ~i2c_imx->hwdata->i2sr_clr_opcode ^ bits;
> + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
> +}
> +
> static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool atomic)
> {
> unsigned long orig_jiffies = jiffies;
> @@ -424,8 +437,7 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool a
>
> /* check for arbitration lost */
> if (temp & I2SR_IAL) {
> - temp &= ~I2SR_IAL;
> - imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
> + i2c_imx_clear_irq(i2c_imx, I2SR_IAL);
> return -EAGAIN;
> }
>
> @@ -623,9 +635,7 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
> if (temp & I2SR_IIF) {
> /* save status register */
> i2c_imx->i2csr = temp;
> - temp &= ~I2SR_IIF;
> - temp |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF);
> - imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
> + i2c_imx_clear_irq(i2c_imx, I2SR_IIF);
> wake_up(&i2c_imx->queue);
> return IRQ_HANDLED;
> }
> --

Otherwise

Acked-by: Oleksij Rempel <[email protected]>

Regards,
Oleksij
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2020-10-09 07:58:01

by Oleksij Rempel

[permalink] [raw]
Subject: Re: [PATCH v5 2/3] i2c: imx: Check for I2SR_IAL after every byte

On Wed, Oct 07, 2020 at 10:45:23AM +0200, Christian Eggers wrote:
> Arbitration Lost (IAL) can happen after every single byte transfer. If
> arbitration is lost, the I2C hardware will autonomously switch from
> master mode to slave. If a transfer is not aborted in this state,
> consecutive transfers will not be executed by the hardware and will
> timeout.
>
> Signed-off-by: Christian Eggers <[email protected]>
> Tested (not extensively) on Vybrid VF500 (Toradex VF50):
> Tested-by: Krzysztof Kozlowski <[email protected]>
> Cc: [email protected]

Acked-by: Oleksij Rempel <[email protected]>

Thank you!

> ---
> drivers/i2c/busses/i2c-imx.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index cbdcab73a055..63575af41c09 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -490,6 +490,16 @@ static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx, bool atomic)
> dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__);
> return -ETIMEDOUT;
> }
> +
> + /* check for arbitration lost */
> + if (i2c_imx->i2csr & I2SR_IAL) {
> + dev_dbg(&i2c_imx->adapter.dev, "<%s> Arbitration lost\n", __func__);
> + i2c_imx_clear_irq(i2c_imx, I2SR_IAL);
> +
> + i2c_imx->i2csr = 0;
> + return -EAGAIN;
> + }
> +
> dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__);
> i2c_imx->i2csr = 0;
> return 0;
> --
> Christian Eggers
> Embedded software developer
>
> Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
> Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
> Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
> Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
> Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler
>
>
>

--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2020-10-09 08:16:25

by Oleksij Rempel

[permalink] [raw]
Subject: Re: [PATCH v5 3/3] i2c: imx: Don't generate STOP condition if arbitration has been lost

On Wed, Oct 07, 2020 at 10:45:24AM +0200, Christian Eggers wrote:
> If arbitration is lost, the master automatically changes to slave mode.
> I2SR_IBB may or may not be reset by hardware. Raising a STOP condition
> by resetting I2CR_MSTA has no effect and will not clear I2SR_IBB.
>
> So calling i2c_imx_bus_busy() is not required and would busy-wait until
> timeout.
>
> Signed-off-by: Christian Eggers <[email protected]>
> Tested (not extensively) on Vybrid VF500 (Toradex VF50):
> Tested-by: Krzysztof Kozlowski <[email protected]>
> Cc: [email protected] # Requires trivial backporting, simple remove
> # the 3rd argument from the calls to
> # i2c_imx_bus_busy().

Acked-by: Oleksij Rempel <[email protected]>
Thank you!


> ---
> drivers/i2c/busses/i2c-imx.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index 63575af41c09..5d8a79319b2b 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -615,6 +615,8 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx, bool atomic)
> /* Stop I2C transaction */
> dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
> temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
> + if (!(temp & I2CR_MSTA))
> + i2c_imx->stopped = 1;
> temp &= ~(I2CR_MSTA | I2CR_MTX);
> if (i2c_imx->dma)
> temp &= ~I2CR_DMAEN;
> @@ -778,9 +780,12 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
> */
> dev_dbg(dev, "<%s> clear MSTA\n", __func__);
> temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
> + if (!(temp & I2CR_MSTA))
> + i2c_imx->stopped = 1;
> temp &= ~(I2CR_MSTA | I2CR_MTX);
> imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
> - i2c_imx_bus_busy(i2c_imx, 0, false);
> + if (!i2c_imx->stopped)
> + i2c_imx_bus_busy(i2c_imx, 0, false);
> } else {
> /*
> * For i2c master receiver repeat restart operation like:
> @@ -905,9 +910,12 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs,
> dev_dbg(&i2c_imx->adapter.dev,
> "<%s> clear MSTA\n", __func__);
> temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
> + if (!(temp & I2CR_MSTA))
> + i2c_imx->stopped = 1;
> temp &= ~(I2CR_MSTA | I2CR_MTX);
> imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
> - i2c_imx_bus_busy(i2c_imx, 0, atomic);
> + if (!i2c_imx->stopped)
> + i2c_imx_bus_busy(i2c_imx, 0, atomic);
> } else {
> /*
> * For i2c master receiver repeat restart operation like:
> --
> Christian Eggers
> Embedded software developer
>
> Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
> Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
> Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
> Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
> Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2020-10-09 10:51:30

by Oleksij Rempel

[permalink] [raw]
Subject: Re: [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag

On Fri, Oct 09, 2020 at 09:11:32AM +0200, Oleksij Rempel wrote:
> Hi Christian,
>
> On Wed, Oct 07, 2020 at 10:45:22AM +0200, Christian Eggers wrote:
> > According to the "VFxxx Controller Reference Manual" (and the comment
> > block starting at line 97), Vybrid requires writing a one for clearing
> > an interrupt flag. Syncing the method for clearing I2SR_IIF in
> > i2c_imx_isr().
> >
> > Signed-off-by: Christian Eggers <[email protected]>
> > Fixes: 4b775022f6fd ("i2c: imx: add struct to hold more configurable quirks")
> > Reviewed-by: Uwe Kleine-König <[email protected]>
> > Cc: [email protected]
> > ---
> > drivers/i2c/busses/i2c-imx.c | 20 +++++++++++++++-----
> > 1 file changed, 15 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> > index 0ab5381aa012..cbdcab73a055 100644
> > --- a/drivers/i2c/busses/i2c-imx.c
> > +++ b/drivers/i2c/busses/i2c-imx.c
> > @@ -412,6 +412,19 @@ static void i2c_imx_dma_free(struct imx_i2c_struct *i2c_imx)
> > dma->chan_using = NULL;
> > }
> >
> > +static void i2c_imx_clear_irq(struct imx_i2c_struct *i2c_imx, unsigned int bits)
> > +{
> > + unsigned int temp;
> > +
> > + /*
> > + * i2sr_clr_opcode is the value to clear all interrupts. Here we want to
> > + * clear only <bits>, so we write ~i2sr_clr_opcode with just <bits>
> > + * toggled. This is required because i.MX needs W1C and Vybrid uses W0C.
> > + */
>
> This comment need correction. The i.MX needs W0C and Vybrid uses W1C
>
> > + temp = ~i2c_imx->hwdata->i2sr_clr_opcode ^ bits;
> > + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
> > +}
> > +
> > static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool atomic)
> > {
> > unsigned long orig_jiffies = jiffies;
> > @@ -424,8 +437,7 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool a
> >
> > /* check for arbitration lost */
> > if (temp & I2SR_IAL) {
> > - temp &= ~I2SR_IAL;
> > - imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
> > + i2c_imx_clear_irq(i2c_imx, I2SR_IAL);
> > return -EAGAIN;
> > }
> >
> > @@ -623,9 +635,7 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
> > if (temp & I2SR_IIF) {
> > /* save status register */
> > i2c_imx->i2csr = temp;
> > - temp &= ~I2SR_IIF;
> > - temp |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF);
> > - imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
> > + i2c_imx_clear_irq(i2c_imx, I2SR_IIF);
> > wake_up(&i2c_imx->queue);
> > return IRQ_HANDLED;
> > }
> > --
>
> Otherwise
>
> Acked-by: Oleksij Rempel <[email protected]>

By reviewing the second patch we found at least one more missing Vybrid
related case in the i2c_imx_trx_complete() function:
imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR);

this is OK for iMX by broken on Vybrid.

Since you already fixing it in this patch for some of IMX_I2C_I2SR
writes, please do it here as well. This is the last unhandled case...:)

Regards,
Oleksij
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |