omap: i2c: add a timeout to the busy waiting
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@slind.org> Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
This commit is contained in:
parent
2dd151ab27
commit
e9f59b9c9b
|
@ -763,17 +763,25 @@ omap_i2c_rev1_isr(int this_irq, void *dev_id)
|
|||
*/
|
||||
static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
|
||||
{
|
||||
while (!(*stat & OMAP_I2C_STAT_XUDF)) {
|
||||
unsigned long timeout = 10000;
|
||||
|
||||
while (--timeout && !(*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 |
|
||||
OMAP_I2C_STAT_XDR));
|
||||
*err |= OMAP_I2C_STAT_XUDF;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
cpu_relax();
|
||||
*stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
|
||||
}
|
||||
|
||||
if (!timeout) {
|
||||
dev_err(dev->dev, "timeout waiting on XUDF bit\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue