Message ID | 1416014452-6712-1-git-send-email-al.kochet@gmail.com |
---|---|
State | Superseded |
Headers | show |
On Sat, Nov 15, 2014 at 05:20:51AM +0400, 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. > Assuming this is really correct (I haven't tested), you need to add: Fixes: 1d7afc9 i2c: omap: ack IRQ in parts Cc: <stable@vger.kernel.org> # v3.7+ here and resend, so it gets backported to older kernels. > 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; > } > > /* > -- > 1.7.9.5 >
> Assuming this is really correct (I haven't tested), you need to add: To help understanding logic, I'd like to provide event traces (with the patch applied): See i2c-omap.c dc418f6e6a8f5021ccf9e9c0957eefae3737168d as a reference. https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/i2c/busses/i2c-omap.c?id=dc418f6e6a8f5021ccf9e9c0957eefae3737168d Typical event sequence for Arbitration Lost case looks like: addr: 0x0058, len: 4, flags: 0x1, stop: 1 omap_i2c_xfer_msg:564 (STAT=0x0140; IE=0x601f; CON=0x8200) omap_i2c_xfer_msg:565 omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); omap_i2c_xfer_msg:566 (STAT=0x0140; IE=0x601f; CON=0x8403) omap_i2c_isr:886 (STAT=0x1141; IE=0x601f; CON=0x8000) omap_i2c_isr_thread:906 (STAT=0x1141; IE=0x601f; CON=0x8000) IRQ (ISR = 0x0001) Arbitration lost Typical event sequence for NACK case looks like: addr: 0x0068, len: 4, flags: 0x1, stop: 1 omap_i2c_xfer_msg:564 (STAT=0x0040; IE=0x601f; CON=0x8000) omap_i2c_xfer_msg:566 (STAT=0x0040; IE=0x601f; CON=0x8403) omap_i2c_isr:886 (STAT=0x0146; IE=0x601f; CON=0x8000) omap_i2c_isr_thread:906 (STAT=0x0146; IE=0x601f; CON=0x8000) IRQ (ISR = 0x0006) NACK IRQ (ISR = 0x0004) ARDY omap_i2c_isr_thread:1030 (STAT=0x0140; IE=0x601f; CON=0x8000) > > Fixes: 1d7afc9 i2c: omap: ack IRQ in parts > Cc: <stable@vger.kernel.org> # v3.7+ > > here and resend, so it gets backported to older kernels. > I'll resend. Thanks. -- 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 --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; } /*
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(-)