linux/drivers/media/mc/mc-entity.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Media entity
 *
 * Copyright (C) 2010 Nokia Corporation
 *
 * Contacts: Laurent Pinchart <[email protected]>
 *	     Sakari Ailus <[email protected]>
 */

#include <linux/bitmap.h>
#include <linux/list.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <media/media-entity.h>
#include <media/media-device.h>

static inline const char *intf_type(struct media_interface *intf)
{
	switch (intf->type) {
	case MEDIA_INTF_T_DVB_FE:
		return "dvb-frontend";
	case MEDIA_INTF_T_DVB_DEMUX:
		return "dvb-demux";
	case MEDIA_INTF_T_DVB_DVR:
		return "dvb-dvr";
	case MEDIA_INTF_T_DVB_CA:
		return  "dvb-ca";
	case MEDIA_INTF_T_DVB_NET:
		return "dvb-net";
	case MEDIA_INTF_T_V4L_VIDEO:
		return "v4l-video";
	case MEDIA_INTF_T_V4L_VBI:
		return "v4l-vbi";
	case MEDIA_INTF_T_V4L_RADIO:
		return "v4l-radio";
	case MEDIA_INTF_T_V4L_SUBDEV:
		return "v4l-subdev";
	case MEDIA_INTF_T_V4L_SWRADIO:
		return "v4l-swradio";
	case MEDIA_INTF_T_V4L_TOUCH:
		return "v4l-touch";
	default:
		return "unknown-intf";
	}
};

static inline const char *link_type_name(struct media_link *link)
{}

__must_check int media_entity_enum_init(struct media_entity_enum *ent_enum,
					struct media_device *mdev)
{}
EXPORT_SYMBOL_GPL();

void media_entity_enum_cleanup(struct media_entity_enum *ent_enum)
{}
EXPORT_SYMBOL_GPL();

/**
 *  dev_dbg_obj - Prints in debug mode a change on some object
 *
 * @event_name:	Name of the event to report. Could be __func__
 * @gobj:	Pointer to the object
 *
 * Enabled only if DEBUG or CONFIG_DYNAMIC_DEBUG. Otherwise, it
 * won't produce any code.
 */
static void dev_dbg_obj(const char *event_name,  struct media_gobj *gobj)
{}

void media_gobj_create(struct media_device *mdev,
			   enum media_gobj_type type,
			   struct media_gobj *gobj)
{}

void media_gobj_destroy(struct media_gobj *gobj)
{}

/*
 * TODO: Get rid of this.
 */
#define MEDIA_ENTITY_MAX_PADS

int media_entity_pads_init(struct media_entity *entity, u16 num_pads,
			   struct media_pad *pads)
{}
EXPORT_SYMBOL_GPL();

/* -----------------------------------------------------------------------------
 * Graph traversal
 */

/**
 * media_entity_has_pad_interdep - Check interdependency between two pads
 *
 * @entity: The entity
 * @pad0: The first pad index
 * @pad1: The second pad index
 *
 * This function checks the interdependency inside the entity between @pad0
 * and @pad1. If two pads are interdependent they are part of the same pipeline
 * and enabling one of the pads means that the other pad will become "locked"
 * and doesn't allow configuration changes.
 *
 * This function uses the &media_entity_operations.has_pad_interdep() operation
 * to check the dependency inside the entity between @pad0 and @pad1. If the
 * has_pad_interdep operation is not implemented, all pads of the entity are
 * considered to be interdependent.
 *
 * One of @pad0 and @pad1 must be a sink pad and the other one a source pad.
 * The function returns false if both pads are sinks or sources.
 *
 * The caller must hold entity->graph_obj.mdev->mutex.
 *
 * Return: true if the pads are connected internally and false otherwise.
 */
static bool media_entity_has_pad_interdep(struct media_entity *entity,
					  unsigned int pad0, unsigned int pad1)
{}

static struct media_entity *
media_entity_other(struct media_entity *entity, struct media_link *link)
{}

/* push an entity to traversal stack */
static void stack_push(struct media_graph *graph,
		       struct media_entity *entity)
{}

static struct media_entity *stack_pop(struct media_graph *graph)
{}

#define link_top(en)
#define stack_top(en)

/**
 * media_graph_walk_init - Allocate resources for graph walk
 * @graph: Media graph structure that will be used to walk the graph
 * @mdev: Media device
 *
 * Reserve resources for graph walk in media device's current
 * state. The memory must be released using
 * media_graph_walk_cleanup().
 *
 * Returns error on failure, zero on success.
 */
__must_check int media_graph_walk_init(
	struct media_graph *graph, struct media_device *mdev)
{}
EXPORT_SYMBOL_GPL();

/**
 * media_graph_walk_cleanup - Release resources related to graph walking
 * @graph: Media graph structure that was used to walk the graph
 */
void media_graph_walk_cleanup(struct media_graph *graph)
{}
EXPORT_SYMBOL_GPL();

void media_graph_walk_start(struct media_graph *graph,
			    struct media_entity *entity)
{}
EXPORT_SYMBOL_GPL();

static void media_graph_walk_iter(struct media_graph *graph)
{}

struct media_entity *media_graph_walk_next(struct media_graph *graph)
{}
EXPORT_SYMBOL_GPL();

/* -----------------------------------------------------------------------------
 * Pipeline management
 */

/*
 * The pipeline traversal stack stores pads that are reached during graph
 * traversal, with a list of links to be visited to continue the traversal.
 * When a new pad is reached, an entry is pushed on the top of the stack and
 * points to the incoming pad and the first link of the entity.
 *
 * To find further pads in the pipeline, the traversal algorithm follows
 * internal pad dependencies in the entity, and then links in the graph. It
 * does so by iterating over all links of the entity, and following enabled
 * links that originate from a pad that is internally connected to the incoming
 * pad, as reported by the media_entity_has_pad_interdep() function.
 */

/**
 * struct media_pipeline_walk_entry - Entry in the pipeline traversal stack
 *
 * @pad: The media pad being visited
 * @links: Links left to be visited
 */
struct media_pipeline_walk_entry {};

/**
 * 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 {};

#define MEDIA_PIPELINE_STACK_GROW_STEP

static struct media_pipeline_walk_entry *
media_pipeline_walk_top(struct media_pipeline_walk *walk)
{}

static bool media_pipeline_walk_empty(struct media_pipeline_walk *walk)
{}

/* Increase the stack size by MEDIA_PIPELINE_STACK_GROW_STEP elements. */
static int media_pipeline_walk_resize(struct media_pipeline_walk *walk)
{}

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

/*
 * 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
 * popped.
 */
static bool media_pipeline_walk_pop(struct media_pipeline_walk *walk)
{}

/* Free all memory allocated while walking the pipeline. */
static void media_pipeline_walk_destroy(struct media_pipeline_walk *walk)
{}

/* Add a pad to the pipeline and push it to the stack. */
static int media_pipeline_add_pad(struct media_pipeline *pipe,
				  struct media_pipeline_walk *walk,
				  struct media_pad *pad)
{}

/* Explore the next link of the entity at the top of the stack. */
static int media_pipeline_explore_next_link(struct media_pipeline *pipe,
					    struct media_pipeline_walk *walk)
{}

static void media_pipeline_cleanup(struct media_pipeline *pipe)
{}

static int media_pipeline_populate(struct media_pipeline *pipe,
				   struct media_pad *pad)
{}

__must_check int __media_pipeline_start(struct media_pad *pad,
					struct media_pipeline *pipe)
{}
EXPORT_SYMBOL_GPL();

__must_check int media_pipeline_start(struct media_pad *pad,
				      struct media_pipeline *pipe)
{}
EXPORT_SYMBOL_GPL();

void __media_pipeline_stop(struct media_pad *pad)
{}
EXPORT_SYMBOL_GPL();

void media_pipeline_stop(struct media_pad *pad)
{}
EXPORT_SYMBOL_GPL();

__must_check int media_pipeline_alloc_start(struct media_pad *pad)
{}
EXPORT_SYMBOL_GPL();

struct media_pad *
__media_pipeline_pad_iter_next(struct media_pipeline *pipe,
			       struct media_pipeline_pad_iter *iter,
			       struct media_pad *pad)
{}
EXPORT_SYMBOL_GPL();

int media_pipeline_entity_iter_init(struct media_pipeline *pipe,
				    struct media_pipeline_entity_iter *iter)
{}
EXPORT_SYMBOL_GPL();

void media_pipeline_entity_iter_cleanup(struct media_pipeline_entity_iter *iter)
{}
EXPORT_SYMBOL_GPL();

struct media_entity *
__media_pipeline_entity_iter_next(struct media_pipeline *pipe,
				  struct media_pipeline_entity_iter *iter,
				  struct media_entity *entity)
{}
EXPORT_SYMBOL_GPL();

/* -----------------------------------------------------------------------------
 * Links management
 */

static struct media_link *media_add_link(struct list_head *head)
{}

static void __media_entity_remove_link(struct media_entity *entity,
				       struct media_link *link)
{}

int media_get_pad_index(struct media_entity *entity, u32 pad_type,
			enum media_pad_signal_type sig_type)
{}
EXPORT_SYMBOL_GPL();

int
media_create_pad_link(struct media_entity *source, u16 source_pad,
			 struct media_entity *sink, u16 sink_pad, u32 flags)
{}
EXPORT_SYMBOL_GPL();

int media_create_pad_links(const struct media_device *mdev,
			   const u32 source_function,
			   struct media_entity *source,
			   const u16 source_pad,
			   const u32 sink_function,
			   struct media_entity *sink,
			   const u16 sink_pad,
			   u32 flags,
			   const bool allow_both_undefined)
{}
EXPORT_SYMBOL_GPL();

void __media_entity_remove_links(struct media_entity *entity)
{}
EXPORT_SYMBOL_GPL();

void media_entity_remove_links(struct media_entity *entity)
{}
EXPORT_SYMBOL_GPL();

static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
{}

int __media_entity_setup_link(struct media_link *link, u32 flags)
{}
EXPORT_SYMBOL_GPL();

int media_entity_setup_link(struct media_link *link, u32 flags)
{}
EXPORT_SYMBOL_GPL();

struct media_link *
media_entity_find_link(struct media_pad *source, struct media_pad *sink)
{}
EXPORT_SYMBOL_GPL();

struct media_pad *media_pad_remote_pad_first(const struct media_pad *pad)
{}
EXPORT_SYMBOL_GPL();

struct media_pad *
media_entity_remote_pad_unique(const struct media_entity *entity,
			       unsigned int type)
{}
EXPORT_SYMBOL_GPL();

struct media_pad *media_pad_remote_pad_unique(const struct media_pad *pad)
{}
EXPORT_SYMBOL_GPL();

int media_entity_get_fwnode_pad(struct media_entity *entity,
				const struct fwnode_handle *fwnode,
				unsigned long direction_flags)
{}
EXPORT_SYMBOL_GPL();

struct media_pipeline *media_entity_pipeline(struct media_entity *entity)
{}
EXPORT_SYMBOL_GPL();

struct media_pipeline *media_pad_pipeline(struct media_pad *pad)
{}
EXPORT_SYMBOL_GPL();

static void media_interface_init(struct media_device *mdev,
				 struct media_interface *intf,
				 u32 gobj_type,
				 u32 intf_type, u32 flags)
{}

/* Functions related to the media interface via device nodes */

struct media_intf_devnode *media_devnode_create(struct media_device *mdev,
						u32 type, u32 flags,
						u32 major, u32 minor)
{}
EXPORT_SYMBOL_GPL();

void media_devnode_remove(struct media_intf_devnode *devnode)
{}
EXPORT_SYMBOL_GPL();

struct media_link *media_create_intf_link(struct media_entity *entity,
					    struct media_interface *intf,
					    u32 flags)
{}
EXPORT_SYMBOL_GPL();

void __media_remove_intf_link(struct media_link *link)
{}
EXPORT_SYMBOL_GPL();

void media_remove_intf_link(struct media_link *link)
{}
EXPORT_SYMBOL_GPL();

void __media_remove_intf_links(struct media_interface *intf)
{}
EXPORT_SYMBOL_GPL();

void media_remove_intf_links(struct media_interface *intf)
{}
EXPORT_SYMBOL_GPL();

struct media_link *media_create_ancillary_link(struct media_entity *primary,
					       struct media_entity *ancillary)
{}
EXPORT_SYMBOL_GPL();

struct media_link *__media_entity_next_link(struct media_entity *entity,
					    struct media_link *link,
					    unsigned long link_type)
{}
EXPORT_SYMBOL_GPL();