Skip to content

Commit

Permalink
omap: i2c: add a timeout to the busy waiting
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alexander Shishkin authored and Ben Dooks committed May 19, 2010
1 parent 2dd151a commit e9f59b9
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion drivers/i2c/busses/i2c-omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down

0 comments on commit e9f59b9

Please sign in to comment.