diff -r a7cbfe0ab659 linux/drivers/media/common/saa7146_core.c --- a/linux/drivers/media/common/saa7146_core.c Mon Aug 13 23:42:26 2007 +0200 +++ b/linux/drivers/media/common/saa7146_core.c Sun Aug 19 09:10:43 2007 +0200 @@ -63,6 +63,10 @@ int saa7146_wait_for_debi_done(struct sa { unsigned long start; int err; + int loop; + u32 psr; + int err_start, err_stop, err_start_jiffies, err_stop_jiffies; + int ret = 0; /* wait for registers to be programmed */ start = jiffies; @@ -79,20 +83,58 @@ int saa7146_wait_for_debi_done(struct sa } /* wait for transfer to complete */ + loop = 0; + err_start = -1; + err_stop = -1; 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; + ret = -ETIMEDOUT; + break; + } +#if 0 + /* 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")); + ret = -EIO; + break; + } +#endif + if ((psr & SPCI_DEBI_E) && err_start == -1) { + err_start_jiffies = jiffies; + err_start = loop; + } + if (!(psr & SPCI_DEBI_E) && err_start >= 0 && err_stop == -1) { + err_stop_jiffies = jiffies; + err_stop = loop; + } + if (nobusyloop) { + msleep(1); + loop += 1000; + } else { + udelay(10); + loop += 10; + } + } + if (err_start >= 0) { + if (err_stop < 0) { + err_stop_jiffies = jiffies; + err_stop = loop; } if (nobusyloop) - msleep(1); - } - + printk("(%s:%d) %s: SEBI_E was active for %d(%d)msec\n", + __FILE__, __LINE__, dev->name, (err_stop - err_start) / 1000, + jiffies_to_msecs(err_stop_jiffies - err_start_jiffies)); + else + printk("(%s:%d) %s: SEBI_E was active for %dusec\n", + __FILE__, __LINE__, dev->name, err_stop - err_start); + } return 0; }