V4L/DVB (6495): saa7146: saa7146_wait_for_debi_done fixes
Two fixes for the 'saa7146_wait_for_debi_done' code: (a) Timeout did not work when the routine was called with interrupts disabled. (b) Reduce PCI I/O load caused by saa7146_wait_for_debi_done. Seems to be very important on fast machines! Based on code posted by Hartmut Birr @vdr-portal. Signed-off-by: Oliver Endriss <o.endriss@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
cb20630cef
commit
26ac14e24f
|
@ -59,43 +59,89 @@ void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
|
/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
|
||||||
int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
|
static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev,
|
||||||
|
unsigned long us1, unsigned long us2)
|
||||||
{
|
{
|
||||||
unsigned long start;
|
unsigned long timeout;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* wait for registers to be programmed */
|
/* wait for registers to be programmed */
|
||||||
start = jiffies;
|
timeout = jiffies + usecs_to_jiffies(us1);
|
||||||
while (1) {
|
while (1) {
|
||||||
err = time_after(jiffies, start + HZ/20);
|
err = time_after(jiffies, timeout);
|
||||||
if (saa7146_read(dev, MC2) & 2)
|
if (saa7146_read(dev, MC2) & 2)
|
||||||
break;
|
break;
|
||||||
if (err) {
|
if (err) {
|
||||||
DEB_S(("timed out while waiting for registers getting programmed\n"));
|
printk(KERN_ERR "%s: %s timed out while waiting for "
|
||||||
|
"registers getting programmed\n",
|
||||||
|
dev->name, __FUNCTION__);
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
if (nobusyloop)
|
|
||||||
msleep(1);
|
msleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for transfer to complete */
|
/* wait for transfer to complete */
|
||||||
start = jiffies;
|
timeout = jiffies + usecs_to_jiffies(us2);
|
||||||
while (1) {
|
while (1) {
|
||||||
err = time_after(jiffies, start + HZ/4);
|
err = time_after(jiffies, timeout);
|
||||||
if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
|
if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
|
||||||
break;
|
break;
|
||||||
saa7146_read(dev, MC2);
|
saa7146_read(dev, MC2);
|
||||||
if (err) {
|
if (err) {
|
||||||
DEB_S(("timed out while waiting for transfer completion\n"));
|
DEB_S(("%s: %s timed out while waiting for transfer "
|
||||||
|
"completion\n", dev->name, __FUNCTION__));
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
if (nobusyloop)
|
|
||||||
msleep(1);
|
msleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev,
|
||||||
|
unsigned long us1, unsigned long us2)
|
||||||
|
{
|
||||||
|
unsigned long loops;
|
||||||
|
|
||||||
|
/* wait for registers to be programmed */
|
||||||
|
loops = us1;
|
||||||
|
while (1) {
|
||||||
|
if (saa7146_read(dev, MC2) & 2)
|
||||||
|
break;
|
||||||
|
if (!loops--) {
|
||||||
|
printk(KERN_ERR "%s: %s timed out while waiting for "
|
||||||
|
"registers getting programmed\n",
|
||||||
|
dev->name, __FUNCTION__);
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
udelay(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wait for transfer to complete */
|
||||||
|
loops = us2 / 5;
|
||||||
|
while (1) {
|
||||||
|
if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
|
||||||
|
break;
|
||||||
|
saa7146_read(dev, MC2);
|
||||||
|
if (!loops--) {
|
||||||
|
DEB_S(("%s: %s timed out while waiting for transfer "
|
||||||
|
"completion\n", dev->name, __FUNCTION__));
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
udelay(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
|
||||||
|
{
|
||||||
|
if (nobusyloop)
|
||||||
|
return saa7146_wait_for_debi_done_sleep(dev, 50000, 250000);
|
||||||
|
else
|
||||||
|
return saa7146_wait_for_debi_done_busyloop(dev, 50000, 250000);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* general helper functions
|
* general helper functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
Loading…
Reference in New Issue