* [PATCH v5 0/3] i2c: imx: Fix handling of arbitration loss
@ 2020-10-07 8:45 Christian Eggers
2020-10-07 8:45 ` [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag Christian Eggers
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Christian Eggers @ 2020-10-07 8:45 UTC (permalink / raw)
To: Oleksij Rempel, Shawn Guo, Sascha Hauer, Fabio Estevam,
Uwe Kleine-König, David Laight
Cc: linux-kernel, Krzysztof Kozlowski, NXP Linux Team,
Pengutronix Kernel Team, Christian Eggers, linux-arm-kernel,
linux-i2c
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
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag
2020-10-07 8:45 [PATCH v5 0/3] i2c: imx: Fix handling of arbitration loss Christian Eggers
@ 2020-10-07 8:45 ` Christian Eggers
2020-10-08 9:56 ` Wolfram Sang
2020-10-09 7:11 ` Oleksij Rempel
2020-10-07 8:45 ` [PATCH v5 2/3] i2c: imx: Check for I2SR_IAL after every byte Christian Eggers
2020-10-07 8:45 ` [PATCH v5 3/3] i2c: imx: Don't generate STOP condition if arbitration has been lost Christian Eggers
2 siblings, 2 replies; 9+ messages in thread
From: Christian Eggers @ 2020-10-07 8:45 UTC (permalink / raw)
To: Oleksij Rempel, Shawn Guo, Sascha Hauer, Fabio Estevam,
Uwe Kleine-König, David Laight
Cc: linux-kernel, Krzysztof Kozlowski, NXP Linux Team,
Pengutronix Kernel Team, stable, Christian Eggers,
linux-arm-kernel, linux-i2c
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 <ceggers@arri.de>
Fixes: 4b775022f6fd ("i2c: imx: add struct to hold more configurable quirks")
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Cc: stable@vger.kernel.org
---
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
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v5 2/3] i2c: imx: Check for I2SR_IAL after every byte
2020-10-07 8:45 [PATCH v5 0/3] i2c: imx: Fix handling of arbitration loss Christian Eggers
2020-10-07 8:45 ` [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag Christian Eggers
@ 2020-10-07 8:45 ` Christian Eggers
2020-10-09 7:53 ` Oleksij Rempel
2020-10-07 8:45 ` [PATCH v5 3/3] i2c: imx: Don't generate STOP condition if arbitration has been lost Christian Eggers
2 siblings, 1 reply; 9+ messages in thread
From: Christian Eggers @ 2020-10-07 8:45 UTC (permalink / raw)
To: Oleksij Rempel, Shawn Guo, Sascha Hauer, Fabio Estevam,
Uwe Kleine-König, David Laight
Cc: linux-kernel, Krzysztof Kozlowski, NXP Linux Team,
Pengutronix Kernel Team, stable, Christian Eggers,
linux-arm-kernel, linux-i2c
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 <ceggers@arri.de>
Tested (not extensively) on Vybrid VF500 (Toradex VF50):
Tested-by: Krzysztof Kozlowski <krzk@kernel.org>
Cc: stable@vger.kernel.org
---
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
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v5 3/3] i2c: imx: Don't generate STOP condition if arbitration has been lost
2020-10-07 8:45 [PATCH v5 0/3] i2c: imx: Fix handling of arbitration loss Christian Eggers
2020-10-07 8:45 ` [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag Christian Eggers
2020-10-07 8:45 ` [PATCH v5 2/3] i2c: imx: Check for I2SR_IAL after every byte Christian Eggers
@ 2020-10-07 8:45 ` Christian Eggers
2020-10-09 8:14 ` Oleksij Rempel
2 siblings, 1 reply; 9+ messages in thread
From: Christian Eggers @ 2020-10-07 8:45 UTC (permalink / raw)
To: Oleksij Rempel, Shawn Guo, Sascha Hauer, Fabio Estevam,
Uwe Kleine-König, David Laight
Cc: linux-kernel, Krzysztof Kozlowski, NXP Linux Team,
Pengutronix Kernel Team, stable, Christian Eggers,
linux-arm-kernel, linux-i2c
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 <ceggers@arri.de>
Tested (not extensively) on Vybrid VF500 (Toradex VF50):
Tested-by: Krzysztof Kozlowski <krzk@kernel.org>
Cc: stable@vger.kernel.org # 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
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag
2020-10-07 8:45 ` [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag Christian Eggers
@ 2020-10-08 9:56 ` Wolfram Sang
2020-10-09 7:11 ` Oleksij Rempel
1 sibling, 0 replies; 9+ messages in thread
From: Wolfram Sang @ 2020-10-08 9:56 UTC (permalink / raw)
To: Christian Eggers
Cc: Shawn Guo, Sascha Hauer, linux-kernel, Krzysztof Kozlowski,
Oleksij Rempel, David Laight, NXP Linux Team,
Pengutronix Kernel Team, Uwe Kleine-König, stable,
Fabio Estevam, linux-arm-kernel, linux-i2c
[-- Attachment #1.1: Type: text/plain, Size: 616 bytes --]
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 <ceggers@arri.de>
> Fixes: 4b775022f6fd ("i2c: imx: add struct to hold more configurable quirks")
> Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> Cc: stable@vger.kernel.org
Applied to for-current, thanks!
Waiting for review tags for patches 2 & 3.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag
2020-10-07 8:45 ` [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag Christian Eggers
2020-10-08 9:56 ` Wolfram Sang
@ 2020-10-09 7:11 ` Oleksij Rempel
2020-10-09 7:52 ` Oleksij Rempel
1 sibling, 1 reply; 9+ messages in thread
From: Oleksij Rempel @ 2020-10-09 7:11 UTC (permalink / raw)
To: Christian Eggers
Cc: Shawn Guo, Sascha Hauer, linux-kernel, Krzysztof Kozlowski,
Oleksij Rempel, David Laight, NXP Linux Team,
Pengutronix Kernel Team, Uwe Kleine-König, stable,
Fabio Estevam, linux-arm-kernel, linux-i2c
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 <ceggers@arri.de>
> Fixes: 4b775022f6fd ("i2c: imx: add struct to hold more configurable quirks")
> Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> Cc: stable@vger.kernel.org
> ---
> 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 <o.rempel@pengutronix.de>
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 |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag
2020-10-09 7:11 ` Oleksij Rempel
@ 2020-10-09 7:52 ` Oleksij Rempel
0 siblings, 0 replies; 9+ messages in thread
From: Oleksij Rempel @ 2020-10-09 7:52 UTC (permalink / raw)
To: Christian Eggers
Cc: Shawn Guo, Sascha Hauer, linux-kernel, Krzysztof Kozlowski,
Oleksij Rempel, David Laight, NXP Linux Team,
Pengutronix Kernel Team, Uwe Kleine-König, stable,
Fabio Estevam, linux-arm-kernel, linux-i2c
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 <ceggers@arri.de>
> > Fixes: 4b775022f6fd ("i2c: imx: add struct to hold more configurable quirks")
> > Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> > Cc: stable@vger.kernel.org
> > ---
> > 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 <o.rempel@pengutronix.de>
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 |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 2/3] i2c: imx: Check for I2SR_IAL after every byte
2020-10-07 8:45 ` [PATCH v5 2/3] i2c: imx: Check for I2SR_IAL after every byte Christian Eggers
@ 2020-10-09 7:53 ` Oleksij Rempel
0 siblings, 0 replies; 9+ messages in thread
From: Oleksij Rempel @ 2020-10-09 7:53 UTC (permalink / raw)
To: Christian Eggers
Cc: Shawn Guo, Sascha Hauer, linux-kernel, Krzysztof Kozlowski,
Oleksij Rempel, David Laight, NXP Linux Team,
Pengutronix Kernel Team, Uwe Kleine-König, stable,
Fabio Estevam, linux-arm-kernel, linux-i2c
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 <ceggers@arri.de>
> Tested (not extensively) on Vybrid VF500 (Toradex VF50):
> Tested-by: Krzysztof Kozlowski <krzk@kernel.org>
> Cc: stable@vger.kernel.org
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
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 |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 3/3] i2c: imx: Don't generate STOP condition if arbitration has been lost
2020-10-07 8:45 ` [PATCH v5 3/3] i2c: imx: Don't generate STOP condition if arbitration has been lost Christian Eggers
@ 2020-10-09 8:14 ` Oleksij Rempel
0 siblings, 0 replies; 9+ messages in thread
From: Oleksij Rempel @ 2020-10-09 8:14 UTC (permalink / raw)
To: Christian Eggers
Cc: Shawn Guo, Sascha Hauer, linux-kernel, Krzysztof Kozlowski,
Oleksij Rempel, David Laight, NXP Linux Team,
Pengutronix Kernel Team, Uwe Kleine-König, stable,
Fabio Estevam, linux-arm-kernel, linux-i2c
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 <ceggers@arri.de>
> Tested (not extensively) on Vybrid VF500 (Toradex VF50):
> Tested-by: Krzysztof Kozlowski <krzk@kernel.org>
> Cc: stable@vger.kernel.org # Requires trivial backporting, simple remove
> # the 3rd argument from the calls to
> # i2c_imx_bus_busy().
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
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
> linux-arm-kernel@lists.infradead.org
> 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 |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2020-10-09 8:16 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-07 8:45 [PATCH v5 0/3] i2c: imx: Fix handling of arbitration loss Christian Eggers
2020-10-07 8:45 ` [PATCH v5 1/3] i2c: imx: Fix reset of I2SR_IAL flag Christian Eggers
2020-10-08 9:56 ` Wolfram Sang
2020-10-09 7:11 ` Oleksij Rempel
2020-10-09 7:52 ` Oleksij Rempel
2020-10-07 8:45 ` [PATCH v5 2/3] i2c: imx: Check for I2SR_IAL after every byte Christian Eggers
2020-10-09 7:53 ` Oleksij Rempel
2020-10-07 8:45 ` [PATCH v5 3/3] i2c: imx: Don't generate STOP condition if arbitration has been lost Christian Eggers
2020-10-09 8:14 ` Oleksij Rempel
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).