From: David Woodhouse While busy-waiting for completion, check the hardware after scheduling; don't schedule and then immediately check the _timeout_. If the yield() took a long time (as it does on my OLPC prototype board when it's busy), we'd report a timeout even though the hardware was now ready. This fixes it, and also switches the yield() for a cond_resched() because we don't actually want to be _that_ nice about it. I see nice tightly-packed SMBus transactions now, rather than waiting for milliseconds between successive phases. Actually, we shouldn't be busy-waiting here at all. We should be using interrupts. That's an exercise for another day though. Signed-off-by: David Woodhouse Cc: Christer Weinigel Cc: Signed-off-by: Andrew Morton --- drivers/i2c/busses/scx200_acb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff -puN drivers/i2c/busses/scx200_acb.c~scx200_acbeliminate-spurious-timeout-errors drivers/i2c/busses/scx200_acb.c --- a/drivers/i2c/busses/scx200_acb.c~scx200_acbeliminate-spurious-timeout-errors +++ a/drivers/i2c/busses/scx200_acb.c @@ -232,7 +232,7 @@ static void scx200_acb_poll(struct scx20 unsigned long timeout; timeout = jiffies + POLL_TIMEOUT; - while (time_before(jiffies, timeout)) { + while (1) { status = inb(ACBST); /* Reset the status register to avoid the hang */ @@ -242,7 +242,10 @@ static void scx200_acb_poll(struct scx20 scx200_acb_machine(iface, status); return; } - yield(); + if (time_after(jiffies, timeout)) + break; + cpu_relax(); + cond_resched(); } dev_err(&iface->adapter.dev, "timeout in state %s\n", _