mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
media: v4l2-subdev: Support hybrid links in v4l2_subdev_link_validate()
The v4l2_subdev_link_validate() helper function is meant to be used as a drop-in implementation of a V4L2 subdev entity .link_validate() handler. It supports subdev-to-subdev links only, and complains if one end of the link is not a subdev. This forces drivers that have video output devices connected to subdevs to implement a custom .link_validate() handler, calling v4l2_subdev_link_validate() for the subdev-to-subdev links, and performing manual link validation for the video-to-subdev links. Video devices embed a media entity, and therefore also have a .link_validate() operation. For video capture devices, the operation should be manually implemented by drivers for validate the subdev-to-video links. For video output devices, on the other hand, that operation is never called, as link validation is performed in the context of the sink entity. As a result, we end up forcing drivers to implement a custom .link_validate() handler for subdevs connected to video output devices, when the video devices provide an operation that could be used for that purpose. To improve that situation, make v4l2_subdev_link_validate() delegate link validation to the source's .link_validate() operation when the link source is a video device and the link sink is a subdev. This allows broader usage of v4l2_subdev_link_validate(), and simplifies drivers by making video device link validation easy to implement in the video device .link_validate(), regardless of whether the video device is an output device or a capture device. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Reviewed-by: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
This commit is contained in:
parent
d1307671e5
commit
5fd3e2412a
@ -1450,13 +1450,46 @@ int v4l2_subdev_link_validate(struct media_link *link)
|
|||||||
if (WARN_ON_ONCE(!is_media_entity_v4l2_subdev(link->sink->entity)))
|
if (WARN_ON_ONCE(!is_media_entity_v4l2_subdev(link->sink->entity)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!is_media_entity_v4l2_subdev(link->source->entity)) {
|
/*
|
||||||
pr_warn_once("source of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n",
|
* If the source is a video device, delegate link validation to it. This
|
||||||
link->source->entity->name, link->source->index,
|
* allows usage of this helper for subdev connected to a video output
|
||||||
link->sink->entity->name, link->sink->index);
|
* device, provided that the driver implement the video output device's
|
||||||
return 0;
|
* .link_validate() operation.
|
||||||
|
*/
|
||||||
|
if (is_media_entity_v4l2_video_device(link->source->entity)) {
|
||||||
|
struct media_entity *source = link->source->entity;
|
||||||
|
|
||||||
|
if (!source->ops || !source->ops->link_validate) {
|
||||||
|
/*
|
||||||
|
* Many existing drivers do not implement the required
|
||||||
|
* .link_validate() operation for their video devices.
|
||||||
|
* Print a warning to get the drivers fixed, and return
|
||||||
|
* 0 to avoid breaking userspace. This should
|
||||||
|
* eventually be turned into a WARN_ON() when all
|
||||||
|
* drivers will have been fixed.
|
||||||
|
*/
|
||||||
|
pr_warn_once("video device '%s' does not implement .link_validate(), driver bug!\n",
|
||||||
|
source->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Avoid infinite loops in case a video device incorrectly uses
|
||||||
|
* this helper function as its .link_validate() handler.
|
||||||
|
*/
|
||||||
|
if (WARN_ON(source->ops->link_validate == v4l2_subdev_link_validate))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return source->ops->link_validate(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the source is still not a subdev, usage of this helper is a clear
|
||||||
|
* driver bug.
|
||||||
|
*/
|
||||||
|
if (WARN_ON(!is_media_entity_v4l2_subdev(link->source->entity)))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
sink_sd = media_entity_to_v4l2_subdev(link->sink->entity);
|
sink_sd = media_entity_to_v4l2_subdev(link->sink->entity);
|
||||||
source_sd = media_entity_to_v4l2_subdev(link->source->entity);
|
source_sd = media_entity_to_v4l2_subdev(link->source->entity);
|
||||||
|
|
||||||
|
@ -1250,6 +1250,12 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
|
|||||||
* calls v4l2_subdev_link_validate_default() to ensure that
|
* calls v4l2_subdev_link_validate_default() to ensure that
|
||||||
* width, height and the media bus pixel code are equal on both
|
* width, height and the media bus pixel code are equal on both
|
||||||
* source and sink of the link.
|
* source and sink of the link.
|
||||||
|
*
|
||||||
|
* The function can be used as a drop-in &media_entity_ops.link_validate
|
||||||
|
* implementation for v4l2_subdev instances. It supports all links between
|
||||||
|
* subdevs, as well as links between subdevs and video devices, provided that
|
||||||
|
* the video devices also implement their &media_entity_ops.link_validate
|
||||||
|
* operation.
|
||||||
*/
|
*/
|
||||||
int v4l2_subdev_link_validate(struct media_link *link);
|
int v4l2_subdev_link_validate(struct media_link *link);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user