drivers/media/common/saa7146/saa7146_core.c

Source file repositories/reference/linux-study-clean/drivers/media/common/saa7146/saa7146_core.c

File Facts

System
Linux kernel
Corpus path
drivers/media/common/saa7146/saa7146_core.c
Extension
.c
Size
14109 bytes
Lines
567
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (err) {
			pr_debug("%s: %s timed out while waiting for registers getting programmed\n",
			       dev->name, __func__);
			return -ETIMEDOUT;
		}
		msleep(1);
	}

	/* wait for transfer to complete */
	timeout = jiffies + usecs_to_jiffies(us2);
	while (1) {
		err = time_after(jiffies, timeout);
		if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
			break;
		saa7146_read(dev, MC2);
		if (err) {
			DEB_S("%s: %s timed out while waiting for transfer completion\n",
			      dev->name, __func__);
			return -ETIMEDOUT;
		}
		msleep(1);
	}

	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--) {
			pr_err("%s: %s timed out while waiting for registers getting programmed\n",
			       dev->name, __func__);
			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, __func__);
			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
 ****************************************************************************/

/* this is videobuf_vmalloc_to_sg() from videobuf-dma-sg.c
   make sure virt has been allocated with vmalloc_32(), otherwise return NULL
   on highmem machines */
static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
{
	struct scatterlist *sglist;
	struct page *pg;
	int i;

	sglist = kmalloc_objs(struct scatterlist, nr_pages);
	if (NULL == sglist)
		return NULL;
	sg_init_table(sglist, nr_pages);
	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
		pg = vmalloc_to_page(virt);
		if (NULL == pg)
			goto err;

Annotation

Implementation Notes