[{"id":1769571,"web_url":"http://patchwork.ozlabs.org/comment/1769571/","msgid":"<20170916070431.GA8257@amd>","list_archive_url":null,"date":"2017-09-16T07:04:31","subject":"Re: [PATCH v13 06/25] omap3isp: Use generic parser for parsing\n\tfwnode endpoints","submitter":{"id":2109,"url":"http://patchwork.ozlabs.org/api/people/2109/","name":"Pavel Machek","email":"pavel@ucw.cz"},"content":"Hi!\n\n> Instead of using driver implementation, use\n> v4l2_async_notifier_parse_fwnode_endpoints() to parse the fwnode endpoints\n> of the device.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\nPatches at least up to here look fine o me.\n\nWe are at version 13 of the series... Is merge of the series expected\nanytimme soon?\n\nIf not, can we at least merge patches up to here, so that less stuff\nis retransmitted over and over?\n\nThanks,\n\t\t\t\t\t\t\t\tPavel","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xvNYj2WvFz9t16\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tSat, 16 Sep 2017 17:04:41 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751233AbdIPHEh (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tSat, 16 Sep 2017 03:04:37 -0400","from atrey.karlin.mff.cuni.cz ([195.113.26.193]:52489 \"EHLO\n\tatrey.karlin.mff.cuni.cz\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751221AbdIPHEh (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Sat, 16 Sep 2017 03:04:37 -0400","by atrey.karlin.mff.cuni.cz (Postfix, from userid 512)\n\tid 544B5824D3; Sat, 16 Sep 2017 09:04:34 +0200 (CEST)"],"Date":"Sat, 16 Sep 2017 09:04:31 +0200","From":"Pavel Machek <pavel@ucw.cz>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com,\n\tdevicetree@vger.kernel.org, sre@kernel.org","Subject":"Re: [PATCH v13 06/25] omap3isp: Use generic parser for parsing\n\tfwnode endpoints","Message-ID":"<20170916070431.GA8257@amd>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-7-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Type":"multipart/signed; micalg=pgp-sha1;\n\tprotocol=\"application/pgp-signature\"; boundary=\"BOKacYhQ+x31HxR3\"","Content-Disposition":"inline","In-Reply-To":"<20170915141724.23124-7-sakari.ailus@linux.intel.com>","User-Agent":"Mutt/1.5.23 (2014-03-12)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1769572,"web_url":"http://patchwork.ozlabs.org/comment/1769572/","msgid":"<20170916071302.GB8257@amd>","list_archive_url":null,"date":"2017-09-16T07:13:02","subject":"Re: [PATCH v13 11/25] v4l: async: Introduce helpers for calling\n\tasync ops callbacks","submitter":{"id":2109,"url":"http://patchwork.ozlabs.org/api/people/2109/","name":"Pavel Machek","email":"pavel@ucw.cz"},"content":"On Fri 2017-09-15 17:17:10, Sakari Ailus wrote:\n> Add three helper functions to call async operations callbacks. Besides\n> simplifying callbacks, this allows async notifiers to have no ops set,\n> i.e. it can be left NULL.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\nI'd remove \"_call\" from these names; they are long enough already and\ndo not add much. But either way is okay.\n\nAcked-by: Pavel Machek <pavel@ucw.cz>","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xvNlS5S3mz9t2M\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tSat, 16 Sep 2017 17:13:08 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751253AbdIPHNH (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tSat, 16 Sep 2017 03:13:07 -0400","from atrey.karlin.mff.cuni.cz ([195.113.26.193]:52697 \"EHLO\n\tatrey.karlin.mff.cuni.cz\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1750909AbdIPHNG (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Sat, 16 Sep 2017 03:13:06 -0400","by atrey.karlin.mff.cuni.cz (Postfix, from userid 512)\n\tid 711FE824E3; Sat, 16 Sep 2017 09:13:05 +0200 (CEST)"],"Date":"Sat, 16 Sep 2017 09:13:02 +0200","From":"Pavel Machek <pavel@ucw.cz>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com,\n\tdevicetree@vger.kernel.org, sre@kernel.org","Subject":"Re: [PATCH v13 11/25] v4l: async: Introduce helpers for calling\n\tasync ops callbacks","Message-ID":"<20170916071302.GB8257@amd>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-12-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Type":"multipart/signed; micalg=pgp-sha1;\n\tprotocol=\"application/pgp-signature\"; boundary=\"3uo+9/B/ebqu+fSQ\"","Content-Disposition":"inline","In-Reply-To":"<20170915141724.23124-12-sakari.ailus@linux.intel.com>","User-Agent":"Mutt/1.5.23 (2014-03-12)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1769574,"web_url":"http://patchwork.ozlabs.org/comment/1769574/","msgid":"<20170916071820.GA9432@amd>","list_archive_url":null,"date":"2017-09-16T07:18:20","subject":"Re: [PATCH v13 06/25] omap3isp: Use generic parser for parsing\n\tfwnode endpoints","submitter":{"id":2109,"url":"http://patchwork.ozlabs.org/api/people/2109/","name":"Pavel Machek","email":"pavel@ucw.cz"},"content":"On Sat 2017-09-16 09:04:31, Pavel Machek wrote:\n> Hi!\n> \n> > Instead of using driver implementation, use\n> > v4l2_async_notifier_parse_fwnode_endpoints() to parse the fwnode endpoints\n> > of the device.\n> > \n> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> > Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> \n> Patches at least up to here look fine o me.\n\nI went through some others.\n\nSo, 2,4,5,6,10,12:\n\nAcked-by: Pavel Machek <pavel@ucw.cz>\n\nBest regards,","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xvNsb3rwwz9t2M\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tSat, 16 Sep 2017 17:18:27 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751231AbdIPHSZ (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tSat, 16 Sep 2017 03:18:25 -0400","from atrey.karlin.mff.cuni.cz ([195.113.26.193]:52823 \"EHLO\n\tatrey.karlin.mff.cuni.cz\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1750909AbdIPHSY (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Sat, 16 Sep 2017 03:18:24 -0400","by atrey.karlin.mff.cuni.cz (Postfix, from userid 512)\n\tid 567C8824E4; Sat, 16 Sep 2017 09:18:23 +0200 (CEST)"],"Date":"Sat, 16 Sep 2017 09:18:20 +0200","From":"Pavel Machek <pavel@ucw.cz>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com,\n\tdevicetree@vger.kernel.org, sre@kernel.org","Subject":"Re: [PATCH v13 06/25] omap3isp: Use generic parser for parsing\n\tfwnode endpoints","Message-ID":"<20170916071820.GA9432@amd>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-7-sakari.ailus@linux.intel.com>\n\t<20170916070431.GA8257@amd>","MIME-Version":"1.0","Content-Type":"multipart/signed; micalg=pgp-sha1;\n\tprotocol=\"application/pgp-signature\"; boundary=\"WIyZ46R2i8wDzkSu\"","Content-Disposition":"inline","In-Reply-To":"<20170916070431.GA8257@amd>","User-Agent":"Mutt/1.5.23 (2014-03-12)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770724,"web_url":"http://patchwork.ozlabs.org/comment/1770724/","msgid":"<a17ab793-b859-f04a-2dff-d8f6a314e9bf@xs4all.nl>","list_archive_url":null,"date":"2017-09-19T08:03:27","subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n> Add two functions for parsing devices graph endpoints:\n> v4l2_async_notifier_parse_fwnode_endpoints and\n> v4l2_async_notifier_parse_fwnode_endpoints_by_port. The former iterates\n> over all endpoints whereas the latter only iterates over the endpoints in\n> a given port.\n> \n> The former is mostly useful for existing drivers that currently implement\n> the iteration over all the endpoints themselves whereas the latter is\n> especially intended for devices with both sinks and sources: async\n> sub-devices for external devices connected to the device's sources will\n> have already been set up, or they are part of the master device.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> ---\n>  drivers/media/v4l2-core/v4l2-async.c  |  30 ++++++\n>  drivers/media/v4l2-core/v4l2-fwnode.c | 185 ++++++++++++++++++++++++++++++++++\n>  include/media/v4l2-async.h            |  24 ++++-\n>  include/media/v4l2-fwnode.h           | 117 +++++++++++++++++++++\n>  4 files changed, 354 insertions(+), 2 deletions(-)\n> \n> diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c\n> index 831f185ecd47..bf0215dde616 100644\n> --- a/drivers/media/v4l2-core/v4l2-async.c\n> +++ b/drivers/media/v4l2-core/v4l2-async.c\n> @@ -22,6 +22,7 @@\n>  \n>  #include <media/v4l2-async.h>\n>  #include <media/v4l2-device.h>\n> +#include <media/v4l2-fwnode.h>\n>  #include <media/v4l2-subdev.h>\n>  \n>  static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)\n> @@ -219,6 +220,35 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)\n>  }\n>  EXPORT_SYMBOL(v4l2_async_notifier_unregister);\n>  \n> +void v4l2_async_notifier_release(struct v4l2_async_notifier *notifier)\n> +{\n> +\tunsigned int i;\n> +\n> +\tif (!notifier->max_subdevs)\n> +\t\treturn;\n> +\n> +\tfor (i = 0; i < notifier->num_subdevs; i++) {\n> +\t\tstruct v4l2_async_subdev *asd = notifier->subdevs[i];\n> +\n> +\t\tswitch (asd->match_type) {\n> +\t\tcase V4L2_ASYNC_MATCH_FWNODE:\n> +\t\t\tfwnode_handle_put(asd->match.fwnode.fwnode);\n> +\t\t\tbreak;\n> +\t\tdefault:\n> +\t\t\tWARN_ON_ONCE(true);\n\nPlease add a break here.\n\n> +\t\t}\n> +\n> +\t\tkfree(asd);\n> +\t}\n> +\n> +\tnotifier->max_subdevs = 0;\n> +\tnotifier->num_subdevs = 0;\n> +\n> +\tkvfree(notifier->subdevs);\n> +\tnotifier->subdevs = NULL;\n> +}\n> +EXPORT_SYMBOL_GPL(v4l2_async_notifier_release);\n> +\n>  int v4l2_async_register_subdev(struct v4l2_subdev *sd)\n>  {\n>  \tstruct v4l2_async_notifier *notifier;\n> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c\n> index 706f9e7b90f1..44ee35f6aad5 100644\n> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> @@ -19,6 +19,7 @@\n>   */\n>  #include <linux/acpi.h>\n>  #include <linux/kernel.h>\n> +#include <linux/mm.h>\n>  #include <linux/module.h>\n>  #include <linux/of.h>\n>  #include <linux/property.h>\n> @@ -26,6 +27,7 @@\n>  #include <linux/string.h>\n>  #include <linux/types.h>\n>  \n> +#include <media/v4l2-async.h>\n>  #include <media/v4l2-fwnode.h>\n>  \n>  enum v4l2_fwnode_bus_type {\n> @@ -313,6 +315,189 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)\n>  }\n>  EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);\n>  \n> +static int v4l2_async_notifier_realloc(struct v4l2_async_notifier *notifier,\n> +\t\t\t\t       unsigned int max_subdevs)\n> +{\n> +\tstruct v4l2_async_subdev **subdevs;\n> +\n> +\tif (max_subdevs <= notifier->max_subdevs)\n> +\t\treturn 0;\n> +\n> +\tsubdevs = kvmalloc_array(\n> +\t\tmax_subdevs, sizeof(*notifier->subdevs),\n> +\t\tGFP_KERNEL | __GFP_ZERO);\n> +\tif (!subdevs)\n> +\t\treturn -ENOMEM;\n> +\n> +\tif (notifier->subdevs) {\n> +\t\tmemcpy(subdevs, notifier->subdevs,\n> +\t\t       sizeof(*subdevs) * notifier->num_subdevs);\n> +\n> +\t\tkvfree(notifier->subdevs);\n> +\t}\n> +\n> +\tnotifier->subdevs = subdevs;\n> +\tnotifier->max_subdevs = max_subdevs;\n> +\n> +\treturn 0;\n> +}\n> +\n> +static int v4l2_async_notifier_fwnode_parse_endpoint(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tstruct fwnode_handle *endpoint, unsigned int asd_struct_size,\n> +\tint (*parse_endpoint)(struct device *dev,\n> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n> +\t\t\t    struct v4l2_async_subdev *asd))\n> +{\n> +\tstruct v4l2_async_subdev *asd;\n> +\tstruct v4l2_fwnode_endpoint *vep;\n> +\tint ret = 0;\n> +\n> +\tasd = kzalloc(asd_struct_size, GFP_KERNEL);\n> +\tif (!asd)\n> +\t\treturn -ENOMEM;\n> +\n> +\tasd->match.fwnode.fwnode =\n> +\t\tfwnode_graph_get_remote_port_parent(endpoint);\n> +\tif (!asd->match.fwnode.fwnode) {\n> +\t\tdev_warn(dev, \"bad remote port parent\\n\");\n> +\t\tret = -EINVAL;\n> +\t\tgoto out_err;\n> +\t}\n> +\n> +\t/* Ignore endpoints the parsing of which failed. */\n> +\tvep = v4l2_fwnode_endpoint_alloc_parse(endpoint);\n> +\tif (IS_ERR(vep)) {\n> +\t\tret = PTR_ERR(vep);\n> +\t\tdev_warn(dev, \"unable to parse V4L2 fwnode endpoint (%d)\\n\",\n> +\t\t\t ret);\n> +\t\tgoto out_err;\n> +\t}\n> +\n> +\tret = parse_endpoint ? parse_endpoint(dev, vep, asd) : 0;\n> +\tif (ret == -ENOTCONN)\n> +\t\tdev_dbg(dev, \"ignoring endpoint %u,%u\\n\", vep->base.port,\n> +\t\t\tvep->base.id);\n> +\telse if (ret < 0)\n> +\t\tdev_warn(dev, \"driver could not parse endpoint %u,%u (%d)\\n\",\n> +\t\t\t vep->base.port, vep->base.id, ret);\n> +\tv4l2_fwnode_endpoint_free(vep);\n> +\tif (ret < 0)\n> +\t\tgoto out_err;\n> +\n> +\tasd->match_type = V4L2_ASYNC_MATCH_FWNODE;\n> +\tnotifier->subdevs[notifier->num_subdevs] = asd;\n> +\tnotifier->num_subdevs++;\n> +\n> +\treturn 0;\n> +\n> +out_err:\n> +\tfwnode_handle_put(asd->match.fwnode.fwnode);\n> +\tkfree(asd);\n> +\n> +\treturn ret == -ENOTCONN ? 0 : ret;\n> +}\n> +\n> +static int __v4l2_async_notifier_parse_fwnode_endpoints(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tsize_t asd_struct_size, unsigned int port, bool has_port,\n> +\tint (*parse_endpoint)(struct device *dev,\n> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n> +\t\t\t    struct v4l2_async_subdev *asd))\n> +{\n> +\tstruct fwnode_handle *fwnode = NULL;\n> +\tunsigned int max_subdevs = notifier->max_subdevs;\n> +\tint ret;\n> +\n> +\tif (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev)))\n> +\t\treturn -EINVAL;\n> +\n> +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n> +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n\nYou can replace this by:\n\n\twhile ((fwnode = fwnode_graph_get_next_endpoint(dev_fwnode(dev), fwnode))) {\n\n> +\t\tif (!fwnode_device_is_available(\n> +\t\t\t    fwnode_graph_get_port_parent(fwnode)))\n> +\t\t\tcontinue;\n> +\n> +\t\tif (has_port) {\n> +\t\t\tstruct fwnode_endpoint ep;\n> +\n> +\t\t\tret = fwnode_graph_parse_endpoint(fwnode, &ep);\n> +\t\t\tif (ret) {\n> +\t\t\t\tfwnode_handle_put(fwnode);\n> +\t\t\t\treturn ret;\n> +\t\t\t}\n> +\n> +\t\t\tif (ep.port != port)\n> +\t\t\t\tcontinue;\n> +\t\t}\n> +\t\tmax_subdevs++;\n> +\t}\n> +\n> +\t/* No subdevs to add? Return here. */\n> +\tif (max_subdevs == notifier->max_subdevs)\n> +\t\treturn 0;\n> +\n> +\tret = v4l2_async_notifier_realloc(notifier, max_subdevs);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n> +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n\nSame here: this can be a 'while'.\n\n> +\t\tif (!fwnode_device_is_available(\n> +\t\t\t    fwnode_graph_get_port_parent(fwnode)))\n> +\t\t\tcontinue;\n> +\n> +\t\tif (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {\n> +\t\t\tret = -EINVAL;\n> +\t\t\tbreak;\n> +\t\t}\n> +\n> +\t\tif (has_port) {\n> +\t\t\tstruct fwnode_endpoint ep;\n> +\n> +\t\t\tret = fwnode_graph_parse_endpoint(fwnode, &ep);\n> +\t\t\tif (ret)\n> +\t\t\t\tbreak;\n> +\n> +\t\t\tif (ep.port != port)\n> +\t\t\t\tcontinue;\n> +\t\t}\n> +\n> +\t\tret = v4l2_async_notifier_fwnode_parse_endpoint(\n> +\t\t\tdev, notifier, fwnode, asd_struct_size, parse_endpoint);\n> +\t\tif (ret < 0)\n> +\t\t\tbreak;\n> +\t}\n> +\n> +\tfwnode_handle_put(fwnode);\n> +\n> +\treturn ret;\n> +}\n> +\n> +int v4l2_async_notifier_parse_fwnode_endpoints(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tsize_t asd_struct_size,\n> +\tint (*parse_endpoint)(struct device *dev,\n> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n> +\t\t\t    struct v4l2_async_subdev *asd))\n> +{\n> +\treturn __v4l2_async_notifier_parse_fwnode_endpoints(\n> +\t\tdev, notifier, asd_struct_size, 0, false, parse_endpoint);\n> +}\n> +EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints);\n> +\n> +int v4l2_async_notifier_parse_fwnode_endpoints_by_port(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tsize_t asd_struct_size, unsigned int port,\n> +\tint (*parse_endpoint)(struct device *dev,\n> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n> +\t\t\t    struct v4l2_async_subdev *asd))\n> +{\n> +\treturn __v4l2_async_notifier_parse_fwnode_endpoints(\n> +\t\tdev, notifier, asd_struct_size, port, true, parse_endpoint);\n> +}\n> +EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port);\n> +\n>  MODULE_LICENSE(\"GPL\");\n>  MODULE_AUTHOR(\"Sakari Ailus <sakari.ailus@linux.intel.com>\");\n>  MODULE_AUTHOR(\"Sylwester Nawrocki <s.nawrocki@samsung.com>\");\n> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h\n> index c69d8c8a66d0..96fa1afc00dd 100644\n> --- a/include/media/v4l2-async.h\n> +++ b/include/media/v4l2-async.h\n> @@ -18,7 +18,6 @@ struct device;\n>  struct device_node;\n>  struct v4l2_device;\n>  struct v4l2_subdev;\n> -struct v4l2_async_notifier;\n>  \n>  /* A random max subdevice number, used to allocate an array on stack */\n>  #define V4L2_MAX_SUBDEVS 128U\n> @@ -50,6 +49,10 @@ enum v4l2_async_match_type {\n>   * @match:\tunion of per-bus type matching data sets\n>   * @list:\tused to link struct v4l2_async_subdev objects, waiting to be\n>   *\t\tprobed, to a notifier->waiting list\n> + *\n> + * When this struct is used as a member in a driver specific struct,\n> + * the driver specific struct shall contain the @struct\n> + * v4l2_async_subdev as its first member.\n>   */\n>  struct v4l2_async_subdev {\n>  \tenum v4l2_async_match_type match_type;\n> @@ -78,7 +81,8 @@ struct v4l2_async_subdev {\n>  /**\n>   * struct v4l2_async_notifier - v4l2_device notifier data\n>   *\n> - * @num_subdevs: number of subdevices\n> + * @num_subdevs: number of subdevices used in the subdevs array\n> + * @max_subdevs: number of subdevices allocated in the subdevs array\n>   * @subdevs:\tarray of pointers to subdevice descriptors\n>   * @v4l2_dev:\tpointer to struct v4l2_device\n>   * @waiting:\tlist of struct v4l2_async_subdev, waiting for their drivers\n> @@ -90,6 +94,7 @@ struct v4l2_async_subdev {\n>   */\n>  struct v4l2_async_notifier {\n>  \tunsigned int num_subdevs;\n> +\tunsigned int max_subdevs;\n>  \tstruct v4l2_async_subdev **subdevs;\n>  \tstruct v4l2_device *v4l2_dev;\n>  \tstruct list_head waiting;\n> @@ -121,6 +126,21 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,\n>  void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);\n>  \n>  /**\n> + * v4l2_async_notifier_release - release notifier resources\n> + * @notifier: the notifier the resources of which are to be released\n> + *\n> + * Release memory resources related to a notifier, including the async\n> + * sub-devices allocated for the purposes of the notifier. The user is\n> + * responsible for releasing the notifier's resources after calling\n> + * @v4l2_async_notifier_parse_fwnode_endpoints.\n> + *\n> + * There is no harm from calling v4l2_async_notifier_release in other\n> + * cases as long as its memory has been zeroed after it has been\n> + * allocated.\n> + */\n> +void v4l2_async_notifier_release(struct v4l2_async_notifier *notifier);\n> +\n> +/**\n>   * v4l2_async_register_subdev - registers a sub-device to the asynchronous\n>   * \tsubdevice framework\n>   *\n> diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h\n> index 68eb22ba571b..83afac48ea6b 100644\n> --- a/include/media/v4l2-fwnode.h\n> +++ b/include/media/v4l2-fwnode.h\n> @@ -25,6 +25,8 @@\n>  #include <media/v4l2-mediabus.h>\n>  \n>  struct fwnode_handle;\n> +struct v4l2_async_notifier;\n> +struct v4l2_async_subdev;\n>  \n>  #define V4L2_FWNODE_CSI2_MAX_DATA_LANES\t4\n>  \n> @@ -201,4 +203,119 @@ int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode,\n>   */\n>  void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);\n>  \n> +/**\n> + * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a\n> + *\t\t\t\t\t\tdevice node\n> + * @dev: the device the endpoints of which are to be parsed\n> + * @notifier: notifier for @dev\n> + * @asd_struct_size: size of the driver's async sub-device struct, including\n> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> + *\t\t     v4l2_async_subdev shall be the first member of\n> + *\t\t     the driver's async sub-device struct, i.e. both\n> + *\t\t     begin at the same memory address.\n> + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n> + *\t\t    endpoint. Optional.\n> + *\t\t    Return: %0 on success\n> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> + *\t\t\t\t       should not be considered as an error\n> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> + *\n> + * Parse the fwnode endpoints of the @dev device and populate the async sub-\n> + * devices array of the notifier. The @parse_endpoint callback function is\n> + * called for each endpoint with the corresponding async sub-device pointer to\n> + * let the caller initialize the driver-specific part of the async sub-device\n> + * structure.\n> + *\n> + * The notifier memory shall be zeroed before this function is called on the\n> + * notifier.\n> + *\n> + * This function may not be called on a registered notifier and may be called on\n> + * a notifier only once.\n> + *\n> + * Do not change the notifier's subdevs array, take references to the subdevs\n> + * array itself or change the notifier's num_subdevs field. This is because this\n> + * function allocates and reallocates the subdevs array based on parsing\n> + * endpoints.\n> + *\n> + * The @struct v4l2_fwnode_endpoint passed to the callback function\n> + * @parse_endpoint is released once the function is finished. If there is a need\n> + * to retain that configuration, the user needs to allocate memory for it.\n> + *\n> + * Any notifier populated using this function must be released with a call to\n> + * v4l2_async_notifier_release() after it has been unregistered and the async\n> + * sub-devices are no longer in use, even if the function returned an error.\n> + *\n> + * Return: %0 on success, including when no async sub-devices are found\n> + *\t   %-ENOMEM if memory allocation failed\n> + *\t   %-EINVAL if graph or endpoint parsing failed\n> + *\t   Other error codes as returned by @parse_endpoint\n> + */\n> +int v4l2_async_notifier_parse_fwnode_endpoints(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tsize_t asd_struct_size,\n> +\tint (*parse_endpoint)(struct device *dev,\n> +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n> +\t\t\t      struct v4l2_async_subdev *asd));\n> +\n> +/**\n> + * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode\n> + *\t\t\t\t\t\t\tendpoints of a port in a\n> + *\t\t\t\t\t\t\tdevice node\n> + * @dev: the device the endpoints of which are to be parsed\n> + * @notifier: notifier for @dev\n> + * @asd_struct_size: size of the driver's async sub-device struct, including\n> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> + *\t\t     v4l2_async_subdev shall be the first member of\n> + *\t\t     the driver's async sub-device struct, i.e. both\n> + *\t\t     begin at the same memory address.\n> + * @port: port number where endpoints are to be parsed\n> + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n> + *\t\t    endpoint. Optional.\n> + *\t\t    Return: %0 on success\n> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> + *\t\t\t\t       should not be considered as an error\n> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> + *\n> + * This function is just like @v4l2_async_notifier_parse_fwnode_endpoints with\n> + * the exception that it only parses endpoints in a given port. This is useful\n> + * on devices that have both sinks and sources: the async sub-devices connected\n\non -> for\n\n> + * to sources have already been set up by another driver (on capture devices).\n\non -> for\n\nSo if I understand this correctly for devices with both sinks and sources you use\nthis function to just parse the sink ports. And you have to give explicit port\nnumbers since you can't tell from parsing the device tree if a port is a sink or\nsource port, right? Only the driver knows this.\n\n> + *\n> + * Parse the fwnode endpoints of the @dev device on a given @port and populate\n> + * the async sub-devices array of the notifier. The @parse_endpoint callback\n> + * function is called for each endpoint with the corresponding async sub-device\n> + * pointer to let the caller initialize the driver-specific part of the async\n> + * sub-device structure.\n> + *\n> + * The notifier memory shall be zeroed before this function is called on the\n> + * notifier the first time.\n> + *\n> + * This function may not be called on a registered notifier and may be called on\n> + * a notifier only once per port.\n> + *\n> + * Do not change the notifier's subdevs array, take references to the subdevs\n> + * array itself or change the notifier's num_subdevs field. This is because this\n> + * function allocates and reallocates the subdevs array based on parsing\n> + * endpoints.\n> + *\n> + * The @struct v4l2_fwnode_endpoint passed to the callback function\n> + * @parse_endpoint is released once the function is finished. If there is a need\n> + * to retain that configuration, the user needs to allocate memory for it.\n> + *\n> + * Any notifier populated using this function must be released with a call to\n> + * v4l2_async_notifier_release() after it has been unregistered and the async\n> + * sub-devices are no longer in use, even if the function returned an error.\n> + *\n> + * Return: %0 on success, including when no async sub-devices are found\n> + *\t   %-ENOMEM if memory allocation failed\n> + *\t   %-EINVAL if graph or endpoint parsing failed\n> + *\t   Other error codes as returned by @parse_endpoint\n> + */\n> +int v4l2_async_notifier_parse_fwnode_endpoints_by_port(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tsize_t asd_struct_size, unsigned int port,\n> +\tint (*parse_endpoint)(struct device *dev,\n> +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n> +\t\t\t      struct v4l2_async_subdev *asd));\n> +\n>  #endif /* _V4L2_FWNODE_H */\n> \n\nRegards,\n\n\tHans\n--\nTo unsubscribe from this list: send the line \"unsubscribe devicetree\" in\nthe body of a message to majordomo@vger.kernel.org\nMore majordomo info at  http://vger.kernel.org/majordomo-info.html","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxFkQ5jjtz9ryT\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 18:03:42 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751445AbdISIDj (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 04:03:39 -0400","from lb1-smtp-cloud8.xs4all.net ([194.109.24.21]:50214 \"EHLO\n\tlb1-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1751024AbdISIDi (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 04:03:38 -0400","from [192.168.2.10] ([212.251.195.8])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid uDVAdXNOtb4gvuDVDdkGmD; Tue, 19 Sep 2017 10:03:36 +0200"],"Subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","Cc":"niklas.soderlund@ragnatech.se, maxime.ripard@free-electrons.com,\n\trobh@kernel.org, laurent.pinchart@ideasonboard.com,\n\tdevicetree@vger.kernel.org, pavel@ucw.cz, sre@kernel.org","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-6-sakari.ailus@linux.intel.com>","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<a17ab793-b859-f04a-2dff-d8f6a314e9bf@xs4all.nl>","Date":"Tue, 19 Sep 2017 10:03:27 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tThunderbird/52.2.1","MIME-Version":"1.0","In-Reply-To":"<20170915141724.23124-6-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfNyccr91KyE/1F/kQqJzg6Te5IM9abT3KHjN9XCYqNwGEHgiAosJmdegUa9t1lDeof+es3jP2NAmCQ/ab6ghEOwK1mONkAxEoX/FDCdMySId3X+r1cwl\n\tWiQdXUar0obkuyZyaRDCq9PtClWXHgpuYMx5GVW5d3BoIlRLnMlJ8wKUruRlizldIVOSsoPs0ZLAuDKxBDjuuZYRjF6aQjXX+JEfCO1gPNuF6bAZS+9jl/lf\n\tuYaIs0WEEWaXfptFe5skwtGOuTgRgdVrn/HT0rFB0OIkWxD3P1cFuH3oXZUPEFhw4VY3PeAJUx/fNDqZDLgQeWBa+B5LcFvHmLRzDixp1h2lq7smZA2fGbY4\n\trFg7WhQx9kJ5jQgTAlj+1KMI2CqqsUCjXNAO6crqn+avWvHH/+Zh6lDjAZ+2i007dzNwoNrwq7wVgyicIINlyEZ8cfMS9Rylo68rkl9d2DjHIiF3WOF+AnZP\n\tBJ+xaL/ackHkWd6QQZCdTfLEiHPfqIvi5v0YxD94Z/NRW8Vt/4wKsbJWHeo=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770730,"web_url":"http://patchwork.ozlabs.org/comment/1770730/","msgid":"<07fff60b-2118-f867-6270-8eb803120392@xs4all.nl>","list_archive_url":null,"date":"2017-09-19T08:06:23","subject":"Re: [PATCH v13 14/25] v4l: async: Allow binding notifiers to\n\tsub-devices","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n> Registering a notifier has required the knowledge of struct v4l2_device\n> for the reason that sub-devices generally are registered to the\n> v4l2_device (as well as the media device, also available through\n> v4l2_device).\n> \n> This information is not available for sub-device drivers at probe time.\n> \n> What this patch does is that it allows registering notifiers without\n> having v4l2_device around. Instead the sub-device pointer is stored in the\n> notifier. Once the sub-device of the driver that registered the notifier\n> is registered, the notifier will gain the knowledge of the v4l2_device,\n> and the binding of async sub-devices from the sub-device driver's notifier\n> may proceed.\n> \n> The root notifier's complete callback is only called when all sub-device\n> notifiers are completed.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n\nAcked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\nRegards,\n\n\tHans\n\n> ---\n>  drivers/media/v4l2-core/v4l2-async.c | 218 ++++++++++++++++++++++++++++++-----\n>  include/media/v4l2-async.h           |  16 ++-\n>  2 files changed, 203 insertions(+), 31 deletions(-)\n> \n> diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c\n> index 4be2f16af051..52fe22b9b6b4 100644\n> --- a/drivers/media/v4l2-core/v4l2-async.c\n> +++ b/drivers/media/v4l2-core/v4l2-async.c\n> @@ -53,6 +53,10 @@ static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n)\n>  \treturn n->ops->complete(n);\n>  }\n>  \n> +static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,\n> +\t\t\t\t   struct v4l2_subdev *sd,\n> +\t\t\t\t   struct v4l2_async_subdev *asd);\n> +\n>  static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)\n>  {\n>  #if IS_ENABLED(CONFIG_I2C)\n> @@ -124,14 +128,127 @@ static struct v4l2_async_subdev *v4l2_async_find_match(\n>  \treturn NULL;\n>  }\n>  \n> +/* Find the sub-device notifier registered by a sub-device driver. */\n> +static struct v4l2_async_notifier *v4l2_async_find_subdev_notifier(\n> +\tstruct v4l2_subdev *sd)\n> +{\n> +\tstruct v4l2_async_notifier *n;\n> +\n> +\tlist_for_each_entry(n, &notifier_list, list)\n> +\t\tif (n->sd == sd)\n> +\t\t\treturn n;\n> +\n> +\treturn NULL;\n> +}\n> +\n> +/* Return true if all sub-device notifiers are complete, false otherwise. */\n> +static bool v4l2_async_subdev_notifiers_complete(\n> +\tstruct v4l2_async_notifier *notifier)\n> +{\n> +\tstruct v4l2_subdev *sd;\n> +\n> +\tif (!list_empty(&notifier->waiting))\n> +\t\treturn false;\n> +\n> +\tlist_for_each_entry(sd, &notifier->done, async_list) {\n> +\t\tstruct v4l2_async_notifier *subdev_notifier =\n> +\t\t\tv4l2_async_find_subdev_notifier(sd);\n> +\n> +\t\tif (subdev_notifier &&\n> +\t\t    !v4l2_async_subdev_notifiers_complete(subdev_notifier))\n> +\t\t\treturn false;\n> +\t}\n> +\n> +\treturn true;\n> +}\n> +\n> +/* Get v4l2_device related to the notifier if one can be found. */\n> +static struct v4l2_device *v4l2_async_notifier_find_v4l2_dev(\n> +\tstruct v4l2_async_notifier *notifier)\n> +{\n> +\twhile (notifier->parent)\n> +\t\tnotifier = notifier->parent;\n> +\n> +\treturn notifier->v4l2_dev;\n> +}\n> +\n> +/* Test all async sub-devices in a notifier for a match. */\n> +static int v4l2_async_notifier_try_all_subdevs(\n> +\tstruct v4l2_async_notifier *notifier)\n> +{\n> +\tstruct v4l2_subdev *sd;\n> +\n> +\tif (!v4l2_async_notifier_find_v4l2_dev(notifier))\n> +\t\treturn 0;\n> +\n> +again:\n> +\tlist_for_each_entry(sd, &subdev_list, async_list) {\n> +\t\tstruct v4l2_async_subdev *asd;\n> +\t\tint ret;\n> +\n> +\t\tasd = v4l2_async_find_match(notifier, sd);\n> +\t\tif (!asd)\n> +\t\t\tcontinue;\n> +\n> +\t\tret = v4l2_async_match_notify(notifier, sd, asd);\n> +\t\tif (ret < 0)\n> +\t\t\treturn ret;\n> +\n> +\t\t/*\n> +\t\t * v4l2_async_match_notify() may lead to registering a\n> +\t\t * new notifier and thus changing the async subdevs\n> +\t\t * list. In order to proceed safely from here, restart\n> +\t\t * parsing the list from the beginning.\n> +\t\t */\n> +\t\tgoto again;\n> +\t}\n> +\n> +\treturn 0;\n> +}\n> +\n> +/* Try completing a notifier. */\n> +static int v4l2_async_notifier_try_complete(\n> +\tstruct v4l2_async_notifier *notifier)\n> +{\n> +\tdo {\n> +\t\tint ret;\n> +\n> +\t\t/* Any local async sub-devices left? */\n> +\t\tif (!list_empty(&notifier->waiting))\n> +\t\t\treturn 0;\n> +\n> +\t\t/*\n> +\t\t * Any sub-device notifiers waiting for async subdevs\n> +\t\t * to be bound?\n> +\t\t */\n> +\t\tif (!v4l2_async_subdev_notifiers_complete(notifier))\n> +\t\t\treturn 0;\n> +\n> +\t\t/* Proceed completing the notifier */\n> +\t\tret = v4l2_async_notifier_call_complete(notifier);\n> +\t\tif (ret < 0)\n> +\t\t\treturn ret;\n> +\n> +\t\t/*\n> +\t\t * Obtain notifier's parent. If there is one, repeat\n> +\t\t * the process, otherwise we're done here.\n> +\t\t */\n> +\t\tnotifier = notifier->parent;\n> +\t} while (notifier);\n> +\n> +\treturn 0;\n> +}\n> +\n>  static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,\n>  \t\t\t\t   struct v4l2_subdev *sd,\n>  \t\t\t\t   struct v4l2_async_subdev *asd)\n>  {\n> +\tstruct v4l2_async_notifier *subdev_notifier;\n>  \tint ret;\n>  \n> -\tret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);\n> -\tif (ret < 0)\n> +\tret = v4l2_device_register_subdev(\n> +\t\tv4l2_async_notifier_find_v4l2_dev(notifier), sd);\n> +\tif (ret)\n>  \t\treturn ret;\n>  \n>  \tret = v4l2_async_notifier_call_bound(notifier, sd, asd);\n> @@ -148,10 +265,20 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,\n>  \t/* Move from the global subdevice list to notifier's done */\n>  \tlist_move(&sd->async_list, &notifier->done);\n>  \n> -\tif (list_empty(&notifier->waiting))\n> -\t\treturn v4l2_async_notifier_call_complete(notifier);\n> +\t/*\n> +\t * See if the sub-device has a notifier. If it does, proceed\n> +\t * with checking for its async sub-devices.\n> +\t */\n> +\tsubdev_notifier = v4l2_async_find_subdev_notifier(sd);\n> +\tif (subdev_notifier && !subdev_notifier->parent) {\n> +\t\tsubdev_notifier->parent = notifier;\n> +\t\tret = v4l2_async_notifier_try_all_subdevs(subdev_notifier);\n> +\t\tif (ret)\n> +\t\t\treturn ret;\n> +\t}\n>  \n> -\treturn 0;\n> +\t/* Try completing the notifier and its parent(s). */\n> +\treturn v4l2_async_notifier_try_complete(notifier);\n>  }\n>  \n>  static void v4l2_async_cleanup(struct v4l2_subdev *sd)\n> @@ -163,17 +290,15 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)\n>  \tsd->dev = NULL;\n>  }\n>  \n> -int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,\n> -\t\t\t\t struct v4l2_async_notifier *notifier)\n> +static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)\n>  {\n> -\tstruct v4l2_subdev *sd, *tmp;\n>  \tstruct v4l2_async_subdev *asd;\n> +\tint ret;\n>  \tint i;\n>  \n> -\tif (!v4l2_dev || notifier->num_subdevs > V4L2_MAX_SUBDEVS)\n> +\tif (notifier->num_subdevs > V4L2_MAX_SUBDEVS)\n>  \t\treturn -EINVAL;\n>  \n> -\tnotifier->v4l2_dev = v4l2_dev;\n>  \tINIT_LIST_HEAD(&notifier->waiting);\n>  \tINIT_LIST_HEAD(&notifier->done);\n>  \n> @@ -200,18 +325,10 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,\n>  \n>  \tmutex_lock(&list_lock);\n>  \n> -\tlist_for_each_entry_safe(sd, tmp, &subdev_list, async_list) {\n> -\t\tint ret;\n> -\n> -\t\tasd = v4l2_async_find_match(notifier, sd);\n> -\t\tif (!asd)\n> -\t\t\tcontinue;\n> -\n> -\t\tret = v4l2_async_match_notify(notifier, sd, asd);\n> -\t\tif (ret < 0) {\n> -\t\t\tmutex_unlock(&list_lock);\n> -\t\t\treturn ret;\n> -\t\t}\n> +\tret = v4l2_async_notifier_try_all_subdevs(notifier);\n> +\tif (ret) {\n> +\t\tmutex_unlock(&list_lock);\n> +\t\treturn ret;\n>  \t}\n>  \n>  \t/* Keep also completed notifiers on the list */\n> @@ -221,29 +338,70 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,\n>  \n>  \treturn 0;\n>  }\n> +\n> +int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,\n> +\t\t\t\t struct v4l2_async_notifier *notifier)\n> +{\n> +\tif (WARN_ON(!v4l2_dev || notifier->sd))\n> +\t\treturn -EINVAL;\n> +\n> +\tnotifier->v4l2_dev = v4l2_dev;\n> +\n> +\treturn __v4l2_async_notifier_register(notifier);\n> +}\n>  EXPORT_SYMBOL(v4l2_async_notifier_register);\n>  \n> -void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)\n> +int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,\n> +\t\t\t\t\tstruct v4l2_async_notifier *notifier)\n>  {\n> -\tstruct v4l2_subdev *sd, *tmp;\n> +\tif (WARN_ON(!sd || notifier->v4l2_dev))\n> +\t\treturn -EINVAL;\n>  \n> -\tif (!notifier->v4l2_dev)\n> -\t\treturn;\n> +\tnotifier->sd = sd;\n>  \n> -\tmutex_lock(&list_lock);\n> +\treturn __v4l2_async_notifier_register(notifier);\n> +}\n> +EXPORT_SYMBOL(v4l2_async_subdev_notifier_register);\n>  \n> -\tlist_del(&notifier->list);\n> +/* Unbind all sub-devices in the notifier tree. */\n> +static void v4l2_async_notifier_unbind_all_subdevs(\n> +\tstruct v4l2_async_notifier *notifier)\n> +{\n> +\tstruct v4l2_subdev *sd, *tmp;\n>  \n>  \tlist_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {\n> +\t\tstruct v4l2_async_notifier *subdev_notifier =\n> +\t\t\tv4l2_async_find_subdev_notifier(sd);\n> +\n> +\t\tif (subdev_notifier)\n> +\t\t\tv4l2_async_notifier_unbind_all_subdevs(subdev_notifier);\n> +\n>  \t\tv4l2_async_cleanup(sd);\n>  \n>  \t\tv4l2_async_notifier_call_unbind(notifier, sd, sd->asd);\n> -\t}\n>  \n> -\tmutex_unlock(&list_lock);\n> +\t\tlist_del(&sd->async_list);\n> +\t\tlist_add(&sd->async_list, &subdev_list);\n> +\t}\n>  \n> +\tnotifier->parent = NULL;\n> +\tnotifier->sd = NULL;\n>  \tnotifier->v4l2_dev = NULL;\n>  }\n> +\n> +void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)\n> +{\n> +\tif (!notifier->v4l2_dev && !notifier->sd)\n> +\t\treturn;\n> +\n> +\tmutex_lock(&list_lock);\n> +\n> +\tv4l2_async_notifier_unbind_all_subdevs(notifier);\n> +\n> +\tlist_del(&notifier->list);\n> +\n> +\tmutex_unlock(&list_lock);\n> +}\n>  EXPORT_SYMBOL(v4l2_async_notifier_unregister);\n>  \n>  void v4l2_async_notifier_release(struct v4l2_async_notifier *notifier)\n> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h\n> index 3bc8a7c0d83f..a13803a6371d 100644\n> --- a/include/media/v4l2-async.h\n> +++ b/include/media/v4l2-async.h\n> @@ -102,7 +102,9 @@ struct v4l2_async_notifier_operations {\n>   * @num_subdevs: number of subdevices used in the subdevs array\n>   * @max_subdevs: number of subdevices allocated in the subdevs array\n>   * @subdevs:\tarray of pointers to subdevice descriptors\n> - * @v4l2_dev:\tpointer to struct v4l2_device\n> + * @v4l2_dev:\tv4l2_device of the root notifier, NULL otherwise\n> + * @sd:\t\tsub-device that registered the notifier, NULL otherwise\n> + * @parent:\tparent notifier\n>   * @waiting:\tlist of struct v4l2_async_subdev, waiting for their drivers\n>   * @done:\tlist of struct v4l2_subdev, already probed\n>   * @list:\tmember in a global list of notifiers\n> @@ -113,6 +115,8 @@ struct v4l2_async_notifier {\n>  \tunsigned int max_subdevs;\n>  \tstruct v4l2_async_subdev **subdevs;\n>  \tstruct v4l2_device *v4l2_dev;\n> +\tstruct v4l2_subdev *sd;\n> +\tstruct v4l2_async_notifier *parent;\n>  \tstruct list_head waiting;\n>  \tstruct list_head done;\n>  \tstruct list_head list;\n> @@ -128,6 +132,16 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,\n>  \t\t\t\t struct v4l2_async_notifier *notifier);\n>  \n>  /**\n> + * v4l2_async_subdev_notifier_register - registers a subdevice asynchronous\n> + *\t\t\t\t\t notifier for a sub-device\n> + *\n> + * @sd: pointer to &struct v4l2_subdev\n> + * @notifier: pointer to &struct v4l2_async_notifier\n> + */\n> +int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,\n> +\t\t\t\t\tstruct v4l2_async_notifier *notifier);\n> +\n> +/**\n>   * v4l2_async_notifier_unregister - unregisters a subdevice asynchronous notifier\n>   *\n>   * @notifier: pointer to &struct v4l2_async_notifier\n> \n\n--\nTo unsubscribe from this list: send the line \"unsubscribe devicetree\" in\nthe body of a message to majordomo@vger.kernel.org\nMore majordomo info at  http://vger.kernel.org/majordomo-info.html","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxFnf0Xb4z9s7M\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 18:06:30 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751550AbdISIG2 (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 04:06:28 -0400","from lb1-smtp-cloud8.xs4all.net ([194.109.24.21]:37565 \"EHLO\n\tlb1-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1751521AbdISIG2 (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 04:06:28 -0400","from [192.168.2.10] ([212.251.195.8])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid uDXzdXPJhb4gvuDY2dkHh7; Tue, 19 Sep 2017 10:06:26 +0200"],"Subject":"Re: [PATCH v13 14/25] v4l: async: Allow binding notifiers to\n\tsub-devices","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","Cc":"niklas.soderlund@ragnatech.se, maxime.ripard@free-electrons.com,\n\trobh@kernel.org, laurent.pinchart@ideasonboard.com,\n\tdevicetree@vger.kernel.org, pavel@ucw.cz, sre@kernel.org","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-15-sakari.ailus@linux.intel.com>","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<07fff60b-2118-f867-6270-8eb803120392@xs4all.nl>","Date":"Tue, 19 Sep 2017 10:06:23 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tThunderbird/52.2.1","MIME-Version":"1.0","In-Reply-To":"<20170915141724.23124-15-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfItOkVzIvQ32HJWuHcCrem3aRC/isJejG8v5OrndvyPgMM7cbbB7oiH1KsRSUYSQbNR1BddbH+3IbYTVCyiZHQMRtx8C5iLTycpv2r4c+qDPUDSBYllS\n\tJ2VTkVPyU9/5q0lmaGo+Sj1BSm2eh1GlZV7xbQ9NfOoYzCQe813smFucZIdHksHBO4mY+gSK0CZumWgw1pdlHdzY6gTlkRydkpaZ0/q8wptpgN7X8A1aYtcZ\n\tMPKg+uQ8bbQaMEnCZb0Sd3U3CeNGvm8IUNqRrSuYjCH8xgR+3/6yiAGN3faYSFo3zQOIztpkS941ZkeidIb7cfB31BwXV0y0RqmS1ogHllhSIl4QxnGW0n8B\n\tHS0fdgqphf8CAxWzsxOzNxJGBGtU7ntIv5Gr4wYL3BgpNO6CB7fFGyCcQGZRXQ2ikRo9wyX8f4cyq/s2N9I8sCzF8XaEWOkNvQYCaIN5wZ+hNDCz4XFs4ri+\n\tbsYUsHFjiAnjJctKM0hmOTYBrvh9c268biAqeJYKJsybGC5k69umlSZis5w=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770736,"web_url":"http://patchwork.ozlabs.org/comment/1770736/","msgid":"<95b5fb2c-cc1e-091a-1d13-1d18cbdfd2ad@xs4all.nl>","list_archive_url":null,"date":"2017-09-19T08:14:07","subject":"Re: [PATCH v13 17/25] v4l: fwnode: Add a helper function for parsing\n\tgeneric references","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n> Add function v4l2_fwnode_reference_parse() for parsing them as async\n> sub-devices. This can be done on e.g. flash or lens async sub-devices that\n> are not part of but are associated with a sensor.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n\nAcked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\nRegards,\n\n\tHans\n\n> ---\n>  drivers/media/v4l2-core/v4l2-fwnode.c | 69 +++++++++++++++++++++++++++++++++++\n>  1 file changed, 69 insertions(+)\n> \n> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c\n> index 44ee35f6aad5..65e84ea1cc35 100644\n> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> @@ -498,6 +498,75 @@ int v4l2_async_notifier_parse_fwnode_endpoints_by_port(\n>  }\n>  EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port);\n>  \n> +/*\n> + * v4l2_fwnode_reference_parse - parse references for async sub-devices\n> + * @dev: the device node the properties of which are parsed for references\n> + * @notifier: the async notifier where the async subdevs will be added\n> + * @prop: the name of the property\n> + *\n> + * Return: 0 on success\n> + *\t   -ENOENT if no entries were found\n> + *\t   -ENOMEM if memory allocation failed\n> + *\t   -EINVAL if property parsing failed\n> + */\n> +static int v4l2_fwnode_reference_parse(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tconst char *prop)\n> +{\n> +\tstruct fwnode_reference_args args;\n> +\tunsigned int index;\n> +\tint ret;\n> +\n> +\tfor (index = 0;\n> +\t     !(ret = fwnode_property_get_reference_args(\n> +\t\t       dev_fwnode(dev), prop, NULL, 0, index, &args));\n> +\t     index++)\n> +\t\tfwnode_handle_put(args.fwnode);\n> +\n> +\tif (!index)\n> +\t\treturn -ENOENT;\n> +\n> +\t/*\n> +\t * Note that right now both -ENODATA and -ENOENT may signal\n> +\t * out-of-bounds access. Return the error in cases other than that.\n> +\t */\n> +\tif (ret != -ENOENT && ret != -ENODATA)\n> +\t\treturn ret;\n> +\n> +\tret = v4l2_async_notifier_realloc(notifier,\n> +\t\t\t\t\t  notifier->num_subdevs + index);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tfor (index = 0; !fwnode_property_get_reference_args(\n> +\t\t     dev_fwnode(dev), prop, NULL, 0, index, &args);\n> +\t     index++) {\n> +\t\tstruct v4l2_async_subdev *asd;\n> +\n> +\t\tif (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {\n> +\t\t\tret = -EINVAL;\n> +\t\t\tgoto error;\n> +\t\t}\n> +\n> +\t\tasd = kzalloc(sizeof(*asd), GFP_KERNEL);\n> +\t\tif (!asd) {\n> +\t\t\tret = -ENOMEM;\n> +\t\t\tgoto error;\n> +\t\t}\n> +\n> +\t\tnotifier->subdevs[notifier->num_subdevs] = asd;\n> +\t\tasd->match.fwnode.fwnode = args.fwnode;\n> +\t\tasd->match_type = V4L2_ASYNC_MATCH_FWNODE;\n> +\t\tnotifier->num_subdevs++;\n> +\t}\n> +\n> +\treturn 0;\n> +\n> +error:\n> +\tfwnode_handle_put(args.fwnode);\n> +\treturn ret;\n> +}\n> +\n>  MODULE_LICENSE(\"GPL\");\n>  MODULE_AUTHOR(\"Sakari Ailus <sakari.ailus@linux.intel.com>\");\n>  MODULE_AUTHOR(\"Sylwester Nawrocki <s.nawrocki@samsung.com>\");\n> \n\n--\nTo unsubscribe from this list: send the line \"unsubscribe devicetree\" in\nthe body of a message to majordomo@vger.kernel.org\nMore majordomo info at  http://vger.kernel.org/majordomo-info.html","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxFyZ4zvjz9s7M\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 18:14:14 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751445AbdISIOM (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 04:14:12 -0400","from lb3-smtp-cloud8.xs4all.net ([194.109.24.29]:56525 \"EHLO\n\tlb3-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1751283AbdISIOM (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 04:14:12 -0400","from [192.168.2.10] ([212.251.195.8])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid uDfTdXUhjb4gvuDfWdkJzL; Tue, 19 Sep 2017 10:14:10 +0200"],"Subject":"Re: [PATCH v13 17/25] v4l: fwnode: Add a helper function for parsing\n\tgeneric references","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","Cc":"niklas.soderlund@ragnatech.se, maxime.ripard@free-electrons.com,\n\trobh@kernel.org, laurent.pinchart@ideasonboard.com,\n\tdevicetree@vger.kernel.org, pavel@ucw.cz, sre@kernel.org","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-18-sakari.ailus@linux.intel.com>","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<95b5fb2c-cc1e-091a-1d13-1d18cbdfd2ad@xs4all.nl>","Date":"Tue, 19 Sep 2017 10:14:07 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tThunderbird/52.2.1","MIME-Version":"1.0","In-Reply-To":"<20170915141724.23124-18-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfKDbaOP6zTwP9ISKBpvz+IoefmZ+BHQcnKbCbIPUaop/RGRrs8hMTEZ7C6aDK2f7R6Vvz7qInS5yxu/RHlE40NwtbE2FejXSTPvbzqRunTWBT6VN69ul\n\tUsWWKKgaaAC8YchQQzX6tjgRV0aU/unOXfsefizuV2q/48zPJ0hA7nwKJaLKzAiI+TUQIO2db67iS3sq+p4fwTXjH/OD4DrTkRTAGKyosZC32qdmBV03ZA+R\n\tpnoPtpa3/UENy/uorGMFPnoVtZJWbVYEBVM3+zmeCJqYlED3ejqY68YBUCcGY0B8Trp6Fg20d0FLAG8UrfiLLpBMCKPYPYj0p6VmbfhOik9ipG+vnuO1ZN4q\n\tcWwHXqoJeMAqoETJEPyWd2fU/j9N0iTQge3uur3WRyWbDcwgkhO///AjoEXv6ADqSSNoraWUwqQN5K9dJ4Reyhn0QTmtJF+mkzarbBiOP/8xExorBhFtlWDe\n\tPVZIxapbCPjTp+7OmxyX5JGO8L8tVerAs80bEt8qz8zm92II0NE4KmeB/PI=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770743,"web_url":"http://patchwork.ozlabs.org/comment/1770743/","msgid":"<20170919082015.vt6olgirnvmpcrpa@paasikivi.fi.intel.com>","list_archive_url":null,"date":"2017-09-19T08:20:15","subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","submitter":{"id":65485,"url":"http://patchwork.ozlabs.org/api/people/65485/","name":"Sakari Ailus","email":"sakari.ailus@linux.intel.com"},"content":"Hi Hans,\n\nThank you for the review.\n\nOn Tue, Sep 19, 2017 at 10:03:27AM +0200, Hans Verkuil wrote:\n> On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n> > Add two functions for parsing devices graph endpoints:\n> > v4l2_async_notifier_parse_fwnode_endpoints and\n> > v4l2_async_notifier_parse_fwnode_endpoints_by_port. The former iterates\n> > over all endpoints whereas the latter only iterates over the endpoints in\n> > a given port.\n> > \n> > The former is mostly useful for existing drivers that currently implement\n> > the iteration over all the endpoints themselves whereas the latter is\n> > especially intended for devices with both sinks and sources: async\n> > sub-devices for external devices connected to the device's sources will\n> > have already been set up, or they are part of the master device.\n> > \n> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> > ---\n> >  drivers/media/v4l2-core/v4l2-async.c  |  30 ++++++\n> >  drivers/media/v4l2-core/v4l2-fwnode.c | 185 ++++++++++++++++++++++++++++++++++\n> >  include/media/v4l2-async.h            |  24 ++++-\n> >  include/media/v4l2-fwnode.h           | 117 +++++++++++++++++++++\n> >  4 files changed, 354 insertions(+), 2 deletions(-)\n> > \n> > diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c\n> > index 831f185ecd47..bf0215dde616 100644\n> > --- a/drivers/media/v4l2-core/v4l2-async.c\n> > +++ b/drivers/media/v4l2-core/v4l2-async.c\n> > @@ -22,6 +22,7 @@\n> >  \n> >  #include <media/v4l2-async.h>\n> >  #include <media/v4l2-device.h>\n> > +#include <media/v4l2-fwnode.h>\n> >  #include <media/v4l2-subdev.h>\n> >  \n> >  static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)\n> > @@ -219,6 +220,35 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)\n> >  }\n> >  EXPORT_SYMBOL(v4l2_async_notifier_unregister);\n> >  \n> > +void v4l2_async_notifier_release(struct v4l2_async_notifier *notifier)\n> > +{\n> > +\tunsigned int i;\n> > +\n> > +\tif (!notifier->max_subdevs)\n> > +\t\treturn;\n> > +\n> > +\tfor (i = 0; i < notifier->num_subdevs; i++) {\n> > +\t\tstruct v4l2_async_subdev *asd = notifier->subdevs[i];\n> > +\n> > +\t\tswitch (asd->match_type) {\n> > +\t\tcase V4L2_ASYNC_MATCH_FWNODE:\n> > +\t\t\tfwnode_handle_put(asd->match.fwnode.fwnode);\n> > +\t\t\tbreak;\n> > +\t\tdefault:\n> > +\t\t\tWARN_ON_ONCE(true);\n> \n> Please add a break here.\n\nYes.\n\n> \n> > +\t\t}\n> > +\n> > +\t\tkfree(asd);\n> > +\t}\n> > +\n> > +\tnotifier->max_subdevs = 0;\n> > +\tnotifier->num_subdevs = 0;\n> > +\n> > +\tkvfree(notifier->subdevs);\n> > +\tnotifier->subdevs = NULL;\n> > +}\n> > +EXPORT_SYMBOL_GPL(v4l2_async_notifier_release);\n> > +\n> >  int v4l2_async_register_subdev(struct v4l2_subdev *sd)\n> >  {\n> >  \tstruct v4l2_async_notifier *notifier;\n> > diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c\n> > index 706f9e7b90f1..44ee35f6aad5 100644\n> > --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> > +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> > @@ -19,6 +19,7 @@\n> >   */\n> >  #include <linux/acpi.h>\n> >  #include <linux/kernel.h>\n> > +#include <linux/mm.h>\n> >  #include <linux/module.h>\n> >  #include <linux/of.h>\n> >  #include <linux/property.h>\n> > @@ -26,6 +27,7 @@\n> >  #include <linux/string.h>\n> >  #include <linux/types.h>\n> >  \n> > +#include <media/v4l2-async.h>\n> >  #include <media/v4l2-fwnode.h>\n> >  \n> >  enum v4l2_fwnode_bus_type {\n> > @@ -313,6 +315,189 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)\n> >  }\n> >  EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);\n> >  \n> > +static int v4l2_async_notifier_realloc(struct v4l2_async_notifier *notifier,\n> > +\t\t\t\t       unsigned int max_subdevs)\n> > +{\n> > +\tstruct v4l2_async_subdev **subdevs;\n> > +\n> > +\tif (max_subdevs <= notifier->max_subdevs)\n> > +\t\treturn 0;\n> > +\n> > +\tsubdevs = kvmalloc_array(\n> > +\t\tmax_subdevs, sizeof(*notifier->subdevs),\n> > +\t\tGFP_KERNEL | __GFP_ZERO);\n> > +\tif (!subdevs)\n> > +\t\treturn -ENOMEM;\n> > +\n> > +\tif (notifier->subdevs) {\n> > +\t\tmemcpy(subdevs, notifier->subdevs,\n> > +\t\t       sizeof(*subdevs) * notifier->num_subdevs);\n> > +\n> > +\t\tkvfree(notifier->subdevs);\n> > +\t}\n> > +\n> > +\tnotifier->subdevs = subdevs;\n> > +\tnotifier->max_subdevs = max_subdevs;\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> > +static int v4l2_async_notifier_fwnode_parse_endpoint(\n> > +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> > +\tstruct fwnode_handle *endpoint, unsigned int asd_struct_size,\n> > +\tint (*parse_endpoint)(struct device *dev,\n> > +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n> > +\t\t\t    struct v4l2_async_subdev *asd))\n> > +{\n> > +\tstruct v4l2_async_subdev *asd;\n> > +\tstruct v4l2_fwnode_endpoint *vep;\n> > +\tint ret = 0;\n> > +\n> > +\tasd = kzalloc(asd_struct_size, GFP_KERNEL);\n> > +\tif (!asd)\n> > +\t\treturn -ENOMEM;\n> > +\n> > +\tasd->match.fwnode.fwnode =\n> > +\t\tfwnode_graph_get_remote_port_parent(endpoint);\n> > +\tif (!asd->match.fwnode.fwnode) {\n> > +\t\tdev_warn(dev, \"bad remote port parent\\n\");\n> > +\t\tret = -EINVAL;\n> > +\t\tgoto out_err;\n> > +\t}\n> > +\n> > +\t/* Ignore endpoints the parsing of which failed. */\n> > +\tvep = v4l2_fwnode_endpoint_alloc_parse(endpoint);\n> > +\tif (IS_ERR(vep)) {\n> > +\t\tret = PTR_ERR(vep);\n> > +\t\tdev_warn(dev, \"unable to parse V4L2 fwnode endpoint (%d)\\n\",\n> > +\t\t\t ret);\n> > +\t\tgoto out_err;\n> > +\t}\n> > +\n> > +\tret = parse_endpoint ? parse_endpoint(dev, vep, asd) : 0;\n> > +\tif (ret == -ENOTCONN)\n> > +\t\tdev_dbg(dev, \"ignoring endpoint %u,%u\\n\", vep->base.port,\n> > +\t\t\tvep->base.id);\n> > +\telse if (ret < 0)\n> > +\t\tdev_warn(dev, \"driver could not parse endpoint %u,%u (%d)\\n\",\n> > +\t\t\t vep->base.port, vep->base.id, ret);\n> > +\tv4l2_fwnode_endpoint_free(vep);\n> > +\tif (ret < 0)\n> > +\t\tgoto out_err;\n> > +\n> > +\tasd->match_type = V4L2_ASYNC_MATCH_FWNODE;\n> > +\tnotifier->subdevs[notifier->num_subdevs] = asd;\n> > +\tnotifier->num_subdevs++;\n> > +\n> > +\treturn 0;\n> > +\n> > +out_err:\n> > +\tfwnode_handle_put(asd->match.fwnode.fwnode);\n> > +\tkfree(asd);\n> > +\n> > +\treturn ret == -ENOTCONN ? 0 : ret;\n> > +}\n> > +\n> > +static int __v4l2_async_notifier_parse_fwnode_endpoints(\n> > +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> > +\tsize_t asd_struct_size, unsigned int port, bool has_port,\n> > +\tint (*parse_endpoint)(struct device *dev,\n> > +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n> > +\t\t\t    struct v4l2_async_subdev *asd))\n> > +{\n> > +\tstruct fwnode_handle *fwnode = NULL;\n> > +\tunsigned int max_subdevs = notifier->max_subdevs;\n> > +\tint ret;\n> > +\n> > +\tif (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev)))\n> > +\t\treturn -EINVAL;\n> > +\n> > +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n> > +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n> \n> You can replace this by:\n> \n> \twhile ((fwnode = fwnode_graph_get_next_endpoint(dev_fwnode(dev), fwnode))) {\n> \n> > +\t\tif (!fwnode_device_is_available(\n> > +\t\t\t    fwnode_graph_get_port_parent(fwnode)))\n> > +\t\t\tcontinue;\n> > +\n> > +\t\tif (has_port) {\n> > +\t\t\tstruct fwnode_endpoint ep;\n> > +\n> > +\t\t\tret = fwnode_graph_parse_endpoint(fwnode, &ep);\n> > +\t\t\tif (ret) {\n> > +\t\t\t\tfwnode_handle_put(fwnode);\n> > +\t\t\t\treturn ret;\n> > +\t\t\t}\n> > +\n> > +\t\t\tif (ep.port != port)\n> > +\t\t\t\tcontinue;\n> > +\t\t}\n> > +\t\tmax_subdevs++;\n> > +\t}\n> > +\n> > +\t/* No subdevs to add? Return here. */\n> > +\tif (max_subdevs == notifier->max_subdevs)\n> > +\t\treturn 0;\n> > +\n> > +\tret = v4l2_async_notifier_realloc(notifier, max_subdevs);\n> > +\tif (ret)\n> > +\t\treturn ret;\n> > +\n> > +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n> > +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n> \n> Same here: this can be a 'while'.\n\nThe fwnode = NULL assignment still needs to be done. A for loop has a\nnatural initialiser for the loop, I think it's cleaner than using while\nhere.\n\nThe macro would be implemented this way as well.\n\nFor the loop above this one, I'd use for for consistency: it's the same\nloop after all.\n\nThis reminds me --- I'll send the patch for the macro.\n\n> \n> > +\t\tif (!fwnode_device_is_available(\n> > +\t\t\t    fwnode_graph_get_port_parent(fwnode)))\n> > +\t\t\tcontinue;\n> > +\n> > +\t\tif (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {\n> > +\t\t\tret = -EINVAL;\n> > +\t\t\tbreak;\n> > +\t\t}\n> > +\n> > +\t\tif (has_port) {\n> > +\t\t\tstruct fwnode_endpoint ep;\n> > +\n> > +\t\t\tret = fwnode_graph_parse_endpoint(fwnode, &ep);\n> > +\t\t\tif (ret)\n> > +\t\t\t\tbreak;\n> > +\n> > +\t\t\tif (ep.port != port)\n> > +\t\t\t\tcontinue;\n> > +\t\t}\n> > +\n> > +\t\tret = v4l2_async_notifier_fwnode_parse_endpoint(\n> > +\t\t\tdev, notifier, fwnode, asd_struct_size, parse_endpoint);\n> > +\t\tif (ret < 0)\n> > +\t\t\tbreak;\n> > +\t}\n> > +\n> > +\tfwnode_handle_put(fwnode);\n> > +\n> > +\treturn ret;\n> > +}\n> > +\n> > +int v4l2_async_notifier_parse_fwnode_endpoints(\n> > +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> > +\tsize_t asd_struct_size,\n> > +\tint (*parse_endpoint)(struct device *dev,\n> > +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n> > +\t\t\t    struct v4l2_async_subdev *asd))\n> > +{\n> > +\treturn __v4l2_async_notifier_parse_fwnode_endpoints(\n> > +\t\tdev, notifier, asd_struct_size, 0, false, parse_endpoint);\n> > +}\n> > +EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints);\n> > +\n> > +int v4l2_async_notifier_parse_fwnode_endpoints_by_port(\n> > +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> > +\tsize_t asd_struct_size, unsigned int port,\n> > +\tint (*parse_endpoint)(struct device *dev,\n> > +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n> > +\t\t\t    struct v4l2_async_subdev *asd))\n> > +{\n> > +\treturn __v4l2_async_notifier_parse_fwnode_endpoints(\n> > +\t\tdev, notifier, asd_struct_size, port, true, parse_endpoint);\n> > +}\n> > +EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port);\n> > +\n> >  MODULE_LICENSE(\"GPL\");\n> >  MODULE_AUTHOR(\"Sakari Ailus <sakari.ailus@linux.intel.com>\");\n> >  MODULE_AUTHOR(\"Sylwester Nawrocki <s.nawrocki@samsung.com>\");\n> > diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h\n> > index c69d8c8a66d0..96fa1afc00dd 100644\n> > --- a/include/media/v4l2-async.h\n> > +++ b/include/media/v4l2-async.h\n> > @@ -18,7 +18,6 @@ struct device;\n> >  struct device_node;\n> >  struct v4l2_device;\n> >  struct v4l2_subdev;\n> > -struct v4l2_async_notifier;\n> >  \n> >  /* A random max subdevice number, used to allocate an array on stack */\n> >  #define V4L2_MAX_SUBDEVS 128U\n> > @@ -50,6 +49,10 @@ enum v4l2_async_match_type {\n> >   * @match:\tunion of per-bus type matching data sets\n> >   * @list:\tused to link struct v4l2_async_subdev objects, waiting to be\n> >   *\t\tprobed, to a notifier->waiting list\n> > + *\n> > + * When this struct is used as a member in a driver specific struct,\n> > + * the driver specific struct shall contain the @struct\n> > + * v4l2_async_subdev as its first member.\n> >   */\n> >  struct v4l2_async_subdev {\n> >  \tenum v4l2_async_match_type match_type;\n> > @@ -78,7 +81,8 @@ struct v4l2_async_subdev {\n> >  /**\n> >   * struct v4l2_async_notifier - v4l2_device notifier data\n> >   *\n> > - * @num_subdevs: number of subdevices\n> > + * @num_subdevs: number of subdevices used in the subdevs array\n> > + * @max_subdevs: number of subdevices allocated in the subdevs array\n> >   * @subdevs:\tarray of pointers to subdevice descriptors\n> >   * @v4l2_dev:\tpointer to struct v4l2_device\n> >   * @waiting:\tlist of struct v4l2_async_subdev, waiting for their drivers\n> > @@ -90,6 +94,7 @@ struct v4l2_async_subdev {\n> >   */\n> >  struct v4l2_async_notifier {\n> >  \tunsigned int num_subdevs;\n> > +\tunsigned int max_subdevs;\n> >  \tstruct v4l2_async_subdev **subdevs;\n> >  \tstruct v4l2_device *v4l2_dev;\n> >  \tstruct list_head waiting;\n> > @@ -121,6 +126,21 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,\n> >  void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);\n> >  \n> >  /**\n> > + * v4l2_async_notifier_release - release notifier resources\n> > + * @notifier: the notifier the resources of which are to be released\n> > + *\n> > + * Release memory resources related to a notifier, including the async\n> > + * sub-devices allocated for the purposes of the notifier. The user is\n> > + * responsible for releasing the notifier's resources after calling\n> > + * @v4l2_async_notifier_parse_fwnode_endpoints.\n> > + *\n> > + * There is no harm from calling v4l2_async_notifier_release in other\n> > + * cases as long as its memory has been zeroed after it has been\n> > + * allocated.\n> > + */\n> > +void v4l2_async_notifier_release(struct v4l2_async_notifier *notifier);\n> > +\n> > +/**\n> >   * v4l2_async_register_subdev - registers a sub-device to the asynchronous\n> >   * \tsubdevice framework\n> >   *\n> > diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h\n> > index 68eb22ba571b..83afac48ea6b 100644\n> > --- a/include/media/v4l2-fwnode.h\n> > +++ b/include/media/v4l2-fwnode.h\n> > @@ -25,6 +25,8 @@\n> >  #include <media/v4l2-mediabus.h>\n> >  \n> >  struct fwnode_handle;\n> > +struct v4l2_async_notifier;\n> > +struct v4l2_async_subdev;\n> >  \n> >  #define V4L2_FWNODE_CSI2_MAX_DATA_LANES\t4\n> >  \n> > @@ -201,4 +203,119 @@ int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode,\n> >   */\n> >  void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);\n> >  \n> > +/**\n> > + * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a\n> > + *\t\t\t\t\t\tdevice node\n> > + * @dev: the device the endpoints of which are to be parsed\n> > + * @notifier: notifier for @dev\n> > + * @asd_struct_size: size of the driver's async sub-device struct, including\n> > + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> > + *\t\t     v4l2_async_subdev shall be the first member of\n> > + *\t\t     the driver's async sub-device struct, i.e. both\n> > + *\t\t     begin at the same memory address.\n> > + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n> > + *\t\t    endpoint. Optional.\n> > + *\t\t    Return: %0 on success\n> > + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> > + *\t\t\t\t       should not be considered as an error\n> > + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> > + *\n> > + * Parse the fwnode endpoints of the @dev device and populate the async sub-\n> > + * devices array of the notifier. The @parse_endpoint callback function is\n> > + * called for each endpoint with the corresponding async sub-device pointer to\n> > + * let the caller initialize the driver-specific part of the async sub-device\n> > + * structure.\n> > + *\n> > + * The notifier memory shall be zeroed before this function is called on the\n> > + * notifier.\n> > + *\n> > + * This function may not be called on a registered notifier and may be called on\n> > + * a notifier only once.\n> > + *\n> > + * Do not change the notifier's subdevs array, take references to the subdevs\n> > + * array itself or change the notifier's num_subdevs field. This is because this\n> > + * function allocates and reallocates the subdevs array based on parsing\n> > + * endpoints.\n> > + *\n> > + * The @struct v4l2_fwnode_endpoint passed to the callback function\n> > + * @parse_endpoint is released once the function is finished. If there is a need\n> > + * to retain that configuration, the user needs to allocate memory for it.\n> > + *\n> > + * Any notifier populated using this function must be released with a call to\n> > + * v4l2_async_notifier_release() after it has been unregistered and the async\n> > + * sub-devices are no longer in use, even if the function returned an error.\n> > + *\n> > + * Return: %0 on success, including when no async sub-devices are found\n> > + *\t   %-ENOMEM if memory allocation failed\n> > + *\t   %-EINVAL if graph or endpoint parsing failed\n> > + *\t   Other error codes as returned by @parse_endpoint\n> > + */\n> > +int v4l2_async_notifier_parse_fwnode_endpoints(\n> > +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> > +\tsize_t asd_struct_size,\n> > +\tint (*parse_endpoint)(struct device *dev,\n> > +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n> > +\t\t\t      struct v4l2_async_subdev *asd));\n> > +\n> > +/**\n> > + * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode\n> > + *\t\t\t\t\t\t\tendpoints of a port in a\n> > + *\t\t\t\t\t\t\tdevice node\n> > + * @dev: the device the endpoints of which are to be parsed\n> > + * @notifier: notifier for @dev\n> > + * @asd_struct_size: size of the driver's async sub-device struct, including\n> > + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> > + *\t\t     v4l2_async_subdev shall be the first member of\n> > + *\t\t     the driver's async sub-device struct, i.e. both\n> > + *\t\t     begin at the same memory address.\n> > + * @port: port number where endpoints are to be parsed\n> > + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n> > + *\t\t    endpoint. Optional.\n> > + *\t\t    Return: %0 on success\n> > + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> > + *\t\t\t\t       should not be considered as an error\n> > + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> > + *\n> > + * This function is just like @v4l2_async_notifier_parse_fwnode_endpoints with\n> > + * the exception that it only parses endpoints in a given port. This is useful\n> > + * on devices that have both sinks and sources: the async sub-devices connected\n> \n> on -> for\n> \n> > + * to sources have already been set up by another driver (on capture devices).\n> \n> on -> for\n\nAgreed on both.\n\n> \n> So if I understand this correctly for devices with both sinks and sources you use\n> this function to just parse the sink ports. And you have to give explicit port\n> numbers since you can't tell from parsing the device tree if a port is a sink or\n> source port, right? Only the driver knows this.\n\nCorrect. The graph data structure in DT isn't directed, so this is only\nknown by the driver.\n\n> \n> > + *\n> > + * Parse the fwnode endpoints of the @dev device on a given @port and populate\n> > + * the async sub-devices array of the notifier. The @parse_endpoint callback\n> > + * function is called for each endpoint with the corresponding async sub-device\n> > + * pointer to let the caller initialize the driver-specific part of the async\n> > + * sub-device structure.\n> > + *\n> > + * The notifier memory shall be zeroed before this function is called on the\n> > + * notifier the first time.\n> > + *\n> > + * This function may not be called on a registered notifier and may be called on\n> > + * a notifier only once per port.\n> > + *\n> > + * Do not change the notifier's subdevs array, take references to the subdevs\n> > + * array itself or change the notifier's num_subdevs field. This is because this\n> > + * function allocates and reallocates the subdevs array based on parsing\n> > + * endpoints.\n> > + *\n> > + * The @struct v4l2_fwnode_endpoint passed to the callback function\n> > + * @parse_endpoint is released once the function is finished. If there is a need\n> > + * to retain that configuration, the user needs to allocate memory for it.\n> > + *\n> > + * Any notifier populated using this function must be released with a call to\n> > + * v4l2_async_notifier_release() after it has been unregistered and the async\n> > + * sub-devices are no longer in use, even if the function returned an error.\n> > + *\n> > + * Return: %0 on success, including when no async sub-devices are found\n> > + *\t   %-ENOMEM if memory allocation failed\n> > + *\t   %-EINVAL if graph or endpoint parsing failed\n> > + *\t   Other error codes as returned by @parse_endpoint\n> > + */\n> > +int v4l2_async_notifier_parse_fwnode_endpoints_by_port(\n> > +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> > +\tsize_t asd_struct_size, unsigned int port,\n> > +\tint (*parse_endpoint)(struct device *dev,\n> > +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n> > +\t\t\t      struct v4l2_async_subdev *asd));\n> > +\n> >  #endif /* _V4L2_FWNODE_H */\n> > \n>","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxG5g3jysz9sBZ\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 18:20:23 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1750982AbdISIUU (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 04:20:20 -0400","from mga01.intel.com ([192.55.52.88]:46184 \"EHLO mga01.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1750713AbdISIUT (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tTue, 19 Sep 2017 04:20:19 -0400","from fmsmga002.fm.intel.com ([10.253.24.26])\n\tby fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t19 Sep 2017 01:20:19 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby fmsmga002.fm.intel.com with ESMTP; 19 Sep 2017 01:20:16 -0700","by paasikivi.fi.intel.com (Postfix, from userid 1000)\n\tid A111D20642; Tue, 19 Sep 2017 11:20:15 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos; i=\"5.42,417,1500966000\"; d=\"scan'208\";\n\ta=\"1220747470\"","Date":"Tue, 19 Sep 2017 11:20:15 +0300","From":"Sakari Ailus <sakari.ailus@linux.intel.com>","To":"Hans Verkuil <hverkuil@xs4all.nl>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","Message-ID":"<20170919082015.vt6olgirnvmpcrpa@paasikivi.fi.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-6-sakari.ailus@linux.intel.com>\n\t<a17ab793-b859-f04a-2dff-d8f6a314e9bf@xs4all.nl>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<a17ab793-b859-f04a-2dff-d8f6a314e9bf@xs4all.nl>","User-Agent":"NeoMutt/20170113 (1.7.2)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770750,"web_url":"http://patchwork.ozlabs.org/comment/1770750/","msgid":"<ee1252cf-3396-9bed-443f-56e3c2d621e5@xs4all.nl>","list_archive_url":null,"date":"2017-09-19T08:31:41","subject":"Re: [PATCH v13 18/25] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"Hi Sakari,\n\nI'm slowly starting to understand this. The example helped a lot. But I still have\nsome questions, see below.\n\nOn 09/15/2017 04:17 PM, Sakari Ailus wrote:\n> v4l2_fwnode_reference_parse_int_prop() will find an fwnode such that under\n> the device's own fwnode, it will follow child fwnodes with the given\n> property-value pair and return the resulting fwnode.\n\nI think both the subject, commit log, function comment and function name should\nreflect the fact that this function is for an ACPI reference.\n\nIt's only called for ACPI (from patch 19):\n\n+\t\tif (props[i].props && is_acpi_node(dev_fwnode(dev)))\n+\t\t\tret = v4l2_fwnode_reference_parse_int_props(\n\nSo renaming it to v4l2_fwnode_acpi_reference_parse_int_props or something similar\nwould clarify this fact.\n\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> ---\n>  drivers/media/v4l2-core/v4l2-fwnode.c | 201 ++++++++++++++++++++++++++++++++++\n>  1 file changed, 201 insertions(+)\n> \n> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c\n> index 65e84ea1cc35..968a345a288f 100644\n> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> @@ -567,6 +567,207 @@ static int v4l2_fwnode_reference_parse(\n>  \treturn ret;\n>  }\n>  \n> +/*\n> + * v4l2_fwnode_reference_get_int_prop - parse a reference with integer\n> + *\t\t\t\t\targuments\n> + * @dev: struct device pointer\n> + * @notifier: notifier for @dev\n> + * @prop: the name of the property\n> + * @index: the index of the reference to get\n> + * @props: the array of integer property names\n> + * @nprops: the number of integer property names in @nprops\n\nYou mean 'in @props'?\n\nOne thing that is not clear to me is when you would use an nprops value > 1.\nWhat's the use-case for that? It only makes sense (I think) if you would have\nproperty names that are all aliases of one another.\n\n> + *\n> + * Find fwnodes referred to by a property @prop, then under that\n> + * iteratively, @nprops times, follow each child node which has a\n> + * property in @props array at a given child index the value of which\n> + * matches the integer argument at an index.\n> + *\n> + * For example, if this function was called with arguments and values\n> + * @dev corresponding to device \"SEN\", @prop == \"flash-leds\", @index\n> + * == 1, @props == { \"led\" }, @nprops == 1, with the ASL snippet below\n> + * it would return the node marked with THISONE. The @dev argument in\n> + * the ASL below.\n\nThat last sentence about the @dev seems incomplete. I'm not sure what is\nmeant by it.\n\n> + *\n> + *\tDevice (LED)\n> + *\t{\n> + *\t\tName (_DSD, Package () {\n> + *\t\t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n> + *\t\t\tPackage () {\n> + *\t\t\t\tPackage () { \"led0\", \"LED0\" },\n> + *\t\t\t\tPackage () { \"led1\", \"LED1\" },\n> + *\t\t\t}\n> + *\t\t})\n> + *\t\tName (LED0, Package () {\n> + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> + *\t\t\tPackage () {\n> + *\t\t\t\tPackage () { \"led\", 0 },\n> + *\t\t\t}\n> + *\t\t})\n> + *\t\tName (LED1, Package () {\n> + *\t\t\t// THISONE\n> + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> + *\t\t\tPackage () {\n> + *\t\t\t\tPackage () { \"led\", 1 },\n> + *\t\t\t}\n> + *\t\t})\n> + *\t}\n> + *\n> + *\tDevice (SEN)\n> + *\t{\n> + *\t\tName (_DSD, Package () {\n> + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> + *\t\t\tPackage () {\n> + *\t\t\t\tPackage () {\n> + *\t\t\t\t\t\"flash-leds\",\n> + *\t\t\t\t\tPackage () { ^LED, 0, ^LED, 1 },\n> + *\t\t\t\t}\n> + *\t\t\t}\n> + *\t\t})\n> + *\t}\n> + *\n> + * where\n> + *\n> + *\tLED\tLED driver device\n> + *\tLED0\tFirst LED\n> + *\tLED1\tSecond LED\n> + *\tSEN\tCamera sensor device (or another device the LED is\n> + *\t\trelated to)\n> + *\n> + * Return: 0 on success\n> + *\t   -ENOENT if no entries (or the property itself) were found\n> + *\t   -EINVAL if property parsing otherwise failed\n> + *\t   -ENOMEM if memory allocation failed\n> + */\n> +static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(\n> +\tstruct fwnode_handle *fwnode, const char *prop, unsigned int index,\n> +\tconst char **props, unsigned int nprops)\n> +{\n> +\tstruct fwnode_reference_args fwnode_args;\n> +\tunsigned int *args = fwnode_args.args;\n> +\tstruct fwnode_handle *child;\n> +\tint ret;\n> +\n> +\t/*\n> +\t * Obtain remote fwnode as well as the integer arguments.\n> +\t *\n> +\t * Note that right now both -ENODATA and -ENOENT may signal\n> +\t * out-of-bounds access. Return -ENOENT in that case.\n> +\t */\n> +\tret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops,\n> +\t\t\t\t\t\t index, &fwnode_args);\n> +\tif (ret)\n> +\t\treturn ERR_PTR(ret == -ENODATA ? -ENOENT : ret);\n> +\n> +\t/*\n> +\t * Find a node in the tree under the referred fwnode corresponding the\n> +\t * integer arguments.\n> +\t */\n> +\tfwnode = fwnode_args.fwnode;\n\nSo given the example above, fwnode would point to the LED device?\n\nIf correct, then mention that in the comment.\n\n> +\twhile (nprops--) {\n> +\t\tu32 val;\n> +\n> +\t\t/* Loop over all child nodes under fwnode. */\n\nAnd here you check if the LED device has child nodes that have a *props\nproperty with a value matching the index.\n\nSo given the example above it is looking for a child with property \"led\"\nand value 1.\n\nIt's useful if that is mentioned in the comment as well.\n\n> +\t\tfwnode_for_each_child_node(fwnode, child) {\n> +\t\t\tif (fwnode_property_read_u32(child, *props, &val))\n> +\t\t\t\tcontinue;\n> +\n> +\t\t\t/* Found property, see if its value matches. */\n> +\t\t\tif (val == *args)\n> +\t\t\t\tbreak;\n> +\t\t}\n> +\n> +\t\tfwnode_handle_put(fwnode);\n> +\n> +\t\t/* No property found; return an error here. */\n> +\t\tif (!child) {\n> +\t\t\tfwnode = ERR_PTR(-ENOENT);\n> +\t\t\tbreak;\n> +\t\t}\n> +\n> +\t\tprops++;\n> +\t\targs++;\n> +\t\tfwnode = child;\n> +\t}\n> +\n> +\treturn fwnode;\n> +}\n> +\n> +/*\n> + * v4l2_fwnode_reference_parse_int_props - parse references for async sub-devices\n> + * @dev: struct device pointer\n> + * @notifier: notifier for @dev\n> + * @prop: the name of the property\n> + * @props: the array of integer property names\n> + * @nprops: the number of integer properties\n> + *\n> + * Use v4l2_fwnode_reference_get_int_prop to find fwnodes through reference in\n> + * property @prop with integer arguments with child nodes matching in properties\n> + * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier\n> + * accordingly.\n> + *\n> + * While it is technically possible to use this function on DT, it is only\n> + * meaningful on ACPI. On Device tree you can refer to any node in the tree but\n> + * on ACPI the references are limited to devices.\n> + *\n> + * Return: 0 on success\n> + *\t   -ENOENT if no entries (or the property itself) were found\n> + *\t   -EINVAL if property parsing otherwisefailed\n> + *\t   -ENOMEM if memory allocation failed\n> + */\n> +static int v4l2_fwnode_reference_parse_int_props(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tconst char *prop, const char **props, unsigned int nprops)\n> +{\n> +\tstruct fwnode_handle *fwnode;\n> +\tunsigned int index;\n> +\tint ret;\n> +\n> +\tfor (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(\n> +\t\t\t\t\t dev_fwnode(dev), prop, index, props,\n> +\t\t\t\t\t nprops))); index++)\n> +\t\tfwnode_handle_put(fwnode);\n> +\n> +\t/*\n> +\t * Note that right now both -ENODATA and -ENOENT may signal\n> +\t * out-of-bounds access. Return the error in cases other than that.\n> +\t */\n> +\tif (PTR_ERR(fwnode) != -ENOENT && PTR_ERR(fwnode) != -ENODATA)\n> +\t\treturn PTR_ERR(fwnode);\n> +\n> +\tret = v4l2_async_notifier_realloc(notifier,\n> +\t\t\t\t\t  notifier->num_subdevs + index);\n> +\tif (ret)\n> +\t\treturn -ENOMEM;\n> +\n> +\tfor (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(\n> +\t\t\t\t\t dev_fwnode(dev), prop, index, props,\n> +\t\t\t\t\t nprops))); index++) {\n> +\t\tstruct v4l2_async_subdev *asd;\n> +\n> +\t\tif (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {\n> +\t\t\tret = -EINVAL;\n> +\t\t\tgoto error;\n> +\t\t}\n> +\n> +\t\tasd = kzalloc(sizeof(struct v4l2_async_subdev), GFP_KERNEL);\n> +\t\tif (!asd) {\n> +\t\t\tret = -ENOMEM;\n> +\t\t\tgoto error;\n> +\t\t}\n> +\n> +\t\tnotifier->subdevs[notifier->num_subdevs] = asd;\n> +\t\tasd->match.fwnode.fwnode = fwnode;\n> +\t\tasd->match_type = V4L2_ASYNC_MATCH_FWNODE;\n> +\t\tnotifier->num_subdevs++;\n> +\t}\n> +\n> +\treturn PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode);\n> +\n> +error:\n> +\tfwnode_handle_put(fwnode);\n> +\treturn ret;\n> +}\n> +\n>  MODULE_LICENSE(\"GPL\");\n>  MODULE_AUTHOR(\"Sakari Ailus <sakari.ailus@linux.intel.com>\");\n>  MODULE_AUTHOR(\"Sylwester Nawrocki <s.nawrocki@samsung.com>\");\n> \n\nRegards,\n\n\tHans\n--\nTo unsubscribe from this list: send the line \"unsubscribe devicetree\" in\nthe body of a message to majordomo@vger.kernel.org\nMore majordomo info at  http://vger.kernel.org/majordomo-info.html","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxGLx06kYz9sBZ\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 18:31:53 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1750973AbdISIbs (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 04:31:48 -0400","from lb1-smtp-cloud8.xs4all.net ([194.109.24.21]:45875 \"EHLO\n\tlb1-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1751499AbdISIbr (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 04:31:47 -0400","from [192.168.2.10] ([212.251.195.8])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid uDwTdXguLb4gvuDwXdkPHt; Tue, 19 Sep 2017 10:31:45 +0200"],"Subject":"Re: [PATCH v13 18/25] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","Cc":"niklas.soderlund@ragnatech.se, maxime.ripard@free-electrons.com,\n\trobh@kernel.org, laurent.pinchart@ideasonboard.com,\n\tdevicetree@vger.kernel.org, pavel@ucw.cz, sre@kernel.org","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-19-sakari.ailus@linux.intel.com>","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<ee1252cf-3396-9bed-443f-56e3c2d621e5@xs4all.nl>","Date":"Tue, 19 Sep 2017 10:31:41 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tThunderbird/52.2.1","MIME-Version":"1.0","In-Reply-To":"<20170915141724.23124-19-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfDrLtJH9QlKkxiXXK/XMXL87RZi4HPMUG8IPZ6qMc61YLlZ3JtYxRsmzPY3Yjw3CBc5tTLb6mZ5FjGx1/l7y7c3aY9JwVSv5qRTzNeRopDx59/Qmn7h9\n\t+fOUgFgih/XJorB0DtYt0rLatxoNFRzbtqdnSQ6ovv0CmNCXUAaWhT3f+SM9vOskRwxGKYv14Bi6UaHm/cEpiNgzA0nWRpIa4+fTyal4ZgYINUEQQLqw4tJO\n\tKliZbK3ZYE2BR9iJ/ZyDvYC+dXR2fdL66qEldOqm7faKwtU7ZuNAeDUZfZVAiFhNSDM6oKrEzpF3RTCKn4rfhZnHQusbT5JrXX+3D2NSIXcGm7qnsyxAGJJS\n\twlzSJt7/wPiMvzqDabIM+f43nIDyAxU7kx5Hgq4fOvgLbQBbIlkRgTFLRDS+yC6Fz31ZXB6BLMvX1rJQP0SLUJET2MSZqOkhXBHbf+1J7pX+peNNV0BMVnrw\n\tQED9E48rI/zLkIT3IArc0ZwQYZm+2VRPJ4VbHIroz/5vwqiS0goxyjs2eQg=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770754,"web_url":"http://patchwork.ozlabs.org/comment/1770754/","msgid":"<af99e12c-6fb8-a633-eec2-c1eb9d82226a@xs4all.nl>","list_archive_url":null,"date":"2017-09-19T08:40:14","subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 09/19/2017 10:20 AM, Sakari Ailus wrote:\n> Hi Hans,\n> \n> Thank you for the review.\n> \n> On Tue, Sep 19, 2017 at 10:03:27AM +0200, Hans Verkuil wrote:\n>> On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n>>> Add two functions for parsing devices graph endpoints:\n>>> v4l2_async_notifier_parse_fwnode_endpoints and\n>>> v4l2_async_notifier_parse_fwnode_endpoints_by_port. The former iterates\n>>> over all endpoints whereas the latter only iterates over the endpoints in\n>>> a given port.\n>>>\n>>> The former is mostly useful for existing drivers that currently implement\n>>> the iteration over all the endpoints themselves whereas the latter is\n>>> especially intended for devices with both sinks and sources: async\n>>> sub-devices for external devices connected to the device's sources will\n>>> have already been set up, or they are part of the master device.\n>>>\n>>> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n>>> ---\n>>>  drivers/media/v4l2-core/v4l2-async.c  |  30 ++++++\n>>>  drivers/media/v4l2-core/v4l2-fwnode.c | 185 ++++++++++++++++++++++++++++++++++\n>>>  include/media/v4l2-async.h            |  24 ++++-\n>>>  include/media/v4l2-fwnode.h           | 117 +++++++++++++++++++++\n>>>  4 files changed, 354 insertions(+), 2 deletions(-)\n>>>\n>>> diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c\n>>> index 831f185ecd47..bf0215dde616 100644\n>>> --- a/drivers/media/v4l2-core/v4l2-async.c\n>>> +++ b/drivers/media/v4l2-core/v4l2-async.c\n>>> @@ -22,6 +22,7 @@\n>>>  \n>>>  #include <media/v4l2-async.h>\n>>>  #include <media/v4l2-device.h>\n>>> +#include <media/v4l2-fwnode.h>\n>>>  #include <media/v4l2-subdev.h>\n>>>  \n>>>  static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)\n>>> @@ -219,6 +220,35 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)\n>>>  }\n>>>  EXPORT_SYMBOL(v4l2_async_notifier_unregister);\n>>>  \n>>> +void v4l2_async_notifier_release(struct v4l2_async_notifier *notifier)\n>>> +{\n>>> +\tunsigned int i;\n>>> +\n>>> +\tif (!notifier->max_subdevs)\n>>> +\t\treturn;\n>>> +\n>>> +\tfor (i = 0; i < notifier->num_subdevs; i++) {\n>>> +\t\tstruct v4l2_async_subdev *asd = notifier->subdevs[i];\n>>> +\n>>> +\t\tswitch (asd->match_type) {\n>>> +\t\tcase V4L2_ASYNC_MATCH_FWNODE:\n>>> +\t\t\tfwnode_handle_put(asd->match.fwnode.fwnode);\n>>> +\t\t\tbreak;\n>>> +\t\tdefault:\n>>> +\t\t\tWARN_ON_ONCE(true);\n>>\n>> Please add a break here.\n> \n> Yes.\n> \n>>\n>>> +\t\t}\n>>> +\n>>> +\t\tkfree(asd);\n>>> +\t}\n>>> +\n>>> +\tnotifier->max_subdevs = 0;\n>>> +\tnotifier->num_subdevs = 0;\n>>> +\n>>> +\tkvfree(notifier->subdevs);\n>>> +\tnotifier->subdevs = NULL;\n>>> +}\n>>> +EXPORT_SYMBOL_GPL(v4l2_async_notifier_release);\n>>> +\n>>>  int v4l2_async_register_subdev(struct v4l2_subdev *sd)\n>>>  {\n>>>  \tstruct v4l2_async_notifier *notifier;\n>>> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c\n>>> index 706f9e7b90f1..44ee35f6aad5 100644\n>>> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n>>> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n>>> @@ -19,6 +19,7 @@\n>>>   */\n>>>  #include <linux/acpi.h>\n>>>  #include <linux/kernel.h>\n>>> +#include <linux/mm.h>\n>>>  #include <linux/module.h>\n>>>  #include <linux/of.h>\n>>>  #include <linux/property.h>\n>>> @@ -26,6 +27,7 @@\n>>>  #include <linux/string.h>\n>>>  #include <linux/types.h>\n>>>  \n>>> +#include <media/v4l2-async.h>\n>>>  #include <media/v4l2-fwnode.h>\n>>>  \n>>>  enum v4l2_fwnode_bus_type {\n>>> @@ -313,6 +315,189 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)\n>>>  }\n>>>  EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);\n>>>  \n>>> +static int v4l2_async_notifier_realloc(struct v4l2_async_notifier *notifier,\n>>> +\t\t\t\t       unsigned int max_subdevs)\n>>> +{\n>>> +\tstruct v4l2_async_subdev **subdevs;\n>>> +\n>>> +\tif (max_subdevs <= notifier->max_subdevs)\n>>> +\t\treturn 0;\n>>> +\n>>> +\tsubdevs = kvmalloc_array(\n>>> +\t\tmax_subdevs, sizeof(*notifier->subdevs),\n>>> +\t\tGFP_KERNEL | __GFP_ZERO);\n>>> +\tif (!subdevs)\n>>> +\t\treturn -ENOMEM;\n>>> +\n>>> +\tif (notifier->subdevs) {\n>>> +\t\tmemcpy(subdevs, notifier->subdevs,\n>>> +\t\t       sizeof(*subdevs) * notifier->num_subdevs);\n>>> +\n>>> +\t\tkvfree(notifier->subdevs);\n>>> +\t}\n>>> +\n>>> +\tnotifier->subdevs = subdevs;\n>>> +\tnotifier->max_subdevs = max_subdevs;\n>>> +\n>>> +\treturn 0;\n>>> +}\n>>> +\n>>> +static int v4l2_async_notifier_fwnode_parse_endpoint(\n>>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n>>> +\tstruct fwnode_handle *endpoint, unsigned int asd_struct_size,\n>>> +\tint (*parse_endpoint)(struct device *dev,\n>>> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n>>> +\t\t\t    struct v4l2_async_subdev *asd))\n>>> +{\n>>> +\tstruct v4l2_async_subdev *asd;\n>>> +\tstruct v4l2_fwnode_endpoint *vep;\n>>> +\tint ret = 0;\n>>> +\n>>> +\tasd = kzalloc(asd_struct_size, GFP_KERNEL);\n>>> +\tif (!asd)\n>>> +\t\treturn -ENOMEM;\n>>> +\n>>> +\tasd->match.fwnode.fwnode =\n>>> +\t\tfwnode_graph_get_remote_port_parent(endpoint);\n>>> +\tif (!asd->match.fwnode.fwnode) {\n>>> +\t\tdev_warn(dev, \"bad remote port parent\\n\");\n>>> +\t\tret = -EINVAL;\n>>> +\t\tgoto out_err;\n>>> +\t}\n>>> +\n>>> +\t/* Ignore endpoints the parsing of which failed. */\n>>> +\tvep = v4l2_fwnode_endpoint_alloc_parse(endpoint);\n>>> +\tif (IS_ERR(vep)) {\n>>> +\t\tret = PTR_ERR(vep);\n>>> +\t\tdev_warn(dev, \"unable to parse V4L2 fwnode endpoint (%d)\\n\",\n>>> +\t\t\t ret);\n>>> +\t\tgoto out_err;\n>>> +\t}\n>>> +\n>>> +\tret = parse_endpoint ? parse_endpoint(dev, vep, asd) : 0;\n>>> +\tif (ret == -ENOTCONN)\n>>> +\t\tdev_dbg(dev, \"ignoring endpoint %u,%u\\n\", vep->base.port,\n>>> +\t\t\tvep->base.id);\n>>> +\telse if (ret < 0)\n>>> +\t\tdev_warn(dev, \"driver could not parse endpoint %u,%u (%d)\\n\",\n>>> +\t\t\t vep->base.port, vep->base.id, ret);\n>>> +\tv4l2_fwnode_endpoint_free(vep);\n>>> +\tif (ret < 0)\n>>> +\t\tgoto out_err;\n>>> +\n>>> +\tasd->match_type = V4L2_ASYNC_MATCH_FWNODE;\n>>> +\tnotifier->subdevs[notifier->num_subdevs] = asd;\n>>> +\tnotifier->num_subdevs++;\n>>> +\n>>> +\treturn 0;\n>>> +\n>>> +out_err:\n>>> +\tfwnode_handle_put(asd->match.fwnode.fwnode);\n>>> +\tkfree(asd);\n>>> +\n>>> +\treturn ret == -ENOTCONN ? 0 : ret;\n>>> +}\n>>> +\n>>> +static int __v4l2_async_notifier_parse_fwnode_endpoints(\n>>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n>>> +\tsize_t asd_struct_size, unsigned int port, bool has_port,\n>>> +\tint (*parse_endpoint)(struct device *dev,\n>>> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n>>> +\t\t\t    struct v4l2_async_subdev *asd))\n>>> +{\n>>> +\tstruct fwnode_handle *fwnode = NULL;\n>>> +\tunsigned int max_subdevs = notifier->max_subdevs;\n>>> +\tint ret;\n>>> +\n>>> +\tif (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev)))\n>>> +\t\treturn -EINVAL;\n>>> +\n>>> +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n>>> +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n>>\n>> You can replace this by:\n>>\n>> \twhile ((fwnode = fwnode_graph_get_next_endpoint(dev_fwnode(dev), fwnode))) {\n>>\n>>> +\t\tif (!fwnode_device_is_available(\n>>> +\t\t\t    fwnode_graph_get_port_parent(fwnode)))\n>>> +\t\t\tcontinue;\n>>> +\n>>> +\t\tif (has_port) {\n>>> +\t\t\tstruct fwnode_endpoint ep;\n>>> +\n>>> +\t\t\tret = fwnode_graph_parse_endpoint(fwnode, &ep);\n>>> +\t\t\tif (ret) {\n>>> +\t\t\t\tfwnode_handle_put(fwnode);\n>>> +\t\t\t\treturn ret;\n>>> +\t\t\t}\n>>> +\n>>> +\t\t\tif (ep.port != port)\n>>> +\t\t\t\tcontinue;\n>>> +\t\t}\n>>> +\t\tmax_subdevs++;\n>>> +\t}\n>>> +\n>>> +\t/* No subdevs to add? Return here. */\n>>> +\tif (max_subdevs == notifier->max_subdevs)\n>>> +\t\treturn 0;\n>>> +\n>>> +\tret = v4l2_async_notifier_realloc(notifier, max_subdevs);\n>>> +\tif (ret)\n>>> +\t\treturn ret;\n>>> +\n>>> +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n>>> +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n>>\n>> Same here: this can be a 'while'.\n> \n> The fwnode = NULL assignment still needs to be done. A for loop has a\n> natural initialiser for the loop, I think it's cleaner than using while\n> here.\n\nAfter the previous while fwnode is NULL again (since that's when the while\nstops).\n\n> \n> The macro would be implemented this way as well.\n> \n> For the loop above this one, I'd use for for consistency: it's the same\n> loop after all.\n> \n> This reminds me --- I'll send the patch for the macro.\n\nIf this is going to be replaced by a macro, then disregard my comment.\n\n> \n>>\n>>> +\t\tif (!fwnode_device_is_available(\n>>> +\t\t\t    fwnode_graph_get_port_parent(fwnode)))\n>>> +\t\t\tcontinue;\n>>> +\n>>> +\t\tif (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {\n>>> +\t\t\tret = -EINVAL;\n>>> +\t\t\tbreak;\n>>> +\t\t}\n>>> +\n>>> +\t\tif (has_port) {\n>>> +\t\t\tstruct fwnode_endpoint ep;\n>>> +\n>>> +\t\t\tret = fwnode_graph_parse_endpoint(fwnode, &ep);\n>>> +\t\t\tif (ret)\n>>> +\t\t\t\tbreak;\n>>> +\n>>> +\t\t\tif (ep.port != port)\n>>> +\t\t\t\tcontinue;\n>>> +\t\t}\n>>> +\n>>> +\t\tret = v4l2_async_notifier_fwnode_parse_endpoint(\n>>> +\t\t\tdev, notifier, fwnode, asd_struct_size, parse_endpoint);\n>>> +\t\tif (ret < 0)\n>>> +\t\t\tbreak;\n>>> +\t}\n>>> +\n>>> +\tfwnode_handle_put(fwnode);\n>>> +\n>>> +\treturn ret;\n>>> +}\n>>> +\n>>> +int v4l2_async_notifier_parse_fwnode_endpoints(\n>>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n>>> +\tsize_t asd_struct_size,\n>>> +\tint (*parse_endpoint)(struct device *dev,\n>>> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n>>> +\t\t\t    struct v4l2_async_subdev *asd))\n>>> +{\n>>> +\treturn __v4l2_async_notifier_parse_fwnode_endpoints(\n>>> +\t\tdev, notifier, asd_struct_size, 0, false, parse_endpoint);\n>>> +}\n>>> +EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints);\n>>> +\n>>> +int v4l2_async_notifier_parse_fwnode_endpoints_by_port(\n>>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n>>> +\tsize_t asd_struct_size, unsigned int port,\n>>> +\tint (*parse_endpoint)(struct device *dev,\n>>> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n>>> +\t\t\t    struct v4l2_async_subdev *asd))\n>>> +{\n>>> +\treturn __v4l2_async_notifier_parse_fwnode_endpoints(\n>>> +\t\tdev, notifier, asd_struct_size, port, true, parse_endpoint);\n>>> +}\n>>> +EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port);\n>>> +\n>>>  MODULE_LICENSE(\"GPL\");\n>>>  MODULE_AUTHOR(\"Sakari Ailus <sakari.ailus@linux.intel.com>\");\n>>>  MODULE_AUTHOR(\"Sylwester Nawrocki <s.nawrocki@samsung.com>\");\n>>> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h\n>>> index c69d8c8a66d0..96fa1afc00dd 100644\n>>> --- a/include/media/v4l2-async.h\n>>> +++ b/include/media/v4l2-async.h\n>>> @@ -18,7 +18,6 @@ struct device;\n>>>  struct device_node;\n>>>  struct v4l2_device;\n>>>  struct v4l2_subdev;\n>>> -struct v4l2_async_notifier;\n>>>  \n>>>  /* A random max subdevice number, used to allocate an array on stack */\n>>>  #define V4L2_MAX_SUBDEVS 128U\n>>> @@ -50,6 +49,10 @@ enum v4l2_async_match_type {\n>>>   * @match:\tunion of per-bus type matching data sets\n>>>   * @list:\tused to link struct v4l2_async_subdev objects, waiting to be\n>>>   *\t\tprobed, to a notifier->waiting list\n>>> + *\n>>> + * When this struct is used as a member in a driver specific struct,\n>>> + * the driver specific struct shall contain the @struct\n>>> + * v4l2_async_subdev as its first member.\n>>>   */\n>>>  struct v4l2_async_subdev {\n>>>  \tenum v4l2_async_match_type match_type;\n>>> @@ -78,7 +81,8 @@ struct v4l2_async_subdev {\n>>>  /**\n>>>   * struct v4l2_async_notifier - v4l2_device notifier data\n>>>   *\n>>> - * @num_subdevs: number of subdevices\n>>> + * @num_subdevs: number of subdevices used in the subdevs array\n>>> + * @max_subdevs: number of subdevices allocated in the subdevs array\n>>>   * @subdevs:\tarray of pointers to subdevice descriptors\n>>>   * @v4l2_dev:\tpointer to struct v4l2_device\n>>>   * @waiting:\tlist of struct v4l2_async_subdev, waiting for their drivers\n>>> @@ -90,6 +94,7 @@ struct v4l2_async_subdev {\n>>>   */\n>>>  struct v4l2_async_notifier {\n>>>  \tunsigned int num_subdevs;\n>>> +\tunsigned int max_subdevs;\n>>>  \tstruct v4l2_async_subdev **subdevs;\n>>>  \tstruct v4l2_device *v4l2_dev;\n>>>  \tstruct list_head waiting;\n>>> @@ -121,6 +126,21 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,\n>>>  void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);\n>>>  \n>>>  /**\n>>> + * v4l2_async_notifier_release - release notifier resources\n>>> + * @notifier: the notifier the resources of which are to be released\n>>> + *\n>>> + * Release memory resources related to a notifier, including the async\n>>> + * sub-devices allocated for the purposes of the notifier. The user is\n>>> + * responsible for releasing the notifier's resources after calling\n>>> + * @v4l2_async_notifier_parse_fwnode_endpoints.\n>>> + *\n>>> + * There is no harm from calling v4l2_async_notifier_release in other\n>>> + * cases as long as its memory has been zeroed after it has been\n>>> + * allocated.\n>>> + */\n>>> +void v4l2_async_notifier_release(struct v4l2_async_notifier *notifier);\n>>> +\n>>> +/**\n>>>   * v4l2_async_register_subdev - registers a sub-device to the asynchronous\n>>>   * \tsubdevice framework\n>>>   *\n>>> diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h\n>>> index 68eb22ba571b..83afac48ea6b 100644\n>>> --- a/include/media/v4l2-fwnode.h\n>>> +++ b/include/media/v4l2-fwnode.h\n>>> @@ -25,6 +25,8 @@\n>>>  #include <media/v4l2-mediabus.h>\n>>>  \n>>>  struct fwnode_handle;\n>>> +struct v4l2_async_notifier;\n>>> +struct v4l2_async_subdev;\n>>>  \n>>>  #define V4L2_FWNODE_CSI2_MAX_DATA_LANES\t4\n>>>  \n>>> @@ -201,4 +203,119 @@ int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode,\n>>>   */\n>>>  void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);\n>>>  \n>>> +/**\n>>> + * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a\n>>> + *\t\t\t\t\t\tdevice node\n>>> + * @dev: the device the endpoints of which are to be parsed\n>>> + * @notifier: notifier for @dev\n>>> + * @asd_struct_size: size of the driver's async sub-device struct, including\n>>> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n>>> + *\t\t     v4l2_async_subdev shall be the first member of\n>>> + *\t\t     the driver's async sub-device struct, i.e. both\n>>> + *\t\t     begin at the same memory address.\n>>> + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n>>> + *\t\t    endpoint. Optional.\n>>> + *\t\t    Return: %0 on success\n>>> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n>>> + *\t\t\t\t       should not be considered as an error\n>>> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n>>> + *\n>>> + * Parse the fwnode endpoints of the @dev device and populate the async sub-\n>>> + * devices array of the notifier. The @parse_endpoint callback function is\n>>> + * called for each endpoint with the corresponding async sub-device pointer to\n>>> + * let the caller initialize the driver-specific part of the async sub-device\n>>> + * structure.\n>>> + *\n>>> + * The notifier memory shall be zeroed before this function is called on the\n>>> + * notifier.\n>>> + *\n>>> + * This function may not be called on a registered notifier and may be called on\n>>> + * a notifier only once.\n>>> + *\n>>> + * Do not change the notifier's subdevs array, take references to the subdevs\n>>> + * array itself or change the notifier's num_subdevs field. This is because this\n>>> + * function allocates and reallocates the subdevs array based on parsing\n>>> + * endpoints.\n>>> + *\n>>> + * The @struct v4l2_fwnode_endpoint passed to the callback function\n>>> + * @parse_endpoint is released once the function is finished. If there is a need\n>>> + * to retain that configuration, the user needs to allocate memory for it.\n>>> + *\n>>> + * Any notifier populated using this function must be released with a call to\n>>> + * v4l2_async_notifier_release() after it has been unregistered and the async\n>>> + * sub-devices are no longer in use, even if the function returned an error.\n>>> + *\n>>> + * Return: %0 on success, including when no async sub-devices are found\n>>> + *\t   %-ENOMEM if memory allocation failed\n>>> + *\t   %-EINVAL if graph or endpoint parsing failed\n>>> + *\t   Other error codes as returned by @parse_endpoint\n>>> + */\n>>> +int v4l2_async_notifier_parse_fwnode_endpoints(\n>>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n>>> +\tsize_t asd_struct_size,\n>>> +\tint (*parse_endpoint)(struct device *dev,\n>>> +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n>>> +\t\t\t      struct v4l2_async_subdev *asd));\n>>> +\n>>> +/**\n>>> + * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode\n>>> + *\t\t\t\t\t\t\tendpoints of a port in a\n>>> + *\t\t\t\t\t\t\tdevice node\n>>> + * @dev: the device the endpoints of which are to be parsed\n>>> + * @notifier: notifier for @dev\n>>> + * @asd_struct_size: size of the driver's async sub-device struct, including\n>>> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n>>> + *\t\t     v4l2_async_subdev shall be the first member of\n>>> + *\t\t     the driver's async sub-device struct, i.e. both\n>>> + *\t\t     begin at the same memory address.\n>>> + * @port: port number where endpoints are to be parsed\n>>> + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n>>> + *\t\t    endpoint. Optional.\n>>> + *\t\t    Return: %0 on success\n>>> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n>>> + *\t\t\t\t       should not be considered as an error\n>>> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n>>> + *\n>>> + * This function is just like @v4l2_async_notifier_parse_fwnode_endpoints with\n>>> + * the exception that it only parses endpoints in a given port. This is useful\n>>> + * on devices that have both sinks and sources: the async sub-devices connected\n>>\n>> on -> for\n>>\n>>> + * to sources have already been set up by another driver (on capture devices).\n>>\n>> on -> for\n> \n> Agreed on both.\n> \n>>\n>> So if I understand this correctly for devices with both sinks and sources you use\n>> this function to just parse the sink ports. And you have to give explicit port\n>> numbers since you can't tell from parsing the device tree if a port is a sink or\n>> source port, right? Only the driver knows this.\n> \n> Correct. The graph data structure in DT isn't directed, so this is only\n> known by the driver.\n\nI think this should be clarified.\n\nI wonder if there is any way around it. I don't have time to dig into this, but\nisn't it possible to tell that the source ports are already configured?\n\nAnyway, that can be looked at later.\n\nRegards,\n\n\tHans\n\n> \n>>\n>>> + *\n>>> + * Parse the fwnode endpoints of the @dev device on a given @port and populate\n>>> + * the async sub-devices array of the notifier. The @parse_endpoint callback\n>>> + * function is called for each endpoint with the corresponding async sub-device\n>>> + * pointer to let the caller initialize the driver-specific part of the async\n>>> + * sub-device structure.\n>>> + *\n>>> + * The notifier memory shall be zeroed before this function is called on the\n>>> + * notifier the first time.\n>>> + *\n>>> + * This function may not be called on a registered notifier and may be called on\n>>> + * a notifier only once per port.\n>>> + *\n>>> + * Do not change the notifier's subdevs array, take references to the subdevs\n>>> + * array itself or change the notifier's num_subdevs field. This is because this\n>>> + * function allocates and reallocates the subdevs array based on parsing\n>>> + * endpoints.\n>>> + *\n>>> + * The @struct v4l2_fwnode_endpoint passed to the callback function\n>>> + * @parse_endpoint is released once the function is finished. If there is a need\n>>> + * to retain that configuration, the user needs to allocate memory for it.\n>>> + *\n>>> + * Any notifier populated using this function must be released with a call to\n>>> + * v4l2_async_notifier_release() after it has been unregistered and the async\n>>> + * sub-devices are no longer in use, even if the function returned an error.\n>>> + *\n>>> + * Return: %0 on success, including when no async sub-devices are found\n>>> + *\t   %-ENOMEM if memory allocation failed\n>>> + *\t   %-EINVAL if graph or endpoint parsing failed\n>>> + *\t   Other error codes as returned by @parse_endpoint\n>>> + */\n>>> +int v4l2_async_notifier_parse_fwnode_endpoints_by_port(\n>>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n>>> +\tsize_t asd_struct_size, unsigned int port,\n>>> +\tint (*parse_endpoint)(struct device *dev,\n>>> +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n>>> +\t\t\t      struct v4l2_async_subdev *asd));\n>>> +\n>>>  #endif /* _V4L2_FWNODE_H */\n>>>\n>>\n> \n\n--\nTo unsubscribe from this list: send the line \"unsubscribe devicetree\" in\nthe body of a message to majordomo@vger.kernel.org\nMore majordomo info at  http://vger.kernel.org/majordomo-info.html","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxGXj1bKmz9s7M\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 18:40:21 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751391AbdISIkU (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 04:40:20 -0400","from lb1-smtp-cloud8.xs4all.net ([194.109.24.21]:33803 \"EHLO\n\tlb1-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1751394AbdISIkT (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 04:40:19 -0400","from [192.168.2.10] ([212.251.195.8])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid uE4kdXmwXb4gvuE4ndkRzB; Tue, 19 Sep 2017 10:40:17 +0200"],"Subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-6-sakari.ailus@linux.intel.com>\n\t<a17ab793-b859-f04a-2dff-d8f6a314e9bf@xs4all.nl>\n\t<20170919082015.vt6olgirnvmpcrpa@paasikivi.fi.intel.com>","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<af99e12c-6fb8-a633-eec2-c1eb9d82226a@xs4all.nl>","Date":"Tue, 19 Sep 2017 10:40:14 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tThunderbird/52.2.1","MIME-Version":"1.0","In-Reply-To":"<20170919082015.vt6olgirnvmpcrpa@paasikivi.fi.intel.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfIS1CYQxKEZebbLwzf+kURi/mefaD7JlPGmyfa+JI2m9ZtFmexHy7dxSQTQj47WURGP+fa1Tp0LxrySj1bFt8x90BJzVp1sCydYw/GbeExm9mvw5acRB\n\tfLkqBlTa45q52B4BnrjBy/V/vQGqegVULPEw9JQQqZmHU5DpRWNXgZrbHaLSxQSzlqlrDlgPffKOn6gZ0MMW8pLktw77omCF6Y2l+QDig6WuNLFAzDMIHnnK\n\tQLWc+3wQntzKmVMUsQeVK0uVbEYMypjWmw4adIv45zzqWev/tqOpdTJANxkUXGkZVCqRw974tGKzrdfq5rOu1/n0F9njI1E/UB3MaszZFWncZqrLu+KnNH0x\n\trUS+E4/G9ag+n6FUSrn0+3UcbcofPXXyKvahakuwZ8qIx9UnJSaKiervzJETSDuedMZD08/+KyI/NP9oqwvllYhM2CcS0VVRGmBiUQCuWJM2rbWsqPY3I2ND\n\tQajh4Y0rVChpZ8XKJ6OQbKkwVXmzzRrLkeZKL6WMqTEFErJ7uOf440ANMpU=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770757,"web_url":"http://patchwork.ozlabs.org/comment/1770757/","msgid":"<20170919084534.ivgmrlmgywdwuhoa@paasikivi.fi.intel.com>","list_archive_url":null,"date":"2017-09-19T08:45:34","subject":"Re: [PATCH v13 18/25] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","submitter":{"id":65485,"url":"http://patchwork.ozlabs.org/api/people/65485/","name":"Sakari Ailus","email":"sakari.ailus@linux.intel.com"},"content":"Hi Hans,\n\nThank you for the review.\n\nOn Tue, Sep 19, 2017 at 10:31:41AM +0200, Hans Verkuil wrote:\n> Hi Sakari,\n> \n> I'm slowly starting to understand this. The example helped a lot. But I still have\n> some questions, see below.\n> \n> On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n> > v4l2_fwnode_reference_parse_int_prop() will find an fwnode such that under\n> > the device's own fwnode, it will follow child fwnodes with the given\n> > property-value pair and return the resulting fwnode.\n> \n> I think both the subject, commit log, function comment and function name should\n> reflect the fact that this function is for an ACPI reference.\n> \n> It's only called for ACPI (from patch 19):\n> \n> +\t\tif (props[i].props && is_acpi_node(dev_fwnode(dev)))\n> +\t\t\tret = v4l2_fwnode_reference_parse_int_props(\n> \n> So renaming it to v4l2_fwnode_acpi_reference_parse_int_props or something similar\n> would clarify this fact.\n\nI don't think we'll see many like this one. I presume we won't use it on DT\nalbeit there are no direct references to ACPI in the code itself.\n\nHow about v4l2_fwnode_parse_acpi_reference (+ \"s\" for the one below)?\n\n> \n> > \n> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> > ---\n> >  drivers/media/v4l2-core/v4l2-fwnode.c | 201 ++++++++++++++++++++++++++++++++++\n> >  1 file changed, 201 insertions(+)\n> > \n> > diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c\n> > index 65e84ea1cc35..968a345a288f 100644\n> > --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> > +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> > @@ -567,6 +567,207 @@ static int v4l2_fwnode_reference_parse(\n> >  \treturn ret;\n> >  }\n> >  \n> > +/*\n> > + * v4l2_fwnode_reference_get_int_prop - parse a reference with integer\n> > + *\t\t\t\t\targuments\n> > + * @dev: struct device pointer\n> > + * @notifier: notifier for @dev\n> > + * @prop: the name of the property\n> > + * @index: the index of the reference to get\n> > + * @props: the array of integer property names\n> > + * @nprops: the number of integer property names in @nprops\n> \n> You mean 'in @props'?\n\nYes, I'll fix that.\n\n> \n> One thing that is not clear to me is when you would use an nprops value > 1.\n> What's the use-case for that? It only makes sense (I think) if you would have\n> property names that are all aliases of one another.\n\nThere may be several flash LEDs related to a sensor. That's the use case,\nfor instance.\n\n> \n> > + *\n> > + * Find fwnodes referred to by a property @prop, then under that\n> > + * iteratively, @nprops times, follow each child node which has a\n> > + * property in @props array at a given child index the value of which\n> > + * matches the integer argument at an index.\n> > + *\n> > + * For example, if this function was called with arguments and values\n> > + * @dev corresponding to device \"SEN\", @prop == \"flash-leds\", @index\n> > + * == 1, @props == { \"led\" }, @nprops == 1, with the ASL snippet below\n> > + * it would return the node marked with THISONE. The @dev argument in\n> > + * the ASL below.\n> \n> That last sentence about the @dev seems incomplete. I'm not sure what is\n> meant by it.\n\nI think it was meant to convey some information but it got added to the\nprevious sentence. I'll remove it.\n\n> \n> > + *\n> > + *\tDevice (LED)\n> > + *\t{\n> > + *\t\tName (_DSD, Package () {\n> > + *\t\t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n> > + *\t\t\tPackage () {\n> > + *\t\t\t\tPackage () { \"led0\", \"LED0\" },\n> > + *\t\t\t\tPackage () { \"led1\", \"LED1\" },\n> > + *\t\t\t}\n> > + *\t\t})\n> > + *\t\tName (LED0, Package () {\n> > + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> > + *\t\t\tPackage () {\n> > + *\t\t\t\tPackage () { \"led\", 0 },\n> > + *\t\t\t}\n> > + *\t\t})\n> > + *\t\tName (LED1, Package () {\n> > + *\t\t\t// THISONE\n> > + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> > + *\t\t\tPackage () {\n> > + *\t\t\t\tPackage () { \"led\", 1 },\n> > + *\t\t\t}\n> > + *\t\t})\n> > + *\t}\n> > + *\n> > + *\tDevice (SEN)\n> > + *\t{\n> > + *\t\tName (_DSD, Package () {\n> > + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> > + *\t\t\tPackage () {\n> > + *\t\t\t\tPackage () {\n> > + *\t\t\t\t\t\"flash-leds\",\n> > + *\t\t\t\t\tPackage () { ^LED, 0, ^LED, 1 },\n> > + *\t\t\t\t}\n> > + *\t\t\t}\n> > + *\t\t})\n> > + *\t}\n> > + *\n> > + * where\n> > + *\n> > + *\tLED\tLED driver device\n> > + *\tLED0\tFirst LED\n> > + *\tLED1\tSecond LED\n> > + *\tSEN\tCamera sensor device (or another device the LED is\n> > + *\t\trelated to)\n> > + *\n> > + * Return: 0 on success\n> > + *\t   -ENOENT if no entries (or the property itself) were found\n> > + *\t   -EINVAL if property parsing otherwise failed\n> > + *\t   -ENOMEM if memory allocation failed\n> > + */\n> > +static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(\n> > +\tstruct fwnode_handle *fwnode, const char *prop, unsigned int index,\n> > +\tconst char **props, unsigned int nprops)\n> > +{\n> > +\tstruct fwnode_reference_args fwnode_args;\n> > +\tunsigned int *args = fwnode_args.args;\n> > +\tstruct fwnode_handle *child;\n> > +\tint ret;\n> > +\n> > +\t/*\n> > +\t * Obtain remote fwnode as well as the integer arguments.\n> > +\t *\n> > +\t * Note that right now both -ENODATA and -ENOENT may signal\n> > +\t * out-of-bounds access. Return -ENOENT in that case.\n> > +\t */\n> > +\tret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops,\n> > +\t\t\t\t\t\t index, &fwnode_args);\n> > +\tif (ret)\n> > +\t\treturn ERR_PTR(ret == -ENODATA ? -ENOENT : ret);\n> > +\n> > +\t/*\n> > +\t * Find a node in the tree under the referred fwnode corresponding the\n> > +\t * integer arguments.\n> > +\t */\n> > +\tfwnode = fwnode_args.fwnode;\n> \n> So given the example above, fwnode would point to the LED device?\n> \n> If correct, then mention that in the comment.\n\nIt could be a LED driver device, but it could be something else as well.\nLike a lens VCM, depending on the property being parsed. That's why I\ndidn't put it in the comments. But this is a device node, not a\nhierarchical data extension node, for instance. That's what I think I\nshould add.\n\n> \n> > +\twhile (nprops--) {\n> > +\t\tu32 val;\n> > +\n> > +\t\t/* Loop over all child nodes under fwnode. */\n> \n> And here you check if the LED device has child nodes that have a *props\n> property with a value matching the index.\n> \n> So given the example above it is looking for a child with property \"led\"\n> and value 1.\n> \n> It's useful if that is mentioned in the comment as well.\n\nBut should I? This isn't specific to LEDs.\n\n> \n> > +\t\tfwnode_for_each_child_node(fwnode, child) {\n> > +\t\t\tif (fwnode_property_read_u32(child, *props, &val))\n> > +\t\t\t\tcontinue;\n> > +\n> > +\t\t\t/* Found property, see if its value matches. */\n> > +\t\t\tif (val == *args)\n> > +\t\t\t\tbreak;\n> > +\t\t}\n> > +\n> > +\t\tfwnode_handle_put(fwnode);\n> > +\n> > +\t\t/* No property found; return an error here. */\n> > +\t\tif (!child) {\n> > +\t\t\tfwnode = ERR_PTR(-ENOENT);\n> > +\t\t\tbreak;\n> > +\t\t}\n> > +\n> > +\t\tprops++;\n> > +\t\targs++;\n> > +\t\tfwnode = child;\n> > +\t}\n> > +\n> > +\treturn fwnode;\n> > +}\n> > +\n> > +/*\n> > + * v4l2_fwnode_reference_parse_int_props - parse references for async sub-devices\n> > + * @dev: struct device pointer\n> > + * @notifier: notifier for @dev\n> > + * @prop: the name of the property\n> > + * @props: the array of integer property names\n> > + * @nprops: the number of integer properties\n> > + *\n> > + * Use v4l2_fwnode_reference_get_int_prop to find fwnodes through reference in\n> > + * property @prop with integer arguments with child nodes matching in properties\n> > + * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier\n> > + * accordingly.\n> > + *\n> > + * While it is technically possible to use this function on DT, it is only\n> > + * meaningful on ACPI. On Device tree you can refer to any node in the tree but\n> > + * on ACPI the references are limited to devices.\n> > + *\n> > + * Return: 0 on success\n> > + *\t   -ENOENT if no entries (or the property itself) were found\n> > + *\t   -EINVAL if property parsing otherwisefailed\n> > + *\t   -ENOMEM if memory allocation failed\n> > + */\n> > +static int v4l2_fwnode_reference_parse_int_props(\n> > +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> > +\tconst char *prop, const char **props, unsigned int nprops)\n> > +{\n> > +\tstruct fwnode_handle *fwnode;\n> > +\tunsigned int index;\n> > +\tint ret;\n> > +\n> > +\tfor (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(\n> > +\t\t\t\t\t dev_fwnode(dev), prop, index, props,\n> > +\t\t\t\t\t nprops))); index++)\n> > +\t\tfwnode_handle_put(fwnode);\n> > +\n> > +\t/*\n> > +\t * Note that right now both -ENODATA and -ENOENT may signal\n> > +\t * out-of-bounds access. Return the error in cases other than that.\n> > +\t */\n> > +\tif (PTR_ERR(fwnode) != -ENOENT && PTR_ERR(fwnode) != -ENODATA)\n> > +\t\treturn PTR_ERR(fwnode);\n> > +\n> > +\tret = v4l2_async_notifier_realloc(notifier,\n> > +\t\t\t\t\t  notifier->num_subdevs + index);\n> > +\tif (ret)\n> > +\t\treturn -ENOMEM;\n> > +\n> > +\tfor (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(\n> > +\t\t\t\t\t dev_fwnode(dev), prop, index, props,\n> > +\t\t\t\t\t nprops))); index++) {\n> > +\t\tstruct v4l2_async_subdev *asd;\n> > +\n> > +\t\tif (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {\n> > +\t\t\tret = -EINVAL;\n> > +\t\t\tgoto error;\n> > +\t\t}\n> > +\n> > +\t\tasd = kzalloc(sizeof(struct v4l2_async_subdev), GFP_KERNEL);\n> > +\t\tif (!asd) {\n> > +\t\t\tret = -ENOMEM;\n> > +\t\t\tgoto error;\n> > +\t\t}\n> > +\n> > +\t\tnotifier->subdevs[notifier->num_subdevs] = asd;\n> > +\t\tasd->match.fwnode.fwnode = fwnode;\n> > +\t\tasd->match_type = V4L2_ASYNC_MATCH_FWNODE;\n> > +\t\tnotifier->num_subdevs++;\n> > +\t}\n> > +\n> > +\treturn PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode);\n> > +\n> > +error:\n> > +\tfwnode_handle_put(fwnode);\n> > +\treturn ret;\n> > +}\n> > +\n> >  MODULE_LICENSE(\"GPL\");\n> >  MODULE_AUTHOR(\"Sakari Ailus <sakari.ailus@linux.intel.com>\");\n> >  MODULE_AUTHOR(\"Sylwester Nawrocki <s.nawrocki@samsung.com>\");","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxGg02zQQz9s7g\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 18:45:48 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751416AbdISIpl (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 04:45:41 -0400","from mga01.intel.com ([192.55.52.88]:8898 \"EHLO mga01.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1750747AbdISIpj (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tTue, 19 Sep 2017 04:45:39 -0400","from orsmga002.jf.intel.com ([10.7.209.21])\n\tby fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t19 Sep 2017 01:45:39 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby orsmga002.jf.intel.com with ESMTP; 19 Sep 2017 01:45:35 -0700","by paasikivi.fi.intel.com (Postfix, from userid 1000)\n\tid 05F5D20642; Tue, 19 Sep 2017 11:45:34 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos;i=\"5.42,417,1500966000\"; d=\"scan'208\";a=\"136945382\"","Date":"Tue, 19 Sep 2017 11:45:34 +0300","From":"Sakari Ailus <sakari.ailus@linux.intel.com>","To":"Hans Verkuil <hverkuil@xs4all.nl>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v13 18/25] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","Message-ID":"<20170919084534.ivgmrlmgywdwuhoa@paasikivi.fi.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-19-sakari.ailus@linux.intel.com>\n\t<ee1252cf-3396-9bed-443f-56e3c2d621e5@xs4all.nl>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<ee1252cf-3396-9bed-443f-56e3c2d621e5@xs4all.nl>","User-Agent":"NeoMutt/20170113 (1.7.2)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770783,"web_url":"http://patchwork.ozlabs.org/comment/1770783/","msgid":"<1891349.nWXO9QHRQ8@avalon>","list_archive_url":null,"date":"2017-09-19T09:21:58","subject":"Re: [PATCH v13 02/25] v4l: async: Remove re-probing support","submitter":{"id":11034,"url":"http://patchwork.ozlabs.org/api/people/11034/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Sakari,\n\n(CC'ing Mike Turquette)\n\nThank you for the patch.\n\nOn Friday, 15 September 2017 17:17:01 EEST Sakari Ailus wrote:\n> Remove V4L2 async re-probing support. The re-probing support has been\n> there to support cases where the sub-devices require resources provided by\n> the main driver's hardware to function, such as clocks.\n> \n> Reprobing has allowed unbinding and again binding the main driver without\n> explicilty unbinding the sub-device drivers. This is certainly not a\n> common need, and the responsibility will be the user's going forward.\n> \n> An alternative could have been to introduce notifier specific locks.\n> Considering the complexity of the re-probing and that it isn't really a\n> solution to a problem but a workaround, remove re-probing instead.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\nAs stated before we need a plan to fix the issue that reprobind was supposed \nto address.\n\nTo my knowledge the only intended user of the reprobind code was the OMAP3 ISP \nwhen it provides a clock to the sensor. I've briefly discussed this with Mike \nlast week, and he believed we could handle the issue by \"un-orphaning\" the \norphaned clock when the OMAP3 ISP is reprobed. Mike, have you had time to \ncheck whether that would be feasible without too much effort and/or pain ?\n\nIn the meantime, for this patch,\n\nAcked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> ---\n>  drivers/media/v4l2-core/v4l2-async.c | 54 --------------------------------\n>  1 file changed, 54 deletions(-)\n> \n> diff --git a/drivers/media/v4l2-core/v4l2-async.c\n> b/drivers/media/v4l2-core/v4l2-async.c index d741a8e0fdac..e109d9da4653\n> 100644\n> --- a/drivers/media/v4l2-core/v4l2-async.c\n> +++ b/drivers/media/v4l2-core/v4l2-async.c\n> @@ -198,78 +198,24 @@ EXPORT_SYMBOL(v4l2_async_notifier_register);\n>  void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)\n>  {\n>  \tstruct v4l2_subdev *sd, *tmp;\n> -\tunsigned int notif_n_subdev = notifier->num_subdevs;\n> -\tunsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);\n> -\tstruct device **dev;\n> -\tint i = 0;\n> \n>  \tif (!notifier->v4l2_dev)\n>  \t\treturn;\n> \n> -\tdev = kvmalloc_array(n_subdev, sizeof(*dev), GFP_KERNEL);\n> -\tif (!dev) {\n> -\t\tdev_err(notifier->v4l2_dev->dev,\n> -\t\t\t\"Failed to allocate device cache!\\n\");\n> -\t}\n> -\n>  \tmutex_lock(&list_lock);\n> \n>  \tlist_del(&notifier->list);\n> \n>  \tlist_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {\n> -\t\tstruct device *d;\n> -\n> -\t\td = get_device(sd->dev);\n> -\n>  \t\tv4l2_async_cleanup(sd);\n> \n> -\t\t/* If we handled USB devices, we'd have to lock the parent too */\n> -\t\tdevice_release_driver(d);\n> -\n>  \t\tif (notifier->unbind)\n>  \t\t\tnotifier->unbind(notifier, sd, sd->asd);\n> -\n> -\t\t/*\n> -\t\t * Store device at the device cache, in order to call\n> -\t\t * put_device() on the final step\n> -\t\t */\n> -\t\tif (dev)\n> -\t\t\tdev[i++] = d;\n> -\t\telse\n> -\t\t\tput_device(d);\n>  \t}\n> \n>  \tmutex_unlock(&list_lock);\n> \n> -\t/*\n> -\t * Call device_attach() to reprobe devices\n> -\t *\n> -\t * NOTE: If dev allocation fails, i is 0, and the whole loop won't be\n> -\t * executed.\n> -\t */\n> -\twhile (i--) {\n> -\t\tstruct device *d = dev[i];\n> -\n> -\t\tif (d && device_attach(d) < 0) {\n> -\t\t\tconst char *name = \"(none)\";\n> -\t\t\tint lock = device_trylock(d);\n> -\n> -\t\t\tif (lock && d->driver)\n> -\t\t\t\tname = d->driver->name;\n> -\t\t\tdev_err(d, \"Failed to re-probe to %s\\n\", name);\n> -\t\t\tif (lock)\n> -\t\t\t\tdevice_unlock(d);\n> -\t\t}\n> -\t\tput_device(d);\n> -\t}\n> -\tkvfree(dev);\n> -\n>  \tnotifier->v4l2_dev = NULL;\n> -\n> -\t/*\n> -\t * Don't care about the waiting list, it is initialised and populated\n> -\t * upon notifier registration.\n> -\t */\n>  }\n>  EXPORT_SYMBOL(v4l2_async_notifier_unregister);","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"PMzN0+uf\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxHSh3xZxz9sMN\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 19:21:56 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751343AbdISJVz (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 05:21:55 -0400","from galahad.ideasonboard.com ([185.26.127.97]:35878 \"EHLO\n\tgalahad.ideasonboard.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1750925AbdISJVy (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 05:21:54 -0400","from avalon.localnet (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby galahad.ideasonboard.com (Postfix) with ESMTPSA id 297DF201C5;\n\tTue, 19 Sep 2017 11:19:17 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1505812757;\n\tbh=2ljn+sLsgrA/UmWB1ud7hXXZxyUX49VLKPYgkOp9blY=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=PMzN0+uf8Tg6qYTGd90huIvGjONhrU8F0snDmT/UPR+AkzOdEHfZQY19juOnhCcGD\n\tv1lVbm4ooLEgbyAIqIPpTOoKvhLcIpxZ8eME9LVKQJMczbEP5KTUegHDBjtzq1QIkH\n\t/bOOMtjDKujqFcpL1FC8o/pJRJxGwB25LII0E8SY=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, devicetree@vger.kernel.org, pavel@ucw.cz,\n\tsre@kernel.org, Michael Turquette <mturquette@baylibre.com>","Subject":"Re: [PATCH v13 02/25] v4l: async: Remove re-probing support","Date":"Tue, 19 Sep 2017 12:21:58 +0300","Message-ID":"<1891349.nWXO9QHRQ8@avalon>","In-Reply-To":"<20170915141724.23124-3-sakari.ailus@linux.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-3-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"7Bit","Content-Type":"text/plain; charset=\"us-ascii\"","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770784,"web_url":"http://patchwork.ozlabs.org/comment/1770784/","msgid":"<09f8ce37-c6e0-e448-c773-e1f3510d1024@xs4all.nl>","list_archive_url":null,"date":"2017-09-19T09:21:50","subject":"Re: [PATCH v13 18/25] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 09/19/17 10:45, Sakari Ailus wrote:\n> Hi Hans,\n> \n> Thank you for the review.\n> \n> On Tue, Sep 19, 2017 at 10:31:41AM +0200, Hans Verkuil wrote:\n>> Hi Sakari,\n>>\n>> I'm slowly starting to understand this. The example helped a lot. But I still have\n>> some questions, see below.\n>>\n>> On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n>>> v4l2_fwnode_reference_parse_int_prop() will find an fwnode such that under\n>>> the device's own fwnode, it will follow child fwnodes with the given\n>>> property-value pair and return the resulting fwnode.\n>>\n>> I think both the subject, commit log, function comment and function name should\n>> reflect the fact that this function is for an ACPI reference.\n>>\n>> It's only called for ACPI (from patch 19):\n>>\n>> +\t\tif (props[i].props && is_acpi_node(dev_fwnode(dev)))\n>> +\t\t\tret = v4l2_fwnode_reference_parse_int_props(\n>>\n>> So renaming it to v4l2_fwnode_acpi_reference_parse_int_props or something similar\n>> would clarify this fact.\n> \n> I don't think we'll see many like this one. I presume we won't use it on DT\n> albeit there are no direct references to ACPI in the code itself.\n> \n> How about v4l2_fwnode_parse_acpi_reference (+ \"s\" for the one below)?\n\nSounds good.\n\n> \n>>\n>>>\n>>> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n>>> ---\n>>>  drivers/media/v4l2-core/v4l2-fwnode.c | 201 ++++++++++++++++++++++++++++++++++\n>>>  1 file changed, 201 insertions(+)\n>>>\n>>> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c\n>>> index 65e84ea1cc35..968a345a288f 100644\n>>> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n>>> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n>>> @@ -567,6 +567,207 @@ static int v4l2_fwnode_reference_parse(\n>>>  \treturn ret;\n>>>  }\n>>>  \n>>> +/*\n>>> + * v4l2_fwnode_reference_get_int_prop - parse a reference with integer\n>>> + *\t\t\t\t\targuments\n>>> + * @dev: struct device pointer\n>>> + * @notifier: notifier for @dev\n>>> + * @prop: the name of the property\n>>> + * @index: the index of the reference to get\n>>> + * @props: the array of integer property names\n>>> + * @nprops: the number of integer property names in @nprops\n>>\n>> You mean 'in @props'?\n> \n> Yes, I'll fix that.\n> \n>>\n>> One thing that is not clear to me is when you would use an nprops value > 1.\n>> What's the use-case for that? It only makes sense (I think) if you would have\n>> property names that are all aliases of one another.\n> \n> There may be several flash LEDs related to a sensor. That's the use case,\n> for instance.\n\nI think it would be helpful if the example shows two LEDs related to a\nsensor. Part of the problem I have in understanding this code is that I\nhave zero experience with ACPI (and that is probably true for most other\ndevelopers), so I don't know how this is encoded. With a good example it\nis much easier to understand.\n\n> \n>>\n>>> + *\n>>> + * Find fwnodes referred to by a property @prop, then under that\n>>> + * iteratively, @nprops times, follow each child node which has a\n>>> + * property in @props array at a given child index the value of which\n>>> + * matches the integer argument at an index.\n>>> + *\n>>> + * For example, if this function was called with arguments and values\n>>> + * @dev corresponding to device \"SEN\", @prop == \"flash-leds\", @index\n>>> + * == 1, @props == { \"led\" }, @nprops == 1, with the ASL snippet below\n>>> + * it would return the node marked with THISONE. The @dev argument in\n>>> + * the ASL below.\n>>\n>> That last sentence about the @dev seems incomplete. I'm not sure what is\n>> meant by it.\n> \n> I think it was meant to convey some information but it got added to the\n> previous sentence. I'll remove it.\n> \n>>\n>>> + *\n>>> + *\tDevice (LED)\n>>> + *\t{\n>>> + *\t\tName (_DSD, Package () {\n>>> + *\t\t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n>>> + *\t\t\tPackage () {\n>>> + *\t\t\t\tPackage () { \"led0\", \"LED0\" },\n>>> + *\t\t\t\tPackage () { \"led1\", \"LED1\" },\n>>> + *\t\t\t}\n>>> + *\t\t})\n>>> + *\t\tName (LED0, Package () {\n>>> + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n>>> + *\t\t\tPackage () {\n>>> + *\t\t\t\tPackage () { \"led\", 0 },\n>>> + *\t\t\t}\n>>> + *\t\t})\n>>> + *\t\tName (LED1, Package () {\n>>> + *\t\t\t// THISONE\n>>> + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n>>> + *\t\t\tPackage () {\n>>> + *\t\t\t\tPackage () { \"led\", 1 },\n>>> + *\t\t\t}\n>>> + *\t\t})\n>>> + *\t}\n>>> + *\n>>> + *\tDevice (SEN)\n>>> + *\t{\n>>> + *\t\tName (_DSD, Package () {\n>>> + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n>>> + *\t\t\tPackage () {\n>>> + *\t\t\t\tPackage () {\n>>> + *\t\t\t\t\t\"flash-leds\",\n>>> + *\t\t\t\t\tPackage () { ^LED, 0, ^LED, 1 },\n>>> + *\t\t\t\t}\n>>> + *\t\t\t}\n>>> + *\t\t})\n>>> + *\t}\n>>> + *\n>>> + * where\n>>> + *\n>>> + *\tLED\tLED driver device\n>>> + *\tLED0\tFirst LED\n>>> + *\tLED1\tSecond LED\n>>> + *\tSEN\tCamera sensor device (or another device the LED is\n>>> + *\t\trelated to)\n>>> + *\n>>> + * Return: 0 on success\n>>> + *\t   -ENOENT if no entries (or the property itself) were found\n>>> + *\t   -EINVAL if property parsing otherwise failed\n>>> + *\t   -ENOMEM if memory allocation failed\n>>> + */\n>>> +static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(\n>>> +\tstruct fwnode_handle *fwnode, const char *prop, unsigned int index,\n>>> +\tconst char **props, unsigned int nprops)\n>>> +{\n>>> +\tstruct fwnode_reference_args fwnode_args;\n>>> +\tunsigned int *args = fwnode_args.args;\n>>> +\tstruct fwnode_handle *child;\n>>> +\tint ret;\n>>> +\n>>> +\t/*\n>>> +\t * Obtain remote fwnode as well as the integer arguments.\n>>> +\t *\n>>> +\t * Note that right now both -ENODATA and -ENOENT may signal\n>>> +\t * out-of-bounds access. Return -ENOENT in that case.\n>>> +\t */\n>>> +\tret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops,\n>>> +\t\t\t\t\t\t index, &fwnode_args);\n>>> +\tif (ret)\n>>> +\t\treturn ERR_PTR(ret == -ENODATA ? -ENOENT : ret);\n>>> +\n>>> +\t/*\n>>> +\t * Find a node in the tree under the referred fwnode corresponding the\n>>> +\t * integer arguments.\n>>> +\t */\n>>> +\tfwnode = fwnode_args.fwnode;\n>>\n>> So given the example above, fwnode would point to the LED device?\n>>\n>> If correct, then mention that in the comment.\n> \n> It could be a LED driver device, but it could be something else as well.\n> Like a lens VCM, depending on the property being parsed. That's why I\n> didn't put it in the comments. But this is a device node, not a\n> hierarchical data extension node, for instance. That's what I think I\n> should add.\n\nI think that will help.\n\n> \n>>\n>>> +\twhile (nprops--) {\n>>> +\t\tu32 val;\n>>> +\n>>> +\t\t/* Loop over all child nodes under fwnode. */\n>>\n>> And here you check if the LED device has child nodes that have a *props\n>> property with a value matching the index.\n>>\n>> So given the example above it is looking for a child with property \"led\"\n>> and value 1.\n>>\n>> It's useful if that is mentioned in the comment as well.\n> \n> But should I? This isn't specific to LEDs.\n\nIgnore this comment for now. I'll take another look when I see v14.\n\nRegards,\n\n\tHans\n--\nTo unsubscribe from this list: send the line \"unsubscribe devicetree\" in\nthe body of a message to majordomo@vger.kernel.org\nMore majordomo info at  http://vger.kernel.org/majordomo-info.html","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxHT63Xkkz9ryr\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 19:22:18 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751000AbdISJWR (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 05:22:17 -0400","from lb3-smtp-cloud7.xs4all.net ([194.109.24.31]:55918 \"EHLO\n\tlb3-smtp-cloud7.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1750925AbdISJWQ (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 05:22:16 -0400","from [IPv6:2001:420:44c1:2579:d841:6302:cc6a:1bf0]\n\t([IPv6:2001:420:44c1:2579:d841:6302:cc6a:1bf0])\n\tby smtp-cloud7.xs4all.net with ESMTPA\n\tid uEj2dy5pcG5oquEjBd5KHM; Tue, 19 Sep 2017 11:22:15 +0200"],"Subject":"Re: [PATCH v13 18/25] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-19-sakari.ailus@linux.intel.com>\n\t<ee1252cf-3396-9bed-443f-56e3c2d621e5@xs4all.nl>\n\t<20170919084534.ivgmrlmgywdwuhoa@paasikivi.fi.intel.com>","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<09f8ce37-c6e0-e448-c773-e1f3510d1024@xs4all.nl>","Date":"Tue, 19 Sep 2017 11:21:50 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tThunderbird/52.2.1","MIME-Version":"1.0","In-Reply-To":"<20170919084534.ivgmrlmgywdwuhoa@paasikivi.fi.intel.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfCWClqr94Xg6kNBuTtPMVuWSv+Xk1t7lkmABZ6ogajVMfFGUmppSzU+aBMeo1Dx0yi8mKp8nna2rukf+Vc4DAAAb46HnQYKLrh9Orvy179+33DmXaxUh\n\tQ6Pd+/Ey99nGyO2WHnkCXksUzcyLVvIHAWZv7knKTSrVULi6UyhYnvIayUmH8n+VXs/vGe7rCEXfVeEMNdMeu/XN5JAigB1CY7jauMUcYJsT2+e4yz7m7Kgp\n\tX+mwbFfHUrFXVPURpCWIECfPfNXpB8oVnDXAS28J8fKiiiSaRb16D4LfpRHIJqVL0Qmur4pJibw4M+IxZL3/bsuM6MBfFy9+dOarzVKJPjWNYW0/bFTuOt/T\n\tOYgrNMPLPyx2nr6uLcemQyyXWQeZyMX3MWHm6yBM3rAdyQP9oktMnhpp7w5PI8LeP3m5Juh80CXDiyDPF0ipDUqRRBVt/bhBNhmLaGxyiqnrfhufWM6lJMGt\n\tIWi8vH642s9eYZee/oPo8XS1h+xY9B805LV/9xsv8/k9DBLE6d761/tg8FN1mVNBSV3klFeLRQ2/GnQ4HbOvKmUitUPJ1qPlYFIz075MdhOy8uO0pB3zk1fm\n\t+r9ZqDsghDQwcZn2/z72jJKMntkx8Wgdau3PUFnpiQ8aSA==","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770790,"web_url":"http://patchwork.ozlabs.org/comment/1770790/","msgid":"<2061043.HYj1Sta8zM@avalon>","list_archive_url":null,"date":"2017-09-19T09:30:34","subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","submitter":{"id":11034,"url":"http://patchwork.ozlabs.org/api/people/11034/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Hans,\n\nOn Tuesday, 19 September 2017 11:40:14 EEST Hans Verkuil wrote:\n> On 09/19/2017 10:20 AM, Sakari Ailus wrote:\n> > On Tue, Sep 19, 2017 at 10:03:27AM +0200, Hans Verkuil wrote:\n> >> On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n> >>> Add two functions for parsing devices graph endpoints:\n> >>> v4l2_async_notifier_parse_fwnode_endpoints and\n> >>> v4l2_async_notifier_parse_fwnode_endpoints_by_port. The former iterates\n> >>> over all endpoints whereas the latter only iterates over the endpoints\n> >>> in a given port.\n> >>> \n> >>> The former is mostly useful for existing drivers that currently\n> >>> implement the iteration over all the endpoints themselves whereas the\n> >>> latter is especially intended for devices with both sinks and sources:\n> >>> async sub-devices for external devices connected to the device's sources\n> >>> will have already been set up, or they are part of the master device.\n> >>> \n> >>> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> >>> ---\n> >>> \n> >>>  drivers/media/v4l2-core/v4l2-async.c  |  30 ++++++\n> >>>  drivers/media/v4l2-core/v4l2-fwnode.c | 185 +++++++++++++++++++++++++++\n> >>>  include/media/v4l2-async.h            |  24 ++++-\n> >>>  include/media/v4l2-fwnode.h           | 117 +++++++++++++++++++++\n> >>>  4 files changed, 354 insertions(+), 2 deletions(-)\n\n[snip]\n\n> >>> diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h\n> >>> index 68eb22ba571b..83afac48ea6b 100644\n> >>> --- a/include/media/v4l2-fwnode.h\n> >>> +++ b/include/media/v4l2-fwnode.h\n> >>> @@ -25,6 +25,8 @@\n> >>> \n> >>>  #include <media/v4l2-mediabus.h>\n> >>>  \n> >>>  struct fwnode_handle;\n> >>> +struct v4l2_async_notifier;\n> >>> +struct v4l2_async_subdev;\n> >>> \n> >>>  #define V4L2_FWNODE_CSI2_MAX_DATA_LANES\t4\n> >>> \n> >>> @@ -201,4 +203,119 @@ int v4l2_fwnode_parse_link(struct fwnode_handle\n> >>> *fwnode,\n> >>>   */\n> >>>  void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);\n> >>> \n> >>> +/**\n> >>> + * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode\n> >>> endpoints in a\n> >>> + *\t\t\t\t\t\tdevice node\n> >>> + * @dev: the device the endpoints of which are to be parsed\n> >>> + * @notifier: notifier for @dev\n> >>> + * @asd_struct_size: size of the driver's async sub-device struct,\n> >>> including\n> >>> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> >>> + *\t\t     v4l2_async_subdev shall be the first member of\n> >>> + *\t\t     the driver's async sub-device struct, i.e. both\n> >>> + *\t\t     begin at the same memory address.\n> >>> + * @parse_endpoint: Driver's callback function called on each V4L2\n> >>> fwnode\n> >>> + *\t\t    endpoint. Optional.\n> >>> + *\t\t    Return: %0 on success\n> >>> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> >>> + *\t\t\t\t       should not be considered as an error\n> >>> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> >>> + *\n> >>> + * Parse the fwnode endpoints of the @dev device and populate the async\n> >>> sub-\n> >>> + * devices array of the notifier. The @parse_endpoint callback function\n> >>> is\n> >>> + * called for each endpoint with the corresponding async sub-device\n> >>> pointer to\n> >>> + * let the caller initialize the driver-specific part of the async sub-\n> >>> device\n> >>> + * structure.\n> >>> + *\n> >>> + * The notifier memory shall be zeroed before this function is called\n> >>> on the\n> >>> + * notifier.\n> >>> + *\n> >>> + * This function may not be called on a registered notifier and may be\n> >>> called on\n> >>> + * a notifier only once.\n> >>> + *\n> >>> + * Do not change the notifier's subdevs array, take references to the\n> >>> subdevs\n> >>> + * array itself or change the notifier's num_subdevs field. This is\n> >>> because this\n> >>> + * function allocates and reallocates the subdevs array based on\n> >>> parsing\n> >>> + * endpoints.\n> >>> + *\n> >>> + * The @struct v4l2_fwnode_endpoint passed to the callback function\n> >>> + * @parse_endpoint is released once the function is finished. If there\n> >>> is a need\n> >>> + * to retain that configuration, the user needs to allocate memory for\n> >>> it.\n> >>> + *\n> >>> + * Any notifier populated using this function must be released with a\n> >>> call to\n> >>> + * v4l2_async_notifier_release() after it has been unregistered and the\n> >>> async\n> >>> + * sub-devices are no longer in use, even if the function returned an\n> >>> error.\n> >>> + *\n> >>> + * Return: %0 on success, including when no async sub-devices are found\n> >>> + *\t   %-ENOMEM if memory allocation failed\n> >>> + *\t   %-EINVAL if graph or endpoint parsing failed\n> >>> + *\t   Other error codes as returned by @parse_endpoint\n> >>> + */\n> >>> +int v4l2_async_notifier_parse_fwnode_endpoints(\n> >>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> >>> +\tsize_t asd_struct_size,\n> >>> +\tint (*parse_endpoint)(struct device *dev,\n> >>> +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n> >>> +\t\t\t      struct v4l2_async_subdev *asd));\n> >>> +\n> >>> +/**\n> >>> + * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2\n> >>> fwnode\n> >>> + *\t\t\t\t\t\t\tendpoints of a port in a\n> >>> + *\t\t\t\t\t\t\tdevice node\n> >>> + * @dev: the device the endpoints of which are to be parsed\n> >>> + * @notifier: notifier for @dev\n> >>> + * @asd_struct_size: size of the driver's async sub-device struct,\n> >>> including\n> >>> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> >>> + *\t\t     v4l2_async_subdev shall be the first member of\n> >>> + *\t\t     the driver's async sub-device struct, i.e. both\n> >>> + *\t\t     begin at the same memory address.\n> >>> + * @port: port number where endpoints are to be parsed\n> >>> + * @parse_endpoint: Driver's callback function called on each V4L2\n> >>> fwnode\n> >>> + *\t\t    endpoint. Optional.\n> >>> + *\t\t    Return: %0 on success\n> >>> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> >>> + *\t\t\t\t       should not be considered as an error\n> >>> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> >>> + *\n> >>> + * This function is just like\n> >>> @v4l2_async_notifier_parse_fwnode_endpoints with \n> >>> + * the exception that it only parses endpoints in a given port. This is\n> >>> useful\n> >>> + * on devices that have both sinks and sources: the async sub-devices\n> >>> connected\n> >> \n> >> on -> for\n> >> \n> >>> + * to sources have already been set up by another driver (on capture\n> >>> devices).\n> >> \n> >> on -> for\n> > \n> > Agreed on both.\n> > \n> >> So if I understand this correctly for devices with both sinks and sources\n> >> you use this function to just parse the sink ports. And you have to give\n> >> explicit port numbers since you can't tell from parsing the device tree\n> >> if a port is a sink or source port, right? Only the driver knows this.\n> > \n> > Correct. The graph data structure in DT isn't directed, so this is only\n> > known by the driver.\n> \n> I think this should be clarified.\n> \n> I wonder if there is any way around it. I don't have time to dig into this,\n> but isn't it possible to tell that the source ports are already configured?\n\nPlease also note that it's not always source ports, it depends in which \ndirection we want to traverse the graph. The usual way is from master to \nslave, so from source to sink for capture devices but from sink to source for \noutput devices.\n\nIt's a bit of a mess, and this is part of the reason why I don't think sub-\nnotifiers are the best idea. It would be better in my opinion to maintain a \nsingle list of async matches, which would be gradually enriched by subdevices \nas they are probed. This would help detecting and handling duplicates.\n\n> Anyway, that can be looked at later.\n\n[snip]","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"v5G+FjWN\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxHfd20rPz9sP1\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 19:30:33 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1750964AbdISJab (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 05:30:31 -0400","from galahad.ideasonboard.com ([185.26.127.97]:35915 \"EHLO\n\tgalahad.ideasonboard.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1750774AbdISJaa (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 05:30:30 -0400","from avalon.localnet (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby galahad.ideasonboard.com (Postfix) with ESMTPSA id C204A201C5;\n\tTue, 19 Sep 2017 11:27:53 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1505813273;\n\tbh=7ZUgF1Q3i/IzYaUReJa78ST4q2mTKFWKw32A9+v6PbU=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=v5G+FjWN39Ej1QIVwH5douVHXqiw747rc12/hCIu+wEr6CKK7WutQalxjbvHwA2uG\n\tzQjMThtXxo1axs/pe1nqGH9Wvx8LP09CChqULaRAV9/ezWfP5LafkKqlHVIoUfxDMd\n\t2PU1uTEu7EoOYhm+di5FeMcfIMXSQOMvzKfwMSCw=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Hans Verkuil <hverkuil@xs4all.nl>","Cc":"Sakari Ailus <sakari.ailus@linux.intel.com>,\n\tlinux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\tdevicetree@vger.kernel.org, pavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","Date":"Tue, 19 Sep 2017 12:30:34 +0300","Message-ID":"<2061043.HYj1Sta8zM@avalon>","In-Reply-To":"<af99e12c-6fb8-a633-eec2-c1eb9d82226a@xs4all.nl>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170919082015.vt6olgirnvmpcrpa@paasikivi.fi.intel.com>\n\t<af99e12c-6fb8-a633-eec2-c1eb9d82226a@xs4all.nl>","MIME-Version":"1.0","Content-Transfer-Encoding":"7Bit","Content-Type":"text/plain; charset=\"us-ascii\"","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770808,"web_url":"http://patchwork.ozlabs.org/comment/1770808/","msgid":"<20170919100048.7jut3benh2vbb32q@paasikivi.fi.intel.com>","list_archive_url":null,"date":"2017-09-19T10:00:48","subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","submitter":{"id":65485,"url":"http://patchwork.ozlabs.org/api/people/65485/","name":"Sakari Ailus","email":"sakari.ailus@linux.intel.com"},"content":"Hi Hans,\n\nOn Tue, Sep 19, 2017 at 10:40:14AM +0200, Hans Verkuil wrote:\n> On 09/19/2017 10:20 AM, Sakari Ailus wrote:\n> > Hi Hans,\n> > \n> > Thank you for the review.\n> > \n> > On Tue, Sep 19, 2017 at 10:03:27AM +0200, Hans Verkuil wrote:\n> >> On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n...\n> >>> +static int __v4l2_async_notifier_parse_fwnode_endpoints(\n> >>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> >>> +\tsize_t asd_struct_size, unsigned int port, bool has_port,\n> >>> +\tint (*parse_endpoint)(struct device *dev,\n> >>> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n> >>> +\t\t\t    struct v4l2_async_subdev *asd))\n> >>> +{\n> >>> +\tstruct fwnode_handle *fwnode = NULL;\n> >>> +\tunsigned int max_subdevs = notifier->max_subdevs;\n> >>> +\tint ret;\n> >>> +\n> >>> +\tif (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev)))\n> >>> +\t\treturn -EINVAL;\n> >>> +\n> >>> +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n> >>> +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n> >>\n> >> You can replace this by:\n> >>\n> >> \twhile ((fwnode = fwnode_graph_get_next_endpoint(dev_fwnode(dev), fwnode))) {\n> >>\n> >>> +\t\tif (!fwnode_device_is_available(\n> >>> +\t\t\t    fwnode_graph_get_port_parent(fwnode)))\n> >>> +\t\t\tcontinue;\n> >>> +\n> >>> +\t\tif (has_port) {\n> >>> +\t\t\tstruct fwnode_endpoint ep;\n> >>> +\n> >>> +\t\t\tret = fwnode_graph_parse_endpoint(fwnode, &ep);\n> >>> +\t\t\tif (ret) {\n> >>> +\t\t\t\tfwnode_handle_put(fwnode);\n> >>> +\t\t\t\treturn ret;\n> >>> +\t\t\t}\n> >>> +\n> >>> +\t\t\tif (ep.port != port)\n> >>> +\t\t\t\tcontinue;\n> >>> +\t\t}\n> >>> +\t\tmax_subdevs++;\n> >>> +\t}\n> >>> +\n> >>> +\t/* No subdevs to add? Return here. */\n> >>> +\tif (max_subdevs == notifier->max_subdevs)\n> >>> +\t\treturn 0;\n> >>> +\n> >>> +\tret = v4l2_async_notifier_realloc(notifier, max_subdevs);\n> >>> +\tif (ret)\n> >>> +\t\treturn ret;\n> >>> +\n> >>> +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n> >>> +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n> >>\n> >> Same here: this can be a 'while'.\n> > \n> > The fwnode = NULL assignment still needs to be done. A for loop has a\n> > natural initialiser for the loop, I think it's cleaner than using while\n> > here.\n> \n> After the previous while fwnode is NULL again (since that's when the while\n> stops).\n> \n> > \n> > The macro would be implemented this way as well.\n> > \n> > For the loop above this one, I'd use for for consistency: it's the same\n> > loop after all.\n> > \n> > This reminds me --- I'll send the patch for the macro.\n> \n> If this is going to be replaced by a macro, then disregard my comment.\n\nYes. I just sent that to linux-acpi (as well as devicetree and to you).\n\n...\n\n> >>> +/**\n> >>> + * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a\n> >>> + *\t\t\t\t\t\tdevice node\n> >>> + * @dev: the device the endpoints of which are to be parsed\n> >>> + * @notifier: notifier for @dev\n> >>> + * @asd_struct_size: size of the driver's async sub-device struct, including\n> >>> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> >>> + *\t\t     v4l2_async_subdev shall be the first member of\n> >>> + *\t\t     the driver's async sub-device struct, i.e. both\n> >>> + *\t\t     begin at the same memory address.\n> >>> + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n> >>> + *\t\t    endpoint. Optional.\n> >>> + *\t\t    Return: %0 on success\n> >>> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> >>> + *\t\t\t\t       should not be considered as an error\n> >>> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> >>> + *\n> >>> + * Parse the fwnode endpoints of the @dev device and populate the async sub-\n> >>> + * devices array of the notifier. The @parse_endpoint callback function is\n> >>> + * called for each endpoint with the corresponding async sub-device pointer to\n> >>> + * let the caller initialize the driver-specific part of the async sub-device\n> >>> + * structure.\n> >>> + *\n> >>> + * The notifier memory shall be zeroed before this function is called on the\n> >>> + * notifier.\n> >>> + *\n> >>> + * This function may not be called on a registered notifier and may be called on\n> >>> + * a notifier only once.\n> >>> + *\n> >>> + * Do not change the notifier's subdevs array, take references to the subdevs\n> >>> + * array itself or change the notifier's num_subdevs field. This is because this\n> >>> + * function allocates and reallocates the subdevs array based on parsing\n> >>> + * endpoints.\n> >>> + *\n> >>> + * The @struct v4l2_fwnode_endpoint passed to the callback function\n> >>> + * @parse_endpoint is released once the function is finished. If there is a need\n> >>> + * to retain that configuration, the user needs to allocate memory for it.\n> >>> + *\n> >>> + * Any notifier populated using this function must be released with a call to\n> >>> + * v4l2_async_notifier_release() after it has been unregistered and the async\n> >>> + * sub-devices are no longer in use, even if the function returned an error.\n> >>> + *\n> >>> + * Return: %0 on success, including when no async sub-devices are found\n> >>> + *\t   %-ENOMEM if memory allocation failed\n> >>> + *\t   %-EINVAL if graph or endpoint parsing failed\n> >>> + *\t   Other error codes as returned by @parse_endpoint\n> >>> + */\n> >>> +int v4l2_async_notifier_parse_fwnode_endpoints(\n> >>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> >>> +\tsize_t asd_struct_size,\n> >>> +\tint (*parse_endpoint)(struct device *dev,\n> >>> +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n> >>> +\t\t\t      struct v4l2_async_subdev *asd));\n> >>> +\n> >>> +/**\n> >>> + * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode\n> >>> + *\t\t\t\t\t\t\tendpoints of a port in a\n> >>> + *\t\t\t\t\t\t\tdevice node\n> >>> + * @dev: the device the endpoints of which are to be parsed\n> >>> + * @notifier: notifier for @dev\n> >>> + * @asd_struct_size: size of the driver's async sub-device struct, including\n> >>> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> >>> + *\t\t     v4l2_async_subdev shall be the first member of\n> >>> + *\t\t     the driver's async sub-device struct, i.e. both\n> >>> + *\t\t     begin at the same memory address.\n> >>> + * @port: port number where endpoints are to be parsed\n> >>> + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n> >>> + *\t\t    endpoint. Optional.\n> >>> + *\t\t    Return: %0 on success\n> >>> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> >>> + *\t\t\t\t       should not be considered as an error\n> >>> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> >>> + *\n> >>> + * This function is just like @v4l2_async_notifier_parse_fwnode_endpoints with\n> >>> + * the exception that it only parses endpoints in a given port. This is useful\n> >>> + * on devices that have both sinks and sources: the async sub-devices connected\n> >>\n> >> on -> for\n> >>\n> >>> + * to sources have already been set up by another driver (on capture devices).\n> >>\n> >> on -> for\n> > \n> > Agreed on both.\n> > \n> >>\n> >> So if I understand this correctly for devices with both sinks and sources you use\n> >> this function to just parse the sink ports. And you have to give explicit port\n> >> numbers since you can't tell from parsing the device tree if a port is a sink or\n> >> source port, right? Only the driver knows this.\n> > \n> > Correct. The graph data structure in DT isn't directed, so this is only\n> > known by the driver.\n> \n> I think this should be clarified.\n> \n> I wonder if there is any way around it. I don't have time to dig into this, but\n> isn't it possible to tell that the source ports are already configured?\n\nWell, this is essentially what the documentation is attempting to convey.\n:-)\n\nI can add this / change the existing wording, if you think it could help.","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxJLK5db7z9s7h\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 20:01:29 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751411AbdISKB2 (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 06:01:28 -0400","from mga14.intel.com ([192.55.52.115]:64102 \"EHLO mga14.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1751057AbdISKB1 (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tTue, 19 Sep 2017 06:01:27 -0400","from orsmga002.jf.intel.com ([10.7.209.21])\n\tby fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t19 Sep 2017 03:01:22 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby orsmga002.jf.intel.com with ESMTP; 19 Sep 2017 03:01:19 -0700","by paasikivi.fi.intel.com (Postfix, from userid 1000)\n\tid C03EA20642; Tue, 19 Sep 2017 13:00:48 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos;i=\"5.42,417,1500966000\"; d=\"scan'208\";a=\"136967544\"","Date":"Tue, 19 Sep 2017 13:00:48 +0300","From":"Sakari Ailus <sakari.ailus@linux.intel.com>","To":"Hans Verkuil <hverkuil@xs4all.nl>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","Message-ID":"<20170919100048.7jut3benh2vbb32q@paasikivi.fi.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-6-sakari.ailus@linux.intel.com>\n\t<a17ab793-b859-f04a-2dff-d8f6a314e9bf@xs4all.nl>\n\t<20170919082015.vt6olgirnvmpcrpa@paasikivi.fi.intel.com>\n\t<af99e12c-6fb8-a633-eec2-c1eb9d82226a@xs4all.nl>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<af99e12c-6fb8-a633-eec2-c1eb9d82226a@xs4all.nl>","User-Agent":"NeoMutt/20170113 (1.7.2)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770815,"web_url":"http://patchwork.ozlabs.org/comment/1770815/","msgid":"<0e18e159-51cc-1473-86c9-ffb9ee4212a8@xs4all.nl>","list_archive_url":null,"date":"2017-09-19T10:10:18","subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 09/19/17 12:00, Sakari Ailus wrote:\n> Hi Hans,\n> \n> On Tue, Sep 19, 2017 at 10:40:14AM +0200, Hans Verkuil wrote:\n>> On 09/19/2017 10:20 AM, Sakari Ailus wrote:\n>>> Hi Hans,\n>>>\n>>> Thank you for the review.\n>>>\n>>> On Tue, Sep 19, 2017 at 10:03:27AM +0200, Hans Verkuil wrote:\n>>>> On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n> ...\n>>>>> +static int __v4l2_async_notifier_parse_fwnode_endpoints(\n>>>>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n>>>>> +\tsize_t asd_struct_size, unsigned int port, bool has_port,\n>>>>> +\tint (*parse_endpoint)(struct device *dev,\n>>>>> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n>>>>> +\t\t\t    struct v4l2_async_subdev *asd))\n>>>>> +{\n>>>>> +\tstruct fwnode_handle *fwnode = NULL;\n>>>>> +\tunsigned int max_subdevs = notifier->max_subdevs;\n>>>>> +\tint ret;\n>>>>> +\n>>>>> +\tif (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev)))\n>>>>> +\t\treturn -EINVAL;\n>>>>> +\n>>>>> +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n>>>>> +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n>>>>\n>>>> You can replace this by:\n>>>>\n>>>> \twhile ((fwnode = fwnode_graph_get_next_endpoint(dev_fwnode(dev), fwnode))) {\n>>>>\n>>>>> +\t\tif (!fwnode_device_is_available(\n>>>>> +\t\t\t    fwnode_graph_get_port_parent(fwnode)))\n>>>>> +\t\t\tcontinue;\n>>>>> +\n>>>>> +\t\tif (has_port) {\n>>>>> +\t\t\tstruct fwnode_endpoint ep;\n>>>>> +\n>>>>> +\t\t\tret = fwnode_graph_parse_endpoint(fwnode, &ep);\n>>>>> +\t\t\tif (ret) {\n>>>>> +\t\t\t\tfwnode_handle_put(fwnode);\n>>>>> +\t\t\t\treturn ret;\n>>>>> +\t\t\t}\n>>>>> +\n>>>>> +\t\t\tif (ep.port != port)\n>>>>> +\t\t\t\tcontinue;\n>>>>> +\t\t}\n>>>>> +\t\tmax_subdevs++;\n>>>>> +\t}\n>>>>> +\n>>>>> +\t/* No subdevs to add? Return here. */\n>>>>> +\tif (max_subdevs == notifier->max_subdevs)\n>>>>> +\t\treturn 0;\n>>>>> +\n>>>>> +\tret = v4l2_async_notifier_realloc(notifier, max_subdevs);\n>>>>> +\tif (ret)\n>>>>> +\t\treturn ret;\n>>>>> +\n>>>>> +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n>>>>> +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n>>>>\n>>>> Same here: this can be a 'while'.\n>>>\n>>> The fwnode = NULL assignment still needs to be done. A for loop has a\n>>> natural initialiser for the loop, I think it's cleaner than using while\n>>> here.\n>>\n>> After the previous while fwnode is NULL again (since that's when the while\n>> stops).\n>>\n>>>\n>>> The macro would be implemented this way as well.\n>>>\n>>> For the loop above this one, I'd use for for consistency: it's the same\n>>> loop after all.\n>>>\n>>> This reminds me --- I'll send the patch for the macro.\n>>\n>> If this is going to be replaced by a macro, then disregard my comment.\n> \n> Yes. I just sent that to linux-acpi (as well as devicetree and to you).\n> \n> ...\n> \n>>>>> +/**\n>>>>> + * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a\n>>>>> + *\t\t\t\t\t\tdevice node\n>>>>> + * @dev: the device the endpoints of which are to be parsed\n>>>>> + * @notifier: notifier for @dev\n>>>>> + * @asd_struct_size: size of the driver's async sub-device struct, including\n>>>>> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n>>>>> + *\t\t     v4l2_async_subdev shall be the first member of\n>>>>> + *\t\t     the driver's async sub-device struct, i.e. both\n>>>>> + *\t\t     begin at the same memory address.\n>>>>> + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n>>>>> + *\t\t    endpoint. Optional.\n>>>>> + *\t\t    Return: %0 on success\n>>>>> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n>>>>> + *\t\t\t\t       should not be considered as an error\n>>>>> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n>>>>> + *\n>>>>> + * Parse the fwnode endpoints of the @dev device and populate the async sub-\n>>>>> + * devices array of the notifier. The @parse_endpoint callback function is\n>>>>> + * called for each endpoint with the corresponding async sub-device pointer to\n>>>>> + * let the caller initialize the driver-specific part of the async sub-device\n>>>>> + * structure.\n>>>>> + *\n>>>>> + * The notifier memory shall be zeroed before this function is called on the\n>>>>> + * notifier.\n>>>>> + *\n>>>>> + * This function may not be called on a registered notifier and may be called on\n>>>>> + * a notifier only once.\n>>>>> + *\n>>>>> + * Do not change the notifier's subdevs array, take references to the subdevs\n>>>>> + * array itself or change the notifier's num_subdevs field. This is because this\n>>>>> + * function allocates and reallocates the subdevs array based on parsing\n>>>>> + * endpoints.\n>>>>> + *\n>>>>> + * The @struct v4l2_fwnode_endpoint passed to the callback function\n>>>>> + * @parse_endpoint is released once the function is finished. If there is a need\n>>>>> + * to retain that configuration, the user needs to allocate memory for it.\n>>>>> + *\n>>>>> + * Any notifier populated using this function must be released with a call to\n>>>>> + * v4l2_async_notifier_release() after it has been unregistered and the async\n>>>>> + * sub-devices are no longer in use, even if the function returned an error.\n>>>>> + *\n>>>>> + * Return: %0 on success, including when no async sub-devices are found\n>>>>> + *\t   %-ENOMEM if memory allocation failed\n>>>>> + *\t   %-EINVAL if graph or endpoint parsing failed\n>>>>> + *\t   Other error codes as returned by @parse_endpoint\n>>>>> + */\n>>>>> +int v4l2_async_notifier_parse_fwnode_endpoints(\n>>>>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n>>>>> +\tsize_t asd_struct_size,\n>>>>> +\tint (*parse_endpoint)(struct device *dev,\n>>>>> +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n>>>>> +\t\t\t      struct v4l2_async_subdev *asd));\n>>>>> +\n>>>>> +/**\n>>>>> + * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode\n>>>>> + *\t\t\t\t\t\t\tendpoints of a port in a\n>>>>> + *\t\t\t\t\t\t\tdevice node\n>>>>> + * @dev: the device the endpoints of which are to be parsed\n>>>>> + * @notifier: notifier for @dev\n>>>>> + * @asd_struct_size: size of the driver's async sub-device struct, including\n>>>>> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n>>>>> + *\t\t     v4l2_async_subdev shall be the first member of\n>>>>> + *\t\t     the driver's async sub-device struct, i.e. both\n>>>>> + *\t\t     begin at the same memory address.\n>>>>> + * @port: port number where endpoints are to be parsed\n>>>>> + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n>>>>> + *\t\t    endpoint. Optional.\n>>>>> + *\t\t    Return: %0 on success\n>>>>> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n>>>>> + *\t\t\t\t       should not be considered as an error\n>>>>> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n>>>>> + *\n>>>>> + * This function is just like @v4l2_async_notifier_parse_fwnode_endpoints with\n>>>>> + * the exception that it only parses endpoints in a given port. This is useful\n>>>>> + * on devices that have both sinks and sources: the async sub-devices connected\n>>>>\n>>>> on -> for\n>>>>\n>>>>> + * to sources have already been set up by another driver (on capture devices).\n>>>>\n>>>> on -> for\n>>>\n>>> Agreed on both.\n>>>\n>>>>\n>>>> So if I understand this correctly for devices with both sinks and sources you use\n>>>> this function to just parse the sink ports. And you have to give explicit port\n>>>> numbers since you can't tell from parsing the device tree if a port is a sink or\n>>>> source port, right? Only the driver knows this.\n>>>\n>>> Correct. The graph data structure in DT isn't directed, so this is only\n>>> known by the driver.\n>>\n>> I think this should be clarified.\n>>\n>> I wonder if there is any way around it. I don't have time to dig into this, but\n>> isn't it possible to tell that the source ports are already configured?\n> \n> Well, this is essentially what the documentation is attempting to convey.\n> :-)\n> \n> I can add this / change the existing wording, if you think it could help.\n\nYes please. The documentation is just missing the little fact that the DT can't\ntell the difference between a sink and source port, hence the driver has to be\nexplicit about which ports to parse in a case like this.\n\nRegards,\n\n\tHans\n--\nTo unsubscribe from this list: send the line \"unsubscribe devicetree\" in\nthe body of a message to majordomo@vger.kernel.org\nMore majordomo info at  http://vger.kernel.org/majordomo-info.html","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxJXg4fX6z9ryr\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 20:10:27 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751024AbdISKKY (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 06:10:24 -0400","from lb2-smtp-cloud8.xs4all.net ([194.109.24.25]:58169 \"EHLO\n\tlb2-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1750952AbdISKKX (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 06:10:23 -0400","from [IPv6:2001:420:44c1:2579:d841:6302:cc6a:1bf0]\n\t([IPv6:2001:420:44c1:2579:d841:6302:cc6a:1bf0])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid uFTudYd8Ob4gvuFTxdks7z; Tue, 19 Sep 2017 12:10:22 +0200"],"Subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-6-sakari.ailus@linux.intel.com>\n\t<a17ab793-b859-f04a-2dff-d8f6a314e9bf@xs4all.nl>\n\t<20170919082015.vt6olgirnvmpcrpa@paasikivi.fi.intel.com>\n\t<af99e12c-6fb8-a633-eec2-c1eb9d82226a@xs4all.nl>\n\t<20170919100048.7jut3benh2vbb32q@paasikivi.fi.intel.com>","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<0e18e159-51cc-1473-86c9-ffb9ee4212a8@xs4all.nl>","Date":"Tue, 19 Sep 2017 12:10:18 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tThunderbird/52.2.1","MIME-Version":"1.0","In-Reply-To":"<20170919100048.7jut3benh2vbb32q@paasikivi.fi.intel.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfLhObvjFmuapYXEtxYc2PR5EZj9MwdS1/icY/kMRuZnrO3rqt/mxEWDy3K6vRuQE916dbMGbYm1W4I8qHhvN3OKWasCglxg5pZ/1Sn8ZduzcGC+I8X07\n\taBhJgX+OfZAup+D4JQD01QPzPmuWf9/1STk6IX/NG2Uh93wQ1EgAlAiV3rns9Qz2bwTC5IOmCLr2dek6MeORpFlRkS1lGsCa438wFX3zd+J8sj8S9VC0pBL/\n\tvPvkQmKkVDgQxN39mRdT184HzO3byMBOudVHX2+0leuWbg4ZvzM72nTJOjELQF8fPNLasi7dzt25b1/9t/JlzEeXZ2jKcNbF37l5FaBBvQzKzNJu24H0e8I5\n\tYSsuTH0yxLFX3WukdB8BRYR2SinZjhK/RzK3FJQCEqwbn6cToob9JaF3IaLM8AeeGlDX3xrZ36O7rEZpS74IjWh3QStFCTmx0TwiFiXVwHUFc+WBMS8TIqSs\n\tL8bczY/hQqdhK6mCoFg81M7b512VVJxdtPCQXarRmqKzY/mdMPcPA7jT/fooqBB4IiRrjjx7QMH5TAMixOQf1u6xdHx7sAY/5pY+gDIBJk6XRLaSmPF5741m\n\t+gRNhboiVlobDMEkP0jxKpcCgadtPW53BkHZHwY+iDSRzQ==","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770825,"web_url":"http://patchwork.ozlabs.org/comment/1770825/","msgid":"<20170919101657.m3yr5sdznndeopkd@paasikivi.fi.intel.com>","list_archive_url":null,"date":"2017-09-19T10:16:57","subject":"Re: [PATCH v13 18/25] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","submitter":{"id":65485,"url":"http://patchwork.ozlabs.org/api/people/65485/","name":"Sakari Ailus","email":"sakari.ailus@linux.intel.com"},"content":"Hi Hans,\n\nOn Tue, Sep 19, 2017 at 11:21:50AM +0200, Hans Verkuil wrote:\n> On 09/19/17 10:45, Sakari Ailus wrote:\n> > Hi Hans,\n> > \n> > Thank you for the review.\n> > \n> > On Tue, Sep 19, 2017 at 10:31:41AM +0200, Hans Verkuil wrote:\n> >> Hi Sakari,\n> >>\n> >> I'm slowly starting to understand this. The example helped a lot. But I still have\n> >> some questions, see below.\n> >>\n> >> On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n> >>> v4l2_fwnode_reference_parse_int_prop() will find an fwnode such that under\n> >>> the device's own fwnode, it will follow child fwnodes with the given\n> >>> property-value pair and return the resulting fwnode.\n> >>\n> >> I think both the subject, commit log, function comment and function name should\n> >> reflect the fact that this function is for an ACPI reference.\n> >>\n> >> It's only called for ACPI (from patch 19):\n> >>\n> >> +\t\tif (props[i].props && is_acpi_node(dev_fwnode(dev)))\n> >> +\t\t\tret = v4l2_fwnode_reference_parse_int_props(\n> >>\n> >> So renaming it to v4l2_fwnode_acpi_reference_parse_int_props or something similar\n> >> would clarify this fact.\n> > \n> > I don't think we'll see many like this one. I presume we won't use it on DT\n> > albeit there are no direct references to ACPI in the code itself.\n> > \n> > How about v4l2_fwnode_parse_acpi_reference (+ \"s\" for the one below)?\n> \n> Sounds good.\n> \n> > \n> >>\n> >>>\n> >>> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> >>> ---\n> >>>  drivers/media/v4l2-core/v4l2-fwnode.c | 201 ++++++++++++++++++++++++++++++++++\n> >>>  1 file changed, 201 insertions(+)\n> >>>\n> >>> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c\n> >>> index 65e84ea1cc35..968a345a288f 100644\n> >>> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> >>> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> >>> @@ -567,6 +567,207 @@ static int v4l2_fwnode_reference_parse(\n> >>>  \treturn ret;\n> >>>  }\n> >>>  \n> >>> +/*\n> >>> + * v4l2_fwnode_reference_get_int_prop - parse a reference with integer\n> >>> + *\t\t\t\t\targuments\n> >>> + * @dev: struct device pointer\n> >>> + * @notifier: notifier for @dev\n> >>> + * @prop: the name of the property\n> >>> + * @index: the index of the reference to get\n> >>> + * @props: the array of integer property names\n> >>> + * @nprops: the number of integer property names in @nprops\n> >>\n> >> You mean 'in @props'?\n> > \n> > Yes, I'll fix that.\n> > \n> >>\n> >> One thing that is not clear to me is when you would use an nprops value > 1.\n> >> What's the use-case for that? It only makes sense (I think) if you would have\n> >> property names that are all aliases of one another.\n> > \n> > There may be several flash LEDs related to a sensor. That's the use case,\n> > for instance.\n> \n> I think it would be helpful if the example shows two LEDs related to a\n> sensor. Part of the problem I have in understanding this code is that I\n> have zero experience with ACPI (and that is probably true for most other\n> developers), so I don't know how this is encoded. With a good example it\n> is much easier to understand.\n\nI'm a bit at loss here. Are you happy with the example below, or do you\nthink something is missing in the documentation here.\n\n> \n> > \n> >>\n> >>> + *\n> >>> + * Find fwnodes referred to by a property @prop, then under that\n> >>> + * iteratively, @nprops times, follow each child node which has a\n> >>> + * property in @props array at a given child index the value of which\n> >>> + * matches the integer argument at an index.\n> >>> + *\n> >>> + * For example, if this function was called with arguments and values\n> >>> + * @dev corresponding to device \"SEN\", @prop == \"flash-leds\", @index\n> >>> + * == 1, @props == { \"led\" }, @nprops == 1, with the ASL snippet below\n> >>> + * it would return the node marked with THISONE. The @dev argument in\n> >>> + * the ASL below.\n> >>\n> >> That last sentence about the @dev seems incomplete. I'm not sure what is\n> >> meant by it.\n> > \n> > I think it was meant to convey some information but it got added to the\n> > previous sentence. I'll remove it.\n> > \n> >>\n> >>> + *\n> >>> + *\tDevice (LED)\n> >>> + *\t{\n> >>> + *\t\tName (_DSD, Package () {\n> >>> + *\t\t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n> >>> + *\t\t\tPackage () {\n> >>> + *\t\t\t\tPackage () { \"led0\", \"LED0\" },\n> >>> + *\t\t\t\tPackage () { \"led1\", \"LED1\" },\n> >>> + *\t\t\t}\n> >>> + *\t\t})\n> >>> + *\t\tName (LED0, Package () {\n> >>> + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> >>> + *\t\t\tPackage () {\n> >>> + *\t\t\t\tPackage () { \"led\", 0 },\n> >>> + *\t\t\t}\n> >>> + *\t\t})\n> >>> + *\t\tName (LED1, Package () {\n> >>> + *\t\t\t// THISONE\n> >>> + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> >>> + *\t\t\tPackage () {\n> >>> + *\t\t\t\tPackage () { \"led\", 1 },\n> >>> + *\t\t\t}\n> >>> + *\t\t})\n> >>> + *\t}\n> >>> + *\n> >>> + *\tDevice (SEN)\n> >>> + *\t{\n> >>> + *\t\tName (_DSD, Package () {\n> >>> + *\t\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> >>> + *\t\t\tPackage () {\n> >>> + *\t\t\t\tPackage () {\n> >>> + *\t\t\t\t\t\"flash-leds\",\n> >>> + *\t\t\t\t\tPackage () { ^LED, 0, ^LED, 1 },\n> >>> + *\t\t\t\t}\n> >>> + *\t\t\t}\n> >>> + *\t\t})\n> >>> + *\t}\n> >>> + *\n> >>> + * where\n> >>> + *\n> >>> + *\tLED\tLED driver device\n> >>> + *\tLED0\tFirst LED\n> >>> + *\tLED1\tSecond LED\n> >>> + *\tSEN\tCamera sensor device (or another device the LED is\n> >>> + *\t\trelated to)\n> >>> + *\n> >>> + * Return: 0 on success\n> >>> + *\t   -ENOENT if no entries (or the property itself) were found\n> >>> + *\t   -EINVAL if property parsing otherwise failed\n> >>> + *\t   -ENOMEM if memory allocation failed\n> >>> + */\n> >>> +static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(\n> >>> +\tstruct fwnode_handle *fwnode, const char *prop, unsigned int index,\n> >>> +\tconst char **props, unsigned int nprops)\n> >>> +{\n> >>> +\tstruct fwnode_reference_args fwnode_args;\n> >>> +\tunsigned int *args = fwnode_args.args;\n> >>> +\tstruct fwnode_handle *child;\n> >>> +\tint ret;\n> >>> +\n> >>> +\t/*\n> >>> +\t * Obtain remote fwnode as well as the integer arguments.\n> >>> +\t *\n> >>> +\t * Note that right now both -ENODATA and -ENOENT may signal\n> >>> +\t * out-of-bounds access. Return -ENOENT in that case.\n> >>> +\t */\n> >>> +\tret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops,\n> >>> +\t\t\t\t\t\t index, &fwnode_args);\n> >>> +\tif (ret)\n> >>> +\t\treturn ERR_PTR(ret == -ENODATA ? -ENOENT : ret);\n> >>> +\n> >>> +\t/*\n> >>> +\t * Find a node in the tree under the referred fwnode corresponding the\n> >>> +\t * integer arguments.\n> >>> +\t */\n> >>> +\tfwnode = fwnode_args.fwnode;\n> >>\n> >> So given the example above, fwnode would point to the LED device?\n> >>\n> >> If correct, then mention that in the comment.\n> > \n> > It could be a LED driver device, but it could be something else as well.\n> > Like a lens VCM, depending on the property being parsed. That's why I\n> > didn't put it in the comments. But this is a device node, not a\n> > hierarchical data extension node, for instance. That's what I think I\n> > should add.\n> \n> I think that will help.\n\nAgreed.\n\nYeah, in DT all fwnodes are DT nodes but in ACPI some are device nodes and\nothers hierarchical data extension nodes. Oh well...\n\n> \n> > \n> >>\n> >>> +\twhile (nprops--) {\n> >>> +\t\tu32 val;\n> >>> +\n> >>> +\t\t/* Loop over all child nodes under fwnode. */\n> >>\n> >> And here you check if the LED device has child nodes that have a *props\n> >> property with a value matching the index.\n> >>\n> >> So given the example above it is looking for a child with property \"led\"\n> >> and value 1.\n> >>\n> >> It's useful if that is mentioned in the comment as well.\n> > \n> > But should I? This isn't specific to LEDs.\n> \n> Ignore this comment for now. I'll take another look when I see v14.","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxJhs67SFz9s7h\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 20:17:33 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1750948AbdISKRc (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 06:17:32 -0400","from mga14.intel.com ([192.55.52.115]:6395 \"EHLO mga14.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1750747AbdISKRb (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tTue, 19 Sep 2017 06:17:31 -0400","from fmsmga004.fm.intel.com ([10.253.24.48])\n\tby fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t19 Sep 2017 03:17:31 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby fmsmga004.fm.intel.com with ESMTP; 19 Sep 2017 03:17:28 -0700","by paasikivi.fi.intel.com (Postfix, from userid 1000)\n\tid 72B2420642; Tue, 19 Sep 2017 13:16:57 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos;i=\"5.42,417,1500966000\"; d=\"scan'208\";a=\"313709145\"","Date":"Tue, 19 Sep 2017 13:16:57 +0300","From":"Sakari Ailus <sakari.ailus@linux.intel.com>","To":"Hans Verkuil <hverkuil@xs4all.nl>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v13 18/25] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","Message-ID":"<20170919101657.m3yr5sdznndeopkd@paasikivi.fi.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-19-sakari.ailus@linux.intel.com>\n\t<ee1252cf-3396-9bed-443f-56e3c2d621e5@xs4all.nl>\n\t<20170919084534.ivgmrlmgywdwuhoa@paasikivi.fi.intel.com>\n\t<09f8ce37-c6e0-e448-c773-e1f3510d1024@xs4all.nl>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<09f8ce37-c6e0-e448-c773-e1f3510d1024@xs4all.nl>","User-Agent":"NeoMutt/20170113 (1.7.2)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770850,"web_url":"http://patchwork.ozlabs.org/comment/1770850/","msgid":"<9077921.hsjkiRftLf@avalon>","list_archive_url":null,"date":"2017-09-19T10:48:27","subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","submitter":{"id":11034,"url":"http://patchwork.ozlabs.org/api/people/11034/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Sakari,\n\nThank you for the patch.\n\nOn Friday, 15 September 2017 17:17:00 EEST Sakari Ailus wrote:\n> In V4L2 the practice is to have the KernelDoc documentation in the header\n> and not in .c source code files. This consequently makes the V4L2 fwnode\n> function documentation part of the Media documentation build.\n> \n> Also correct the link related function and argument naming in\n> documentation.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> Acked-by: Pavel Machek <pavel@ucw.cz>\n\nI'm still very opposed to this. In addition to increasing the risk of \ndocumentation becoming stale, it also makes review more difficult. I'm \nreviewing patch 05/25 of this series and I have to jump around the patch to \nverify that the documentation matches the implementation, it's really \nannoying.\n\nWe should instead move all function documentation from header files to source \nfiles.\n\n> ---\n>  drivers/media/v4l2-core/v4l2-fwnode.c | 75 --------------------------------\n> include/media/v4l2-fwnode.h            | 81 +++++++++++++++++++++++++++++++-\n> 2 files changed, 80 insertions(+), 76 deletions(-)\n\n[snip]","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"nUdR41BW\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxKNT0j7hz9sBZ\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 20:48:25 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751306AbdISKsY (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 06:48:24 -0400","from galahad.ideasonboard.com ([185.26.127.97]:37573 \"EHLO\n\tgalahad.ideasonboard.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751237AbdISKsX (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 06:48:23 -0400","from avalon.localnet (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby galahad.ideasonboard.com (Postfix) with ESMTPSA id 706A2200AD;\n\tTue, 19 Sep 2017 12:45:46 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1505817946;\n\tbh=aeFxoIBaYz8830uMDPpfO1qZxEXGdAi6dbh80yHv8nU=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=nUdR41BWY5nTHJ7V2DPcvt/mJKgwEBDpuAfMGMVLf2ZhklZZqweskhNu7AA8m/s5U\n\ttf84327e668BSsCh2kDQK29twz2G7Wr7kN8YhcD4pjfVFpcTZ3olm1al6OyMGTbCol\n\ta/7cZrhC9y/qczuf14htF5xwhkQ7XyVMlImIm+i0=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, devicetree@vger.kernel.org, pavel@ucw.cz,\n\tsre@kernel.org","Subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","Date":"Tue, 19 Sep 2017 13:48:27 +0300","Message-ID":"<9077921.hsjkiRftLf@avalon>","In-Reply-To":"<20170915141724.23124-2-sakari.ailus@linux.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-2-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","Content-Type":"text/plain; charset=\"iso-8859-1\"","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770871,"web_url":"http://patchwork.ozlabs.org/comment/1770871/","msgid":"<29354478-ec46-278b-c457-4e6f3cc6848c@xs4all.nl>","list_archive_url":null,"date":"2017-09-19T11:04:36","subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 09/19/17 12:48, Laurent Pinchart wrote:\n> Hi Sakari,\n> \n> Thank you for the patch.\n> \n> On Friday, 15 September 2017 17:17:00 EEST Sakari Ailus wrote:\n>> In V4L2 the practice is to have the KernelDoc documentation in the header\n>> and not in .c source code files. This consequently makes the V4L2 fwnode\n>> function documentation part of the Media documentation build.\n>>\n>> Also correct the link related function and argument naming in\n>> documentation.\n>>\n>> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n>> Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n>> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n>> Acked-by: Pavel Machek <pavel@ucw.cz>\n> \n> I'm still very opposed to this. In addition to increasing the risk of \n> documentation becoming stale, it also makes review more difficult. I'm \n> reviewing patch 05/25 of this series and I have to jump around the patch to \n> verify that the documentation matches the implementation, it's really \n> annoying.\n> \n> We should instead move all function documentation from header files to source \n> files.\n\nI disagree with this. Yes, it makes reviewing harder, but when you have to\n*use* these functions as e.g. a driver developer, then having it in the\nheader is much more convenient.\n\nRegards,\n\n\tHans\n\n> \n>> ---\n>>  drivers/media/v4l2-core/v4l2-fwnode.c | 75 --------------------------------\n>> include/media/v4l2-fwnode.h            | 81 +++++++++++++++++++++++++++++++-\n>> 2 files changed, 80 insertions(+), 76 deletions(-)\n> \n> [snip]\n> \n\n--\nTo unsubscribe from this list: send the line \"unsubscribe devicetree\" in\nthe body of a message to majordomo@vger.kernel.org\nMore majordomo info at  http://vger.kernel.org/majordomo-info.html","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxKlH1hN9z9rxj\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:04:43 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751394AbdISLEl (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:04:41 -0400","from lb2-smtp-cloud9.xs4all.net ([194.109.24.26]:60196 \"EHLO\n\tlb2-smtp-cloud9.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1751237AbdISLEl (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 07:04:41 -0400","from [IPv6:2001:420:44c1:2579:9817:b73d:bf46:4273]\n\t([IPv6:2001:420:44c1:2579:9817:b73d:bf46:4273])\n\tby smtp-cloud9.xs4all.net with ESMTPA\n\tid uGKSdiC1vmRxPuGKVdsL3E; Tue, 19 Sep 2017 13:04:40 +0200"],"Subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tSakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\tdevicetree@vger.kernel.org, pavel@ucw.cz, sre@kernel.org","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-2-sakari.ailus@linux.intel.com>\n\t<9077921.hsjkiRftLf@avalon>","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<29354478-ec46-278b-c457-4e6f3cc6848c@xs4all.nl>","Date":"Tue, 19 Sep 2017 13:04:36 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tThunderbird/52.2.1","MIME-Version":"1.0","In-Reply-To":"<9077921.hsjkiRftLf@avalon>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"8bit","X-CMAE-Envelope":"MS4wfHt2tSmJ2B4CNmm7lHQOb6EGdx2ZkOA6c3lGn4Gu0iT4UJjui591KKXNeMjggRGx3qJEVcmizIeUBvGKWsJAxRAC2ipZuhil+WFZQeBwnWhOLAfZlb1m\n\tmk+C/NMhp6N8eey4ob2brezVkDxeMRMfPZZBgZFgP7x5Y3wAfzsCvmV9fdWeouuK7t1EFH9/Cs0JoN9kH9WeaAvAvqrBHONlsPNTRcVTgmHO/W5OEpSWVQjQ\n\tYJC5o9v/PhmLAuPvSb3FWOJW2gzXyOfH6Ltdytusjc1RKwr3JrP4dwj3mt1/9gGAEBdkyxs0M2ulCnuWaImy97bUTEUluyVjsvHNm/iNH5xadrT4WpY3VHBU\n\tU05cryWM9tw1Tim9ZEO5EsxILSdIot2gskyH5NoYGJkSGb1SFQMfdoMZjJq4CWKp3G9RL/2hjDeL812cb6FPXtz2Wnpdej4085lFLhrl8MMJUvUrnTnoh3Pw\n\tXsr8B+BdtHvvQers+NOu+F6IKf2HZDFilL7SFtbuMs5gzC95az/oDpLvvesuGSdzF7px6TSZpYTYHJiYtaO2R1J6zmQeld2JZyFLBn4hfSzEiClrAoFNmDpi\n\t2qte0ludpf8fPopDB9FgaJDoCZctc/8ixs4pn5qAihP+BAuOhpJNb3PbziJgPNSPzdRHOREv0y1l/PdaVvwoDmfeVvgb4AoPfQbJ1wC0ftEHpQ==","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770875,"web_url":"http://patchwork.ozlabs.org/comment/1770875/","msgid":"<15064920.NAWzJTdLf5@avalon>","list_archive_url":null,"date":"2017-09-19T11:07:08","subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","submitter":{"id":11034,"url":"http://patchwork.ozlabs.org/api/people/11034/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Hans,\n\nOn Tuesday, 19 September 2017 14:04:36 EEST Hans Verkuil wrote:\n> On 09/19/17 12:48, Laurent Pinchart wrote:\n> > On Friday, 15 September 2017 17:17:00 EEST Sakari Ailus wrote:\n> >> In V4L2 the practice is to have the KernelDoc documentation in the header\n> >> and not in .c source code files. This consequently makes the V4L2 fwnode\n> >> function documentation part of the Media documentation build.\n> >> \n> >> Also correct the link related function and argument naming in\n> >> documentation.\n> >> \n> >> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> >> Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n> >> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> >> Acked-by: Pavel Machek <pavel@ucw.cz>\n> > \n> > I'm still very opposed to this. In addition to increasing the risk of\n> > documentation becoming stale, it also makes review more difficult. I'm\n> > reviewing patch 05/25 of this series and I have to jump around the patch\n> > to verify that the documentation matches the implementation, it's really\n> > annoying.\n> > \n> > We should instead move all function documentation from header files to\n> > source files.\n> \n> I disagree with this. Yes, it makes reviewing harder, but when you have to\n> *use* these functions as e.g. a driver developer, then having it in the\n> header is much more convenient.\n\nWhen writing a driver you can use the compiled documentation. We're lacking \nreviewers in V4L2, we should make their life easier if we want to attract \nmore.\n\nFurthermore, if documentation becomes stale, it will become useless for driver \nauthors, regardless of where it's stored.\n\n> >> ---\n> >> \n> >>  drivers/media/v4l2-core/v4l2-fwnode.c | 75 -----------------------------\n> >>  include/media/v4l2-fwnode.h           | 81 +++++++++++++++++++++++++++-\n> >>  2 files changed, 80 insertions(+), 76 deletions(-)","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Tcf/u80n\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxKp16nHlz9s7m\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:07:05 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751685AbdISLHE (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:07:04 -0400","from galahad.ideasonboard.com ([185.26.127.97]:37633 \"EHLO\n\tgalahad.ideasonboard.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751669AbdISLHD (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 07:07:03 -0400","from avalon.localnet (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby galahad.ideasonboard.com (Postfix) with ESMTPSA id D090B200AD;\n\tTue, 19 Sep 2017 13:04:26 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1505819066;\n\tbh=7M/tePfMyd8bFrF+pJ82xcvqqn0UbF+CzWf40riYn3w=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=Tcf/u80nVmyqWkuJH3jyd3aBAfFVhGcLXklnBYQRPMuYmiTwSLIjyl4LwZqdoFuqc\n\tUfeqxV7nkS/u5Zqd0x7t9l4nefXkiqHMZdIYeLmEyucjsZUquTu7cotV/xioZyI6BM\n\tK/2DKW3VVeVhB4+VLrLi6ZkLkcgVjbxBB3TBnHgk=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Hans Verkuil <hverkuil@xs4all.nl>","Cc":"Sakari Ailus <sakari.ailus@linux.intel.com>,\n\tlinux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\tdevicetree@vger.kernel.org, pavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","Date":"Tue, 19 Sep 2017 14:07:08 +0300","Message-ID":"<15064920.NAWzJTdLf5@avalon>","In-Reply-To":"<29354478-ec46-278b-c457-4e6f3cc6848c@xs4all.nl>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<9077921.hsjkiRftLf@avalon>\n\t<29354478-ec46-278b-c457-4e6f3cc6848c@xs4all.nl>","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","Content-Type":"text/plain; charset=\"iso-8859-1\"","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770879,"web_url":"http://patchwork.ozlabs.org/comment/1770879/","msgid":"<20170919111036.5va2unwqh2vymojr@valkosipuli.retiisi.org.uk>","list_archive_url":null,"date":"2017-09-19T11:10:37","subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","submitter":{"id":1593,"url":"http://patchwork.ozlabs.org/api/people/1593/","name":"Sakari Ailus","email":"sakari.ailus@iki.fi"},"content":"Hi Laurent,\n\nOn Tue, Sep 19, 2017 at 01:48:27PM +0300, Laurent Pinchart wrote:\n> Hi Sakari,\n> \n> Thank you for the patch.\n> \n> On Friday, 15 September 2017 17:17:00 EEST Sakari Ailus wrote:\n> > In V4L2 the practice is to have the KernelDoc documentation in the header\n> > and not in .c source code files. This consequently makes the V4L2 fwnode\n> > function documentation part of the Media documentation build.\n> > \n> > Also correct the link related function and argument naming in\n> > documentation.\n> > \n> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> > Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n> > Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> > Acked-by: Pavel Machek <pavel@ucw.cz>\n> \n> I'm still very opposed to this. In addition to increasing the risk of \n> documentation becoming stale, it also makes review more difficult. I'm \n> reviewing patch 05/25 of this series and I have to jump around the patch to \n> verify that the documentation matches the implementation, it's really \n> annoying.\n\nI'd like to have this discussion separately from the patchset, which is\nright now in its 13th version. This patch simply makes the current state\nconsistent; V4L2 async was the only part of V4L2 with KernelDoc\ndocumentation in .c files.","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxKtC01d0z9s7m\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:10:42 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751408AbdISLKl (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:10:41 -0400","from nblzone-211-213.nblnetworks.fi ([83.145.211.213]:59468 \"EHLO\n\thillosipuli.retiisi.org.uk\" rhost-flags-OK-OK-OK-FAIL)\n\tby vger.kernel.org with ESMTP id S1751237AbdISLKl (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 07:10:41 -0400","from valkosipuli.localdomain (valkosipuli.retiisi.org.uk\n\t[IPv6:2001:1bc8:1a6:d3d5::80:2])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby hillosipuli.retiisi.org.uk (Postfix) with ESMTPS id 4A1B0600D9;\n\tTue, 19 Sep 2017 14:10:38 +0300 (EEST)","from sakke by valkosipuli.localdomain with local (Exim 4.89)\n\t(envelope-from <sakke@valkosipuli.retiisi.org.uk>)\n\tid 1duGQH-00059v-Gp; Tue, 19 Sep 2017 14:10:37 +0300"],"Date":"Tue, 19 Sep 2017 14:10:37 +0300","From":"Sakari Ailus <sakari.ailus@iki.fi>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"Sakari Ailus <sakari.ailus@linux.intel.com>,\n\tlinux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, devicetree@vger.kernel.org, pavel@ucw.cz,\n\tsre@kernel.org","Subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","Message-ID":"<20170919111036.5va2unwqh2vymojr@valkosipuli.retiisi.org.uk>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-2-sakari.ailus@linux.intel.com>\n\t<9077921.hsjkiRftLf@avalon>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<9077921.hsjkiRftLf@avalon>","User-Agent":"NeoMutt/20170113 (1.7.2)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770883,"web_url":"http://patchwork.ozlabs.org/comment/1770883/","msgid":"<20634394.E3nNBE0rok@avalon>","list_archive_url":null,"date":"2017-09-19T11:14:39","subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","submitter":{"id":11034,"url":"http://patchwork.ozlabs.org/api/people/11034/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Sakari,\n\nOn Tuesday, 19 September 2017 14:10:37 EEST Sakari Ailus wrote:\n> On Tue, Sep 19, 2017 at 01:48:27PM +0300, Laurent Pinchart wrote:\n> > On Friday, 15 September 2017 17:17:00 EEST Sakari Ailus wrote:\n> >> In V4L2 the practice is to have the KernelDoc documentation in the\n> >> header and not in .c source code files. This consequently makes the V4L2\n> >> fwnode function documentation part of the Media documentation build.\n> >> \n> >> Also correct the link related function and argument naming in\n> >> documentation.\n> >> \n> >> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> >> Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n> >> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> >> Acked-by: Pavel Machek <pavel@ucw.cz>\n> > \n> > I'm still very opposed to this. In addition to increasing the risk of\n> > documentation becoming stale, it also makes review more difficult. I'm\n> > reviewing patch 05/25 of this series and I have to jump around the patch\n> > to verify that the documentation matches the implementation, it's really\n> > annoying.\n> \n> I'd like to have this discussion separately from the patchset, which is\n> right now in its 13th version. This patch simply makes the current state\n> consistent; V4L2 async was the only part of V4L2 with KernelDoc\n> documentation in .c files.\n\nBut there's no need to move the documentation at this point until we reach an \nagreement, is there ?","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"XpLakJDF\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxKyj4VQQz9s7B\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:14:37 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751408AbdISLOf (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:14:35 -0400","from galahad.ideasonboard.com ([185.26.127.97]:37687 \"EHLO\n\tgalahad.ideasonboard.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1750964AbdISLOf (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 07:14:35 -0400","from avalon.localnet (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby galahad.ideasonboard.com (Postfix) with ESMTPSA id 5AEF3200AD;\n\tTue, 19 Sep 2017 13:11:58 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1505819518;\n\tbh=vtT5DHvaDdmMyaSQW3ZJEMnzUA5qPaQpnMq1QXkVogg=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=XpLakJDFqjLqftycozzI9VbTI5K4iqBDs0LpYj9La6IQc2oiRng77mChFEQY4fRZh\n\tDX/CoshuXkf2vlnUh66NMwgLErLwhMtkzaqzUMC/ULuDIZeZQDp5YoD+rkKUrSe/kM\n\tdxfehJ5WBO9i3+yIAnkqrbmA5TCznzT6WqTiK7lo=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Sakari Ailus <sakari.ailus@iki.fi>","Cc":"Sakari Ailus <sakari.ailus@linux.intel.com>,\n\tlinux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, devicetree@vger.kernel.org, pavel@ucw.cz,\n\tsre@kernel.org","Subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","Date":"Tue, 19 Sep 2017 14:14:39 +0300","Message-ID":"<20634394.E3nNBE0rok@avalon>","In-Reply-To":"<20170919111036.5va2unwqh2vymojr@valkosipuli.retiisi.org.uk>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<9077921.hsjkiRftLf@avalon>\n\t<20170919111036.5va2unwqh2vymojr@valkosipuli.retiisi.org.uk>","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","Content-Type":"text/plain; charset=\"iso-8859-1\"","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770888,"web_url":"http://patchwork.ozlabs.org/comment/1770888/","msgid":"<20170919112210.pnlipm6mfaazmo6b@valkosipuli.retiisi.org.uk>","list_archive_url":null,"date":"2017-09-19T11:22:10","subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","submitter":{"id":1593,"url":"http://patchwork.ozlabs.org/api/people/1593/","name":"Sakari Ailus","email":"sakari.ailus@iki.fi"},"content":"Hi Hans,\n\nOn Tue, Sep 19, 2017 at 01:04:36PM +0200, Hans Verkuil wrote:\n> On 09/19/17 12:48, Laurent Pinchart wrote:\n> > Hi Sakari,\n> > \n> > Thank you for the patch.\n> > \n> > On Friday, 15 September 2017 17:17:00 EEST Sakari Ailus wrote:\n> >> In V4L2 the practice is to have the KernelDoc documentation in the header\n> >> and not in .c source code files. This consequently makes the V4L2 fwnode\n> >> function documentation part of the Media documentation build.\n> >>\n> >> Also correct the link related function and argument naming in\n> >> documentation.\n> >>\n> >> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> >> Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n> >> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> >> Acked-by: Pavel Machek <pavel@ucw.cz>\n> > \n> > I'm still very opposed to this. In addition to increasing the risk of \n> > documentation becoming stale, it also makes review more difficult. I'm \n> > reviewing patch 05/25 of this series and I have to jump around the patch to \n> > verify that the documentation matches the implementation, it's really \n> > annoying.\n> > \n> > We should instead move all function documentation from header files to source \n> > files.\n> \n> I disagree with this. Yes, it makes reviewing harder, but when you have to\n> *use* these functions as e.g. a driver developer, then having it in the\n> header is much more convenient.\n\nFor developers writing a driver and _not_ using e.g. the HTML\ndocumentation, programs like cscope point the user to the implementation of\nthe function --- which is in the .c file, not the header. This is what I\npersonally tend to do at least; for most of the time I ignore where exactly\na given function is implemented (this is actually not self-evident in V4L2\noutside async / fwnode).\n\nThe rest of the kernel appears to generally have the KernelDoc in .c files,\nfor a reason or another:\n\n14:05:15 nauris sailus [~/scratch/src/linux]git grep '/\\*\\*$' -- include/|wc -l\n6997\n14:14:46 nauris sailus [~/scratch/src/linux]git grep '/\\*\\*$' -- drivers/ net/ mm/ lib/ kernel/ fs/ firmware/ init/ ipc/ block/ crypto/ |wc -l\n44756\n\nI think I'm slightly leaning towards moving it: having the documentation\nwhere the implementation is does help keeping it up-to-date. It's currently\nall too easy to change a function without realising it was actually\ndocumented somewhere.","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxL7W5SSVz9s7m\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:22:15 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751340AbdISLWO (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:22:14 -0400","from nblzone-211-213.nblnetworks.fi ([83.145.211.213]:59614 \"EHLO\n\thillosipuli.retiisi.org.uk\" rhost-flags-OK-OK-OK-FAIL)\n\tby vger.kernel.org with ESMTP id S1750964AbdISLWN (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 07:22:13 -0400","from valkosipuli.localdomain (valkosipuli.retiisi.org.uk\n\t[IPv6:2001:1bc8:1a6:d3d5::80:2])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby hillosipuli.retiisi.org.uk (Postfix) with ESMTPS id 551D860130;\n\tTue, 19 Sep 2017 14:22:11 +0300 (EEST)","from sakke by valkosipuli.localdomain with local (Exim 4.89)\n\t(envelope-from <sakke@valkosipuli.retiisi.org.uk>)\n\tid 1duGbS-0005AF-TS; Tue, 19 Sep 2017 14:22:10 +0300"],"Date":"Tue, 19 Sep 2017 14:22:10 +0300","From":"Sakari Ailus <sakari.ailus@iki.fi>","To":"Hans Verkuil <hverkuil@xs4all.nl>","Cc":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tSakari Ailus <sakari.ailus@linux.intel.com>,\n\tlinux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\tdevicetree@vger.kernel.org, pavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","Message-ID":"<20170919112210.pnlipm6mfaazmo6b@valkosipuli.retiisi.org.uk>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-2-sakari.ailus@linux.intel.com>\n\t<9077921.hsjkiRftLf@avalon>\n\t<29354478-ec46-278b-c457-4e6f3cc6848c@xs4all.nl>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<29354478-ec46-278b-c457-4e6f3cc6848c@xs4all.nl>","User-Agent":"NeoMutt/20170113 (1.7.2)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770890,"web_url":"http://patchwork.ozlabs.org/comment/1770890/","msgid":"<20170919112551.grmbc7sf6d4olyzn@valkosipuli.retiisi.org.uk>","list_archive_url":null,"date":"2017-09-19T11:25:52","subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","submitter":{"id":1593,"url":"http://patchwork.ozlabs.org/api/people/1593/","name":"Sakari Ailus","email":"sakari.ailus@iki.fi"},"content":"Hi Laurent,\n\nOn Tue, Sep 19, 2017 at 02:14:39PM +0300, Laurent Pinchart wrote:\n> Hi Sakari,\n> \n> On Tuesday, 19 September 2017 14:10:37 EEST Sakari Ailus wrote:\n> > On Tue, Sep 19, 2017 at 01:48:27PM +0300, Laurent Pinchart wrote:\n> > > On Friday, 15 September 2017 17:17:00 EEST Sakari Ailus wrote:\n> > >> In V4L2 the practice is to have the KernelDoc documentation in the\n> > >> header and not in .c source code files. This consequently makes the V4L2\n> > >> fwnode function documentation part of the Media documentation build.\n> > >> \n> > >> Also correct the link related function and argument naming in\n> > >> documentation.\n> > >> \n> > >> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> > >> Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>\n> > >> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> > >> Acked-by: Pavel Machek <pavel@ucw.cz>\n> > > \n> > > I'm still very opposed to this. In addition to increasing the risk of\n> > > documentation becoming stale, it also makes review more difficult. I'm\n> > > reviewing patch 05/25 of this series and I have to jump around the patch\n> > > to verify that the documentation matches the implementation, it's really\n> > > annoying.\n> > \n> > I'd like to have this discussion separately from the patchset, which is\n> > right now in its 13th version. This patch simply makes the current state\n> > consistent; V4L2 async was the only part of V4L2 with KernelDoc\n> > documentation in .c files.\n> \n> But there's no need to move the documentation at this point until we reach an \n> agreement, is there ?\n\nThe status quo has is that the KernelDoc is in headers. Generally, if you\nchange parts that appear to lack framework-wide changes already done, you\ndo those changes before making other changes since it's a no-brainer.\n\nWhich is what this patch represents.\n\nIf we end up moving the KernelDoc to .c files moving this back could result\ninto an extra patch. I'm not too worried about that frankly.","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxLCm6JPmz9s7B\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:25:56 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751361AbdISLZz (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:25:55 -0400","from nblzone-211-213.nblnetworks.fi ([83.145.211.213]:59648 \"EHLO\n\thillosipuli.retiisi.org.uk\" rhost-flags-OK-OK-OK-FAIL)\n\tby vger.kernel.org with ESMTP id S1750964AbdISLZy (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 07:25:54 -0400","from valkosipuli.localdomain (valkosipuli.retiisi.org.uk\n\t[IPv6:2001:1bc8:1a6:d3d5::80:2])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby hillosipuli.retiisi.org.uk (Postfix) with ESMTPS id CC7D760101;\n\tTue, 19 Sep 2017 14:25:52 +0300 (EEST)","from sakke by valkosipuli.localdomain with local (Exim 4.89)\n\t(envelope-from <sakke@valkosipuli.retiisi.org.uk>)\n\tid 1duGf2-0005AL-7T; Tue, 19 Sep 2017 14:25:52 +0300"],"Date":"Tue, 19 Sep 2017 14:25:52 +0300","From":"Sakari Ailus <sakari.ailus@iki.fi>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"Sakari Ailus <sakari.ailus@linux.intel.com>,\n\tlinux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, devicetree@vger.kernel.org, pavel@ucw.cz,\n\tsre@kernel.org","Subject":"Re: [PATCH v13 01/25] v4l: fwnode: Move KernelDoc documentation to\n\tthe header","Message-ID":"<20170919112551.grmbc7sf6d4olyzn@valkosipuli.retiisi.org.uk>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<9077921.hsjkiRftLf@avalon>\n\t<20170919111036.5va2unwqh2vymojr@valkosipuli.retiisi.org.uk>\n\t<20634394.E3nNBE0rok@avalon>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20634394.E3nNBE0rok@avalon>","User-Agent":"NeoMutt/20170113 (1.7.2)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770891,"web_url":"http://patchwork.ozlabs.org/comment/1770891/","msgid":"<2463205.SWm3RcFI57@avalon>","list_archive_url":null,"date":"2017-09-19T11:35:01","subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","submitter":{"id":11034,"url":"http://patchwork.ozlabs.org/api/people/11034/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Sakari,\n\nThank you for the patch.\n\nOn Friday, 15 September 2017 17:17:04 EEST Sakari Ailus wrote:\n> Add two functions for parsing devices graph endpoints:\n> v4l2_async_notifier_parse_fwnode_endpoints and\n> v4l2_async_notifier_parse_fwnode_endpoints_by_port. The former iterates\n> over all endpoints whereas the latter only iterates over the endpoints in\n> a given port.\n> \n> The former is mostly useful for existing drivers that currently implement\n> the iteration over all the endpoints themselves whereas the latter is\n> especially intended for devices with both sinks and sources: async\n> sub-devices for external devices connected to the device's sources will\n> have already been set up, or they are part of the master device.\n\nDid you mean s/or they/as they/ ?\n\n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> ---\n>  drivers/media/v4l2-core/v4l2-async.c  |  30 ++++++\n>  drivers/media/v4l2-core/v4l2-fwnode.c | 185 +++++++++++++++++++++++++++++++\n>  include/media/v4l2-async.h            |  24 ++++-\n>  include/media/v4l2-fwnode.h           | 117 +++++++++++++++++++++\n>  4 files changed, 354 insertions(+), 2 deletions(-)\n\n[snip]\n\n> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c\n> b/drivers/media/v4l2-core/v4l2-fwnode.c index 706f9e7b90f1..44ee35f6aad5\n> 100644\n> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n\n[snip]\n\n> +static int v4l2_async_notifier_fwnode_parse_endpoint(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tstruct fwnode_handle *endpoint, unsigned int asd_struct_size,\n> +\tint (*parse_endpoint)(struct device *dev,\n> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n> +\t\t\t    struct v4l2_async_subdev *asd))\n> +{\n> +\tstruct v4l2_async_subdev *asd;\n> +\tstruct v4l2_fwnode_endpoint *vep;\n> +\tint ret = 0;\n> +\n> +\tasd = kzalloc(asd_struct_size, GFP_KERNEL);\n> +\tif (!asd)\n> +\t\treturn -ENOMEM;\n> +\n> +\tasd->match.fwnode.fwnode =\n> +\t\tfwnode_graph_get_remote_port_parent(endpoint);\n> +\tif (!asd->match.fwnode.fwnode) {\n> +\t\tdev_warn(dev, \"bad remote port parent\\n\");\n> +\t\tret = -EINVAL;\n> +\t\tgoto out_err;\n> +\t}\n> +\n> +\t/* Ignore endpoints the parsing of which failed. */\n\nI think this comment is outdated.\n\n> +\tvep = v4l2_fwnode_endpoint_alloc_parse(endpoint);\n> +\tif (IS_ERR(vep)) {\n> +\t\tret = PTR_ERR(vep);\n> +\t\tdev_warn(dev, \"unable to parse V4L2 fwnode endpoint (%d)\\n\",\n> +\t\t\t ret);\n> +\t\tgoto out_err;\n> +\t}\n> +\n> +\tret = parse_endpoint ? parse_endpoint(dev, vep, asd) : 0;\n> +\tif (ret == -ENOTCONN)\n> +\t\tdev_dbg(dev, \"ignoring endpoint %u,%u\\n\", vep->base.port,\n> +\t\t\tvep->base.id);\n\nHow about \"ignoring port@%u/endpoint@%u\\n\" ? It would make the message more \nexplicit.\n\n> +\telse if (ret < 0)\n> +\t\tdev_warn(dev, \"driver could not parse endpoint %u,%u (%d)\\n\",\n\nSame here.\n\n> +\t\t\t vep->base.port, vep->base.id, ret);\n> +\tv4l2_fwnode_endpoint_free(vep);\n> +\tif (ret < 0)\n> +\t\tgoto out_err;\n> +\n> +\tasd->match_type = V4L2_ASYNC_MATCH_FWNODE;\n\nI'd move this line right before setting asd->match.fwnode.fwnode.\n\n> +\tnotifier->subdevs[notifier->num_subdevs] = asd;\n> +\tnotifier->num_subdevs++;\n> +\n> +\treturn 0;\n> +\n> +out_err:\n> +\tfwnode_handle_put(asd->match.fwnode.fwnode);\n> +\tkfree(asd);\n> +\n> +\treturn ret == -ENOTCONN ? 0 : ret;\n> +}\n> +\n> +static int __v4l2_async_notifier_parse_fwnode_endpoints(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tsize_t asd_struct_size, unsigned int port, bool has_port,\n> +\tint (*parse_endpoint)(struct device *dev,\n> +\t\t\t    struct v4l2_fwnode_endpoint *vep,\n> +\t\t\t    struct v4l2_async_subdev *asd))\n> +{\n> +\tstruct fwnode_handle *fwnode = NULL;\n> +\tunsigned int max_subdevs = notifier->max_subdevs;\n> +\tint ret;\n> +\n> +\tif (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev)))\n> +\t\treturn -EINVAL;\n> +\n> +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n> +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n> +\t\tif (!fwnode_device_is_available(\n> +\t\t\t    fwnode_graph_get_port_parent(fwnode)))\n\nDoesn't fwnode_graph_get_port_parent() increment the refcount on the parent, \nwhich you should then release ?\n\n> +\t\t\tcontinue;\n> +\n> +\t\tif (has_port) {\n> +\t\t\tstruct fwnode_endpoint ep;\n> +\n> +\t\t\tret = fwnode_graph_parse_endpoint(fwnode, &ep);\n> +\t\t\tif (ret) {\n> +\t\t\t\tfwnode_handle_put(fwnode);\n> +\t\t\t\treturn ret;\n> +\t\t\t}\n> +\n> +\t\t\tif (ep.port != port)\n> +\t\t\t\tcontinue;\n> +\t\t}\n> +\t\tmax_subdevs++;\n> +\t}\n> +\n> +\t/* No subdevs to add? Return here. */\n> +\tif (max_subdevs == notifier->max_subdevs)\n> +\t\treturn 0;\n> +\n> +\tret = v4l2_async_notifier_realloc(notifier, max_subdevs);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tfor (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(\n> +\t\t\t\t     dev_fwnode(dev), fwnode)); ) {\n> +\t\tif (!fwnode_device_is_available(\n> +\t\t\t    fwnode_graph_get_port_parent(fwnode)))\n\nSame here.\n\n> +\t\t\tcontinue;\n> +\n> +\t\tif (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {\n> +\t\t\tret = -EINVAL;\n> +\t\t\tbreak;\n> +\t\t}\n> +\n> +\t\tif (has_port) {\n> +\t\t\tstruct fwnode_endpoint ep;\n> +\n> +\t\t\tret = fwnode_graph_parse_endpoint(fwnode, &ep);\n> +\t\t\tif (ret)\n> +\t\t\t\tbreak;\n> +\n> +\t\t\tif (ep.port != port)\n> +\t\t\t\tcontinue;\n> +\t\t}\n> +\n> +\t\tret = v4l2_async_notifier_fwnode_parse_endpoint(\n> +\t\t\tdev, notifier, fwnode, asd_struct_size, parse_endpoint);\n> +\t\tif (ret < 0)\n> +\t\t\tbreak;\n> +\t}\n> +\n> +\tfwnode_handle_put(fwnode);\n> +\n> +\treturn ret;\n> +}\n\n[snip]\n\n> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h\n> index c69d8c8a66d0..96fa1afc00dd 100644\n> --- a/include/media/v4l2-async.h\n> +++ b/include/media/v4l2-async.h\n> @@ -18,7 +18,6 @@ struct device;\n>  struct device_node;\n>  struct v4l2_device;\n>  struct v4l2_subdev;\n> -struct v4l2_async_notifier;\n> \n>  /* A random max subdevice number, used to allocate an array on stack */\n>  #define V4L2_MAX_SUBDEVS 128U\n> @@ -50,6 +49,10 @@ enum v4l2_async_match_type {\n>   * @match:\tunion of per-bus type matching data sets\n>   * @list:\tused to link struct v4l2_async_subdev objects, waiting to be\n>   *\t\tprobed, to a notifier->waiting list\n> + *\n> + * When this struct is used as a member in a driver specific struct,\n> + * the driver specific struct shall contain the @struct\n> + * v4l2_async_subdev as its first member.\n\nUnless I'm mistaken @ is used to refer to function arguments (sphinx typesets \nit using <strong> in HTML). References to structures can be created with &. \nHave you compiled the documentation ? :-)\n\n>   */\n>  struct v4l2_async_subdev {\n>  \tenum v4l2_async_match_type match_type;\n> @@ -78,7 +81,8 @@ struct v4l2_async_subdev {\n>  /**\n>   * struct v4l2_async_notifier - v4l2_device notifier data\n>   *\n> - * @num_subdevs: number of subdevices\n> + * @num_subdevs: number of subdevices used in the subdevs array\n> + * @max_subdevs: number of subdevices allocated in the subdevs array\n>   * @subdevs:\tarray of pointers to subdevice descriptors\n>   * @v4l2_dev:\tpointer to struct v4l2_device\n>   * @waiting:\tlist of struct v4l2_async_subdev, waiting for their drivers\n> @@ -90,6 +94,7 @@ struct v4l2_async_subdev {\n>   */\n>  struct v4l2_async_notifier {\n>  \tunsigned int num_subdevs;\n> +\tunsigned int max_subdevs;\n>  \tstruct v4l2_async_subdev **subdevs;\n>  \tstruct v4l2_device *v4l2_dev;\n>  \tstruct list_head waiting;\n> @@ -121,6 +126,21 @@ int v4l2_async_notifier_register(struct v4l2_device\n> *v4l2_dev, void v4l2_async_notifier_unregister(struct v4l2_async_notifier\n> *notifier);\n> \n>  /**\n> + * v4l2_async_notifier_release - release notifier resources\n> + * @notifier: the notifier the resources of which are to be released\n> + *\n> + * Release memory resources related to a notifier, including the async\n> + * sub-devices allocated for the purposes of the notifier. The user is\n> + * responsible for releasing the notifier's resources after calling\n> + * @v4l2_async_notifier_parse_fwnode_endpoints.\n\nDon't use @. If you want sphinx to generate a link, just append () after the \nfunction name.\n\n> + *\n> + * There is no harm from calling v4l2_async_notifier_release in other\n\nHere too.\n\n> + * cases as long as its memory has been zeroed after it has been\n> + * allocated.\n\nAs the function WARNs for types other than V4L2_ASYNC_MATCH_FWNODE you might \nwant to mention that in the documentation.\n\n> + */\n> +void v4l2_async_notifier_release(struct v4l2_async_notifier *notifier);\n> +\n> +/**\n>   * v4l2_async_register_subdev - registers a sub-device to the asynchronous\n>   * \tsubdevice framework\n>   *\n> diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h\n> index 68eb22ba571b..83afac48ea6b 100644\n> --- a/include/media/v4l2-fwnode.h\n> +++ b/include/media/v4l2-fwnode.h\n> @@ -25,6 +25,8 @@\n>  #include <media/v4l2-mediabus.h>\n> \n>  struct fwnode_handle;\n> +struct v4l2_async_notifier;\n> +struct v4l2_async_subdev;\n> \n>  #define V4L2_FWNODE_CSI2_MAX_DATA_LANES\t4\n> \n> @@ -201,4 +203,119 @@ int v4l2_fwnode_parse_link(struct fwnode_handle\n> *fwnode, */\n>  void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);\n> \n> +/**\n> + * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints\n> in a\n> + *\t\t\t\t\t\tdevice node\n> + * @dev: the device the endpoints of which are to be parsed\n> + * @notifier: notifier for @dev\n> + * @asd_struct_size: size of the driver's async sub-device struct,\n> including\n> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> + *\t\t     v4l2_async_subdev shall be the first member of\n> + *\t\t     the driver's async sub-device struct, i.e. both\n> + *\t\t     begin at the same memory address.\n> + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n> + *\t\t    endpoint. Optional.\n> + *\t\t    Return: %0 on success\n> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> + *\t\t\t\t       should not be considered as an error\n> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> + *\n> + * Parse the fwnode endpoints of the @dev device and populate the async\n> sub-\n> + * devices array of the notifier. The @parse_endpoint callback function is\n> + * called for each endpoint with the corresponding async sub-device pointer\n> to\n> + * let the caller initialize the driver-specific part of the async sub-\n> device\n> + * structure.\n> + *\n> + * The notifier memory shall be zeroed before this function is called on\n> the\n> + * notifier.\n> + *\n> + * This function may not be called on a registered notifier and may be\n> called on\n> + * a notifier only once.\n> + *\n> + * Do not change the notifier's subdevs array, take references to the\n> subdevs\n> + * array itself or change the notifier's num_subdevs field. This is because\n> this\n> + * function allocates and reallocates the subdevs array based on parsing\n> + * endpoints.\n> + *\n> + * The @struct v4l2_fwnode_endpoint passed to the callback function\n> + * @parse_endpoint is released once the function is finished. If there is a\n> need\n> + * to retain that configuration, the user needs to allocate memory for it.\n> + *\n> + * Any notifier populated using this function must be released with a call\n> to\n> + * v4l2_async_notifier_release() after it has been unregistered and the\n> async\n> + * sub-devices are no longer in use, even if the function returned an\n> error.\n> + *\n> + * Return: %0 on success, including when no async sub-devices are found\n> + *\t   %-ENOMEM if memory allocation failed\n> + *\t   %-EINVAL if graph or endpoint parsing failed\n> + *\t   Other error codes as returned by @parse_endpoint\n> + */\n> +int v4l2_async_notifier_parse_fwnode_endpoints(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tsize_t asd_struct_size,\n> +\tint (*parse_endpoint)(struct device *dev,\n> +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n> +\t\t\t      struct v4l2_async_subdev *asd));\n> +\n> +/**\n> + * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode\n> + *\t\t\t\t\t\t\tendpoints of a port in a\n> + *\t\t\t\t\t\t\tdevice node\n\nThis clearly shows that the function name is getting a bit long :-)\n\n> + * @dev: the device the endpoints of which are to be parsed\n> + * @notifier: notifier for @dev\n> + * @asd_struct_size: size of the driver's async sub-device struct,\n> including\n> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> + *\t\t     v4l2_async_subdev shall be the first member of\n> + *\t\t     the driver's async sub-device struct, i.e. both\n> + *\t\t     begin at the same memory address.\n> + * @port: port number where endpoints are to be parsed\n> + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode\n> + *\t\t    endpoint. Optional.\n> + *\t\t    Return: %0 on success\n> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> + *\t\t\t\t       should not be considered as an error\n> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> + *\n> + * This function is just like @v4l2_async_notifier_parse_fwnode_endpoints\n> with\n> + * the exception that it only parses endpoints in a given port. This is\n> useful\n> + * on devices that have both sinks and sources: the async sub-devices\n> connected\n> + * to sources have already been set up by another driver (on capture\n> devices).\n> + *\n> + * Parse the fwnode endpoints of the @dev device on a given @port and\n> populate\n> + * the async sub-devices array of the notifier. The @parse_endpoint\n> callback\n> + * function is called for each endpoint with the corresponding async sub-\n> device\n> + * pointer to let the caller initialize the driver-specific part of the\n> async\n> + * sub-device structure.\n> + *\n> + * The notifier memory shall be zeroed before this function is called on\n> the\n> + * notifier the first time.\n> + *\n> + * This function may not be called on a registered notifier and may be\n> called on\n> + * a notifier only once per port.\n> + *\n> + * Do not change the notifier's subdevs array, take references to the\n> subdevs\n> + * array itself or change the notifier's num_subdevs field. This is because\n> this\n> + * function allocates and reallocates the subdevs array based on parsing\n> + * endpoints.\n> + *\n> + * The @struct v4l2_fwnode_endpoint passed to the callback function\n> + * @parse_endpoint is released once the function is finished. If there is a\n> need\n> + * to retain that configuration, the user needs to allocate memory for it.\n> + *\n> + * Any notifier populated using this function must be released with a call\n> to\n> + * v4l2_async_notifier_release() after it has been unregistered and the\n> async\n> + * sub-devices are no longer in use, even if the function returned an\n> error.\n> + *\n> + * Return: %0 on success, including when no async sub-devices are found\n> + *\t   %-ENOMEM if memory allocation failed\n> + *\t   %-EINVAL if graph or endpoint parsing failed\n> + *\t   Other error codes as returned by @parse_endpoint\n> + */\n> +int v4l2_async_notifier_parse_fwnode_endpoints_by_port(\n> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> +\tsize_t asd_struct_size, unsigned int port,\n> +\tint (*parse_endpoint)(struct device *dev,\n> +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n> +\t\t\t      struct v4l2_async_subdev *asd));\n> +\n>  #endif /* _V4L2_FWNODE_H */","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"To/ewxne\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxLQD17z3z9s7m\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:35:00 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751408AbdISLe6 (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:34:58 -0400","from galahad.ideasonboard.com ([185.26.127.97]:37814 \"EHLO\n\tgalahad.ideasonboard.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751205AbdISLe5 (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 07:34:57 -0400","from avalon.localnet (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby galahad.ideasonboard.com (Postfix) with ESMTPSA id 76FBC200AD;\n\tTue, 19 Sep 2017 13:32:20 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1505820740;\n\tbh=e5qRv9DuCmpqaTfcf3r8jL8K2VlQYlI3dZEE3q4cJJg=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=To/ewxneh/P8gVxL+eWnzTDxsBVUQiQpQ09Qv1VmSoh7CXywA0lSIJEYrzg3eAaL3\n\tUQ6ibhGkA0thilJItc++uJljbEHLLsYexZADyd0SK5F4s2vNOWl+hJjZjNuWUhv6Zt\n\tMNUB2owAcn5iKP0YwU3IAfMFdzLw/DZ2/giXBmYI=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, devicetree@vger.kernel.org, pavel@ucw.cz,\n\tsre@kernel.org","Subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","Date":"Tue, 19 Sep 2017 14:35:01 +0300","Message-ID":"<2463205.SWm3RcFI57@avalon>","In-Reply-To":"<20170915141724.23124-6-sakari.ailus@linux.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-6-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"7Bit","Content-Type":"text/plain; charset=\"us-ascii\"","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770892,"web_url":"http://patchwork.ozlabs.org/comment/1770892/","msgid":"<20170919113754.k4ff6un5pw3nk2sa@paasikivi.fi.intel.com>","list_archive_url":null,"date":"2017-09-19T11:37:55","subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","submitter":{"id":65485,"url":"http://patchwork.ozlabs.org/api/people/65485/","name":"Sakari Ailus","email":"sakari.ailus@linux.intel.com"},"content":"Hi Laurent,\n\nOn Tue, Sep 19, 2017 at 12:30:34PM +0300, Laurent Pinchart wrote:\n> Hi Hans,\n> \n> On Tuesday, 19 September 2017 11:40:14 EEST Hans Verkuil wrote:\n> > On 09/19/2017 10:20 AM, Sakari Ailus wrote:\n> > > On Tue, Sep 19, 2017 at 10:03:27AM +0200, Hans Verkuil wrote:\n> > >> On 09/15/2017 04:17 PM, Sakari Ailus wrote:\n> > >>> Add two functions for parsing devices graph endpoints:\n> > >>> v4l2_async_notifier_parse_fwnode_endpoints and\n> > >>> v4l2_async_notifier_parse_fwnode_endpoints_by_port. The former iterates\n> > >>> over all endpoints whereas the latter only iterates over the endpoints\n> > >>> in a given port.\n> > >>> \n> > >>> The former is mostly useful for existing drivers that currently\n> > >>> implement the iteration over all the endpoints themselves whereas the\n> > >>> latter is especially intended for devices with both sinks and sources:\n> > >>> async sub-devices for external devices connected to the device's sources\n> > >>> will have already been set up, or they are part of the master device.\n> > >>> \n> > >>> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> > >>> ---\n> > >>> \n> > >>>  drivers/media/v4l2-core/v4l2-async.c  |  30 ++++++\n> > >>>  drivers/media/v4l2-core/v4l2-fwnode.c | 185 +++++++++++++++++++++++++++\n> > >>>  include/media/v4l2-async.h            |  24 ++++-\n> > >>>  include/media/v4l2-fwnode.h           | 117 +++++++++++++++++++++\n> > >>>  4 files changed, 354 insertions(+), 2 deletions(-)\n> \n> [snip]\n> \n> > >>> diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h\n> > >>> index 68eb22ba571b..83afac48ea6b 100644\n> > >>> --- a/include/media/v4l2-fwnode.h\n> > >>> +++ b/include/media/v4l2-fwnode.h\n> > >>> @@ -25,6 +25,8 @@\n> > >>> \n> > >>>  #include <media/v4l2-mediabus.h>\n> > >>>  \n> > >>>  struct fwnode_handle;\n> > >>> +struct v4l2_async_notifier;\n> > >>> +struct v4l2_async_subdev;\n> > >>> \n> > >>>  #define V4L2_FWNODE_CSI2_MAX_DATA_LANES\t4\n> > >>> \n> > >>> @@ -201,4 +203,119 @@ int v4l2_fwnode_parse_link(struct fwnode_handle\n> > >>> *fwnode,\n> > >>>   */\n> > >>>  void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);\n> > >>> \n> > >>> +/**\n> > >>> + * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode\n> > >>> endpoints in a\n> > >>> + *\t\t\t\t\t\tdevice node\n> > >>> + * @dev: the device the endpoints of which are to be parsed\n> > >>> + * @notifier: notifier for @dev\n> > >>> + * @asd_struct_size: size of the driver's async sub-device struct,\n> > >>> including\n> > >>> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> > >>> + *\t\t     v4l2_async_subdev shall be the first member of\n> > >>> + *\t\t     the driver's async sub-device struct, i.e. both\n> > >>> + *\t\t     begin at the same memory address.\n> > >>> + * @parse_endpoint: Driver's callback function called on each V4L2\n> > >>> fwnode\n> > >>> + *\t\t    endpoint. Optional.\n> > >>> + *\t\t    Return: %0 on success\n> > >>> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> > >>> + *\t\t\t\t       should not be considered as an error\n> > >>> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> > >>> + *\n> > >>> + * Parse the fwnode endpoints of the @dev device and populate the async\n> > >>> sub-\n> > >>> + * devices array of the notifier. The @parse_endpoint callback function\n> > >>> is\n> > >>> + * called for each endpoint with the corresponding async sub-device\n> > >>> pointer to\n> > >>> + * let the caller initialize the driver-specific part of the async sub-\n> > >>> device\n> > >>> + * structure.\n> > >>> + *\n> > >>> + * The notifier memory shall be zeroed before this function is called\n> > >>> on the\n> > >>> + * notifier.\n> > >>> + *\n> > >>> + * This function may not be called on a registered notifier and may be\n> > >>> called on\n> > >>> + * a notifier only once.\n> > >>> + *\n> > >>> + * Do not change the notifier's subdevs array, take references to the\n> > >>> subdevs\n> > >>> + * array itself or change the notifier's num_subdevs field. This is\n> > >>> because this\n> > >>> + * function allocates and reallocates the subdevs array based on\n> > >>> parsing\n> > >>> + * endpoints.\n> > >>> + *\n> > >>> + * The @struct v4l2_fwnode_endpoint passed to the callback function\n> > >>> + * @parse_endpoint is released once the function is finished. If there\n> > >>> is a need\n> > >>> + * to retain that configuration, the user needs to allocate memory for\n> > >>> it.\n> > >>> + *\n> > >>> + * Any notifier populated using this function must be released with a\n> > >>> call to\n> > >>> + * v4l2_async_notifier_release() after it has been unregistered and the\n> > >>> async\n> > >>> + * sub-devices are no longer in use, even if the function returned an\n> > >>> error.\n> > >>> + *\n> > >>> + * Return: %0 on success, including when no async sub-devices are found\n> > >>> + *\t   %-ENOMEM if memory allocation failed\n> > >>> + *\t   %-EINVAL if graph or endpoint parsing failed\n> > >>> + *\t   Other error codes as returned by @parse_endpoint\n> > >>> + */\n> > >>> +int v4l2_async_notifier_parse_fwnode_endpoints(\n> > >>> +\tstruct device *dev, struct v4l2_async_notifier *notifier,\n> > >>> +\tsize_t asd_struct_size,\n> > >>> +\tint (*parse_endpoint)(struct device *dev,\n> > >>> +\t\t\t      struct v4l2_fwnode_endpoint *vep,\n> > >>> +\t\t\t      struct v4l2_async_subdev *asd));\n> > >>> +\n> > >>> +/**\n> > >>> + * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2\n> > >>> fwnode\n> > >>> + *\t\t\t\t\t\t\tendpoints of a port in a\n> > >>> + *\t\t\t\t\t\t\tdevice node\n> > >>> + * @dev: the device the endpoints of which are to be parsed\n> > >>> + * @notifier: notifier for @dev\n> > >>> + * @asd_struct_size: size of the driver's async sub-device struct,\n> > >>> including\n> > >>> + *\t\t     sizeof(struct v4l2_async_subdev). The &struct\n> > >>> + *\t\t     v4l2_async_subdev shall be the first member of\n> > >>> + *\t\t     the driver's async sub-device struct, i.e. both\n> > >>> + *\t\t     begin at the same memory address.\n> > >>> + * @port: port number where endpoints are to be parsed\n> > >>> + * @parse_endpoint: Driver's callback function called on each V4L2\n> > >>> fwnode\n> > >>> + *\t\t    endpoint. Optional.\n> > >>> + *\t\t    Return: %0 on success\n> > >>> + *\t\t\t    %-ENOTCONN if the endpoint is to be skipped but this\n> > >>> + *\t\t\t\t       should not be considered as an error\n> > >>> + *\t\t\t    %-EINVAL if the endpoint configuration is invalid\n> > >>> + *\n> > >>> + * This function is just like\n> > >>> @v4l2_async_notifier_parse_fwnode_endpoints with \n> > >>> + * the exception that it only parses endpoints in a given port. This is\n> > >>> useful\n> > >>> + * on devices that have both sinks and sources: the async sub-devices\n> > >>> connected\n> > >> \n> > >> on -> for\n> > >> \n> > >>> + * to sources have already been set up by another driver (on capture\n> > >>> devices).\n> > >> \n> > >> on -> for\n> > > \n> > > Agreed on both.\n> > > \n> > >> So if I understand this correctly for devices with both sinks and sources\n> > >> you use this function to just parse the sink ports. And you have to give\n> > >> explicit port numbers since you can't tell from parsing the device tree\n> > >> if a port is a sink or source port, right? Only the driver knows this.\n> > > \n> > > Correct. The graph data structure in DT isn't directed, so this is only\n> > > known by the driver.\n> > \n> > I think this should be clarified.\n> > \n> > I wonder if there is any way around it. I don't have time to dig into this,\n> > but isn't it possible to tell that the source ports are already configured?\n> \n> Please also note that it's not always source ports, it depends in which \n> direction we want to traverse the graph. The usual way is from master to \n> slave, so from source to sink for capture devices but from sink to source for \n> output devices.\n> \n> It's a bit of a mess, and this is part of the reason why I don't think sub-\n> notifiers are the best idea. It would be better in my opinion to maintain a \n> single list of async matches, which would be gradually enriched by subdevices \n> as they are probed. This would help detecting and handling duplicates.\n\nWell, there are indeed corner cases looming ahead where a driver might not\nhave enough information on what to parse and what not to. What I'd still do\nis to proceed with what likely addresses more than 95 % of the cases\nimaginable, and all we have today.\n\nIn the future setting up async sub-devices and parsing endpoints need to be\nseparated. With that, drivers won't need to know anymore which ports to\nparse and which ones not. Creating links to the newly V4L2 async registered\nsub-devices could be added to this. This will be more complicated than just\nexpressing an idea though. :-)","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxLTj4fnMz9s7g\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:38:01 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751408AbdISLiA (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:38:00 -0400","from mga09.intel.com ([134.134.136.24]:1635 \"EHLO mga09.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1751237AbdISLiA (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tTue, 19 Sep 2017 07:38:00 -0400","from orsmga003.jf.intel.com ([10.7.209.27])\n\tby orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t19 Sep 2017 04:37:59 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby orsmga003.jf.intel.com with ESMTP; 19 Sep 2017 04:37:55 -0700","by paasikivi.fi.intel.com (Postfix, from userid 1000)\n\tid 1EBCD20642; Tue, 19 Sep 2017 14:37:55 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos; i=\"5.42,418,1500966000\"; d=\"scan'208\";\n\ta=\"1016096996\"","Date":"Tue, 19 Sep 2017 14:37:55 +0300","From":"Sakari Ailus <sakari.ailus@linux.intel.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"Hans Verkuil <hverkuil@xs4all.nl>, linux-media@vger.kernel.org,\n\tniklas.soderlund@ragnatech.se, maxime.ripard@free-electrons.com,\n\trobh@kernel.org, devicetree@vger.kernel.org, pavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v13 05/25] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","Message-ID":"<20170919113754.k4ff6un5pw3nk2sa@paasikivi.fi.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170919082015.vt6olgirnvmpcrpa@paasikivi.fi.intel.com>\n\t<af99e12c-6fb8-a633-eec2-c1eb9d82226a@xs4all.nl>\n\t<2061043.HYj1Sta8zM@avalon>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<2061043.HYj1Sta8zM@avalon>","User-Agent":"NeoMutt/20170113 (1.7.2)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770893,"web_url":"http://patchwork.ozlabs.org/comment/1770893/","msgid":"<1555926.RTv2yyCEgl@avalon>","list_archive_url":null,"date":"2017-09-19T11:40:29","subject":"Re: [PATCH v13 06/25] omap3isp: Use generic parser for parsing\n\tfwnode endpoints","submitter":{"id":11034,"url":"http://patchwork.ozlabs.org/api/people/11034/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Sakari,\n\nThank you for the patch.\n\nOn Friday, 15 September 2017 17:17:05 EEST Sakari Ailus wrote:\n> Instead of using driver implementation, use\n\nDid you mean s/using driver implementation/using a driver implementation/ (or \nperhaps \"custom driver implementation\") ?\n\n> v4l2_async_notifier_parse_fwnode_endpoints() to parse the fwnode endpoints\n> of the device.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> ---\n>  drivers/media/platform/omap3isp/isp.c | 115 ++++++++++---------------------\n>  drivers/media/platform/omap3isp/isp.h |   5 +-\n>  2 files changed, 37 insertions(+), 83 deletions(-)\n> \n> diff --git a/drivers/media/platform/omap3isp/isp.c\n> b/drivers/media/platform/omap3isp/isp.c index 1a428fe9f070..a546cf774d40\n> 100644\n> --- a/drivers/media/platform/omap3isp/isp.c\n> +++ b/drivers/media/platform/omap3isp/isp.c\n\n[snip]\n\n> @@ -2256,7 +2210,9 @@ static int isp_probe(struct platform_device *pdev)\n>  \tif (ret)\n>  \t\treturn ret;\n> \n> -\tret = isp_fwnodes_parse(&pdev->dev, &isp->notifier);\n> +\tret = v4l2_async_notifier_parse_fwnode_endpoints(\n> +\t\t&pdev->dev, &isp->notifier, sizeof(struct isp_async_subdev),\n> +\t\tisp_fwnode_parse);\n>  \tif (ret < 0)\n\nThe documentation in patch 05/25 states that v4l2_async_notifier_release() \nshould be called even if v4l2_async_notifier_parse_fwnode_endpoints() fails. I \ndon't think that's needed here, so you might want to update the documentation \n(and possibly the implementation of the function).\n\nApart from that,\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n>  \t\treturn ret;\n> \n> @@ -2407,6 +2363,7 @@ static int isp_probe(struct platform_device *pdev)\n>  \t__omap3isp_put(isp, false);\n>  error:\n>  \tmutex_destroy(&isp->isp_mutex);\n> +\tv4l2_async_notifier_release(&isp->notifier);\n> \n>  \treturn ret;\n>  }\n\n[snip]","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"JvELCOQM\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxLXW1zvNz9s7m\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:40:27 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751594AbdISLkZ (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:40:25 -0400","from galahad.ideasonboard.com ([185.26.127.97]:37857 \"EHLO\n\tgalahad.ideasonboard.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751476AbdISLkZ (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 07:40:25 -0400","from avalon.localnet (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby galahad.ideasonboard.com (Postfix) with ESMTPSA id 1A98A200AD;\n\tTue, 19 Sep 2017 13:37:48 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1505821068;\n\tbh=okZnjP0Oe3BlnIsmgaZ1F4G76cqpagHQZVG9Xt8LteE=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=JvELCOQMjxRpPL+GDc/xDkWeU45l9tjE7EKZKEvSM+FdIFnuJuvizPoes/Jsmqhwq\n\twb0LuFVkOfE40aLjfEFR4QHx5PsqY/JGZ+VLDR/PaVNZlic+6RL32xqEHX3erTiNIU\n\tes0fFXRHX/ePCMls+qh+UWNopcYQkf++UUJ1jI5A=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, devicetree@vger.kernel.org, pavel@ucw.cz,\n\tsre@kernel.org","Subject":"Re: [PATCH v13 06/25] omap3isp: Use generic parser for parsing\n\tfwnode endpoints","Date":"Tue, 19 Sep 2017 14:40:29 +0300","Message-ID":"<1555926.RTv2yyCEgl@avalon>","In-Reply-To":"<20170915141724.23124-7-sakari.ailus@linux.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-7-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"7Bit","Content-Type":"text/plain; charset=\"us-ascii\"","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770899,"web_url":"http://patchwork.ozlabs.org/comment/1770899/","msgid":"<3549838.F21OCYHXEu@avalon>","list_archive_url":null,"date":"2017-09-19T11:53:16","subject":"Re: [PATCH v13 07/25] rcar-vin: Use generic parser for parsing\n\tfwnode endpoints","submitter":{"id":11034,"url":"http://patchwork.ozlabs.org/api/people/11034/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Sakari,\n\nThank you for the patch.\n\nOn Friday, 15 September 2017 17:17:06 EEST Sakari Ailus wrote:\n> Instead of using driver implementation, use\n\nSame comment as for patch 06/25.\n\n> v4l2_async_notifier_parse_fwnode_endpoints() to parse the fwnode endpoints\n> of the device.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> ---\n>  drivers/media/platform/rcar-vin/rcar-core.c | 112 ++++++++-----------------\n>  drivers/media/platform/rcar-vin/rcar-dma.c  |  10 +--\n>  drivers/media/platform/rcar-vin/rcar-v4l2.c |  14 ++--\n>  drivers/media/platform/rcar-vin/rcar-vin.h  |   4 +-\n>  4 files changed, 48 insertions(+), 92 deletions(-)\n> \n> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c\n> b/drivers/media/platform/rcar-vin/rcar-core.c index\n> 142de447aaaa..62b4a94f9a39 100644\n> --- a/drivers/media/platform/rcar-vin/rcar-core.c\n> +++ b/drivers/media/platform/rcar-vin/rcar-core.c\n\n[snip]\n\n> @@ -120,117 +121,70 @@ static int rvin_digital_notify_bound(struct\n\n[snip]\n\n> -static int rvin_digitial_parse_v4l2(struct rvin_dev *vin,\n> -\t\t\t\t    struct device_node *ep,\n> -\t\t\t\t    struct v4l2_mbus_config *mbus_cfg)\n> +static int rvin_digital_parse_v4l2(struct device *dev,\n> +\t\t\t\t   struct v4l2_fwnode_endpoint *vep,\n> +\t\t\t\t   struct v4l2_async_subdev *asd)\n>  {\n> -\tstruct v4l2_fwnode_endpoint v4l2_ep;\n> -\tint ret;\n> +\tstruct rvin_dev *vin = dev_get_drvdata(dev);\n\nDoesn't this show that we miss a context argument to the callback function ? \nStoring the context in device driver data is probably OK if the driver parsing \nthe endpoints controls the struct device, but is that always the case ?\n\n> +\tstruct rvin_graph_entity *rvge =\n> +\t\tcontainer_of(asd, struct rvin_graph_entity, asd);\n> \n> -\tret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &v4l2_ep);\n> -\tif (ret) {\n> -\t\tvin_err(vin, \"Could not parse v4l2 endpoint\\n\");\n> -\t\treturn -EINVAL;\n> -\t}\n> +\tif (vep->base.port || vep->base.id)\n> +\t\treturn -ENOTCONN;\n> \n> -\tmbus_cfg->type = v4l2_ep.bus_type;\n> +\trvge->mbus_cfg.type = vep->bus_type;\n> \n> -\tswitch (mbus_cfg->type) {\n> +\tswitch (rvge->mbus_cfg.type) {\n>  \tcase V4L2_MBUS_PARALLEL:\n>  \t\tvin_dbg(vin, \"Found PARALLEL media bus\\n\");\n> -\t\tmbus_cfg->flags = v4l2_ep.bus.parallel.flags;\n> +\t\trvge->mbus_cfg.flags = vep->bus.parallel.flags;\n>  \t\tbreak;\n>  \tcase V4L2_MBUS_BT656:\n>  \t\tvin_dbg(vin, \"Found BT656 media bus\\n\");\n> -\t\tmbus_cfg->flags = 0;\n> +\t\trvge->mbus_cfg.flags = 0;\n>  \t\tbreak;\n>  \tdefault:\n>  \t\tvin_err(vin, \"Unknown media bus type\\n\");\n>  \t\treturn -EINVAL;\n>  \t}\n> \n> -\treturn 0;\n> -}\n> -\n> -static int rvin_digital_graph_parse(struct rvin_dev *vin)\n> -{\n> -\tstruct device_node *ep, *np;\n> -\tint ret;\n> -\n> -\tvin->digital.asd.match.fwnode.fwnode = NULL;\n> -\tvin->digital.subdev = NULL;\n> -\n> -\t/*\n> -\t * Port 0 id 0 is local digital input, try to get it.\n> -\t * Not all instances can or will have this, that is OK\n> -\t */\n> -\tep = of_graph_get_endpoint_by_regs(vin->dev->of_node, 0, 0);\n> -\tif (!ep)\n> -\t\treturn 0;\n> -\n> -\tnp = of_graph_get_remote_port_parent(ep);\n> -\tif (!np) {\n> -\t\tvin_err(vin, \"No remote parent for digital input\\n\");\n> -\t\tof_node_put(ep);\n> -\t\treturn -EINVAL;\n> -\t}\n> -\tof_node_put(np);\n> -\n> -\tret = rvin_digitial_parse_v4l2(vin, ep, &vin->digital.mbus_cfg);\n> -\tof_node_put(ep);\n> -\tif (ret)\n> -\t\treturn ret;\n> -\n> -\tvin->digital.asd.match.fwnode.fwnode = of_fwnode_handle(np);\n> -\tvin->digital.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;\n> +\tvin->digital = rvge;\n> \n>  \treturn 0;\n>  }\n> \n>  static int rvin_digital_graph_init(struct rvin_dev *vin)\n>  {\n> -\tstruct v4l2_async_subdev **subdevs = NULL;\n>  \tint ret;\n> \n> -\tret = rvin_digital_graph_parse(vin);\n> +\tret = v4l2_async_notifier_parse_fwnode_endpoints(\n> +\t\tvin->dev, &vin->notifier,\n> +\t\tsizeof(struct rvin_graph_entity), rvin_digital_parse_v4l2);\n>  \tif (ret)\n>  \t\treturn ret;\n> \n> -\tif (!vin->digital.asd.match.fwnode.fwnode) {\n> -\t\tvin_dbg(vin, \"No digital subdevice found\\n\");\n> -\t\treturn -ENODEV;\n> -\t}\n> -\n> -\t/* Register the subdevices notifier. */\n> -\tsubdevs = devm_kzalloc(vin->dev, sizeof(*subdevs), GFP_KERNEL);\n> -\tif (subdevs == NULL)\n> -\t\treturn -ENOMEM;\n> -\n> -\tsubdevs[0] = &vin->digital.asd;\n> -\n> -\tvin_dbg(vin, \"Found digital subdevice %pOF\\n\",\n> -\t\tto_of_node(subdevs[0]->match.fwnode.fwnode));\n> +\tif (vin->digital)\n> +\t\tvin_dbg(vin, \"Found digital subdevice %pOF\\n\",\n> +\t\t\tto_of_node(\n> +\t\t\t\tvin->digital->asd.match.fwnode.fwnode));\n\nIsn't this is a change in behaviour ? The driver currently returns -ENODEV \nwhen no digital subdev is found.\n\n> -\tvin->notifier.num_subdevs = 1;\n> -\tvin->notifier.subdevs = subdevs;\n>  \tvin->notifier.bound = rvin_digital_notify_bound;\n>  \tvin->notifier.unbind = rvin_digital_notify_unbind;\n>  \tvin->notifier.complete = rvin_digital_notify_complete;\n> -\n>  \tret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);\n>  \tif (ret < 0) {\n>  \t\tvin_err(vin, \"Notifier registration failed\\n\");\n\n\n[snip]","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"dlZ0eAhT\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxLqG4yR2z9sBZ\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:53:14 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751726AbdISLxN (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:53:13 -0400","from galahad.ideasonboard.com ([185.26.127.97]:37924 \"EHLO\n\tgalahad.ideasonboard.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751378AbdISLxM (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 07:53:12 -0400","from avalon.localnet (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby galahad.ideasonboard.com (Postfix) with ESMTPSA id 2E96A200AD;\n\tTue, 19 Sep 2017 13:50:35 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1505821835;\n\tbh=sL+KIoxvU+OOPpmtJpZJ4RxDtbsJdO4P71UilZIgw9w=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=dlZ0eAhT2Xk/+O2lHVANKPSTpuNyUQiuRX9gxGq4fjZT6bVoN0Bp3xSFxj1POZvqs\n\tCUj0pTW8aEHmyezobrOdj9F8yrDcTxzMFghaGMKBAOgKQod+TNPpzuJQBjAU3r8Ed0\n\tY+Gjf6mHqGI9Fy+11z4b3w4huF38Rv4pta/5YS00=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, devicetree@vger.kernel.org, pavel@ucw.cz,\n\tsre@kernel.org","Subject":"Re: [PATCH v13 07/25] rcar-vin: Use generic parser for parsing\n\tfwnode endpoints","Date":"Tue, 19 Sep 2017 14:53:16 +0300","Message-ID":"<3549838.F21OCYHXEu@avalon>","In-Reply-To":"<20170915141724.23124-8-sakari.ailus@linux.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-8-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"7Bit","Content-Type":"text/plain; charset=\"us-ascii\"","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770901,"web_url":"http://patchwork.ozlabs.org/comment/1770901/","msgid":"<3444678.JLWYLn9vNP@avalon>","list_archive_url":null,"date":"2017-09-19T11:55:43","subject":"Re: [PATCH v13 08/25] omap3isp: Fix check for our own sub-devices","submitter":{"id":11034,"url":"http://patchwork.ozlabs.org/api/people/11034/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Sakari,\n\nThank you for the patch.\n\nOn Friday, 15 September 2017 17:17:07 EEST Sakari Ailus wrote:\n> We only want to link sub-devices that were bound to the async notifier the\n> isp driver registered but there may be other sub-devices in the\n> v4l2_device as well. Check for the correct async notifier.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> Acked-by: Pavel Machek <pavel@ucw.cz>\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> ---\n>  drivers/media/platform/omap3isp/isp.c | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n> \n> diff --git a/drivers/media/platform/omap3isp/isp.c\n> b/drivers/media/platform/omap3isp/isp.c index a546cf774d40..3b1a9cd0e591\n> 100644\n> --- a/drivers/media/platform/omap3isp/isp.c\n> +++ b/drivers/media/platform/omap3isp/isp.c\n> @@ -2155,7 +2155,7 @@ static int isp_subdev_notifier_complete(struct\n> v4l2_async_notifier *async) return ret;\n> \n>  \tlist_for_each_entry(sd, &v4l2_dev->subdevs, list) {\n> -\t\tif (!sd->asd)\n> +\t\tif (sd->notifier != &isp->notifier)\n>  \t\t\tcontinue;\n> \n>  \t\tret = isp_link_entity(isp, &sd->entity,","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Etv8Fd6o\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxLt503ZHz9sBZ\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:55:41 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751606AbdISLzj (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:55:39 -0400","from galahad.ideasonboard.com ([185.26.127.97]:37945 \"EHLO\n\tgalahad.ideasonboard.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751564AbdISLzi (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 07:55:38 -0400","from avalon.localnet (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby galahad.ideasonboard.com (Postfix) with ESMTPSA id 8E468200AD;\n\tTue, 19 Sep 2017 13:53:01 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1505821981;\n\tbh=N8sHXyEEtWeKv3dN1ARfst9hA3R8UCLrKRRwntSWO1g=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=Etv8Fd6oh8RU77vQuR1wou7T6U6g/GgF7yo5Hc/ljPdyCgkhompKJ/BGJTlNFvzmQ\n\ta1dohFiWFOceHhP4zkc4UCMnPJPRg9ZB1Fa+Hl+ilUwiT2SRUqjhWfRoT26cD76QsO\n\ttI/ZIS8roLHdeZ2fqP+/99u0Xep1IpUEjPonAVK8=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, devicetree@vger.kernel.org, pavel@ucw.cz,\n\tsre@kernel.org","Subject":"Re: [PATCH v13 08/25] omap3isp: Fix check for our own sub-devices","Date":"Tue, 19 Sep 2017 14:55:43 +0300","Message-ID":"<3444678.JLWYLn9vNP@avalon>","In-Reply-To":"<20170915141724.23124-9-sakari.ailus@linux.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-9-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"7Bit","Content-Type":"text/plain; charset=\"us-ascii\"","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770904,"web_url":"http://patchwork.ozlabs.org/comment/1770904/","msgid":"<3405875.r0PdsRIrir@avalon>","list_archive_url":null,"date":"2017-09-19T11:56:24","subject":"Re: [PATCH v13 09/25] omap3isp: Print the name of the entity where\n\tno source pads could be found","submitter":{"id":11034,"url":"http://patchwork.ozlabs.org/api/people/11034/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Sakari,\n\nThank you for the patch.\n\nOn Friday, 15 September 2017 17:17:08 EEST Sakari Ailus wrote:\n> If no source pads are found in an entity, print the name of the entity.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> Acked-by: Pavel Machek <pavel@ucw.cz>\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> ---\n>  drivers/media/platform/omap3isp/isp.c | 4 ++--\n>  1 file changed, 2 insertions(+), 2 deletions(-)\n> \n> diff --git a/drivers/media/platform/omap3isp/isp.c\n> b/drivers/media/platform/omap3isp/isp.c index 3b1a9cd0e591..9a694924e46e\n> 100644\n> --- a/drivers/media/platform/omap3isp/isp.c\n> +++ b/drivers/media/platform/omap3isp/isp.c\n> @@ -1669,8 +1669,8 @@ static int isp_link_entity(\n>  \t\t\tbreak;\n>  \t}\n>  \tif (i == entity->num_pads) {\n> -\t\tdev_err(isp->dev, \"%s: no source pad in external entity\\n\",\n> -\t\t\t__func__);\n> +\t\tdev_err(isp->dev, \"%s: no source pad in external entity %s\\n\",\n> +\t\t\t__func__, entity->name);\n>  \t\treturn -EINVAL;\n>  \t}","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"MZFq0WAb\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxLtt26lQz9sMN\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 21:56:22 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751109AbdISL4U (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 07:56:20 -0400","from galahad.ideasonboard.com ([185.26.127.97]:37957 \"EHLO\n\tgalahad.ideasonboard.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751476AbdISL4U (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 07:56:20 -0400","from avalon.localnet (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby galahad.ideasonboard.com (Postfix) with ESMTPSA id 200BD200AD;\n\tTue, 19 Sep 2017 13:53:43 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1505822023;\n\tbh=yD4YtRdplMRtiQrXKDwO4ZsUXJt6esqAPgf+J+i4YZw=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=MZFq0WAbma/sI+kSQwcDPS8uLmm0JClHLCMFFLE21lUzqoI/T0TR8pXQnosHSgfIn\n\ttQlmBUFPXlOWvtA5beE5gQv1bCSYIwTZIZ1JwcxvolEvjP5yv81htdEnGPTuwFTqc1\n\t1iIzw7leeDceb0tUSq2hoXepAGyRJxRN4rcHpgmw=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, devicetree@vger.kernel.org, pavel@ucw.cz,\n\tsre@kernel.org","Subject":"Re: [PATCH v13 09/25] omap3isp: Print the name of the entity where\n\tno source pads could be found","Date":"Tue, 19 Sep 2017 14:56:24 +0300","Message-ID":"<3405875.r0PdsRIrir@avalon>","In-Reply-To":"<20170915141724.23124-10-sakari.ailus@linux.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-10-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"7Bit","Content-Type":"text/plain; charset=\"us-ascii\"","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1770908,"web_url":"http://patchwork.ozlabs.org/comment/1770908/","msgid":"<1751597.tWjkEME5YS@avalon>","list_archive_url":null,"date":"2017-09-19T12:01:14","subject":"Re: [PATCH v13 11/25] v4l: async: Introduce helpers for calling\n\tasync ops callbacks","submitter":{"id":11034,"url":"http://patchwork.ozlabs.org/api/people/11034/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Sakari,\n\nThank you for the patch.\n\nOn Friday, 15 September 2017 17:17:10 EEST Sakari Ailus wrote:\n> Add three helper functions to call async operations callbacks. Besides\n> simplifying callbacks, this allows async notifiers to have no ops set,\n> i.e. it can be left NULL.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> ---\n>  drivers/media/v4l2-core/v4l2-async.c | 49 ++++++++++++++++++++++++--------\n>  include/media/v4l2-async.h           |  1 +\n>  2 files changed, 37 insertions(+), 13 deletions(-)\n> \n> diff --git a/drivers/media/v4l2-core/v4l2-async.c\n> b/drivers/media/v4l2-core/v4l2-async.c index 7b2125b3d62f..c35d04b9122f\n> 100644\n> --- a/drivers/media/v4l2-core/v4l2-async.c\n> +++ b/drivers/media/v4l2-core/v4l2-async.c\n> @@ -25,6 +25,34 @@\n>  #include <media/v4l2-fwnode.h>\n>  #include <media/v4l2-subdev.h>\n> \n> +static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n,\n> +\t\t\t\t\t  struct v4l2_subdev *subdev,\n> +\t\t\t\t\t  struct v4l2_async_subdev *asd)\n> +{\n> +\tif (!n->ops || !n->ops->bound)\n> +\t\treturn 0;\n> +\n> +\treturn n->ops->bound(n, subdev, asd);\n> +}\n> +\n> +static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n,\n> +\t\t\t\t\t    struct v4l2_subdev *subdev,\n> +\t\t\t\t\t    struct v4l2_async_subdev *asd)\n> +{\n> +\tif (!n->ops || !n->ops->unbind)\n> +\t\treturn;\n> +\n> +\tn->ops->unbind(n, subdev, asd);\n> +}\n> +\n> +static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n)\n> +{\n> +\tif (!n->ops || !n->ops->complete)\n> +\t\treturn 0;\n> +\n> +\treturn n->ops->complete(n);\n> +}\n> +\n\nWouldn't it be enough to add a single v4l2_async_notifier_call() macro ?\n\n#define v4l2_async_notifier_call(n, op, args...) \\\n\t((n)->ops && (n)->ops->op ? (n)->ops->op(n, ##args) : 0)\n\nApart from that,\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n>  static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev\n> *asd) {\n>  #if IS_ENABLED(CONFIG_I2C)\n> @@ -102,16 +130,13 @@ static int v4l2_async_match_notify(struct\n> v4l2_async_notifier *notifier, {\n>  \tint ret;\n> \n> -\tif (notifier->ops->bound) {\n> -\t\tret = notifier->ops->bound(notifier, sd, asd);\n> -\t\tif (ret < 0)\n> -\t\t\treturn ret;\n> -\t}\n> +\tret = v4l2_async_notifier_call_bound(notifier, sd, asd);\n> +\tif (ret < 0)\n> +\t\treturn ret;\n> \n>  \tret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);\n>  \tif (ret < 0) {\n> -\t\tif (notifier->ops->unbind)\n> -\t\t\tnotifier->ops->unbind(notifier, sd, asd);\n> +\t\tv4l2_async_notifier_call_unbind(notifier, sd, asd);\n>  \t\treturn ret;\n>  \t}\n> \n> @@ -123,8 +148,8 @@ static int v4l2_async_match_notify(struct\n> v4l2_async_notifier *notifier, /* Move from the global subdevice list to\n> notifier's done */\n>  \tlist_move(&sd->async_list, &notifier->done);\n> \n> -\tif (list_empty(&notifier->waiting) && notifier->ops->complete)\n> -\t\treturn notifier->ops->complete(notifier);\n> +\tif (list_empty(&notifier->waiting))\n> +\t\treturn v4l2_async_notifier_call_complete(notifier);\n> \n>  \treturn 0;\n>  }\n> @@ -210,8 +235,7 @@ void v4l2_async_notifier_unregister(struct\n> v4l2_async_notifier *notifier) list_for_each_entry_safe(sd, tmp,\n> &notifier->done, async_list) { v4l2_async_cleanup(sd);\n> \n> -\t\tif (notifier->ops->unbind)\n> -\t\t\tnotifier->ops->unbind(notifier, sd, sd->asd);\n> +\t\tv4l2_async_notifier_call_unbind(notifier, sd, sd->asd);\n>  \t}\n> \n>  \tmutex_unlock(&list_lock);\n> @@ -300,8 +324,7 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev\n> *sd)\n> \n>  \tv4l2_async_cleanup(sd);\n> \n> -\tif (notifier->ops->unbind)\n> -\t\tnotifier->ops->unbind(notifier, sd, sd->asd);\n> +\tv4l2_async_notifier_call_unbind(notifier, sd, sd->asd);\n> \n>  \tmutex_unlock(&list_lock);\n>  }\n> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h\n> index 3c48f8b66d12..3bc8a7c0d83f 100644\n> --- a/include/media/v4l2-async.h\n> +++ b/include/media/v4l2-async.h\n> @@ -164,4 +164,5 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd);\n>   * @sd: pointer to &struct v4l2_subdev\n>   */\n>  void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);\n> +\n>  #endif","headers":{"Return-Path":"<devicetree-owner@vger.kernel.org>","X-Original-To":"incoming-dt@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming-dt@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"QKHJDtgj\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxM0S0x48z9s7m\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 22:01:12 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751797AbdISMBK (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 19 Sep 2017 08:01:10 -0400","from galahad.ideasonboard.com ([185.26.127.97]:37984 \"EHLO\n\tgalahad.ideasonboard.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751794AbdISMBK (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 19 Sep 2017 08:01:10 -0400","from avalon.localnet (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby galahad.ideasonboard.com (Postfix) with ESMTPSA id ABAC1200AD;\n\tTue, 19 Sep 2017 13:58:32 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1505822312;\n\tbh=xTjuuzO9BA3+jHrXsmYyi33z4wR17mmIhxsXui0YitY=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=QKHJDtgjWKGESjGuhvpnMDu9HhOsVcBLsUnPNKR9beCGY8LHjgD2+TFooNDVdy9EB\n\ttiHUm+LdOb+BE61LU03EPi0wExlIwoYpTD2qDJZAUcoXPximTV2AlMHHkpp1OTbCfT\n\tEjSUOIEEdXZQbeF2+p10riBxnxYEnthNzmTclmJ4=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, niklas.soderlund@ragnatech.se,\n\tmaxime.ripard@free-electrons.com, robh@kernel.org,\n\thverkuil@xs4all.nl, devicetree@vger.kernel.org, pavel@ucw.cz,\n\tsre@kernel.org","Subject":"Re: [PATCH v13 11/25] v4l: async: Introduce helpers for calling\n\tasync ops callbacks","Date":"Tue, 19 Sep 2017 15:01:14 +0300","Message-ID":"<1751597.tWjkEME5YS@avalon>","In-Reply-To":"<20170915141724.23124-12-sakari.ailus@linux.intel.com>","References":"<20170915141724.23124-1-sakari.ailus@linux.intel.com>\n\t<20170915141724.23124-12-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"7Bit","Content-Type":"text/plain; charset=\"us-ascii\"","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}}]