Re: [PATCH v12 06/26] v4l: fwnode: Support generic parsing of graph endpoints, per port

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 09/12/2017 03:41 PM, Sakari Ailus wrote:
> This is just like like v4l2_async_notifier_parse_fwnode_endpoints but it
> only parses endpoints on a single port. The behaviour is useful on devices
> that have both sinks and sources, in other words only some of these should
> be parsed.

I think it would be better to merge this patch with the preceding patch. It
does not make a lot of sense to have this separate IMHO.

That said:

Acked-by: Hans Verkuil <hans.verkuil@xxxxxxxxx>

Regards,

	Hans

> 
> Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
> ---
>  drivers/media/v4l2-core/v4l2-fwnode.c | 59 ++++++++++++++++++++++++++++++++---
>  include/media/v4l2-fwnode.h           | 59 +++++++++++++++++++++++++++++++++++
>  2 files changed, 113 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
> index d978f2d714ca..44ee35f6aad5 100644
> --- a/drivers/media/v4l2-core/v4l2-fwnode.c
> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c
> @@ -398,9 +398,9 @@ static int v4l2_async_notifier_fwnode_parse_endpoint(
>  	return ret == -ENOTCONN ? 0 : ret;
>  }
>  
> -int v4l2_async_notifier_parse_fwnode_endpoints(
> +static int __v4l2_async_notifier_parse_fwnode_endpoints(
>  	struct device *dev, struct v4l2_async_notifier *notifier,
> -	size_t asd_struct_size,
> +	size_t asd_struct_size, unsigned int port, bool has_port,
>  	int (*parse_endpoint)(struct device *dev,
>  			    struct v4l2_fwnode_endpoint *vep,
>  			    struct v4l2_async_subdev *asd))
> @@ -413,10 +413,25 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
>  		return -EINVAL;
>  
>  	for (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(
> -				     dev_fwnode(dev), fwnode)); )
> -		if (fwnode_device_is_available(
> +				     dev_fwnode(dev), fwnode)); ) {
> +		if (!fwnode_device_is_available(
>  			    fwnode_graph_get_port_parent(fwnode)))
> -			max_subdevs++;
> +			continue;
> +
> +		if (has_port) {
> +			struct fwnode_endpoint ep;
> +
> +			ret = fwnode_graph_parse_endpoint(fwnode, &ep);
> +			if (ret) {
> +				fwnode_handle_put(fwnode);
> +				return ret;
> +			}
> +
> +			if (ep.port != port)
> +				continue;
> +		}
> +		max_subdevs++;
> +	}
>  
>  	/* No subdevs to add? Return here. */
>  	if (max_subdevs == notifier->max_subdevs)
> @@ -437,6 +452,17 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
>  			break;
>  		}
>  
> +		if (has_port) {
> +			struct fwnode_endpoint ep;
> +
> +			ret = fwnode_graph_parse_endpoint(fwnode, &ep);
> +			if (ret)
> +				break;
> +
> +			if (ep.port != port)
> +				continue;
> +		}
> +
>  		ret = v4l2_async_notifier_fwnode_parse_endpoint(
>  			dev, notifier, fwnode, asd_struct_size, parse_endpoint);
>  		if (ret < 0)
> @@ -447,8 +473,31 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
>  
>  	return ret;
>  }
> +
> +int v4l2_async_notifier_parse_fwnode_endpoints(
> +	struct device *dev, struct v4l2_async_notifier *notifier,
> +	size_t asd_struct_size,
> +	int (*parse_endpoint)(struct device *dev,
> +			    struct v4l2_fwnode_endpoint *vep,
> +			    struct v4l2_async_subdev *asd))
> +{
> +	return __v4l2_async_notifier_parse_fwnode_endpoints(
> +		dev, notifier, asd_struct_size, 0, false, parse_endpoint);
> +}
>  EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints);
>  
> +int v4l2_async_notifier_parse_fwnode_endpoints_by_port(
> +	struct device *dev, struct v4l2_async_notifier *notifier,
> +	size_t asd_struct_size, unsigned int port,
> +	int (*parse_endpoint)(struct device *dev,
> +			    struct v4l2_fwnode_endpoint *vep,
> +			    struct v4l2_async_subdev *asd))
> +{
> +	return __v4l2_async_notifier_parse_fwnode_endpoints(
> +		dev, notifier, asd_struct_size, port, true, parse_endpoint);
> +}
> +EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port);
> +
>  MODULE_LICENSE("GPL");
>  MODULE_AUTHOR("Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>");
>  MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@xxxxxxxxxxx>");
> diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
> index 31fb77e470fa..b2eed4f33e6a 100644
> --- a/include/media/v4l2-fwnode.h
> +++ b/include/media/v4l2-fwnode.h
> @@ -257,4 +257,63 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
>  			      struct v4l2_fwnode_endpoint *vep,
>  			      struct v4l2_async_subdev *asd));
>  
> +/**
> + * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode
> + *							endpoints of a port in a
> + *							device node
> + * @dev: the device the endpoints of which are to be parsed
> + * @notifier: notifier for @dev
> + * @asd_struct_size: size of the driver's async sub-device struct, including
> + *		     sizeof(struct v4l2_async_subdev). The &struct
> + *		     v4l2_async_subdev shall be the first member of
> + *		     the driver's async sub-device struct, i.e. both
> + *		     begin at the same memory address.
> + * @port: port number where endpoints are to be parsed
> + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode
> + *		    endpoint. Optional.
> + *		    Return: %0 on success
> + *			    %-ENOTCONN if the endpoint is to be skipped but this
> + *				       should not be considered as an error
> + *			    %-EINVAL if the endpoint configuration is invalid
> + *
> + * This function is just like @v4l2_async_notifier_parse_fwnode_endpoints with
> + * the exception that it only parses endpoints in a given port.
> + *
> + * Parse the fwnode endpoints of the @dev device on a given @port and populate
> + * the async sub-devices array of the notifier. The @parse_endpoint callback
> + * function is called for each endpoint with the corresponding async sub-device
> + * pointer to let the caller initialize the driver-specific part of the async
> + * sub-device structure.
> + *
> + * The notifier memory shall be zeroed before this function is called on the
> + * notifier.
> + *
> + * This function may not be called on a registered notifier and may be called on
> + * a notifier only once, per port.
> + *
> + * Do not change the notifier's subdevs array, take references to the subdevs
> + * array itself or change the notifier's num_subdevs field. This is because this
> + * function allocates and reallocates the subdevs array based on parsing
> + * endpoints.
> + *
> + * The @struct v4l2_fwnode_endpoint passed to the callback function
> + * @parse_endpoint is released once the function is finished. If there is a need
> + * to retain that configuration, the user needs to allocate memory for it.
> + *
> + * Any notifier populated using this function must be released with a call to
> + * v4l2_async_notifier_release() after it has been unregistered and the async
> + * sub-devices are no longer in use, even if the function returned an error.
> + *
> + * Return: %0 on success, including when no async sub-devices are found
> + *	   %-ENOMEM if memory allocation failed
> + *	   %-EINVAL if graph or endpoint parsing failed
> + *	   Other error codes as returned by @parse_endpoint
> + */
> +int v4l2_async_notifier_parse_fwnode_endpoints_by_port(
> +	struct device *dev, struct v4l2_async_notifier *notifier,
> +	size_t asd_struct_size, unsigned int port,
> +	int (*parse_endpoint)(struct device *dev,
> +			      struct v4l2_fwnode_endpoint *vep,
> +			      struct v4l2_async_subdev *asd));
> +
>  #endif /* _V4L2_FWNODE_H */
> 




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux