From 3e3183bab0257a6d02038658c53b491e1378612f Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 5 Aug 2006 12:15:19 -0700 Subject: [PATCH] SCX200_ACB: eliminate spurious timeout errors 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 Signed-off-by: Linus Torvalds --- drivers/i2c/busses/scx200_acb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index ced309f..eae9e81 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -232,7 +232,7 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface) 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 scx200_acb_iface *iface) 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", -- cgit v1.1