drivers/media/mc/mc-entity.c

Source file repositories/reference/linux-study-clean/drivers/media/mc/mc-entity.c

File Facts

System
Linux kernel
Corpus path
drivers/media/mc/mc-entity.c
Extension
.c
Size
41304 bytes
Lines
1676
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

struct media_pipeline_walk_entry {
	struct media_pad *pad;
	struct list_head *links;
};

/**
 * struct media_pipeline_walk - State used by the media pipeline traversal
 *				algorithm
 *
 * @mdev: The media device
 * @stack: Depth-first search stack
 * @stack.size: Number of allocated entries in @stack.entries
 * @stack.top: Index of the top stack entry (-1 if the stack is empty)
 * @stack.entries: Stack entries
 */
struct media_pipeline_walk {
	struct media_device *mdev;

	struct {
		unsigned int size;
		int top;
		struct media_pipeline_walk_entry *entries;
	} stack;
};

#define MEDIA_PIPELINE_STACK_GROW_STEP		16

static struct media_pipeline_walk_entry *
media_pipeline_walk_top(struct media_pipeline_walk *walk)
{
	return &walk->stack.entries[walk->stack.top];
}

static bool media_pipeline_walk_empty(struct media_pipeline_walk *walk)
{
	return walk->stack.top == -1;
}

/* Increase the stack size by MEDIA_PIPELINE_STACK_GROW_STEP elements. */
static int media_pipeline_walk_resize(struct media_pipeline_walk *walk)
{
	struct media_pipeline_walk_entry *entries;
	unsigned int new_size;

	/* Safety check, to avoid stack overflows in case of bugs. */
	if (walk->stack.size >= 256)
		return -E2BIG;

	new_size = walk->stack.size + MEDIA_PIPELINE_STACK_GROW_STEP;

	entries = krealloc(walk->stack.entries,
			   new_size * sizeof(*walk->stack.entries),
			   GFP_KERNEL);
	if (!entries)
		return -ENOMEM;

	walk->stack.entries = entries;
	walk->stack.size = new_size;

	return 0;
}

/* Push a new entry on the stack. */
static int media_pipeline_walk_push(struct media_pipeline_walk *walk,
				    struct media_pad *pad)
{
	struct media_pipeline_walk_entry *entry;
	int ret;

	if (walk->stack.top + 1 >= walk->stack.size) {
		ret = media_pipeline_walk_resize(walk);
		if (ret)
			return ret;
	}

	walk->stack.top++;
	entry = media_pipeline_walk_top(walk);
	entry->pad = pad;
	entry->links = pad->entity->links.next;

	dev_dbg(walk->mdev->dev,
		"media pipeline: pushed entry %u: '%s':%u\n",
		walk->stack.top, pad->entity->name, pad->index);

	return 0;
}

/*
 * Move the top entry link cursor to the next link. If all links of the entry
 * have been visited, pop the entry itself. Return true if the entry has been

Annotation

Implementation Notes