From 88867c1d96684925027a0ecc9e25c6ea70040cc6 Mon Sep 17 00:00:00 2001 From: Denys Dmytriyenko Date: Mon, 11 Jun 2012 20:44:56 -0400 Subject: extras: move things to extras Move non-essential, outdated, best-effort pieces, as well, as those requiring extra non-standard dependencies besides oe-core. Signed-off-by: Denys Dmytriyenko --- .../linux-omap/media/0015-media-Links-setup.patch | 517 +++++++++++++++++++++ 1 file changed, 517 insertions(+) create mode 100644 extras/recipes-kernel/linux/linux-omap/media/0015-media-Links-setup.patch (limited to 'extras/recipes-kernel/linux/linux-omap/media/0015-media-Links-setup.patch') diff --git a/extras/recipes-kernel/linux/linux-omap/media/0015-media-Links-setup.patch b/extras/recipes-kernel/linux/linux-omap/media/0015-media-Links-setup.patch new file mode 100644 index 00000000..4ea39740 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/media/0015-media-Links-setup.patch @@ -0,0 +1,517 @@ +From 9991c219079532183cc33f16064f86680b80237c Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart +Date: Wed, 9 Dec 2009 12:40:03 +0100 +Subject: [PATCH 15/43] media: Links setup + +Create the following ioctl and implement it at the media device level to +setup links. + +- MEDIA_IOC_SETUP_LINK: Modify the properties of a given link + +The only property that can currently be modified is the ENABLED link +flag to enable/disable a link. Links marked with the IMMUTABLE link flag +can not be enabled or disabled. + +Enabling or disabling a link has effects on entities' use count. Those +changes are automatically propagated through the graph. + +Signed-off-by: Laurent Pinchart +Signed-off-by: Stanimir Varbanov +Signed-off-by: Sakari Ailus +--- + Documentation/DocBook/media-entities.tmpl | 2 + + Documentation/DocBook/v4l/media-controller.xml | 1 + + Documentation/DocBook/v4l/media-ioc-setup-link.xml | 90 +++++++++++ + Documentation/media-framework.txt | 42 ++++++ + drivers/media/media-device.c | 45 ++++++ + drivers/media/media-entity.c | 155 ++++++++++++++++++++ + include/linux/media.h | 1 + + include/media/media-device.h | 3 + + include/media/media-entity.h | 17 ++ + 9 files changed, 356 insertions(+), 0 deletions(-) + create mode 100644 Documentation/DocBook/v4l/media-ioc-setup-link.xml + +diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl +index 6e7dae4..679c585 100644 +--- a/Documentation/DocBook/media-entities.tmpl ++++ b/Documentation/DocBook/media-entities.tmpl +@@ -94,6 +94,7 @@ + MEDIA_IOC_DEVICE_INFO"> + MEDIA_IOC_ENUM_ENTITIES"> + MEDIA_IOC_ENUM_LINKS"> ++MEDIA_IOC_SETUP_LINK"> + + + v4l2_std_id"> +@@ -342,6 +343,7 @@ + + + ++ + + + +diff --git a/Documentation/DocBook/v4l/media-controller.xml b/Documentation/DocBook/v4l/media-controller.xml +index 2c4fd2b..2dc25e1 100644 +--- a/Documentation/DocBook/v4l/media-controller.xml ++++ b/Documentation/DocBook/v4l/media-controller.xml +@@ -85,4 +85,5 @@ + &sub-media-ioc-device-info; + &sub-media-ioc-enum-entities; + &sub-media-ioc-enum-links; ++ &sub-media-ioc-setup-link; + +diff --git a/Documentation/DocBook/v4l/media-ioc-setup-link.xml b/Documentation/DocBook/v4l/media-ioc-setup-link.xml +new file mode 100644 +index 0000000..09ab3d2 +--- /dev/null ++++ b/Documentation/DocBook/v4l/media-ioc-setup-link.xml +@@ -0,0 +1,90 @@ ++ ++ ++ ioctl MEDIA_IOC_SETUP_LINK ++ &manvol; ++ ++ ++ ++ MEDIA_IOC_SETUP_LINK ++ Modify the properties of a link ++ ++ ++ ++ ++ ++ int ioctl ++ int fd ++ int request ++ struct media_link_desc *argp ++ ++ ++ ++ ++ ++ Arguments ++ ++ ++ ++ fd ++ ++ File descriptor returned by ++ open(). ++ ++ ++ ++ request ++ ++ MEDIA_IOC_ENUM_LINKS ++ ++ ++ ++ argp ++ ++ ++ ++ ++ ++ ++ ++ ++ Description ++ ++ To change link properties applications fill a &media-link-desc; with ++ link identification information (source and sink pad) and the new requested ++ link flags. They then call the MEDIA_IOC_SETUP_LINK ioctl with a pointer to ++ that structure. ++ The only configurable property is the ENABLED ++ link flag to enable/disable a link. Links marked with the ++ IMMUTABLE link flag can not be enabled or disabled. ++ ++ Link configuration has no side effect on other links. If an enabled ++ link at the sink pad prevents the link from being enabled, the driver ++ returns with an &EBUSY;. ++ If the specified link can't be found the driver returns with an ++ &EINVAL;. ++ ++ ++ ++ &return-value; ++ ++ ++ ++ EBUSY ++ ++ The link properties can't be changed because the link is ++ currently busy. This can be caused, for instance, by an active media ++ stream (audio or video) on the link. The ioctl shouldn't be retried if ++ no other action is performed before to fix the problem. ++ ++ ++ ++ EINVAL ++ ++ The &media-link-desc; references a non-existing link, or the ++ link is immutable and an attempt to modify its configuration was made. ++ ++ ++ ++ ++ ++ +diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt +index 9017a41..634845e 100644 +--- a/Documentation/media-framework.txt ++++ b/Documentation/media-framework.txt +@@ -259,6 +259,16 @@ When the graph traversal is complete the function will return NULL. + Graph traversal can be interrupted at any moment. No cleanup function call is + required and the graph structure can be freed normally. + ++Helper functions can be used to find a link between two given pads, or a pad ++connected to another pad through an enabled link ++ ++ media_entity_find_link(struct media_pad *source, ++ struct media_pad *sink); ++ ++ media_entity_remote_source(struct media_pad *pad); ++ ++Refer to the kerneldoc documentation for more information. ++ + + Use count and power handling + ---------------------------- +@@ -271,3 +281,35 @@ track the number of users of every entity for power management needs. + The use_count field is owned by media drivers and must not be touched by entity + drivers. Access to the field must be protected by the media device graph_mutex + lock. ++ ++ ++Links setup ++----------- ++ ++Link properties can be modified at runtime by calling ++ ++ media_entity_setup_link(struct media_link *link, u32 flags); ++ ++The flags argument contains the requested new link flags. ++ ++The only configurable property is the ENABLED link flag to enable/disable a ++link. Links marked with the IMMUTABLE link flag can not be enabled or disabled. ++ ++When a link is enabled or disabled, the media framework calls the ++link_setup operation for the two entities at the source and sink of the link, ++in that order. If the second link_setup call fails, another link_setup call is ++made on the first entity to restore the original link flags. ++ ++Media device drivers can be notified of link setup operations by setting the ++media_device::link_notify pointer to a callback function. If provided, the ++notification callback will be called before enabling and after disabling ++links. ++ ++Entity drivers must implement the link_setup operation if any of their links ++is non-immutable. The operation must either configure the hardware or store ++the configuration information to be applied later. ++ ++Link configuration must not have any side effect on other links. If an enabled ++link at a sink pad prevents another link at the same pad from being disabled, ++the link_setup operation must return -EBUSY and can't implicitly disable the ++first enabled link. +diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c +index 1f46acb..719deba 100644 +--- a/drivers/media/media-device.c ++++ b/drivers/media/media-device.c +@@ -172,6 +172,44 @@ static long media_device_enum_links(struct media_device *mdev, + return 0; + } + ++static long media_device_setup_link(struct media_device *mdev, ++ struct media_link_desc __user *_ulink) ++{ ++ struct media_link *link = NULL; ++ struct media_link_desc ulink; ++ struct media_entity *source; ++ struct media_entity *sink; ++ int ret; ++ ++ if (copy_from_user(&ulink, _ulink, sizeof(ulink))) ++ return -EFAULT; ++ ++ /* Find the source and sink entities and link. ++ */ ++ source = find_entity(mdev, ulink.source.entity); ++ sink = find_entity(mdev, ulink.sink.entity); ++ ++ if (source == NULL || sink == NULL) ++ return -EINVAL; ++ ++ if (ulink.source.index >= source->num_pads || ++ ulink.sink.index >= sink->num_pads) ++ return -EINVAL; ++ ++ link = media_entity_find_link(&source->pads[ulink.source.index], ++ &sink->pads[ulink.sink.index]); ++ if (link == NULL) ++ return -EINVAL; ++ ++ /* Setup the link on both entities. */ ++ ret = __media_entity_setup_link(link, ulink.flags); ++ ++ if (copy_to_user(_ulink, &ulink, sizeof(ulink))) ++ return -EFAULT; ++ ++ return ret; ++} ++ + static long media_device_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) + { +@@ -197,6 +235,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd, + mutex_unlock(&dev->graph_mutex); + break; + ++ case MEDIA_IOC_SETUP_LINK: ++ mutex_lock(&dev->graph_mutex); ++ ret = media_device_setup_link(dev, ++ (struct media_link_desc __user *)arg); ++ mutex_unlock(&dev->graph_mutex); ++ break; ++ + default: + ret = -ENOIOCTLCMD; + } +diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c +index fe6bfd2..d703ce8 100644 +--- a/drivers/media/media-entity.c ++++ b/drivers/media/media-entity.c +@@ -306,3 +306,158 @@ media_entity_create_link(struct media_entity *source, u16 source_pad, + return 0; + } + EXPORT_SYMBOL_GPL(media_entity_create_link); ++ ++static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) ++{ ++ const u32 mask = MEDIA_LNK_FL_ENABLED; ++ int ret; ++ ++ /* Notify both entities. */ ++ ret = media_entity_call(link->source->entity, link_setup, ++ link->source, link->sink, flags); ++ if (ret < 0 && ret != -ENOIOCTLCMD) ++ return ret; ++ ++ ret = media_entity_call(link->sink->entity, link_setup, ++ link->sink, link->source, flags); ++ if (ret < 0 && ret != -ENOIOCTLCMD) { ++ media_entity_call(link->source->entity, link_setup, ++ link->source, link->sink, link->flags); ++ return ret; ++ } ++ ++ link->flags = (link->flags & ~mask) | (flags & mask); ++ link->reverse->flags = link->flags; ++ ++ return 0; ++} ++ ++/** ++ * __media_entity_setup_link - Configure a media link ++ * @link: The link being configured ++ * @flags: Link configuration flags ++ * ++ * The bulk of link setup is handled by the two entities connected through the ++ * link. This function notifies both entities of the link configuration change. ++ * ++ * If the link is immutable or if the current and new configuration are ++ * identical, return immediately. ++ * ++ * The user is expected to hold link->source->parent->mutex. If not, ++ * media_entity_setup_link() should be used instead. ++ */ ++int __media_entity_setup_link(struct media_link *link, u32 flags) ++{ ++ struct media_device *mdev; ++ struct media_entity *source, *sink; ++ int ret = -EBUSY; ++ ++ if (link == NULL) ++ return -EINVAL; ++ ++ if (link->flags & MEDIA_LNK_FL_IMMUTABLE) ++ return link->flags == flags ? 0 : -EINVAL; ++ ++ if (link->flags == flags) ++ return 0; ++ ++ source = link->source->entity; ++ sink = link->sink->entity; ++ ++ mdev = source->parent; ++ ++ if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) { ++ ret = mdev->link_notify(link->source, link->sink, ++ MEDIA_LNK_FL_ENABLED); ++ if (ret < 0) ++ return ret; ++ } ++ ++ ret = __media_entity_setup_link_notify(link, flags); ++ if (ret < 0) ++ goto err; ++ ++ if (!(flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) ++ mdev->link_notify(link->source, link->sink, 0); ++ ++ return 0; ++ ++err: ++ if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) ++ mdev->link_notify(link->source, link->sink, 0); ++ ++ return ret; ++} ++ ++int media_entity_setup_link(struct media_link *link, u32 flags) ++{ ++ int ret; ++ ++ mutex_lock(&link->source->entity->parent->graph_mutex); ++ ret = __media_entity_setup_link(link, flags); ++ mutex_unlock(&link->source->entity->parent->graph_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(media_entity_setup_link); ++ ++/** ++ * media_entity_find_link - Find a link between two pads ++ * @source: Source pad ++ * @sink: Sink pad ++ * ++ * Return a pointer to the link between the two entities. If no such link ++ * exists, return NULL. ++ */ ++struct media_link * ++media_entity_find_link(struct media_pad *source, struct media_pad *sink) ++{ ++ struct media_link *link; ++ unsigned int i; ++ ++ for (i = 0; i < source->entity->num_links; ++i) { ++ link = &source->entity->links[i]; ++ ++ if (link->source->entity == source->entity && ++ link->source->index == source->index && ++ link->sink->entity == sink->entity && ++ link->sink->index == sink->index) ++ return link; ++ } ++ ++ return NULL; ++} ++EXPORT_SYMBOL_GPL(media_entity_find_link); ++ ++/** ++ * media_entity_remote_source - Find the source pad at the remote end of a link ++ * @pad: Sink pad at the local end of the link ++ * ++ * Search for a remote source pad connected to the given sink pad by iterating ++ * over all links originating or terminating at that pad until an enabled link ++ * is found. ++ * ++ * Return a pointer to the pad at the remote end of the first found enabled ++ * link, or NULL if no enabled link has been found. ++ */ ++struct media_pad *media_entity_remote_source(struct media_pad *pad) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < pad->entity->num_links; i++) { ++ struct media_link *link = &pad->entity->links[i]; ++ ++ if (!(link->flags & MEDIA_LNK_FL_ENABLED)) ++ continue; ++ ++ if (link->source == pad) ++ return link->sink; ++ ++ if (link->sink == pad) ++ return link->source; ++ } ++ ++ return NULL; ++ ++} ++EXPORT_SYMBOL_GPL(media_entity_remote_source); +diff --git a/include/linux/media.h b/include/linux/media.h +index 64c0313..2f67ed2 100644 +--- a/include/linux/media.h ++++ b/include/linux/media.h +@@ -126,5 +126,6 @@ struct media_links_enum { + #define MEDIA_IOC_DEVICE_INFO _IOWR('M', 1, struct media_device_info) + #define MEDIA_IOC_ENUM_ENTITIES _IOWR('M', 2, struct media_entity_desc) + #define MEDIA_IOC_ENUM_LINKS _IOWR('M', 3, struct media_links_enum) ++#define MEDIA_IOC_SETUP_LINK _IOWR('M', 4, struct media_link_desc) + + #endif /* __LINUX_MEDIA_H */ +diff --git a/include/media/media-device.h b/include/media/media-device.h +index 260d59c..ad93e66 100644 +--- a/include/media/media-device.h ++++ b/include/media/media-device.h +@@ -73,6 +73,9 @@ struct media_device { + spinlock_t lock; + /* Serializes graph operations. */ + struct mutex graph_mutex; ++ ++ int (*link_notify)(struct media_pad *source, ++ struct media_pad *sink, u32 flags); + }; + + /* media_devnode to media_device */ +diff --git a/include/media/media-entity.h b/include/media/media-entity.h +index 0954490..60fc7bd 100644 +--- a/include/media/media-entity.h ++++ b/include/media/media-entity.h +@@ -39,6 +39,12 @@ struct media_pad { + unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ + }; + ++struct media_entity_operations { ++ int (*link_setup)(struct media_entity *entity, ++ const struct media_pad *local, ++ const struct media_pad *remote, u32 flags); ++}; ++ + struct media_entity { + struct list_head list; + struct media_device *parent; /* Media device this entity belongs to*/ +@@ -59,6 +65,8 @@ struct media_entity { + struct media_pad *pads; /* Pads array (num_pads elements) */ + struct media_link *links; /* Links array (max_links elements)*/ + ++ const struct media_entity_operations *ops; /* Entity operations */ ++ + int use_count; /* Use count for the entity. */ + + union { +@@ -108,6 +116,11 @@ int media_entity_init(struct media_entity *entity, u16 num_pads, + void media_entity_cleanup(struct media_entity *entity); + int media_entity_create_link(struct media_entity *source, u16 source_pad, + struct media_entity *sink, u16 sink_pad, u32 flags); ++int __media_entity_setup_link(struct media_link *link, u32 flags); ++int media_entity_setup_link(struct media_link *link, u32 flags); ++struct media_link *media_entity_find_link(struct media_pad *source, ++ struct media_pad *sink); ++struct media_pad *media_entity_remote_source(struct media_pad *pad); + + struct media_entity *media_entity_get(struct media_entity *entity); + void media_entity_put(struct media_entity *entity); +@@ -117,4 +130,8 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, + struct media_entity * + media_entity_graph_walk_next(struct media_entity_graph *graph); + ++#define media_entity_call(entity, operation, args...) \ ++ (((entity)->ops && (entity)->ops->operation) ? \ ++ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) ++ + #endif +-- +1.6.6.1 + -- cgit v1.2.3-54-g00ecf