signed off by: Hartmut Birr diff -r dc1611a2006f linux/drivers/media/common/saa7146_core.c --- a/linux/drivers/media/common/saa7146_core.c Fri Aug 17 17:49:41 2007 -0300 +++ b/linux/drivers/media/common/saa7146_core.c Sat Aug 18 10:45:08 2007 +0200 @@ -63,6 +63,8 @@ int saa7146_wait_for_debi_done(struct sa { unsigned long start; int err; + int loop; + u32 psr; /* wait for registers to be programmed */ start = jiffies; @@ -79,20 +81,31 @@ int saa7146_wait_for_debi_done(struct sa } /* wait for transfer to complete */ + loop = 0; start = jiffies; while (1) { err = time_after(jiffies, start + HZ/4); - if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S)) + psr = saa7146_read(dev, PSR); + if (!(psr & SPCI_DEBI_S)) break; saa7146_read(dev, MC2); if (err) { DEB_S(("timed out while waiting for transfer completion\n")); return -ETIMEDOUT; } - if (nobusyloop) + /* leave the loop, if the DEBI_E isn't reset after 500usec */ + if (loop >= 500 && (psr & SPCI_DEBI_E)) { + DEB_S(("error while waiting for transfer completion\n")); + return -EIO; + } + if (nobusyloop) { msleep(1); - } - + loop += 1000; + } else { + udelay(10); + loop += 10; + } + } return 0; }