drivers/media/platform/xilinx/xilinx-vipp.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/xilinx/xilinx-vipp.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/xilinx/xilinx-vipp.c
Extension
.c
Size
15075 bytes
Lines
626
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source 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 xvip_graph_entity {
	struct v4l2_async_connection asd; /* must be first */
	struct media_entity *entity;
	struct v4l2_subdev *subdev;
};

static inline struct xvip_graph_entity *
to_xvip_entity(struct v4l2_async_connection *asd)
{
	return container_of(asd, struct xvip_graph_entity, asd);
}

/* -----------------------------------------------------------------------------
 * Graph Management
 */

static struct xvip_graph_entity *
xvip_graph_find_entity(struct xvip_composite_device *xdev,
		       const struct fwnode_handle *fwnode)
{
	struct xvip_graph_entity *entity;
	struct v4l2_async_connection *asd;
	struct list_head *lists[] = {
		&xdev->notifier.done_list,
		&xdev->notifier.waiting_list
	};
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(lists); i++) {
		list_for_each_entry(asd, lists[i], asc_entry) {
			entity = to_xvip_entity(asd);
			if (entity->asd.match.fwnode == fwnode)
				return entity;
		}
	}

	return NULL;
}

static int xvip_graph_build_one(struct xvip_composite_device *xdev,
				struct xvip_graph_entity *entity)
{
	u32 link_flags = MEDIA_LNK_FL_ENABLED;
	struct media_entity *local = entity->entity;
	struct media_entity *remote;
	struct media_pad *local_pad;
	struct media_pad *remote_pad;
	struct xvip_graph_entity *ent;
	struct v4l2_fwnode_link link;
	struct fwnode_handle *ep = NULL;
	int ret = 0;

	dev_dbg(xdev->dev, "creating links for entity %s\n", local->name);

	while (1) {
		/* Get the next endpoint and parse its link. */
		ep = fwnode_graph_get_next_endpoint(entity->asd.match.fwnode,
						    ep);
		if (ep == NULL)
			break;

		dev_dbg(xdev->dev, "processing endpoint %p\n", ep);

		ret = v4l2_fwnode_parse_link(ep, &link);
		if (ret < 0) {
			dev_err(xdev->dev, "failed to parse link for %p\n",
				ep);
			continue;
		}

		/* Skip sink ports, they will be processed from the other end of
		 * the link.
		 */
		if (link.local_port >= local->num_pads) {
			dev_err(xdev->dev, "invalid port number %u for %p\n",
				link.local_port, link.local_node);
			v4l2_fwnode_put_link(&link);
			ret = -EINVAL;
			break;
		}

		local_pad = &local->pads[link.local_port];

		if (local_pad->flags & MEDIA_PAD_FL_SINK) {
			dev_dbg(xdev->dev, "skipping sink port %p:%u\n",
				link.local_node, link.local_port);
			v4l2_fwnode_put_link(&link);
			continue;
		}

Annotation

Implementation Notes