diff mbox

i2c: omap: fix NACK and Arbitration Lost irq handling

Message ID 1416013976-6441-1-git-send-email-al.kochet@gmail.com
State Superseded
Headers show

Commit Message

Alexander Kochetkov Nov. 15, 2014, 1:12 a.m. UTC
commit 1d7afc95946487945cc7f5019b41255b72224b70 (i2c: omap: ack IRQ in parts)
changed the interrupt handler to complete transfers without clearing
XRDY (AL case) and ARDY (NACK case) flags. XRDY or ARDY interrupt will be
fired again (in parallel with omap_i2c_xfer_msg). Interrupt handler will
complete transfers second time. As a result, NACK and AL transfers
terminates with "transfer timeout" and sometimes client code segfault.

The patch restore original logic of handling NACK and AL interrupts and
fix race between interrupt handler and omap_i2c_xfer_msg (for AL and
NACK case only).

Tested on Beagleboard XM C.

Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
---
 drivers/i2c/busses/i2c-omap.c |    2 --
 1 file changed, 2 deletions(-)

Comments

Grygorii Strashko Nov. 17, 2014, 2:41 p.m. UTC | #1
On 11/15/2014 03:12 AM, Alexander Kochetkov wrote:
> commit 1d7afc95946487945cc7f5019b41255b72224b70 (i2c: omap: ack IRQ in parts)
> changed the interrupt handler to complete transfers without clearing
> XRDY (AL case) and ARDY (NACK case) flags. XRDY or ARDY interrupt will be
> fired again (in parallel with omap_i2c_xfer_msg). Interrupt handler will
> complete transfers second time. As a result, NACK and AL transfers
> terminates with "transfer timeout" and sometimes client code segfault.
>
> The patch restore original logic of handling NACK and AL interrupts and
> fix race between interrupt handler and omap_i2c_xfer_msg (for AL and
> NACK case only).
>
> Tested on Beagleboard XM C.

Seems you've got the same issue as I :) long time ago
https://lkml.org/lkml/2013/6/7/530

>
> Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
> ---
>   drivers/i2c/busses/i2c-omap.c |    2 --
>   1 file changed, 2 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index 90dcc2e..9af7095 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -926,14 +926,12 @@ omap_i2c_isr_thread(int this_irq, void *dev_id)
>   		if (stat & OMAP_I2C_STAT_NACK) {
>   			err |= OMAP_I2C_STAT_NACK;
>   			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
> -			break;
>   		}
>
>   		if (stat & OMAP_I2C_STAT_AL) {
>   			dev_err(dev->dev, "Arbitration lost\n");
>   			err |= OMAP_I2C_STAT_AL;
>   			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL);
> -			break;
>   		}
>
>   		/*
>

--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 90dcc2e..9af7095 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -926,14 +926,12 @@  omap_i2c_isr_thread(int this_irq, void *dev_id)
 		if (stat & OMAP_I2C_STAT_NACK) {
 			err |= OMAP_I2C_STAT_NACK;
 			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
-			break;
 		}
 
 		if (stat & OMAP_I2C_STAT_AL) {
 			dev_err(dev->dev, "Arbitration lost\n");
 			err |= OMAP_I2C_STAT_AL;
 			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL);
-			break;
 		}
 
 		/*