Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26ac14e2 authored by Oliver Endriss's avatar Oliver Endriss Committed by Mauro Carvalho Chehab
Browse files

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: default avatarOliver Endriss <o.endriss@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent cb20630c
Loading
Loading
Loading
Loading
+58 −12
Original line number Original line Diff line number Diff line
@@ -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
 ****************************************************************************/
 ****************************************************************************/