The errata 1.153 workaround is busy waiting on XUDF bit in interrupt context, which may lead to kernel hangs. The problem can be reproduced by running the bus with wrong (too high) speed. Signed-off-by: Alexander Shishkin <virtuoso@xxxxxxxxx> CC: linux-i2c@xxxxxxxxxxxxxxx CC: linux-omap@xxxxxxxxxxxxxxx CC: nm@xxxxxx --- drivers/i2c/busses/i2c-omap.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 2d146ac..7d56a25 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -678,6 +678,8 @@ omap_i2c_rev1_isr(int this_irq, void *dev_id) */ static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err) { + unsigned long timeout = jiffies + msecs_to_jiffies(1); + while (!(*stat & OMAP_I2C_STAT_XUDF)) { if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY | @@ -685,6 +687,12 @@ static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err) *err |= OMAP_I2C_STAT_XUDF; return -ETIMEDOUT; } + + if (time_after(jiffies, timeout)) { + dev_err(dev->dev, "timeout waiting on XUDF bit\n"); + return 0; + } + cpu_relax(); *stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); } -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html