[{"id":1775231,"web_url":"http://patchwork.ozlabs.org/comment/1775231/","msgid":"<0afab3ba-23fc-556e-1db6-f168fdea3be6@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:06:52","subject":"Re: [PATCH v14 05/28] 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 26/09/17 00:25, 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\nI have two small comments below. After fixing that you can add my:\n\nAcked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\nRegards,\n\n\tHans\n\n> ---\n>  drivers/media/v4l2-core/v4l2-async.c  |  30 ++++++\n>  drivers/media/v4l2-core/v4l2-fwnode.c | 196 ++++++++++++++++++++++++++++++++++\n>  include/media/v4l2-async.h            |  24 ++++-\n>  include/media/v4l2-fwnode.h           | 118 ++++++++++++++++++++\n>  4 files changed, 366 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 60ac2f4fc69e..dd2559316ccd 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> @@ -221,6 +222,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_cleanup(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\nMissing break.\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_cleanup);\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..ea67d673c4a8 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,200 @@ 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_type = V4L2_ASYNC_MATCH_FWNODE;\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> +\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 port@%u/endpoint@%u\\n\", vep->base.port,\n> +\t\t\tvep->base.id);\n> +\telse if (ret < 0)\n> +\t\tdev_warn(dev,\n> +\t\t\t \"driver could not parse port@%u/endpoint@%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> +\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\nYou can drop the = NULL since the for-loop initializes it anyway.\n\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\tstruct fwnode_handle *dev_fwnode;\n> +\t\tbool is_available;\n> +\n> +\t\tdev_fwnode = fwnode_graph_get_port_parent(fwnode);\n> +\t\tis_available = fwnode_device_is_available(dev_fwnode);\n> +\t\tfwnode_handle_put(dev_fwnode);\n> +\t\tif (!is_available)\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\tstruct fwnode_handle *dev_fwnode;\n> +\t\tbool is_available;\n> +\n> +\t\tdev_fwnode = fwnode_graph_get_port_parent(fwnode);\n> +\t\tis_available = fwnode_device_is_available(dev_fwnode);\n> +\t\tfwnode_handle_put(dev_fwnode);\n> +\n> +\t\tif (!fwnode_device_is_available(dev_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..329aeebd1a80 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_cleanup - clean up notifier resources\n> + * @notifier: the notifier the resources of which are to be cleaned up\n> + *\n> + * Release memory resources related to a notifier, including the async\n> + * sub-devices allocated for the purposes of the notifier but not the notifier\n> + * itself. The user is responsible for calling this function to clean up the\n> + * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints.\n> + *\n> + * There is no harm from calling v4l2_async_notifier_cleanup in other\n> + * cases as long as its memory has been zeroed after it has been\n> + * allocated.\n> + */\n> +void v4l2_async_notifier_cleanup(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..add721695fbd 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,120 @@ 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_cleanup() 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> + * to sources have already been configured by another driver (on capture\n> + * devices). In this case the driver must know which ports to parse.\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_cleanup() 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--\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 3y1YT93CCLz9tX4\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:07:09 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S965142AbdIZIHH (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:07:07 -0400","from lb3-smtp-cloud8.xs4all.net ([194.109.24.29]:50860 \"EHLO\n\tlb3-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S967138AbdIZIHB (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:07:01 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid wktJdUdIYb4gvwktKdC3c2; Tue, 26 Sep 2017 10:06:59 +0200"],"Subject":"Re: [PATCH v14 05/28] 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","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-6-sakari.ailus@linux.intel.com>","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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<0afab3ba-23fc-556e-1db6-f168fdea3be6@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:06:52 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170925222540.371-6-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfEXF7xUuTWOU7lbIqyh9lq7jnCRHsLx+IJVLoBq3qYq+lG3UAmeXrpb8B9DbI4ljSbyv+QuvF2on6EGDAi0lUuFzZsk12Yg2hdHX1PZYyah2hgDnuAgI\n\tywrIAMVIBdEnRoz95dohKraVjKVM8IB/m50mN/3yi2qYfslszXUqyrYZP0qfaWgZDd4oknJlkzeN1bsvtfx6twIpVN14dYmS4UAJeFUp5Ie/bjdPxY+Fg6c6\n\tNytPUX/gY2/xmCKRjwFInL5/WVeFLdRqTanjc0qghSWzGiTpWagR7qtNrN6X4gIZFZBbM8AcqOKGnJ1b6bKyo1IF0u9WRZf6XiQ2YZJGmvWEa6yXWmwGYVFs\n\tIlabJFqz3bOQr93A/cVT69y8b/FywqYec7vitA5oCypW4qfzuZ/GGjViC5NilQ8UcJwkJD6kDI+lodBBeI9sM9ScdcZ0g0bQKL3WCFrCXZ6M7Z/SP2+e1G6b\n\tJMZiHMLSycfBdWFeCTi/heZFhx9FYskjSwATQvRYdYZW3aVmCNTW/xHppgg=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775232,"web_url":"http://patchwork.ozlabs.org/comment/1775232/","msgid":"<20170926081111.lu6efij4uagjepwh@paasikivi.fi.intel.com>","list_archive_url":null,"date":"2017-09-26T08:11:11","subject":"Re: [PATCH v14 05/28] 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":"On Tue, Sep 26, 2017 at 10:06:52AM +0200, Hans Verkuil wrote:\n> On 26/09/17 00:25, 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> I have two small comments below. After fixing that you can add my:\n> \n> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\nThanks; fixed the issues below.\n\n> \n> Regards,\n> \n> \tHans\n> \n> > ---\n> >  drivers/media/v4l2-core/v4l2-async.c  |  30 ++++++\n> >  drivers/media/v4l2-core/v4l2-fwnode.c | 196 ++++++++++++++++++++++++++++++++++\n> >  include/media/v4l2-async.h            |  24 ++++-\n> >  include/media/v4l2-fwnode.h           | 118 ++++++++++++++++++++\n> >  4 files changed, 366 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 60ac2f4fc69e..dd2559316ccd 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> > @@ -221,6 +222,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_cleanup(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> Missing break.\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_cleanup);\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..ea67d673c4a8 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,200 @@ 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_type = V4L2_ASYNC_MATCH_FWNODE;\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> > +\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 port@%u/endpoint@%u\\n\", vep->base.port,\n> > +\t\t\tvep->base.id);\n> > +\telse if (ret < 0)\n> > +\t\tdev_warn(dev,\n> > +\t\t\t \"driver could not parse port@%u/endpoint@%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> > +\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> \n> You can drop the = NULL since the for-loop initializes it anyway.\n> \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\tstruct fwnode_handle *dev_fwnode;\n> > +\t\tbool is_available;\n> > +\n> > +\t\tdev_fwnode = fwnode_graph_get_port_parent(fwnode);\n> > +\t\tis_available = fwnode_device_is_available(dev_fwnode);\n> > +\t\tfwnode_handle_put(dev_fwnode);\n> > +\t\tif (!is_available)\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\tstruct fwnode_handle *dev_fwnode;\n> > +\t\tbool is_available;\n> > +\n> > +\t\tdev_fwnode = fwnode_graph_get_port_parent(fwnode);\n> > +\t\tis_available = fwnode_device_is_available(dev_fwnode);\n> > +\t\tfwnode_handle_put(dev_fwnode);\n> > +\n> > +\t\tif (!fwnode_device_is_available(dev_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..329aeebd1a80 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_cleanup - clean up notifier resources\n> > + * @notifier: the notifier the resources of which are to be cleaned up\n> > + *\n> > + * Release memory resources related to a notifier, including the async\n> > + * sub-devices allocated for the purposes of the notifier but not the notifier\n> > + * itself. The user is responsible for calling this function to clean up the\n> > + * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints.\n> > + *\n> > + * There is no harm from calling v4l2_async_notifier_cleanup in other\n> > + * cases as long as its memory has been zeroed after it has been\n> > + * allocated.\n> > + */\n> > +void v4l2_async_notifier_cleanup(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..add721695fbd 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,120 @@ 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_cleanup() 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> > + * to sources have already been configured by another driver (on capture\n> > + * devices). In this case the driver must know which ports to parse.\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_cleanup() 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 3y1YZ525x4z9tXc\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:11:25 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S967902AbdIZILY (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:11:24 -0400","from mga14.intel.com ([192.55.52.115]:30214 \"EHLO mga14.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S965970AbdIZILT (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tTue, 26 Sep 2017 04:11:19 -0400","from orsmga001.jf.intel.com ([10.7.209.18])\n\tby fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t26 Sep 2017 01:11:18 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby orsmga001.jf.intel.com with ESMTP; 26 Sep 2017 01:11:12 -0700","by paasikivi.fi.intel.com (Postfix, from userid 1000)\n\tid 816CE206D7; Tue, 26 Sep 2017 11:11:11 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos; i=\"5.42,440,1500966000\"; d=\"scan'208\";\n\ta=\"1175849787\"","Date":"Tue, 26 Sep 2017 11:11:11 +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 v14 05/28] v4l: fwnode: Support generic parsing of graph\n\tendpoints in a device","Message-ID":"<20170926081111.lu6efij4uagjepwh@paasikivi.fi.intel.com>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-6-sakari.ailus@linux.intel.com>\n\t<0afab3ba-23fc-556e-1db6-f168fdea3be6@xs4all.nl>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<0afab3ba-23fc-556e-1db6-f168fdea3be6@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":1775233,"web_url":"http://patchwork.ozlabs.org/comment/1775233/","msgid":"<ba80e242-a3c2-39af-01cd-6aa54649fb93@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:12:50","subject":"Re: [PATCH v14 14/28] v4l: async: Prepare for async sub-device\n\tnotifiers","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 26/09/17 00:25, Sakari Ailus wrote:\n> Refactor the V4L2 async framework a little in preparation for async\n> sub-device notifiers.\n\nPerhaps extend this a bit to also state the reason for these changes?\n\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n\nAnyway,\n\nAcked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\n> ---\n>  drivers/media/v4l2-core/v4l2-async.c | 66 +++++++++++++++++++++++++-----------\n>  1 file changed, 47 insertions(+), 19 deletions(-)\n> \n> diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c\n> index 77b9f851bfa9..1d4132305243 100644\n> --- a/drivers/media/v4l2-core/v4l2-async.c\n> +++ b/drivers/media/v4l2-core/v4l2-async.c\n> @@ -125,12 +125,13 @@ static struct v4l2_async_subdev *v4l2_async_find_match(\n>  }\n>  \n>  static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,\n> +\t\t\t\t   struct v4l2_device *v4l2_dev,\n>  \t\t\t\t   struct v4l2_subdev *sd,\n>  \t\t\t\t   struct v4l2_async_subdev *asd)\n>  {\n>  \tint ret;\n>  \n> -\tret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);\n> +\tret = v4l2_device_register_subdev(v4l2_dev, sd);\n>  \tif (ret < 0)\n>  \t\treturn ret;\n>  \n> @@ -154,6 +155,31 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,\n>  \treturn 0;\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_device *v4l2_dev = notifier->v4l2_dev;\n> +\tstruct v4l2_subdev *sd, *tmp;\n> +\n> +\tlist_for_each_entry_safe(sd, tmp, &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, v4l2_dev, sd, asd);\n> +\t\tif (ret < 0) {\n> +\t\t\tmutex_unlock(&list_lock);\n> +\t\t\treturn ret;\n> +\t\t}\n> +\t}\n> +\n> +\treturn 0;\n> +}\n> +\n>  static void v4l2_async_cleanup(struct v4l2_subdev *sd)\n>  {\n>  \tv4l2_device_unregister_subdev(sd);\n> @@ -163,17 +189,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> @@ -206,18 +230,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> @@ -227,6 +243,17 @@ 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))\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> @@ -303,7 +330,8 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)\n>  \t\tstruct v4l2_async_subdev *asd = v4l2_async_find_match(notifier,\n>  \t\t\t\t\t\t\t\t      sd);\n>  \t\tif (asd) {\n> -\t\t\tint ret = v4l2_async_match_notify(notifier, sd, asd);\n> +\t\t\tint ret = v4l2_async_match_notify(\n> +\t\t\t\tnotifier, notifier->v4l2_dev, sd, asd);\n>  \t\t\tmutex_unlock(&list_lock);\n>  \t\t\treturn ret;\n>  \t\t}\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 3y1Yc01QLrz9tXc\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:13:04 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S967933AbdIZINB (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:13:01 -0400","from lb3-smtp-cloud8.xs4all.net ([194.109.24.29]:40557 \"EHLO\n\tlb3-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S967934AbdIZIMw (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:12:52 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid wkz4dUjMbb4gvwkz5dC7FQ; Tue, 26 Sep 2017 10:12:51 +0200"],"Subject":"Re: [PATCH v14 14/28] v4l: async: Prepare for async sub-device\n\tnotifiers","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-15-sakari.ailus@linux.intel.com>","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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<ba80e242-a3c2-39af-01cd-6aa54649fb93@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:12:50 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170925222540.371-15-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfCw1HJfDF4eLvTauGCTA9v0XTzyLrFWbBJY6D5qFPCiSZNh1Rfc4P/oLl9G+NxudRJP8SsEwiqFcexx+OrxqJG6jDPFsRpb1ywRfxu71AI9Po8JboDyo\n\ttU5cAiJ8k6WfZcy+4+u0FBHQeAtYKJDa+1eq49a/uAMQu5Z/CRpLZqBAIQs2QjqfznrI4ogxj1Udc+5H92Em9xAQ+AURzF58rCypMZoBlKWccK6pa2cpbThu\n\t/QRpuDUXEJeY6H4qlwdRXqrydJhxa4K0s6QUpw1QwPRjGPYDHuWvpi7jpNiGIMr+WKJu+6rAOs1a6JGDnOMNedxEeGqDUiv2HDnoatrBEc2PURmjPdBXVInn\n\tY1cbNvG8Rq5QtHi9Qgr9IXYrpEaZs/2RWyGVEGUFykS6qMiyFLUiQfl3uarHgp7qXmMH5GZhy+EsbjIpwP5DB5YjKtfiQy357AFVSAZ3N2jleYOIk7tuBR3K\n\thErH8m8olY310PPZizBB0HU+ZXDojwP/QNgNwFAo0W/+whEjgQCfZY76Ci8=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775235,"web_url":"http://patchwork.ozlabs.org/comment/1775235/","msgid":"<7438d5da-699c-9369-7a50-2176ce799268@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:16:36","subject":"Re: [PATCH v14 15/28] 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 26/09/17 00:25, 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\n> ---\n>  drivers/media/v4l2-core/v4l2-async.c | 218 +++++++++++++++++++++++++++++------\n>  include/media/v4l2-async.h           |  16 ++-\n>  2 files changed, 199 insertions(+), 35 deletions(-)\n> \n> diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c\n> index 1d4132305243..735f72f81740 100644\n> --- a/drivers/media/v4l2-core/v4l2-async.c\n> +++ b/drivers/media/v4l2-core/v4l2-async.c\n> @@ -124,11 +124,109 @@ 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> +/* 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> +/*\n> + * Return true if all child sub-device notifiers are complete, false otherwise.\n> + */\n> +static bool v4l2_async_notifier_can_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_notifier_can_complete(subdev_notifier))\n> +\t\t\treturn false;\n> +\t}\n> +\n> +\treturn true;\n> +}\n> +\n> +/* Complete all notifiers. Call on the root notifier. */\n> +static int v4l2_async_notifier_complete(\n> +\tstruct v4l2_async_notifier *notifier)\n> +{\n> +\tstruct v4l2_subdev *sd;\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> +\t\tint ret;\n> +\n> +\t\tif (!subdev_notifier)\n> +\t\t\tcontinue;\n> +\n> +\t\tret = v4l2_async_notifier_complete(subdev_notifier);\n> +\t\tif (ret)\n> +\t\t\treturn ret;\n> +\t}\n> +\n> +\treturn v4l2_async_notifier_call_complete(notifier);\n> +}\n> +\n> +/*\n> + * Complete notifiers if possible. This is done when all async sub-devices have\n> + * been bound; v4l2_device is also available then.\n> + */\n> +static int v4l2_async_notifier_try_complete(\n> +\tstruct v4l2_async_notifier *notifier)\n> +{\n> +\t/* Quick check whether there are still more sub-devices here. */\n> +\tif (!list_empty(&notifier->waiting))\n> +\t\treturn 0;\n> +\n> +\t/* Check the entire notifier tree; find the root notifier first. */\n> +\twhile (notifier->parent)\n> +\t\tnotifier = notifier->parent;\n> +\n> +\t/* This is root if it has v4l2_dev. */\n> +\tif (!notifier->v4l2_dev)\n> +\t\treturn 0;\n> +\n> +\t/* Is everything ready? */\n> +\tif (!v4l2_async_notifier_can_complete(notifier))\n> +\t\treturn 0;\n> +\n> +\treturn v4l2_async_notifier_complete(notifier);\n> +}\n> +\n> +static int v4l2_async_notifier_try_all_subdevs(\n> +\tstruct v4l2_async_notifier *notifier);\n> +\n>  static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,\n>  \t\t\t\t   struct v4l2_device *v4l2_dev,\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(v4l2_dev, sd);\n> @@ -149,8 +247,17 @@ 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>  }\n> @@ -159,10 +266,15 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,\n>  static int v4l2_async_notifier_try_all_subdevs(\n>  \tstruct v4l2_async_notifier *notifier)\n>  {\n> -\tstruct v4l2_device *v4l2_dev = notifier->v4l2_dev;\n> -\tstruct v4l2_subdev *sd, *tmp;\n> +\tstruct v4l2_device *v4l2_dev =\n> +\t\tv4l2_async_notifier_find_v4l2_dev(notifier);\n> +\tstruct v4l2_subdev *sd;\n>  \n> -\tlist_for_each_entry_safe(sd, tmp, &subdev_list, async_list) {\n> +\tif (!v4l2_dev)\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> @@ -171,10 +283,16 @@ static int v4l2_async_notifier_try_all_subdevs(\n>  \t\t\tcontinue;\n>  \n>  \t\tret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);\n> -\t\tif (ret < 0) {\n> -\t\t\tmutex_unlock(&list_lock);\n> +\t\tif (ret < 0)\n>  \t\t\treturn ret;\n> -\t\t}\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> @@ -201,15 +319,6 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)\n>  \tINIT_LIST_HEAD(&notifier->waiting);\n>  \tINIT_LIST_HEAD(&notifier->done);\n>  \n> -\tif (!notifier->num_subdevs) {\n> -\t\tint ret;\n> -\n> -\t\tret = v4l2_async_notifier_call_complete(notifier);\n> -\t\tnotifier->v4l2_dev = NULL;\n> -\n> -\t\treturn ret;\n> -\t}\n> -\n>  \tfor (i = 0; i < notifier->num_subdevs; i++) {\n>  \t\tasd = notifier->subdevs[i];\n>  \n> @@ -236,18 +345,20 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)\n>  \t\treturn ret;\n>  \t}\n>  \n> +\tret = v4l2_async_notifier_try_complete(notifier);\n> +\n>  \t/* Keep also completed notifiers on the list */\n>  \tlist_add(&notifier->list, &notifier_list);\n>  \n>  \tmutex_unlock(&list_lock);\n>  \n> -\treturn 0;\n> +\treturn ret;\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))\n> +\tif (WARN_ON(!v4l2_dev || notifier->sd))\n>  \t\treturn -EINVAL;\n>  \n>  \tnotifier->v4l2_dev = v4l2_dev;\n> @@ -256,18 +367,31 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,\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> @@ -275,9 +399,24 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)\n>  \t\tlist_move(&sd->async_list, &subdev_list);\n>  \t}\n>  \n> -\tmutex_unlock(&list_lock);\n> +\tnotifier->parent = 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> +\tnotifier->sd = NULL;\n>  \tnotifier->v4l2_dev = NULL;\n> +\n> +\tlist_del(&notifier->list);\n> +\n> +\tmutex_unlock(&list_lock);\n>  }\n>  EXPORT_SYMBOL(v4l2_async_notifier_unregister);\n>  \n> @@ -327,14 +466,25 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)\n>  \tINIT_LIST_HEAD(&sd->async_list);\n>  \n>  \tlist_for_each_entry(notifier, &notifier_list, list) {\n> -\t\tstruct v4l2_async_subdev *asd = v4l2_async_find_match(notifier,\n> -\t\t\t\t\t\t\t\t      sd);\n> -\t\tif (asd) {\n> -\t\t\tint ret = v4l2_async_match_notify(\n> -\t\t\t\tnotifier, notifier->v4l2_dev, sd, asd);\n> -\t\t\tmutex_unlock(&list_lock);\n> -\t\t\treturn ret;\n> -\t\t}\n> +\t\tstruct v4l2_device *v4l2_dev =\n> +\t\t\tv4l2_async_notifier_find_v4l2_dev(notifier);\n> +\t\tstruct v4l2_async_subdev *asd;\n> +\t\tint ret;\n> +\n> +\t\tif (!v4l2_dev)\n> +\t\t\tcontinue;\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, v4l2_dev, sd, asd);\n> +\n> +\t\tif (!ret)\n> +\t\t\tret = v4l2_async_notifier_try_complete(notifier);\n> +\n> +\t\tmutex_unlock(&list_lock);\n> +\t\treturn ret;\n>  \t}\n>  \n>  \t/* None matched, wait for hot-plugging */\n> diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h\n> index 7d56c355138b..0b30a631ad19 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 3y1YhQ54Rcz9sBd\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:16:54 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S967969AbdIZIQq (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:16:46 -0400","from lb1-smtp-cloud8.xs4all.net ([194.109.24.21]:58486 \"EHLO\n\tlb1-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S967968AbdIZIQj (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:16:39 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid wl2idUn3Wb4gvwl2jdC9QV; Tue, 26 Sep 2017 10:16:37 +0200"],"Subject":"Re: [PATCH v14 15/28] v4l: async: Allow binding notifiers to\n\tsub-devices","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-16-sakari.ailus@linux.intel.com>","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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<7438d5da-699c-9369-7a50-2176ce799268@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:16:36 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170925222540.371-16-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfBjEdW/D60LMlrq7shOw1LlwjVa19xgzmdwLgM+OGJIwtv0k7UjpV8JTZWGNFbAnItXPPJwI0HMQaL/yOoz7EOcWrKTsF1VAzyYYo5HwjrDbwTUrfkwN\n\thAUIxZH4udb8MsCGhVVhzL31dGfXiVZpSVkrGRwuE9osEixLwhsS//bmXCMNLKVoEuXnFM0rVcejty8G3RW63jYTswQoxUWfqxmZQUAk89wLCILxlBuHQKpD\n\td+Sh91eXgDhu2xOMwStXBv1fEg5jfQT/Z4vfmctIKtY9i1HulUAHYbcOdsUTyd59lyJDt49T0o13tFadcp4V+0dhR2m0xpKeVMvDUWsgKQgXyprXXPhT/nRN\n\t4hRIVFPD0IMuqa8sZB1fxz6hZKGADUSGOAsNZXnvDUZSnYt2J+7wcoqR01LooM9Wkxzv05nW/yd8GOJ7MysUF/S8hG8pUSlSJ/FuWOm+XC5SoQ/eAAOTzlWC\n\tI6mIspTMmoene3XGcWCJ7izEjUbX/okZ6/HRXonWp+Zwm+eMZAwgqCF5zHg=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775237,"web_url":"http://patchwork.ozlabs.org/comment/1775237/","msgid":"<20170926081700.hqm6b4abpqvszrro@paasikivi.fi.intel.com>","list_archive_url":null,"date":"2017-09-26T08:17:00","subject":"Re: [PATCH v14 14/28] v4l: async: Prepare for async sub-device\n\tnotifiers","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 26, 2017 at 10:12:50AM +0200, Hans Verkuil wrote:\n> On 26/09/17 00:25, Sakari Ailus wrote:\n> > Refactor the V4L2 async framework a little in preparation for async\n> > sub-device notifiers.\n> \n> Perhaps extend this a bit to also state the reason for these changes?\n\nWell, the true reason is that Laurent felt the following patch was doing\ntoo much, but most of the changes in it are actually tightly\ninterconnected.\n\nHow about adding:\n\nThis avoids making some structural changes in the patch actually\nimplementing sub-device notifiers, making that patch easier to review.\n\n> \n> > \n> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> \n> Anyway,\n> \n> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\nThanks!\n\n> \n> > ---\n> >  drivers/media/v4l2-core/v4l2-async.c | 66 +++++++++++++++++++++++++-----------\n> >  1 file changed, 47 insertions(+), 19 deletions(-)\n> > \n> > diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c\n> > index 77b9f851bfa9..1d4132305243 100644\n> > --- a/drivers/media/v4l2-core/v4l2-async.c\n> > +++ b/drivers/media/v4l2-core/v4l2-async.c\n> > @@ -125,12 +125,13 @@ static struct v4l2_async_subdev *v4l2_async_find_match(\n> >  }\n> >  \n> >  static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,\n> > +\t\t\t\t   struct v4l2_device *v4l2_dev,\n> >  \t\t\t\t   struct v4l2_subdev *sd,\n> >  \t\t\t\t   struct v4l2_async_subdev *asd)\n> >  {\n> >  \tint ret;\n> >  \n> > -\tret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);\n> > +\tret = v4l2_device_register_subdev(v4l2_dev, sd);\n> >  \tif (ret < 0)\n> >  \t\treturn ret;\n> >  \n> > @@ -154,6 +155,31 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,\n> >  \treturn 0;\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_device *v4l2_dev = notifier->v4l2_dev;\n> > +\tstruct v4l2_subdev *sd, *tmp;\n> > +\n> > +\tlist_for_each_entry_safe(sd, tmp, &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, v4l2_dev, sd, asd);\n> > +\t\tif (ret < 0) {\n> > +\t\t\tmutex_unlock(&list_lock);\n> > +\t\t\treturn ret;\n> > +\t\t}\n> > +\t}\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> >  static void v4l2_async_cleanup(struct v4l2_subdev *sd)\n> >  {\n> >  \tv4l2_device_unregister_subdev(sd);\n> > @@ -163,17 +189,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> > @@ -206,18 +230,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> > @@ -227,6 +243,17 @@ 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))\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> > @@ -303,7 +330,8 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)\n> >  \t\tstruct v4l2_async_subdev *asd = v4l2_async_find_match(notifier,\n> >  \t\t\t\t\t\t\t\t      sd);\n> >  \t\tif (asd) {\n> > -\t\t\tint ret = v4l2_async_match_notify(notifier, sd, asd);\n> > +\t\t\tint ret = v4l2_async_match_notify(\n> > +\t\t\t\tnotifier, notifier->v4l2_dev, sd, asd);\n> >  \t\t\tmutex_unlock(&list_lock);\n> >  \t\t\treturn ret;\n> >  \t\t}\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 3y1Yjq2YYyz9sBd\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:18:07 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S936342AbdIZISF (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:18:05 -0400","from mga14.intel.com ([192.55.52.115]:42667 \"EHLO mga14.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S934968AbdIZISE (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tTue, 26 Sep 2017 04:18:04 -0400","from fmsmga003.fm.intel.com ([10.253.24.29])\n\tby fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t26 Sep 2017 01:18:03 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby FMSMGA003.fm.intel.com with ESMTP; 26 Sep 2017 01:18:01 -0700","by paasikivi.fi.intel.com (Postfix, from userid 1000)\n\tid 8BF1E206D7; Tue, 26 Sep 2017 11:17:00 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos;i=\"5.42,440,1500966000\"; d=\"scan'208\";a=\"903902299\"","Date":"Tue, 26 Sep 2017 11:17:00 +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 v14 14/28] v4l: async: Prepare for async sub-device\n\tnotifiers","Message-ID":"<20170926081700.hqm6b4abpqvszrro@paasikivi.fi.intel.com>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-15-sakari.ailus@linux.intel.com>\n\t<ba80e242-a3c2-39af-01cd-6aa54649fb93@xs4all.nl>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<ba80e242-a3c2-39af-01cd-6aa54649fb93@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":1775240,"web_url":"http://patchwork.ozlabs.org/comment/1775240/","msgid":"<b2bf3d67-ee85-c0b5-a9c7-2492652eea4c@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:20:31","subject":"Re: [PATCH v14 14/28] v4l: async: Prepare for async sub-device\n\tnotifiers","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 26/09/17 10:17, Sakari Ailus wrote:\n> Hi Hans,\n> \n> On Tue, Sep 26, 2017 at 10:12:50AM +0200, Hans Verkuil wrote:\n>> On 26/09/17 00:25, Sakari Ailus wrote:\n>>> Refactor the V4L2 async framework a little in preparation for async\n>>> sub-device notifiers.\n>>\n>> Perhaps extend this a bit to also state the reason for these changes?\n> \n> Well, the true reason is that Laurent felt the following patch was doing\n> too much, but most of the changes in it are actually tightly\n> interconnected.\n> \n> How about adding:\n> \n> This avoids making some structural changes in the patch actually\n> implementing sub-device notifiers, making that patch easier to review.\n\nThat will do.\n\nI preferred the original version, that way I could see WHY things were done,\neven though the patch was larger.\n\nRegards,\n\n\tHans\n\n> \n>>\n>>>\n>>> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n>>\n>> Anyway,\n>>\n>> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>\n> \n> Thanks!\n> \n>>\n>>> ---\n>>>  drivers/media/v4l2-core/v4l2-async.c | 66 +++++++++++++++++++++++++-----------\n>>>  1 file changed, 47 insertions(+), 19 deletions(-)\n>>>\n>>> diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c\n>>> index 77b9f851bfa9..1d4132305243 100644\n>>> --- a/drivers/media/v4l2-core/v4l2-async.c\n>>> +++ b/drivers/media/v4l2-core/v4l2-async.c\n>>> @@ -125,12 +125,13 @@ static struct v4l2_async_subdev *v4l2_async_find_match(\n>>>  }\n>>>  \n>>>  static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,\n>>> +\t\t\t\t   struct v4l2_device *v4l2_dev,\n>>>  \t\t\t\t   struct v4l2_subdev *sd,\n>>>  \t\t\t\t   struct v4l2_async_subdev *asd)\n>>>  {\n>>>  \tint ret;\n>>>  \n>>> -\tret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);\n>>> +\tret = v4l2_device_register_subdev(v4l2_dev, sd);\n>>>  \tif (ret < 0)\n>>>  \t\treturn ret;\n>>>  \n>>> @@ -154,6 +155,31 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,\n>>>  \treturn 0;\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_device *v4l2_dev = notifier->v4l2_dev;\n>>> +\tstruct v4l2_subdev *sd, *tmp;\n>>> +\n>>> +\tlist_for_each_entry_safe(sd, tmp, &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, v4l2_dev, sd, asd);\n>>> +\t\tif (ret < 0) {\n>>> +\t\t\tmutex_unlock(&list_lock);\n>>> +\t\t\treturn ret;\n>>> +\t\t}\n>>> +\t}\n>>> +\n>>> +\treturn 0;\n>>> +}\n>>> +\n>>>  static void v4l2_async_cleanup(struct v4l2_subdev *sd)\n>>>  {\n>>>  \tv4l2_device_unregister_subdev(sd);\n>>> @@ -163,17 +189,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>>> @@ -206,18 +230,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>>> @@ -227,6 +243,17 @@ 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))\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>>> @@ -303,7 +330,8 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)\n>>>  \t\tstruct v4l2_async_subdev *asd = v4l2_async_find_match(notifier,\n>>>  \t\t\t\t\t\t\t\t      sd);\n>>>  \t\tif (asd) {\n>>> -\t\t\tint ret = v4l2_async_match_notify(notifier, sd, asd);\n>>> +\t\t\tint ret = v4l2_async_match_notify(\n>>> +\t\t\t\tnotifier, notifier->v4l2_dev, sd, asd);\n>>>  \t\t\tmutex_unlock(&list_lock);\n>>>  \t\t\treturn ret;\n>>>  \t\t}\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 3y1Ymh4B4bz9t1t\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:20:36 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S967423AbdIZIUe (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:20:34 -0400","from lb2-smtp-cloud8.xs4all.net ([194.109.24.25]:35177 \"EHLO\n\tlb2-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S967292AbdIZIUd (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:20:33 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid wl6VdUqqAb4gvwl6WdCBnj; Tue, 26 Sep 2017 10:20:32 +0200"],"Subject":"Re: [PATCH v14 14/28] v4l: async: Prepare for async sub-device\n\tnotifiers","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-15-sakari.ailus@linux.intel.com>\n\t<ba80e242-a3c2-39af-01cd-6aa54649fb93@xs4all.nl>\n\t<20170926081700.hqm6b4abpqvszrro@paasikivi.fi.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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<b2bf3d67-ee85-c0b5-a9c7-2492652eea4c@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:20:31 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170926081700.hqm6b4abpqvszrro@paasikivi.fi.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfFmpXzwMunb9FqD+HLCfKEmpu01/FFlnTC26vx6FjIJS17FbSCSCxMnWgPZ9H97ENPkrdc2VkwcX/LPkhOC1nOlZHMMBNzdb9gnnVA65DZbFByJItWEf\n\tOY6weRXixNAF0ZnnZMHwfNnxgu1WI4jIGeX5gPvxmbuacAxjTXTcb93cb63AB2i0R+itDK7leCWq4qFdsbBy6WPHmASKz2C4xI6Ie6CmChlQcmNQM0DbwJ0L\n\taAVFThHEjDh1O1LwEFLl2hKGcjn233M3USX7aiJh1PfGPmoHRUoIQwaA8blverVw1IrVEh0tB62Fm1K+k3tk6E0t/tw9b4kLELcBLqDE4hXWf8GXXZZszWw6\n\txhXSXQnfggjwee25DP70q4rMIr0qhmKTG8ATJelfg1A3VQLN4iSMwvnGrUT4zD201V1B74TS8lhklHXCiK6athdZ7fwI9CYsxXe/QVMcCeuD8S1Pih+Nr//r\n\tDwIj7cQyqyZVbjsyCRh5uH9gN3D1G0Og8ldcU/mA/G+Lf/JaHfpLCexoU1E=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775241,"web_url":"http://patchwork.ozlabs.org/comment/1775241/","msgid":"<20170926082046.sfmhyf7xmkutzjbe@valkosipuli.retiisi.org.uk>","list_archive_url":null,"date":"2017-09-26T08:20:46","subject":"Re: [PATCH v14 15/28] v4l: async: Allow binding notifiers to\n\tsub-devices","submitter":{"id":1593,"url":"http://patchwork.ozlabs.org/api/people/1593/","name":"Sakari Ailus","email":"sakari.ailus@iki.fi"},"content":"On Tue, Sep 26, 2017 at 01:25:26AM +0300, 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\nThis paragraph is actually no longer true. I changed it to:\n\n\tThe complete callbacks will be called only when the v4l2_device is\n\tavailable and no notifier has pending sub-devices to bind.","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 3y1Yn051Yxz9tXc\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:20:52 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S967996AbdIZIUv (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:20:51 -0400","from nblzone-211-213.nblnetworks.fi ([83.145.211.213]:55318 \"EHLO\n\thillosipuli.retiisi.org.uk\" rhost-flags-OK-OK-OK-FAIL)\n\tby vger.kernel.org with ESMTP id S967292AbdIZIUu (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:20:50 -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 78E87600FE;\n\tTue, 26 Sep 2017 11:20:47 +0300 (EEST)","from sakke by valkosipuli.localdomain with local (Exim 4.89)\n\t(envelope-from <sakke@valkosipuli.retiisi.org.uk>)\n\tid 1dwl6k-0007DQ-Pm; Tue, 26 Sep 2017 11:20:47 +0300"],"Date":"Tue, 26 Sep 2017 11:20:46 +0300","From":"Sakari Ailus <sakari.ailus@iki.fi>","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, pavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v14 15/28] v4l: async: Allow binding notifiers to\n\tsub-devices","Message-ID":"<20170926082046.sfmhyf7xmkutzjbe@valkosipuli.retiisi.org.uk>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-16-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20170925222540.371-16-sakari.ailus@linux.intel.com>","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":1775244,"web_url":"http://patchwork.ozlabs.org/comment/1775244/","msgid":"<e5dbe28c-6afc-2dcf-3b85-07e044522258@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:22:29","subject":"Re: [PATCH v14 16/28] v4l: async: Ensure only unique fwnodes are\n\tregistered to notifiers","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 26/09/17 00:25, Sakari Ailus wrote:\n> While registering a notifier, check that each newly added fwnode is\n> unique, and return an error if it is not. Also check that a newly added\n> notifier does not have the same fwnodes twice.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n\nAcked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\n> ---\n>  drivers/media/v4l2-core/v4l2-async.c | 88 ++++++++++++++++++++++++++++++++----\n>  1 file changed, 79 insertions(+), 9 deletions(-)\n> \n> diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c\n> index 735f72f81740..470607da96b2 100644\n> --- a/drivers/media/v4l2-core/v4l2-async.c\n> +++ b/drivers/media/v4l2-core/v4l2-async.c\n> @@ -307,8 +307,71 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)\n>  \tsd->dev = NULL;\n>  }\n>  \n> +/* See if an fwnode can be found in a notifier's lists. */\n> +static bool __v4l2_async_notifier_fwnode_has_async_subdev(\n> +\tstruct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode)\n> +{\n> +\tstruct v4l2_async_subdev *asd;\n> +\tstruct v4l2_subdev *sd;\n> +\n> +\tlist_for_each_entry(asd, &notifier->waiting, list) {\n> +\t\tif (asd->match_type != V4L2_ASYNC_MATCH_FWNODE)\n> +\t\t\tcontinue;\n> +\n> +\t\tif (asd->match.fwnode.fwnode == fwnode)\n> +\t\t\treturn true;\n> +\t}\n> +\n> +\tlist_for_each_entry(sd, &notifier->done, async_list) {\n> +\t\tif (WARN_ON(!sd->asd))\n> +\t\t\tcontinue;\n> +\n> +\t\tif (sd->asd->match_type != V4L2_ASYNC_MATCH_FWNODE)\n> +\t\t\tcontinue;\n> +\n> +\t\tif (sd->asd->match.fwnode.fwnode == fwnode)\n> +\t\t\treturn true;\n> +\t}\n> +\n> +\treturn false;\n> +}\n> +\n> +/*\n> + * Find out whether an async sub-device was set up for an fwnode already or\n> + * whether it exists in a given notifier before @this_index.\n> + */\n> +static bool v4l2_async_notifier_fwnode_has_async_subdev(\n> +\tstruct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode,\n> +\tunsigned int this_index)\n> +{\n> +\tunsigned int j;\n> +\n> +\tlockdep_assert_held(&list_lock);\n> +\n> +\t/* Check that an fwnode is not being added more than once. */\n> +\tfor (j = 0; j < this_index; j++) {\n> +\t\tstruct v4l2_async_subdev *asd = notifier->subdevs[this_index];\n> +\t\tstruct v4l2_async_subdev *other_asd = notifier->subdevs[j];\n> +\n> +\t\tif (other_asd->match_type == V4L2_ASYNC_MATCH_FWNODE &&\n> +\t\t    asd->match.fwnode.fwnode ==\n> +\t\t    other_asd->match.fwnode.fwnode)\n> +\t\t\treturn true;\n> +\t}\n> +\n> +\t/* Check than an fwnode did not exist in other notifiers. */\n> +\tlist_for_each_entry(notifier, &notifier_list, list)\n> +\t\tif (__v4l2_async_notifier_fwnode_has_async_subdev(\n> +\t\t\t    notifier, fwnode))\n> +\t\t\treturn true;\n> +\n> +\treturn false;\n> +}\n> +\n>  static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)\n>  {\n> +\tstruct device *dev =\n> +\t\tnotifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL;\n>  \tstruct v4l2_async_subdev *asd;\n>  \tint ret;\n>  \tint i;\n> @@ -319,6 +382,8 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)\n>  \tINIT_LIST_HEAD(&notifier->waiting);\n>  \tINIT_LIST_HEAD(&notifier->done);\n>  \n> +\tmutex_lock(&list_lock);\n> +\n>  \tfor (i = 0; i < notifier->num_subdevs; i++) {\n>  \t\tasd = notifier->subdevs[i];\n>  \n> @@ -326,30 +391,35 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)\n>  \t\tcase V4L2_ASYNC_MATCH_CUSTOM:\n>  \t\tcase V4L2_ASYNC_MATCH_DEVNAME:\n>  \t\tcase V4L2_ASYNC_MATCH_I2C:\n> +\t\t\tbreak;\n>  \t\tcase V4L2_ASYNC_MATCH_FWNODE:\n> +\t\t\tif (v4l2_async_notifier_fwnode_has_async_subdev(\n> +\t\t\t\t    notifier, asd->match.fwnode.fwnode, i)) {\n> +\t\t\t\tdev_err(dev,\n> +\t\t\t\t\t\"fwnode has already been registered or in notifier's subdev list\\n\");\n> +\t\t\t\tret = -EEXIST;\n> +\t\t\t\tgoto out_unlock;\n> +\t\t\t}\n>  \t\t\tbreak;\n>  \t\tdefault:\n> -\t\t\tdev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,\n> -\t\t\t\t\"Invalid match type %u on %p\\n\",\n> +\t\t\tdev_err(dev, \"Invalid match type %u on %p\\n\",\n>  \t\t\t\tasd->match_type, asd);\n> -\t\t\treturn -EINVAL;\n> +\t\t\tret = -EINVAL;\n> +\t\t\tgoto out_unlock;\n>  \t\t}\n>  \t\tlist_add_tail(&asd->list, &notifier->waiting);\n>  \t}\n>  \n> -\tmutex_lock(&list_lock);\n> -\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> +\tif (ret)\n> +\t\tgoto out_unlock;\n>  \n>  \tret = v4l2_async_notifier_try_complete(notifier);\n>  \n>  \t/* Keep also completed notifiers on the list */\n>  \tlist_add(&notifier->list, &notifier_list);\n>  \n> +out_unlock:\n>  \tmutex_unlock(&list_lock);\n>  \n>  \treturn ret;\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 3y1Ypy0rnbz9t1t\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:22:34 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S967333AbdIZIWc (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:22:32 -0400","from lb3-smtp-cloud8.xs4all.net ([194.109.24.29]:46870 \"EHLO\n\tlb3-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S967292AbdIZIWb (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:22:31 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid wl8PdUvEib4gvwl8QdCCw6; Tue, 26 Sep 2017 10:22:30 +0200"],"Subject":"Re: [PATCH v14 16/28] v4l: async: Ensure only unique fwnodes are\n\tregistered to notifiers","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-17-sakari.ailus@linux.intel.com>","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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<e5dbe28c-6afc-2dcf-3b85-07e044522258@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:22:29 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170925222540.371-17-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfE2e3AKo4wprObjE0UASJFFWZxdSlH9rgjYQPaK+MeOAoObz24UKTsPFo1HOFValQTEiGdEisXRyww+TcWlGVKUU+8RQ+EEZf+4gQb7b5GUkQSHKjhIa\n\tzWOanWR8cdPhCtSfQBa5wNimWIR6NkiZHWa570BKQ+fBr094d42aU5T/PtWdsA6J9UeD8e7Y+ScxCAnmaQh1oF7h9+3oyMyFtnuWUA5KqBDVTKMsq94wbffU\n\tXkZ+B1801Ktaa0EHiJzZ3wLGlgFR/9973BdspMWn8/HwFad9Pz05uiQodvVsP0eieLOcDcoQF63HQpwUf3WYcluJVOuXc+2h9R6gVFUnyk3okvqgAoGSUj6y\n\tPUP1CBF2X8Rdp2fqJ08arZg03961fBl+J0PnSZDd2jpoVnluj7HpdMDaZz1cdbmUmkIeBQBxUbNBubeOXcerTinHtASluVtCaO7TDuzOmHMLxiR4ur+pB2U+\n\t5GxqBXEQVfulZ/62PJ/dw9QACA7mdOnOE/F06a3jb28w1sksrSQIdVWUROM=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775249,"web_url":"http://patchwork.ozlabs.org/comment/1775249/","msgid":"<f82b3fc9-4250-197c-9bfe-d8a712901362@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:24:20","subject":"Re: [PATCH v14 22/28] v4l: async: Add a convenience function for\n\tregistering sensors","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 26/09/17 00:25, Sakari Ailus wrote:\n> Add a convenience function for parsing firmware for information on related\n> devices using v4l2_async_notifier_parse_fwnode_sensor_common() registering\n> the notifier and finally the async sub-device itself.\n> \n> This should be useful for sensor drivers that do not have device specific\n> requirements related to firmware information parsing or the async\n> framework.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n\nNice, makes sense.\n\nAcked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\nRegards,\n\n\tHans\n\n> ---\n>  drivers/media/v4l2-core/v4l2-async.c  |  5 +++++\n>  drivers/media/v4l2-core/v4l2-fwnode.c | 41 +++++++++++++++++++++++++++++++++++\n>  include/media/v4l2-async.h            | 22 +++++++++++++++++++\n>  include/media/v4l2-subdev.h           |  3 +++\n>  4 files changed, 71 insertions(+)\n> \n> diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c\n> index fe383c5d1215..f2c82f5a9747 100644\n> --- a/drivers/media/v4l2-core/v4l2-async.c\n> +++ b/drivers/media/v4l2-core/v4l2-async.c\n> @@ -580,6 +580,11 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)\n>  {\n>  \tstruct v4l2_async_notifier *notifier = sd->notifier;\n>  \n> +\tif (sd->subdev_notifier)\n> +\t\tv4l2_async_notifier_unregister(sd->subdev_notifier);\n> +\tv4l2_async_notifier_cleanup(sd->subdev_notifier);\n> +\tkfree(sd->subdev_notifier);\n> +\n>  \tif (!sd->asd) {\n>  \t\tif (!list_empty(&sd->async_list))\n>  \t\t\tv4l2_async_cleanup(sd);\n> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c\n> index 4976096a1d83..622bdcc2df2d 100644\n> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> @@ -29,6 +29,7 @@\n>  \n>  #include <media/v4l2-async.h>\n>  #include <media/v4l2-fwnode.h>\n> +#include <media/v4l2-subdev.h>\n>  \n>  enum v4l2_fwnode_bus_type {\n>  \tV4L2_FWNODE_BUS_TYPE_GUESS = 0,\n> @@ -814,6 +815,46 @@ int v4l2_async_notifier_parse_fwnode_sensor_common(\n>  }\n>  EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_sensor_common);\n>  \n> +int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd)\n> +{\n> +\tstruct v4l2_async_notifier *notifier;\n> +\tint ret;\n> +\n> +\tif (WARN_ON(!sd->dev))\n> +\t\treturn -ENODEV;\n> +\n> +\tnotifier = kzalloc(sizeof(*notifier), GFP_KERNEL);\n> +\tif (!notifier)\n> +\t\treturn -ENOMEM;\n> +\n> +\tret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev,\n> +\t\t\t\t\t\t\t     notifier);\n> +\tif (ret < 0)\n> +\t\tgoto out_cleanup;\n> +\n> +\tret = v4l2_async_subdev_notifier_register(sd, notifier);\n> +\tif (ret < 0)\n> +\t\tgoto out_cleanup;\n> +\n> +\tret = v4l2_async_register_subdev(sd);\n> +\tif (ret < 0)\n> +\t\tgoto out_unregister;\n> +\n> +\tsd->subdev_notifier = notifier;\n> +\n> +\treturn 0;\n> +\n> +out_unregister:\n> +\tv4l2_async_notifier_unregister(notifier);\n> +\n> +out_cleanup:\n> +\tv4l2_async_notifier_cleanup(notifier);\n> +\tkfree(notifier);\n> +\n> +\treturn ret;\n> +}\n> +EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common);\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 479c317fab2f..74f2ea27d117 100644\n> --- a/include/media/v4l2-async.h\n> +++ b/include/media/v4l2-async.h\n> @@ -173,6 +173,28 @@ void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier);\n>  int v4l2_async_register_subdev(struct v4l2_subdev *sd);\n>  \n>  /**\n> + * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device to\n> + *\t\t\t\t\t      the asynchronous sub-device\n> + *\t\t\t\t\t      framework and parse set up common\n> + *\t\t\t\t\t      sensor related devices\n> + *\n> + * @sd: pointer to struct &v4l2_subdev\n> + *\n> + * This function is just like v4l2_async_register_subdev() with the exception\n> + * that calling it will also parse firmware interfaces for remote references\n> + * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the\n> + * async sub-devices. The sub-device is similarly unregistered by calling\n> + * v4l2_async_unregister_subdev().\n> + *\n> + * While registered, the subdev module is marked as in-use.\n> + *\n> + * An error is returned if the module is no longer loaded on any attempts\n> + * to register it.\n> + */\n> +int __must_check v4l2_async_register_subdev_sensor_common(\n> +\tstruct v4l2_subdev *sd);\n> +\n> +/**\n>   * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous\n>   * \tsubdevice framework\n>   *\n> diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h\n> index e83872078376..ec399c770301 100644\n> --- a/include/media/v4l2-subdev.h\n> +++ b/include/media/v4l2-subdev.h\n> @@ -793,6 +793,8 @@ struct v4l2_subdev_platform_data {\n>   *\tlist.\n>   * @asd: Pointer to respective &struct v4l2_async_subdev.\n>   * @notifier: Pointer to the managing notifier.\n> + * @subdev_notifier: A sub-device notifier implicitly registered for the sub-\n> + *\t\t     device using v4l2_device_register_sensor_subdev().\n>   * @pdata: common part of subdevice platform data\n>   *\n>   * Each instance of a subdev driver should create this struct, either\n> @@ -823,6 +825,7 @@ struct v4l2_subdev {\n>  \tstruct list_head async_list;\n>  \tstruct v4l2_async_subdev *asd;\n>  \tstruct v4l2_async_notifier *notifier;\n> +\tstruct v4l2_async_notifier *subdev_notifier;\n>  \tstruct v4l2_subdev_platform_data *pdata;\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 3y1Ys80Qcwz9tX8\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:24:28 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S935472AbdIZIYZ (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:24:25 -0400","from lb2-smtp-cloud8.xs4all.net ([194.109.24.25]:39266 \"EHLO\n\tlb2-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S968007AbdIZIYW (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:24:22 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid wlACdUx3Jb4gvwlADdCE79; Tue, 26 Sep 2017 10:24:21 +0200"],"Subject":"Re: [PATCH v14 22/28] v4l: async: Add a convenience function for\n\tregistering sensors","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-23-sakari.ailus@linux.intel.com>","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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<f82b3fc9-4250-197c-9bfe-d8a712901362@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:24:20 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170925222540.371-23-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfE9hpV8Ka4+Myp5YEqudhs0BHpCh7fqNGe4u2mk8twu+LNdRiH5o7mr3o/pywIwfRrUW/2iS6vtn7dq9dpx9Lasa1ZA1eG+0QuxXFx/bpMXwOewPMnEi\n\tJnxi9gac5aj/ve9hvj49el7RYuuuetFLgahozZH1dJn2tzI+c7YRpkJ1Lsc98Q1NbSPoPWAUHBthzfXnGwqHV48NJ1MJjF1urqxrdeCLoIoJRPd4ojpiWedP\n\t7WNyXqijf3+pPEZ+IOS0HDa7tVlLIVos06hbGl+/DdPCNEHaFz711seDJa8ChO8+exqXPRX5VU46XGEjHijm8wj3fnx6yPw9F99hq6VNaqYNOPuTnwfMlf9U\n\tt+LkIAQWWptOUJhYbV/Xe89IIQz8SekSHhlIkVmOUIiKmIKkXqspwWofRDoOT6UtydTtzPaL/QEh9VGaR9WoPm7A7bZIYzEG1rtF2Rutk3C5C7nUnliLjTSM\n\tRcRosFbKwqL5dPer7vYnN2YXYtLFHMU1CWqinTgLYT8hpAzgV+OweuPuj5c=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775251,"web_url":"http://patchwork.ozlabs.org/comment/1775251/","msgid":"<ac50fc71-c528-a703-04bb-6abc1fc7c19a@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:26:35","subject":"Re: [PATCH v14 22/28] v4l: fwnode: Add a convenience function for\n\tregistering sensors","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 26/09/17 00:25, Sakari Ailus wrote:\n> Add a convenience function for parsing firmware for information on related\n> devices using v4l2_async_notifier_parse_fwnode_sensor_common() registering\n> the notifier and finally the async sub-device itself.\n> \n> This should be useful for sensor drivers that do not have device specific\n> requirements related to firmware information parsing or the async\n> framework.\n\nI'm confused. This is a second patch 22/28 that appears to be identical to the\nprevious one.\n\nI'm ignoring this one, I assume something went wrong when you mailed this series.\n\nRegards,\n\n\tHans\n\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n> ---\n>  drivers/media/v4l2-core/v4l2-async.c  |  5 +++++\n>  drivers/media/v4l2-core/v4l2-fwnode.c | 41 +++++++++++++++++++++++++++++++++++\n>  include/media/v4l2-async.h            | 22 +++++++++++++++++++\n>  include/media/v4l2-subdev.h           |  3 +++\n>  4 files changed, 71 insertions(+)\n> \n> diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c\n> index 470607da96b2..f388892f43ec 100644\n> --- a/drivers/media/v4l2-core/v4l2-async.c\n> +++ b/drivers/media/v4l2-core/v4l2-async.c\n> @@ -570,6 +570,11 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)\n>  {\n>  \tstruct v4l2_async_notifier *notifier = sd->notifier;\n>  \n> +\tif (sd->subdev_notifier)\n> +\t\tv4l2_async_notifier_unregister(sd->subdev_notifier);\n> +\tv4l2_async_notifier_cleanup(sd->subdev_notifier);\n> +\tkfree(sd->subdev_notifier);\n> +\n>  \tif (!sd->asd) {\n>  \t\tif (!list_empty(&sd->async_list))\n>  \t\t\tv4l2_async_cleanup(sd);\n> diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c\n> index 4976096a1d83..622bdcc2df2d 100644\n> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> @@ -29,6 +29,7 @@\n>  \n>  #include <media/v4l2-async.h>\n>  #include <media/v4l2-fwnode.h>\n> +#include <media/v4l2-subdev.h>\n>  \n>  enum v4l2_fwnode_bus_type {\n>  \tV4L2_FWNODE_BUS_TYPE_GUESS = 0,\n> @@ -814,6 +815,46 @@ int v4l2_async_notifier_parse_fwnode_sensor_common(\n>  }\n>  EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_sensor_common);\n>  \n> +int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd)\n> +{\n> +\tstruct v4l2_async_notifier *notifier;\n> +\tint ret;\n> +\n> +\tif (WARN_ON(!sd->dev))\n> +\t\treturn -ENODEV;\n> +\n> +\tnotifier = kzalloc(sizeof(*notifier), GFP_KERNEL);\n> +\tif (!notifier)\n> +\t\treturn -ENOMEM;\n> +\n> +\tret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev,\n> +\t\t\t\t\t\t\t     notifier);\n> +\tif (ret < 0)\n> +\t\tgoto out_cleanup;\n> +\n> +\tret = v4l2_async_subdev_notifier_register(sd, notifier);\n> +\tif (ret < 0)\n> +\t\tgoto out_cleanup;\n> +\n> +\tret = v4l2_async_register_subdev(sd);\n> +\tif (ret < 0)\n> +\t\tgoto out_unregister;\n> +\n> +\tsd->subdev_notifier = notifier;\n> +\n> +\treturn 0;\n> +\n> +out_unregister:\n> +\tv4l2_async_notifier_unregister(notifier);\n> +\n> +out_cleanup:\n> +\tv4l2_async_notifier_cleanup(notifier);\n> +\tkfree(notifier);\n> +\n> +\treturn ret;\n> +}\n> +EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common);\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 479c317fab2f..74f2ea27d117 100644\n> --- a/include/media/v4l2-async.h\n> +++ b/include/media/v4l2-async.h\n> @@ -173,6 +173,28 @@ void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier);\n>  int v4l2_async_register_subdev(struct v4l2_subdev *sd);\n>  \n>  /**\n> + * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device to\n> + *\t\t\t\t\t      the asynchronous sub-device\n> + *\t\t\t\t\t      framework and parse set up common\n> + *\t\t\t\t\t      sensor related devices\n> + *\n> + * @sd: pointer to struct &v4l2_subdev\n> + *\n> + * This function is just like v4l2_async_register_subdev() with the exception\n> + * that calling it will also parse firmware interfaces for remote references\n> + * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the\n> + * async sub-devices. The sub-device is similarly unregistered by calling\n> + * v4l2_async_unregister_subdev().\n> + *\n> + * While registered, the subdev module is marked as in-use.\n> + *\n> + * An error is returned if the module is no longer loaded on any attempts\n> + * to register it.\n> + */\n> +int __must_check v4l2_async_register_subdev_sensor_common(\n> +\tstruct v4l2_subdev *sd);\n> +\n> +/**\n>   * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous\n>   * \tsubdevice framework\n>   *\n> diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h\n> index e83872078376..ec399c770301 100644\n> --- a/include/media/v4l2-subdev.h\n> +++ b/include/media/v4l2-subdev.h\n> @@ -793,6 +793,8 @@ struct v4l2_subdev_platform_data {\n>   *\tlist.\n>   * @asd: Pointer to respective &struct v4l2_async_subdev.\n>   * @notifier: Pointer to the managing notifier.\n> + * @subdev_notifier: A sub-device notifier implicitly registered for the sub-\n> + *\t\t     device using v4l2_device_register_sensor_subdev().\n>   * @pdata: common part of subdevice platform data\n>   *\n>   * Each instance of a subdev driver should create this struct, either\n> @@ -823,6 +825,7 @@ struct v4l2_subdev {\n>  \tstruct list_head async_list;\n>  \tstruct v4l2_async_subdev *asd;\n>  \tstruct v4l2_async_notifier *notifier;\n> +\tstruct v4l2_async_notifier *subdev_notifier;\n>  \tstruct v4l2_subdev_platform_data *pdata;\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 3y1Yvk3tmhz9tXc\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:26:42 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S965861AbdIZI0j (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:26:39 -0400","from lb3-smtp-cloud8.xs4all.net ([194.109.24.29]:46351 \"EHLO\n\tlb3-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S934968AbdIZI0i (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:26:38 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid wlCOdUztfb4gvwlCPdCFgY; Tue, 26 Sep 2017 10:26:37 +0200"],"Subject":"Re: [PATCH v14 22/28] v4l: fwnode: Add a convenience function for\n\tregistering sensors","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-24-sakari.ailus@linux.intel.com>","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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<ac50fc71-c528-a703-04bb-6abc1fc7c19a@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:26:35 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170925222540.371-24-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfLEBJ/T38uuwfjlwMhNDttvQSWGnL3b4pDBNz0ub1igprSqBHpg/xJp0eVII7e4mcFsp5PGmcUDuw3ikz+5bVJZBOpbQG3pxhH8SUOMtS8KJsW6vbl5R\n\tCU1W+7AyYjbMhE5hYK4wmNQmTzZe6KWBII9IEd1bS6DOWo6F9Uc7VZ6irYngfz0Xp7xHdmmjGFcN8CPk/z9F0gywi25WUA1cFhcVrvrr6fyxbFXvkr2Z4GEr\n\tzcg8LNchY8yHnO2qF5QHbdQy4D//UQs/O3nKp0yS641EWfSo/OSA3UW1ywpd8F4WqIvjja9kJ3lQviFHDxEQyeC+mHDYodqV77DsxARAh9qbLkO7nZJGRnjb\n\tUNo3N+rBRkqfR4I+P5DlfGnMkj7iVcKviseYKOISNRspNGzKBDrj+17fJkM3SMhcpLqX0ZcY47xDrGRtAVX45vIDa9jf29LSbrP9NpQ+WXdRpWBryihxm2XJ\n\tBbZ8Si5/BN1ZgiiVeaqVeU+N6H5GWtmdwm+4vIyaaBxDkJDe+b0rCp32pYY=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775253,"web_url":"http://patchwork.ozlabs.org/comment/1775253/","msgid":"<9c1d4bc0-63b1-65be-2444-0c5c8e74c7b0@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:26:49","subject":"Re: [PATCH v14 24/28] smiapp: Add support for flash and lens devices","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 26/09/17 00:25, Sakari Ailus wrote:\n> Parse async sub-devices related to the sensor by switching the async\n> sub-device registration function.\n> \n> These types devices aren't directly related to the sensor, but are\n> nevertheless handled by the smiapp driver due to the relationship of these\n> component to the main part of the camera module --- the sensor.\n> \n> This does not yet address providing the user space with information on how\n> to associate the sensor or lens devices but the kernel now has the\n> necessary information to do that.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n\nAcked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\n> ---\n>  drivers/media/i2c/smiapp/smiapp-core.c | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n> \n> diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c\n> index 700f433261d0..3d9a251ca825 100644\n> --- a/drivers/media/i2c/smiapp/smiapp-core.c\n> +++ b/drivers/media/i2c/smiapp/smiapp-core.c\n> @@ -3092,7 +3092,7 @@ static int smiapp_probe(struct i2c_client *client,\n>  \tif (rval < 0)\n>  \t\tgoto out_media_entity_cleanup;\n>  \n> -\trval = v4l2_async_register_subdev(&sensor->src->sd);\n> +\trval = v4l2_async_register_subdev_sensor_common(&sensor->src->sd);\n>  \tif (rval < 0)\n>  \t\tgoto out_media_entity_cleanup;\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 3y1Yw21F8Hz9tXk\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:26:58 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S968015AbdIZI0y (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:26:54 -0400","from lb2-smtp-cloud8.xs4all.net ([194.109.24.25]:57298 \"EHLO\n\tlb2-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S936633AbdIZI0w (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:26:52 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid wlCbdV09Sb4gvwlCcdCFqQ; Tue, 26 Sep 2017 10:26:50 +0200"],"Subject":"Re: [PATCH v14 24/28] smiapp: Add support for flash and lens devices","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-26-sakari.ailus@linux.intel.com>","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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<9c1d4bc0-63b1-65be-2444-0c5c8e74c7b0@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:26:49 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170925222540.371-26-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfAkXA0TKS2M3LKqq3OnEY0QWQkbOQml0WBGE4MAAnF8Wim2qxvJOufcJbZRoKSE+9k/2ctUwllxC7xE6x0hYF3EwBs8088kVR1QEhJ1QezzBcNs/0dbt\n\tyJtqhL5ARxk9X71L2scDqDydhRcZz9OPJNyFmKqV8+IEcHKugoUGEw6kaN6s2Lnq3efw+KfekuNGtgnVfurKNbZydO1cNiPZjdL/8eD8GrSedlBVMioYsC/9\n\twhishR6hJ84QCDHD43l02l5rg4+t9OuB+jKC9Nw8cScWrNJhRR/QDoLWQBG/41mskol/Y0IAPfZHfoJXECHvKJ6zo7qi4s+PNVPlqoa7t1+Py3nYJFyJ2r8D\n\tb9zDlfQCYpy44KYCL07eet7lWICITCGiX6F1EYUxwfydiXY+ZCtSw07PzXaVLWbwe4E2v1hhMkaFj/1sjd26ud2jgOjkRosUZSeBeO0HFckI6TiQD5eszK8D\n\tJIXa+gMXSWgaJsdrettihSUdUtc6voE7Yje6SwUY7YlEAlPXz4uCVpG0eas=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775254,"web_url":"http://patchwork.ozlabs.org/comment/1775254/","msgid":"<c6e8b44e-94d2-77a0-bfbc-48b45edc0c34@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:27:00","subject":"Re: [PATCH v14 25/28] et8ek8: Add support for flash and lens devices","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 26/09/17 00:25, Sakari Ailus wrote:\n> Parse async sub-devices related to the sensor by switching the async\n> sub-device registration function.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n\nAcked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\n> ---\n>  drivers/media/i2c/et8ek8/et8ek8_driver.c | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n> \n> diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c\n> index c14f0fd6ded3..e9eff9039ef5 100644\n> --- a/drivers/media/i2c/et8ek8/et8ek8_driver.c\n> +++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c\n> @@ -1453,7 +1453,7 @@ static int et8ek8_probe(struct i2c_client *client,\n>  \t\tgoto err_mutex;\n>  \t}\n>  \n> -\tret = v4l2_async_register_subdev(&sensor->subdev);\n> +\tret = v4l2_async_register_subdev_sensor_common(&sensor->subdev);\n>  \tif (ret < 0)\n>  \t\tgoto err_entity;\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 3y1YwD3Tjxz9tX8\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:27:08 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S968019AbdIZI1E (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:27:04 -0400","from lb2-smtp-cloud8.xs4all.net ([194.109.24.25]:57298 \"EHLO\n\tlb2-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S968016AbdIZI1C (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:27:02 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid wlCmdV0Ldb4gvwlCndCFxI; Tue, 26 Sep 2017 10:27:01 +0200"],"Subject":"Re: [PATCH v14 25/28] et8ek8: Add support for flash and lens devices","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-27-sakari.ailus@linux.intel.com>","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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<c6e8b44e-94d2-77a0-bfbc-48b45edc0c34@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:27:00 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170925222540.371-27-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfGAzHOaVhsOdLJ2XI+0K4uL/qZuAxsFO43975Y8kbP5zJft08pUst9D2AVpqObx2T6e2QwfxBOYrnVPhqp4eZLtvf8U59ElpxuslefH/2UiOUkfEPm+7\n\tjAnP6nI+fCIzQRUvR7UaYNo5lNyldOOzn9ADeJFKVHpbQsfC3TrYCx9PM7ikmnXctl4ABvScHr7/n+RujAGXhRfF5fhwzwhCKIseSVCi4i/SNsqjkRpkhPR9\n\tDGU50miyIQmkL80xAuHsgsyMoPxLBDdmAd4pNc2FccV1bY7A8wp2/yKj9kodziloDMw81Jc1EMg6RZnR4J3EhBzU5vGN0i9GPflAx1Yof+caxq2QnceFGH4h\n\t1IdWT+938kMH+Bhp3TW/8c0A+HcUx/6qdMxTBqMVTuNpShVsXJJoCPOg2JZFppCrW/R5RNwotbz2jgfantnMiquZS2LAn48DRiQTn/sw80jOXZV9j5undO2H\n\tfRtxWoeoJeQGDcHxpjiyD5U7fJbYtDbODtJxi4cmT0Wgmqmrl5SZvF8xFiw=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775255,"web_url":"http://patchwork.ozlabs.org/comment/1775255/","msgid":"<7978e2fb-6c6c-ec9a-6576-b067d8b30542@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:27:08","subject":"Re: [PATCH v14 26/28] ov5670: Add support for flash and lens devices","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 26/09/17 00:25, Sakari Ailus wrote:\n> Parse async sub-devices related to the sensor by switching the async\n> sub-device registration function.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n\nAcked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\n> ---\n>  drivers/media/i2c/ov5670.c | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n> \n> diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c\n> index 6f7a1d6d2200..0a1723f5a66c 100644\n> --- a/drivers/media/i2c/ov5670.c\n> +++ b/drivers/media/i2c/ov5670.c\n> @@ -2514,7 +2514,7 @@ static int ov5670_probe(struct i2c_client *client)\n>  \t}\n>  \n>  \t/* Async register for subdev */\n> -\tret = v4l2_async_register_subdev(&ov5670->sd);\n> +\tret = v4l2_async_register_subdev_sensor_common(&ov5670->sd);\n>  \tif (ret < 0) {\n>  \t\terr_msg = \"v4l2_async_register_subdev() error\";\n>  \t\tgoto error_entity_cleanup;\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 3y1YwJ5jFHz9tX8\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:27:12 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S968020AbdIZI1L (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:27:11 -0400","from lb1-smtp-cloud8.xs4all.net ([194.109.24.21]:59341 \"EHLO\n\tlb1-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S968016AbdIZI1L (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:27:11 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid wlCudV0UYb4gvwlCvdCG2P; Tue, 26 Sep 2017 10:27:09 +0200"],"Subject":"Re: [PATCH v14 26/28] ov5670: Add support for flash and lens devices","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-28-sakari.ailus@linux.intel.com>","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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<7978e2fb-6c6c-ec9a-6576-b067d8b30542@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:27:08 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170925222540.371-28-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfMkbgtHi+jSaokZ6EHkkJzixe2WZ3WydYFOaFD2Qcra1zBtHABzmBdMa5IVw6F/Of1KjMdf4iDlaWGqghk+tE0RmD+2Fwm4ShSHBfLmmHU2n4I2VkxLb\n\tJcOep4b5byj1Y4yPcMoKJKhO6rvnVavzGEC/lQOQ/TKpa33l0rxr3iwiNmmkn57fph81Se8vaZomAAq61vED6hKZgqR59ujVloZr8zE2xNGijo6dTsJRZCT7\n\tCLjbAY36DVe1x4XBNupY40NSouapktzuSFpnKHu5xji0rwxXI8alyR2ebzfDVCYL+M5xOJK6xcoxwmXUE7SRwa+Ht7A0VKe5g0DFoXaSG5qF783cCWiGiGTN\n\tzzauPaS4biCZG+z+7ubH4mHlTfhpeNOF+Tq8jiM10sEO3h4WzpWwP3D1yQ1QV4TWBKR32cOdJuPVBPYfWy95I6TJcZ2Xv7PO5HtqS9PH9NEM8G9XiLo3zoxG\n\tFpeOXP250Oc+svodOqTtao4VaN8ngmgYkz+EOEhG/ahE5JlqJEjx0AXcVMQ=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775256,"web_url":"http://patchwork.ozlabs.org/comment/1775256/","msgid":"<483250c9-ba06-a778-b88f-0e4734a36834@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:27:19","subject":"Re: [PATCH v14 27/28] ov13858: Add support for flash and lens\n\tdevices","submitter":{"id":723,"url":"http://patchwork.ozlabs.org/api/people/723/","name":"Hans Verkuil","email":"hverkuil@xs4all.nl"},"content":"On 26/09/17 00:25, Sakari Ailus wrote:\n> Parse async sub-devices related to the sensor by switching the async\n> sub-device registration function.\n> \n> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>\n\nAcked-by: Hans Verkuil <hans.verkuil@cisco.com>\n\n> ---\n>  drivers/media/i2c/ov13858.c | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n> \n> diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c\n> index af7af0d14c69..c86525982e17 100644\n> --- a/drivers/media/i2c/ov13858.c\n> +++ b/drivers/media/i2c/ov13858.c\n> @@ -1746,7 +1746,7 @@ static int ov13858_probe(struct i2c_client *client,\n>  \t\tgoto error_handler_free;\n>  \t}\n>  \n> -\tret = v4l2_async_register_subdev(&ov13858->sd);\n> +\tret = v4l2_async_register_subdev_sensor_common(&ov13858->sd);\n>  \tif (ret < 0)\n>  \t\tgoto error_media_entity;\n>  \n> \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 3y1YwX1bmlz9tX8\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:27:24 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S968024AbdIZI1V (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:27:21 -0400","from lb2-smtp-cloud8.xs4all.net ([194.109.24.25]:57298 \"EHLO\n\tlb2-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S968016AbdIZI1U (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:27:20 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid wlD5dV0fsb4gvwlD6dCG9b; Tue, 26 Sep 2017 10:27:20 +0200"],"Subject":"Re: [PATCH v14 27/28] ov13858: Add support for flash and lens\n\tdevices","To":"Sakari Ailus <sakari.ailus@linux.intel.com>, linux-media@vger.kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-29-sakari.ailus@linux.intel.com>","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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<483250c9-ba06-a778-b88f-0e4734a36834@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:27:19 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170925222540.371-29-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfPmTxJ7qiw0TM56+msj2DqK4nrXTAgXdroLbYHuylcdZn4+oLoGPHQbsaRmA3Esf927TsCSzI23D/xYJ3xY6/SDv8rLuetQ424YzDO9li/Eg9ZS6jyJf\n\t+weYaIZYlJPoOofdQFVIx8jKq0d5YiAuHKlng9N79uNYPM0WsMoAAxsrCrCOht5ZHT9EXmSrQMBgh6YMrMLSyhKWaqBW+C+V0SFXfdnWEFf6ZLv39GBckzuK\n\tscBsnLMIW2SFRgcp6VrpSMASpVbADHipRbKiVard08vqg7l9ivQ9ez9DEdNRxwnCimVm7mmZrwP60NJl9+l6P3knSh614KiHnykrioea6+pYpb0nE/OXiCr1\n\tv1y7NdPg64qP0EBo/Vn0ACjkp0AjTP03ZnS3hy9GubypyN7D7PMRYJ6SydHcjxzIH0IQYxICyaGXqcnAG0mk7FVCNCXYd88TZkIL5sfbqxWNSppz0RNgcOri\n\t+b4XqIamZWLQH9sJg8MMxUGyfo0ccdb566doRdJ+2jxNM9+zysPTEVofAN0=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775257,"web_url":"http://patchwork.ozlabs.org/comment/1775257/","msgid":"<20170926082947.xwwhn6k2v5dktviz@paasikivi.fi.intel.com>","list_archive_url":null,"date":"2017-09-26T08:29:47","subject":"Re: [PATCH v14 22/28] v4l: fwnode: Add a convenience function for\n\tregistering sensors","submitter":{"id":65485,"url":"http://patchwork.ozlabs.org/api/people/65485/","name":"Sakari Ailus","email":"sakari.ailus@linux.intel.com"},"content":"On Tue, Sep 26, 2017 at 10:26:35AM +0200, Hans Verkuil wrote:\n> On 26/09/17 00:25, Sakari Ailus wrote:\n> > Add a convenience function for parsing firmware for information on related\n> > devices using v4l2_async_notifier_parse_fwnode_sensor_common() registering\n> > the notifier and finally the async sub-device itself.\n> > \n> > This should be useful for sensor drivers that do not have device specific\n> > requirements related to firmware information parsing or the async\n> > framework.\n> \n> I'm confused. This is a second patch 22/28 that appears to be identical to the\n> previous one.\n> \n> I'm ignoring this one, I assume something went wrong when you mailed this series.\n\nYes. I changed the subject but accidentally used the same directory for the\npatches. The patch is the same.\n\nThe intended subject prefix is \"v4l: fwnode\".","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 3y1YzS1kgBz9tXc\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:29:56 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S968084AbdIZI3w (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:29:52 -0400","from mga14.intel.com ([192.55.52.115]:38899 \"EHLO mga14.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S936633AbdIZI3v (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tTue, 26 Sep 2017 04:29:51 -0400","from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t26 Sep 2017 01:29:50 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby fmsmga001.fm.intel.com with ESMTP; 26 Sep 2017 01:29:48 -0700","by paasikivi.fi.intel.com (Postfix, from userid 1000)\n\tid 77CB2206D7; Tue, 26 Sep 2017 11:29:47 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos; i=\"5.42,440,1500966000\"; d=\"scan'208\";\n\ta=\"1199075029\"","Date":"Tue, 26 Sep 2017 11:29:47 +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 v14 22/28] v4l: fwnode: Add a convenience function for\n\tregistering sensors","Message-ID":"<20170926082947.xwwhn6k2v5dktviz@paasikivi.fi.intel.com>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-24-sakari.ailus@linux.intel.com>\n\t<ac50fc71-c528-a703-04bb-6abc1fc7c19a@xs4all.nl>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<ac50fc71-c528-a703-04bb-6abc1fc7c19a@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":1775268,"web_url":"http://patchwork.ozlabs.org/comment/1775268/","msgid":"<fbd2f71d-aa6d-08ef-1723-132864bde27b@xs4all.nl>","list_archive_url":null,"date":"2017-09-26T08:47:40","subject":"Re: [PATCH v14 20/28] 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 26/09/17 00:25, 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> 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 f739dfd16cf7..f93049c361e4 100644\n> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> @@ -578,6 +578,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> + * 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\"at an index\". Still makes no sense to me. Which index?\n\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\nI know I asked for this before, but can you change the example to one where\nnprops = 2? I think that will help understanding this.\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\ncorresponding -> corresponding to\n\n> +\t * integer arguments.\n> +\t */\n> +\tfwnode = fwnode_args.fwnode;\n> +\twhile (nprops--) {\n> +\t\tu32 val;\n> +\n> +\t\t/* Loop over all child nodes under fwnode. */\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 3y1ZND4WpMz9tXK\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 18:47:56 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S934425AbdIZIru (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 04:47:50 -0400","from lb1-smtp-cloud9.xs4all.net ([194.109.24.22]:47493 \"EHLO\n\tlb1-smtp-cloud9.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S937098AbdIZIro (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 26 Sep 2017 04:47:44 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud9.xs4all.net with ESMTPA\n\tid wlWmdFuDsnIXbwlWndkD0f; Tue, 26 Sep 2017 10:47:42 +0200"],"Subject":"Re: [PATCH v14 20/28] 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","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-21-sakari.ailus@linux.intel.com>","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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<fbd2f71d-aa6d-08ef-1723-132864bde27b@xs4all.nl>","Date":"Tue, 26 Sep 2017 10:47:40 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170925222540.371-21-sakari.ailus@linux.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfD3HYb30H0oZFqNkWXVuaGJ8X9ZaNbNsNDWPXEQd+diaaYruuI92jv+DpVXM4EZtbVystDrMu5KRYG/Fi/nfTjFS2lCQiW+PkYLkSHBAiBk/17ZgC6WK\n\t8KG6sAhhwbSDhBQEcNTQBUbJg8o5877FOiiFRvh+Tkbfy0HQzmMfH8nToXkJTUg2yHrywpf8XrKmwJtekObVzr09E9yJWEIJnIDZeysanWHHa0D7XbYA/bMu\n\tGLjN5NU9YgsomMld2O8K6q9DBZ86tgeivwR3K5WbFMcIJHj/t/BdUx3X15sYe3FZ43igXyso8+wxUuy8IraFPxRuBBpzk8W6gZGfuTtifaUkQ4kMvGPU1fX5\n\tX52tSdq1BLTpmWul+Ph2+e3/WWf5by9ZvfiPhbGGWgsKxgBSXBTlJwI2mIV2eP1JZzhK5qM0+UvUr2ABduU631ohiI/9CFY6BZBRKf8x+A1OcVSi2nIVrsu9\n\t7hfHdD83SVCjJUUyftv9s36R+tU77Cf8OAIhrlJQEoLApLOS25HdSfK4dEA=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1775387,"web_url":"http://patchwork.ozlabs.org/comment/1775387/","msgid":"<20170926113029.eh5i4sp6we6lvgow@paasikivi.fi.intel.com>","list_archive_url":null,"date":"2017-09-26T11:30:30","subject":"Re: [PATCH v14 20/28] 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\nThanks for the review.\n\nOn Tue, Sep 26, 2017 at 10:47:40AM +0200, Hans Verkuil wrote:\n> On 26/09/17 00:25, 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> > 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 f739dfd16cf7..f93049c361e4 100644\n> > --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> > +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> > @@ -578,6 +578,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> > + * 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> \"at an index\". Still makes no sense to me. Which index?\n\nHow about this:\n\nFirst find an fwnode referred to by the reference at @index in @prop.\n\nThen under that fwnode, @nprops times, for each property in @props,\niteratively follow child nodes starting from fwnode such that they have the\nproperty in @props array at the index of the child node distance from the\nroot node and the value of that property matching with the integer argument of\nthe reference, at the same index.\n\n> \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> I know I asked for this before, but can you change the example to one where\n> nprops = 2? I think that will help understanding this.\n\nI could do that but then the example no longer corresponds to any actual\ncase that exists at the moment. LED nodes will use a single integer\nargument and lens-focus nodes none.\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> \n> corresponding -> corresponding to\n\nFixed.\n\n> \n> > +\t * integer arguments.\n> > +\t */\n> > +\tfwnode = fwnode_args.fwnode;\n> > +\twhile (nprops--) {\n> > +\t\tu32 val;\n> > +\n> > +\t\t/* Loop over all child nodes under fwnode. */\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> \n> Regards,\n> \n> \tHans","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 3y1dzy2SxGz9tXb\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 21:30:38 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S968356AbdIZLag (ORCPT <rfc822; incoming-dt@patchwork.ozlabs.org>);\n\tTue, 26 Sep 2017 07:30:36 -0400","from mga14.intel.com ([192.55.52.115]:60427 \"EHLO mga14.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S968350AbdIZLae (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tTue, 26 Sep 2017 07:30:34 -0400","from orsmga003.jf.intel.com ([10.7.209.27])\n\tby fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t26 Sep 2017 04:30:34 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby orsmga003.jf.intel.com with ESMTP; 26 Sep 2017 04:30:31 -0700","by paasikivi.fi.intel.com (Postfix, from userid 1000)\n\tid 1E103206D7; Tue, 26 Sep 2017 14:30:30 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos; i=\"5.42,440,1500966000\"; d=\"scan'208\";\n\ta=\"1018530451\"","Date":"Tue, 26 Sep 2017 14:30:30 +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 v14 20/28] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","Message-ID":"<20170926113029.eh5i4sp6we6lvgow@paasikivi.fi.intel.com>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-21-sakari.ailus@linux.intel.com>\n\t<fbd2f71d-aa6d-08ef-1723-132864bde27b@xs4all.nl>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<fbd2f71d-aa6d-08ef-1723-132864bde27b@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":1777910,"web_url":"http://patchwork.ozlabs.org/comment/1777910/","msgid":"<20170930131709.GP17182@bigcity.dyn.berto.se>","list_archive_url":null,"date":"2017-09-30T13:17:09","subject":"Re: [PATCH v14 07/28] rcar-vin: Use generic parser for parsing\n\tfwnode endpoints","submitter":{"id":67773,"url":"http://patchwork.ozlabs.org/api/people/67773/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Sakari,\n\nThanks for your patch, I like it. Unfortunately it causes issues :-(\n\nI picked the first 7 patches of this series on top of media-next and it \nproduce problems when tested on Koelsch with CONFIG_OF_DYNAMIC=y.\n\n1. It print's 'OF: ERROR: Bad of_node_put() on /video@e6ef0000/port' \n   messages during boot.\n\n   OF: ERROR: Bad of_node_put() on /video@e6ef0000/port\n   CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.13.0-rc4-00632-gfae12f9c98a8c567 #7\n   Hardware name: Generic R8A7791 (Flattened Device Tree)\n   Backtrace: \n   [<c010b16c>] (dump_backtrace) from [<c010b3b8>] (show_stack+0x18/0x1c)\n    r7:00000001 r6:60000013 r5:00000000 r4:c0a7c88c\n   [<c010b3a0>] (show_stack) from [<c06d9034>] (dump_stack+0x84/0xa0)\n   [<c06d8fb0>] (dump_stack) from [<c05814ac>] (of_node_release+0x2c/0x94)\n    r7:00000001 r6:c0a6fc4c r5:eb1284c0 r4:eb7c7a00\n   [<c0581480>] (of_node_release) from [<c06dcd3c>] (kobject_put+0xbc/0xdc)\n    r7:00000001 r6:c0a6fc4c r5:eb1284c0 r4:eb7c7a00\n   [<c06dcc80>] (kobject_put) from [<c0580d48>] (of_node_put+0x1c/0x20)\n    r6:eb7c7af8 r5:eb7c79e0 r4:eb7c7798\n   [<c0580d2c>] (of_node_put) from [<c057fc18>] (of_fwnode_put+0x38/0x44)\n   [<c057fbe0>] (of_fwnode_put) from [<c04244a8>] (fwnode_handle_put+0x30/0x34)\n   [<c0424478>] (fwnode_handle_put) from [<c0424714>] (fwnode_graph_get_port_parent+0x44/0x4c)\n   [<c04246d0>] (fwnode_graph_get_port_parent) from [<c0514820>] (__v4l2_async_notifier_parse_fwnode_endpoints+0x1dc/0x2d8)\n    r5:eaa56bd8 r4:00000000\n   [<c0514644>] (__v4l2_async_notifier_parse_fwnode_endpoints) from [<c0514a9c>] (v4l2_async_notifier_parse_fwnode_endpoints+0x20/0x28)\n    r10:00000000 r9:eaa56bd8 r8:c0a6c504 r7:eb251a10 r6:eb251a00 r5:00000000\n    r4:eaa56810\n   [<c0514a7c>] (v4l2_async_notifier_parse_fwnode_endpoints) from [<c05433b8>] (rcar_vin_probe+0xcc/0x178)\n   [<c05432ec>] (rcar_vin_probe) from [<c0420a3c>] (platform_drv_probe+0x58/0xa4)\n    r9:00000000 r8:c0a6c504 r7:00000000 r6:c0a6c504 r5:eb251a10 r4:c05432ec\n   [<c04209e4>] (platform_drv_probe) from [<c041f320>] (driver_probe_device+0x210/0x2d8)\n    r7:00000000 r6:c0ac72d4 r5:c0ac72c8 r4:eb251a10\n   [<c041f110>] (driver_probe_device) from [<c041f46c>] (__driver_attach+0x84/0xb0)\n    r10:00000000 r9:c096d224 r8:00000000 r7:c0a50cf0 r6:c0a6c504 r5:eb251a44\n    r4:eb251a10 r3:00000000\n   [<c041f3e8>] (__driver_attach) from [<c041da08>] (bus_for_each_dev+0x88/0x98)\n    r7:c0a50cf0 r6:c041f3e8 r5:c0a6c504 r4:00000000\n   [<c041d980>] (bus_for_each_dev) from [<c041f5bc>] (driver_attach+0x20/0x28)\n    r6:00000000 r5:eaa55f80 r4:c0a6c504\n   [<c041f59c>] (driver_attach) from [<c041e190>] (bus_add_driver+0x170/0x1e0)\n   [<c041e020>] (bus_add_driver) from [<c0420068>] (driver_register+0xa8/0xe8)\n    r7:c095883c r6:000000cb r5:ffffe000 r4:c0a6c504\n   [<c041ffc0>] (driver_register) from [<c04214b0>] (__platform_driver_register+0x38/0x4c)\n    r5:ffffe000 r4:c0935328\n   [<c0421478>] (__platform_driver_register) from [<c0935340>] (rcar_vin_driver_init+0x18/0x20)\n   [<c0935328>] (rcar_vin_driver_init) from [<c0900ecc>] (do_one_initcall+0x12c/0x154)\n   [<c0900da0>] (do_one_initcall) from [<c0901080>] (kernel_init_freeable+0x18c/0x1d0)\n    r8:c0a8a700 r7:c095883c r6:000000cb r5:c0a8a700 r4:00000007\n   [<c0900ef4>] (kernel_init_freeable) from [<c06eac64>] (kernel_init+0x10/0x110)\n    r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c06eac54 r4:00000000\n   [<c06eac54>] (kernel_init) from [<c0106db8>] (ret_from_fork+0x14/0x3c)\n    r5:c06eac54 r4:00000000\n\n2. It then proceeds to OOPS.\n\n   Unable to handle kernel NULL pointer dereference at virtual address 0000000c\n   pgd = c0004000\n   [0000000c] *pgd=00000000\n   Internal error: Oops: 5 [#1] SMP ARM\n   CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.13.0-rc4-00632-gfae12f9c98a8c567 #7\n   Hardware name: Generic R8A7791 (Flattened Device Tree)\n   task: eb09b840 task.stack: eb09c000\n   PC is at rvin_v4l2_probe+0x38/0x1ec\n   LR is at rvin_digital_notify_complete+0x10c/0x11c\n   pc : [<c054594c>]    lr : [<c0543614>]    psr: a0000013\n   sp : eb09dcf8  ip : eb09dd20  fp : eb09dd1c\n   r10: 00000000  r9 : eaa56bd8  r8 : 00002006\n   r7 : eaa56810  r6 : c0a1e6dc  r5 : 00000000  r4 : eaa56810\n   r3 : 00000000  r2 : 00000001  r1 : eaa57ec0  r0 : eaa56810\n   Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none\n   Control: 10c5387d  Table: 4000406a  DAC: 00000051\n   Process swapper/0 (pid: 1, stack limit = 0xeb09c210)\n   Stack: (0xeb09dcf8 to 0xeb09e000)\n   dce0:                                                       ea9e2868 eb1284c0\n   dd00: eaa56bd8 00000000 eb1284c0 eaa56810 eb09dd74 eb09dd20 c0543614 c0545920\n   dd20: 00000001 00000001 0000100a 00000001 00000000 00000000 00000000 00000000\n   dd40: 00000000 00000000 00000000 00000000 c051c17c eaa56bd8 c0543508 ea9e2868\n   dd60: eb1284c0 c0a5ff2c eb09dd94 eb09dd78 c0525164 c0543514 eaa56bd8 c0a5ff18\n   dd80: ea9e2868 eb3cda50 eb09ddbc eb09dd98 c0525288 c0525088 eaa56810 00000000\n   dda0: eb251a00 eb251a10 00000000 eaa56bd8 eb09dde4 eb09ddc0 c05433f0 c0525178\n   ddc0: c05432ec eb251a10 c0a6c504 00000000 c0a6c504 00000000 eb09de04 eb09dde8\n   dde0: c0420a3c c05432f8 eb251a10 c0ac72c8 c0ac72d4 00000000 eb09de34 eb09de08\n   de00: c041f320 c04209f0 00000000 eb251a10 eb251a44 c0a6c504 c0a50cf0 00000000\n   de20: c096d224 00000000 eb09de54 eb09de38 c041f46c c041f11c 00000000 c0a6c504\n   de40: c041f3e8 c0a50cf0 eb09de7c eb09de58 c041da08 c041f3f4 eb0eff58 eb2259b4\n   de60: eb0eff6c c0a6c504 eaa55f80 00000000 eb09de8c eb09de80 c041f5bc c041d98c\n   de80: eb09deb4 eb09de90 c041e190 c041f5a8 c0890798 eb09dea0 c0a6c504 ffffe000\n   dea0: 000000cb c095883c eb09decc eb09deb8 c0420068 c041e02c c0935328 ffffe000\n   dec0: eb09dedc eb09ded0 c04214b0 c041ffcc eb09deec eb09dee0 c0935340 c0421484\n   dee0: eb09df5c eb09def0 c0900ecc c0935334 00000000 c08b0334 eb09df00 eb09df08\n   df00: c013baa8 c09006a4 c010bf8c c08b0348 000000ca c08b0348 00000006 00000006\n   df20: 000000cb c08af36c ebfffca1 ebfffca4 c0a8a700 00000007 c0a8a700 00000007\n   df40: c0a8a700 000000cb c095883c c0a8a700 eb09df94 eb09df60 c0901080 c0900dac\n   df60: 00000006 00000006 00000000 c0900698 00000000 c06eac54 00000000 00000000\n   df80: 00000000 00000000 eb09dfac eb09df98 c06eac64 c0900f00 00000000 c06eac54\n   dfa0: 00000000 eb09dfb0 c0106db8 c06eac60 00000000 00000000 00000000 00000000\n   dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000\n   dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 420113b0 60d05413\n   Backtrace: \n   [<c0545914>] (rvin_v4l2_probe) from [<c0543614>] (rvin_digital_notify_complete+0x10c/0x11c)\n    r7:eaa56810 r6:eb1284c0 r5:00000000 r4:eaa56bd8\n   [<c0543508>] (rvin_digital_notify_complete) from [<c0525164>] \n   (v4l2_async_match_notify+0xe8/0xf0)\n    r8:c0a5ff2c r7:eb1284c0 r6:ea9e2868 r5:c0543508 r4:eaa56bd8\n   [<c052507c>] (v4l2_async_match_notify) from [<c0525288>] (v4l2_async_notifier_register+0x11c/0x150)\n    r7:eb3cda50 r6:ea9e2868 r5:c0a5ff18 r4:eaa56bd8\n   [<c052516c>] (v4l2_async_notifier_register) from [<c05433f0>] (rcar_vin_probe+0x104/0x178)\n    r9:eaa56bd8 r8:00000000 r7:eb251a10 r6:eb251a00 r5:00000000 r4:eaa56810\n   [<c05432ec>] (rcar_vin_probe) from [<c0420a3c>] \n   (platform_drv_probe+0x58/0xa4)\n    r9:00000000 r8:c0a6c504 r7:00000000 r6:c0a6c504 r5:eb251a10 r4:c05432ec\n   [<c04209e4>] (platform_drv_probe) from [<c041f320>] (driver_probe_device+0x210/0x2d8)\n    r7:00000000 r6:c0ac72d4 r5:c0ac72c8 r4:eb251a10\n   [<c041f110>] (driver_probe_device) from [<c041f46c>] (__driver_attach+0x84/0xb0)\n    r10:00000000 r9:c096d224 r8:00000000 r7:c0a50cf0 r6:c0a6c504 r5:eb251a44\n    r4:eb251a10 r3:00000000\n   [<c041f3e8>] (__driver_attach) from [<c041da08>] (bus_for_each_dev+0x88/0x98)\n    r7:c0a50cf0 r6:c041f3e8 r5:c0a6c504 r4:00000000\n   [<c041d980>] (bus_for_each_dev) from [<c041f5bc>] (driver_attach+0x20/0x28)\n    r6:00000000 r5:eaa55f80 r4:c0a6c504\n   [<c041f59c>] (driver_attach) from [<c041e190>] (bus_add_driver+0x170/0x1e0)\n   [<c041e020>] (bus_add_driver) from [<c0420068>] (driver_register+0xa8/0xe8)\n    r7:c095883c r6:000000cb r5:ffffe000 r4:c0a6c504\n   [<c041ffc0>] (driver_register) from [<c04214b0>] (__platform_driver_register+0x38/0x4c)\n    r5:ffffe000 r4:c0935328\n   [<c0421478>] (__platform_driver_register) from [<c0935340>] (rcar_vin_driver_init+0x18/0x20)\n   [<c0935328>] (rcar_vin_driver_init) from [<c0900ecc>] (do_one_initcall+0x12c/0x154)\n   [<c0900da0>] (do_one_initcall) from [<c0901080>] (kernel_init_freeable+0x18c/0x1d0)\n    r8:c0a8a700 r7:c095883c r6:000000cb r5:c0a8a700 r4:00000007\n   [<c0900ef4>] (kernel_init_freeable) from [<c06eac64>] (kernel_init+0x10/0x110)\n    r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c06eac54 r4:00000000\n   [<c06eac54>] (kernel_init) from [<c0106db8>] (ret_from_fork+0x14/0x3c)\n    r5:c06eac54 r4:00000000\n   Code: 03e05012 e5803368 0a00000a e5963068 (e593300c) \n   ---[ end trace 82aa2a1c6173a5f6 ]---\n\n\nOddly enough setting CONFIG_OF_DYNAMIC=n or applying the patch\n'[PATCH v2] device property: preserve usecount for node passed to \nof_fwnode_graph_get_port_parent()' fixes _both_ issues. It obviously \nwould fix the 'Bad of_node_put() on ...' messages that it also fixes the \nOOPS is strange, so I did some digging.\n\nThe problem is introduced when rcar-vin in its complete callback calls \nv4l2_device_register_subdev_nodes(). Before the call \nvin->digital->subdev pointer is correct but after the call the \nvin->digital->subdev pointer is changed to a for me random value. And \nthis is what is causing the OOPS in rvin_v4l2_probe() once it tries to \noperate on the subdevice using v4l2_subdev_call() using this bad \npointer.\n\nI tried to track down the issue but I can't understand what is causing \nit, but I managed to narrow it down. The callchain is:\n\n- rvin_digital_notify_complete\n  - pr_dbg(\"sd: %p\\n\", vin->digital->subdev); # prints good pointer\n  - v4l2_device_register_subdev_nodes()\n    - __video_register_device()\n      - cdev_alloc()         # Here the pointer gets corrupted\n  - pr_dbg(\"sd: %p\\n\", vin->digital->subdev); # prints bad pointer\n\nI can't figure out why cdev_alloc() would corrupt it. I can even corrupt \nthe pointer by calling cdev_alloc() directly from the rcar-vin driver \nitself. I added to following to the top  of the complete callback before \nv4l2_device_register_subdev_nodes() is called.\n\n  pr_err(\"digital: %p sd: %p\\n\", vin->digital, vin->digital->subdev);\n  cdev_alloc();\n  pr_err(\"digital: %p sd: %p\\n\", vin->digital, vin->digital->subdev);\n\nAnd the result is:\n\n[    2.865306] digital: eb1284c0 sd: ea953068\n[    2.869414] digital: eb1284c0 sd: c0a1e6dc\n\nIf I set CONFIG_OF_DYNAMIC=n or apply the patch above the result is OK, \n\n[    1.961142] digital: ea8f8cc0 sd: ea8bac50\n[    1.965240] digital: ea8f8cc0 sd: ea8bac50\n\nI can capture without issues so this patch in it self is good I think.  \nSo please add\n\nAcked-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> \n\nHowever I would like the issue that is revealed by this patch to be \nsorted out before this patch is picked up as it causes problems with \nCONFIG_OF_DYNAMIC=y which is enabled by using the shmobile_defconfig.\n\nOn 2017-09-26 01:25:18 +0300, Sakari Ailus wrote:\n> Instead of using a custom 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>  drivers/media/platform/rcar-vin/rcar-core.c | 107 +++++++++-------------------\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, 46 insertions(+), 89 deletions(-)\n> \n> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c\n> index 142de447aaaa..380288658601 100644\n> --- a/drivers/media/platform/rcar-vin/rcar-core.c\n> +++ b/drivers/media/platform/rcar-vin/rcar-core.c\n> @@ -21,6 +21,7 @@\n>  #include <linux/platform_device.h>\n>  #include <linux/pm_runtime.h>\n>  \n> +#include <media/v4l2-async.h>\n>  #include <media/v4l2-fwnode.h>\n>  \n>  #include \"rcar-vin.h\"\n> @@ -77,14 +78,14 @@ static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)\n>  \tint ret;\n>  \n>  \t/* Verify subdevices mbus format */\n> -\tif (!rvin_mbus_supported(&vin->digital)) {\n> +\tif (!rvin_mbus_supported(vin->digital)) {\n>  \t\tvin_err(vin, \"Unsupported media bus format for %s\\n\",\n> -\t\t\tvin->digital.subdev->name);\n> +\t\t\tvin->digital->subdev->name);\n>  \t\treturn -EINVAL;\n>  \t}\n>  \n>  \tvin_dbg(vin, \"Found media bus format for %s: %d\\n\",\n> -\t\tvin->digital.subdev->name, vin->digital.code);\n> +\t\tvin->digital->subdev->name, vin->digital->code);\n>  \n>  \tret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);\n>  \tif (ret < 0) {\n> @@ -103,7 +104,7 @@ static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier,\n>  \n>  \tvin_dbg(vin, \"unbind digital subdev %s\\n\", subdev->name);\n>  \trvin_v4l2_remove(vin);\n> -\tvin->digital.subdev = NULL;\n> +\tvin->digital->subdev = NULL;\n>  }\n>  \n>  static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,\n> @@ -120,117 +121,71 @@ static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,\n>  \tret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);\n>  \tif (ret < 0)\n>  \t\treturn ret;\n> -\tvin->digital.source_pad = ret;\n> +\tvin->digital->source_pad = ret;\n>  \n>  \tret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);\n> -\tvin->digital.sink_pad = ret < 0 ? 0 : ret;\n> +\tvin->digital->sink_pad = ret < 0 ? 0 : ret;\n>  \n> -\tvin->digital.subdev = subdev;\n> +\tvin->digital->subdev = subdev;\n>  \n>  \tvin_dbg(vin, \"bound subdev %s source pad: %u sink pad: %u\\n\",\n> -\t\tsubdev->name, vin->digital.source_pad,\n> -\t\tvin->digital.sink_pad);\n> +\t\tsubdev->name, vin->digital->source_pad,\n> +\t\tvin->digital->sink_pad);\n>  \n>  \treturn 0;\n>  }\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> +\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> +\tif (!vin->digital)\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> +\t\tto_of_node(vin->digital->asd.match.fwnode.fwnode));\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> @@ -290,6 +245,8 @@ static int rcar_vin_probe(struct platform_device *pdev)\n>  \tif (ret)\n>  \t\treturn ret;\n>  \n> +\tplatform_set_drvdata(pdev, vin);\n> +\n>  \tret = rvin_digital_graph_init(vin);\n>  \tif (ret < 0)\n>  \t\tgoto error;\n> @@ -297,11 +254,10 @@ static int rcar_vin_probe(struct platform_device *pdev)\n>  \tpm_suspend_ignore_children(&pdev->dev, true);\n>  \tpm_runtime_enable(&pdev->dev);\n>  \n> -\tplatform_set_drvdata(pdev, vin);\n> -\n>  \treturn 0;\n>  error:\n>  \trvin_dma_remove(vin);\n> +\tv4l2_async_notifier_cleanup(&vin->notifier);\n>  \n>  \treturn ret;\n>  }\n> @@ -313,6 +269,7 @@ static int rcar_vin_remove(struct platform_device *pdev)\n>  \tpm_runtime_disable(&pdev->dev);\n>  \n>  \tv4l2_async_notifier_unregister(&vin->notifier);\n> +\tv4l2_async_notifier_cleanup(&vin->notifier);\n>  \n>  \trvin_dma_remove(vin);\n>  \n> diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c\n> index b136844499f6..23fdff7a7370 100644\n> --- a/drivers/media/platform/rcar-vin/rcar-dma.c\n> +++ b/drivers/media/platform/rcar-vin/rcar-dma.c\n> @@ -183,7 +183,7 @@ static int rvin_setup(struct rvin_dev *vin)\n>  \t/*\n>  \t * Input interface\n>  \t */\n> -\tswitch (vin->digital.code) {\n> +\tswitch (vin->digital->code) {\n>  \tcase MEDIA_BUS_FMT_YUYV8_1X16:\n>  \t\t/* BT.601/BT.1358 16bit YCbCr422 */\n>  \t\tvnmc |= VNMC_INF_YUV16;\n> @@ -191,7 +191,7 @@ static int rvin_setup(struct rvin_dev *vin)\n>  \t\tbreak;\n>  \tcase MEDIA_BUS_FMT_UYVY8_2X8:\n>  \t\t/* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */\n> -\t\tvnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ?\n> +\t\tvnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?\n>  \t\t\tVNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;\n>  \t\tinput_is_yuv = true;\n>  \t\tbreak;\n> @@ -200,7 +200,7 @@ static int rvin_setup(struct rvin_dev *vin)\n>  \t\tbreak;\n>  \tcase MEDIA_BUS_FMT_UYVY10_2X10:\n>  \t\t/* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */\n> -\t\tvnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ?\n> +\t\tvnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?\n>  \t\t\tVNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;\n>  \t\tinput_is_yuv = true;\n>  \t\tbreak;\n> @@ -212,11 +212,11 @@ static int rvin_setup(struct rvin_dev *vin)\n>  \tdmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);\n>  \n>  \t/* Hsync Signal Polarity Select */\n> -\tif (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))\n> +\tif (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))\n>  \t\tdmr2 |= VNDMR2_HPS;\n>  \n>  \t/* Vsync Signal Polarity Select */\n> -\tif (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))\n> +\tif (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))\n>  \t\tdmr2 |= VNDMR2_VPS;\n>  \n>  \t/*\n> diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c\n> index dd37ea811680..b479b882da12 100644\n> --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c\n> +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c\n> @@ -111,7 +111,7 @@ static int rvin_reset_format(struct rvin_dev *vin)\n>  \tstruct v4l2_mbus_framefmt *mf = &fmt.format;\n>  \tint ret;\n>  \n> -\tfmt.pad = vin->digital.source_pad;\n> +\tfmt.pad = vin->digital->source_pad;\n>  \n>  \tret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);\n>  \tif (ret)\n> @@ -172,13 +172,13 @@ static int __rvin_try_format_source(struct rvin_dev *vin,\n>  \n>  \tsd = vin_to_source(vin);\n>  \n> -\tv4l2_fill_mbus_format(&format.format, pix, vin->digital.code);\n> +\tv4l2_fill_mbus_format(&format.format, pix, vin->digital->code);\n>  \n>  \tpad_cfg = v4l2_subdev_alloc_pad_config(sd);\n>  \tif (pad_cfg == NULL)\n>  \t\treturn -ENOMEM;\n>  \n> -\tformat.pad = vin->digital.source_pad;\n> +\tformat.pad = vin->digital->source_pad;\n>  \n>  \tfield = pix->field;\n>  \n> @@ -555,7 +555,7 @@ static int rvin_enum_dv_timings(struct file *file, void *priv_fh,\n>  \tif (timings->pad)\n>  \t\treturn -EINVAL;\n>  \n> -\ttimings->pad = vin->digital.sink_pad;\n> +\ttimings->pad = vin->digital->sink_pad;\n>  \n>  \tret = v4l2_subdev_call(sd, pad, enum_dv_timings, timings);\n>  \n> @@ -607,7 +607,7 @@ static int rvin_dv_timings_cap(struct file *file, void *priv_fh,\n>  \tif (cap->pad)\n>  \t\treturn -EINVAL;\n>  \n> -\tcap->pad = vin->digital.sink_pad;\n> +\tcap->pad = vin->digital->sink_pad;\n>  \n>  \tret = v4l2_subdev_call(sd, pad, dv_timings_cap, cap);\n>  \n> @@ -625,7 +625,7 @@ static int rvin_g_edid(struct file *file, void *fh, struct v4l2_edid *edid)\n>  \tif (edid->pad)\n>  \t\treturn -EINVAL;\n>  \n> -\tedid->pad = vin->digital.sink_pad;\n> +\tedid->pad = vin->digital->sink_pad;\n>  \n>  \tret = v4l2_subdev_call(sd, pad, get_edid, edid);\n>  \n> @@ -643,7 +643,7 @@ static int rvin_s_edid(struct file *file, void *fh, struct v4l2_edid *edid)\n>  \tif (edid->pad)\n>  \t\treturn -EINVAL;\n>  \n> -\tedid->pad = vin->digital.sink_pad;\n> +\tedid->pad = vin->digital->sink_pad;\n>  \n>  \tret = v4l2_subdev_call(sd, pad, set_edid, edid);\n>  \n> diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h\n> index 9bfb5a7c4dc4..5382078143fb 100644\n> --- a/drivers/media/platform/rcar-vin/rcar-vin.h\n> +++ b/drivers/media/platform/rcar-vin/rcar-vin.h\n> @@ -126,7 +126,7 @@ struct rvin_dev {\n>  \tstruct v4l2_device v4l2_dev;\n>  \tstruct v4l2_ctrl_handler ctrl_handler;\n>  \tstruct v4l2_async_notifier notifier;\n> -\tstruct rvin_graph_entity digital;\n> +\tstruct rvin_graph_entity *digital;\n>  \n>  \tstruct mutex lock;\n>  \tstruct vb2_queue queue;\n> @@ -145,7 +145,7 @@ struct rvin_dev {\n>  \tstruct v4l2_rect compose;\n>  };\n>  \n> -#define vin_to_source(vin)\t\tvin->digital.subdev\n> +#define vin_to_source(vin)\t\t((vin)->digital->subdev)\n>  \n>  /* Debug */\n>  #define vin_dbg(d, fmt, arg...)\t\tdev_dbg(d->dev, fmt, ##arg)\n> -- \n> 2.11.0\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>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com header.b=\"pwR9d9MN\"; \n\tdkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3y489B2WkSz9t6m\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tSat, 30 Sep 2017 23:17:18 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751069AbdI3NRP (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tSat, 30 Sep 2017 09:17:15 -0400","from mail-lf0-f53.google.com ([209.85.215.53]:47030 \"EHLO\n\tmail-lf0-f53.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1750810AbdI3NRN (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Sat, 30 Sep 2017 09:17:13 -0400","by mail-lf0-f53.google.com with SMTP id m199so1997148lfe.3\n\tfor <devicetree@vger.kernel.org>;\n\tSat, 30 Sep 2017 06:17:12 -0700 (PDT)","from localhost ([89.233.230.99]) by smtp.gmail.com with ESMTPSA id\n\t15sm1294965ljf.22.2017.09.30.06.17.10\n\t(version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);\n\tSat, 30 Sep 2017 06:17:10 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to\n\t:user-agent; bh=d21TFEuE84D+Z+YqiNiYtPrFfWNEiS7jdMe6lBmkLXk=;\n\tb=pwR9d9MNpu4cvPYdLESLgiQ2C3mCIlAZHAvOb7cHiHW9Z51w65H1r9u8560WIJ10gp\n\tGS59mWG7jqSXPND9psHkJRNtjm9MzjEEhWCHoo1GBp/E/iDyCQkw73d9Nm961g2C9+qL\n\tbujne5wKpAUYuApplHqf/cN76DrWKr8kTI9m8ZbI2Fud1e1KamILrGMGLKo7hqQLM8Hi\n\t2X5a92R+o1uh5YU72p4p0dZNKC+EvpGrAyS68Q97hB/uykGYoVvDRMwrWh9FiGWT2ZJY\n\tiF4MoObaOtvpfc1IObMIARKsg7f1QVp8N57q3uVHF1eGOqOCBaTLZ+HQZofgVPWeKthU\n\tujNA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to:user-agent;\n\tbh=d21TFEuE84D+Z+YqiNiYtPrFfWNEiS7jdMe6lBmkLXk=;\n\tb=PgUjRFFbS8l3NRVrEkw381GLjdfTYui1XegqaUOU299q6GGIbAAnZXsy6L4ZV/9bsD\n\t9kwOeg/QnEjo0OKPV3J+skZTmUp1r9oo053uz1/pTDIsDUnbh3HkGLM1rilQCC7worf4\n\toZbnlEwREj9iQa0bPuvWK9LDHd3dMms3iUyB1DVzscqz3ipmtwuYIayQI4TItgQHd3Gy\n\tPQ9wYtGlJoBnLt6JOoSspGupr2zk3BrVw80Va6SZXGGSCjjVunL59WpmNGSxFqwJd49s\n\tQ/AzvGZ6uVQOF8B7LI6d1e6MtSli4mX3NGOwTGUiOKnbcaDlxL5JHm4Ls1+NOkjdzpyT\n\tCaDg==","X-Gm-Message-State":"AHPjjUhu2461J4beYMpU/rMC5ci2uC4grPsjQGrw4VKDztDwcjM0mJn6\n\tCCbmtgC4MDgdqBAndAhxGMKSbA==","X-Google-Smtp-Source":"AOwi7QCWRxTehYfCItOHSJQyOYCRYUWBL9xV+H1eE59ly+m3XyDHI6xd6RdPjndKhh1H8qCXDdWwxA==","X-Received":"by 10.46.17.90 with SMTP id f87mr4634462lje.160.1506777431491;\n\tSat, 30 Sep 2017 06:17:11 -0700 (PDT)","Date":"Sat, 30 Sep 2017 15:17:09 +0200","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, maxime.ripard@free-electrons.com,\n\trobh@kernel.org, hverkuil@xs4all.nl,\n\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v14 07/28] rcar-vin: Use generic parser for parsing\n\tfwnode endpoints","Message-ID":"<20170930131709.GP17182@bigcity.dyn.berto.se>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-8-sakari.ailus@linux.intel.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20170925222540.371-8-sakari.ailus@linux.intel.com>","User-Agent":"Mutt/1.9.0 (2017-09-02)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1778278,"web_url":"http://patchwork.ozlabs.org/comment/1778278/","msgid":"<3f940721-f190-4662-cfda-d99a0d97bf08@linux.intel.com>","list_archive_url":null,"date":"2017-10-02T11:58:10","subject":"Re: [PATCH v14 07/28] rcar-vin: Use generic parser for parsing\n\tfwnode endpoints","submitter":{"id":65485,"url":"http://patchwork.ozlabs.org/api/people/65485/","name":"Sakari Ailus","email":"sakari.ailus@linux.intel.com"},"content":"Hi Niklas,\n\nOn 09/30/17 16:17, Niklas Söderlund wrote:\n> Hi Sakari,\n> \n> Thanks for your patch, I like it. Unfortunately it causes issues :-(\n> \n> I picked the first 7 patches of this series on top of media-next and it \n> produce problems when tested on Koelsch with CONFIG_OF_DYNAMIC=y.\n> \n> 1. It print's 'OF: ERROR: Bad of_node_put() on /video@e6ef0000/port' \n>    messages during boot.\n\nDo you have your own patch to fix fwnode_graph_get_port_parent()\napplied? I noticed it doesn't seem to be in Rob's tree; let's continue\nin the other thread.\n\n<URL:https://www.mail-archive.com/linux-media@vger.kernel.org/msg117450.html>\n\n> \n>    OF: ERROR: Bad of_node_put() on /video@e6ef0000/port\n>    CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.13.0-rc4-00632-gfae12f9c98a8c567 #7\n>    Hardware name: Generic R8A7791 (Flattened Device Tree)\n>    Backtrace: \n>    [<c010b16c>] (dump_backtrace) from [<c010b3b8>] (show_stack+0x18/0x1c)\n>     r7:00000001 r6:60000013 r5:00000000 r4:c0a7c88c\n>    [<c010b3a0>] (show_stack) from [<c06d9034>] (dump_stack+0x84/0xa0)\n>    [<c06d8fb0>] (dump_stack) from [<c05814ac>] (of_node_release+0x2c/0x94)\n>     r7:00000001 r6:c0a6fc4c r5:eb1284c0 r4:eb7c7a00\n>    [<c0581480>] (of_node_release) from [<c06dcd3c>] (kobject_put+0xbc/0xdc)\n>     r7:00000001 r6:c0a6fc4c r5:eb1284c0 r4:eb7c7a00\n>    [<c06dcc80>] (kobject_put) from [<c0580d48>] (of_node_put+0x1c/0x20)\n>     r6:eb7c7af8 r5:eb7c79e0 r4:eb7c7798\n>    [<c0580d2c>] (of_node_put) from [<c057fc18>] (of_fwnode_put+0x38/0x44)\n>    [<c057fbe0>] (of_fwnode_put) from [<c04244a8>] (fwnode_handle_put+0x30/0x34)\n>    [<c0424478>] (fwnode_handle_put) from [<c0424714>] (fwnode_graph_get_port_parent+0x44/0x4c)\n>    [<c04246d0>] (fwnode_graph_get_port_parent) from [<c0514820>] (__v4l2_async_notifier_parse_fwnode_endpoints+0x1dc/0x2d8)\n>     r5:eaa56bd8 r4:00000000\n>    [<c0514644>] (__v4l2_async_notifier_parse_fwnode_endpoints) from [<c0514a9c>] (v4l2_async_notifier_parse_fwnode_endpoints+0x20/0x28)\n>     r10:00000000 r9:eaa56bd8 r8:c0a6c504 r7:eb251a10 r6:eb251a00 r5:00000000\n>     r4:eaa56810\n>    [<c0514a7c>] (v4l2_async_notifier_parse_fwnode_endpoints) from [<c05433b8>] (rcar_vin_probe+0xcc/0x178)\n>    [<c05432ec>] (rcar_vin_probe) from [<c0420a3c>] (platform_drv_probe+0x58/0xa4)\n>     r9:00000000 r8:c0a6c504 r7:00000000 r6:c0a6c504 r5:eb251a10 r4:c05432ec\n>    [<c04209e4>] (platform_drv_probe) from [<c041f320>] (driver_probe_device+0x210/0x2d8)\n>     r7:00000000 r6:c0ac72d4 r5:c0ac72c8 r4:eb251a10\n>    [<c041f110>] (driver_probe_device) from [<c041f46c>] (__driver_attach+0x84/0xb0)\n>     r10:00000000 r9:c096d224 r8:00000000 r7:c0a50cf0 r6:c0a6c504 r5:eb251a44\n>     r4:eb251a10 r3:00000000\n>    [<c041f3e8>] (__driver_attach) from [<c041da08>] (bus_for_each_dev+0x88/0x98)\n>     r7:c0a50cf0 r6:c041f3e8 r5:c0a6c504 r4:00000000\n>    [<c041d980>] (bus_for_each_dev) from [<c041f5bc>] (driver_attach+0x20/0x28)\n>     r6:00000000 r5:eaa55f80 r4:c0a6c504\n>    [<c041f59c>] (driver_attach) from [<c041e190>] (bus_add_driver+0x170/0x1e0)\n>    [<c041e020>] (bus_add_driver) from [<c0420068>] (driver_register+0xa8/0xe8)\n>     r7:c095883c r6:000000cb r5:ffffe000 r4:c0a6c504\n>    [<c041ffc0>] (driver_register) from [<c04214b0>] (__platform_driver_register+0x38/0x4c)\n>     r5:ffffe000 r4:c0935328\n>    [<c0421478>] (__platform_driver_register) from [<c0935340>] (rcar_vin_driver_init+0x18/0x20)\n>    [<c0935328>] (rcar_vin_driver_init) from [<c0900ecc>] (do_one_initcall+0x12c/0x154)\n>    [<c0900da0>] (do_one_initcall) from [<c0901080>] (kernel_init_freeable+0x18c/0x1d0)\n>     r8:c0a8a700 r7:c095883c r6:000000cb r5:c0a8a700 r4:00000007\n>    [<c0900ef4>] (kernel_init_freeable) from [<c06eac64>] (kernel_init+0x10/0x110)\n>     r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c06eac54 r4:00000000\n>    [<c06eac54>] (kernel_init) from [<c0106db8>] (ret_from_fork+0x14/0x3c)\n>     r5:c06eac54 r4:00000000\n> \n> 2. It then proceeds to OOPS.\n> \n>    Unable to handle kernel NULL pointer dereference at virtual address 0000000c\n>    pgd = c0004000\n>    [0000000c] *pgd=00000000\n>    Internal error: Oops: 5 [#1] SMP ARM\n>    CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.13.0-rc4-00632-gfae12f9c98a8c567 #7\n>    Hardware name: Generic R8A7791 (Flattened Device Tree)\n>    task: eb09b840 task.stack: eb09c000\n>    PC is at rvin_v4l2_probe+0x38/0x1ec\n>    LR is at rvin_digital_notify_complete+0x10c/0x11c\n>    pc : [<c054594c>]    lr : [<c0543614>]    psr: a0000013\n>    sp : eb09dcf8  ip : eb09dd20  fp : eb09dd1c\n>    r10: 00000000  r9 : eaa56bd8  r8 : 00002006\n>    r7 : eaa56810  r6 : c0a1e6dc  r5 : 00000000  r4 : eaa56810\n>    r3 : 00000000  r2 : 00000001  r1 : eaa57ec0  r0 : eaa56810\n>    Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none\n>    Control: 10c5387d  Table: 4000406a  DAC: 00000051\n>    Process swapper/0 (pid: 1, stack limit = 0xeb09c210)\n>    Stack: (0xeb09dcf8 to 0xeb09e000)\n>    dce0:                                                       ea9e2868 eb1284c0\n>    dd00: eaa56bd8 00000000 eb1284c0 eaa56810 eb09dd74 eb09dd20 c0543614 c0545920\n>    dd20: 00000001 00000001 0000100a 00000001 00000000 00000000 00000000 00000000\n>    dd40: 00000000 00000000 00000000 00000000 c051c17c eaa56bd8 c0543508 ea9e2868\n>    dd60: eb1284c0 c0a5ff2c eb09dd94 eb09dd78 c0525164 c0543514 eaa56bd8 c0a5ff18\n>    dd80: ea9e2868 eb3cda50 eb09ddbc eb09dd98 c0525288 c0525088 eaa56810 00000000\n>    dda0: eb251a00 eb251a10 00000000 eaa56bd8 eb09dde4 eb09ddc0 c05433f0 c0525178\n>    ddc0: c05432ec eb251a10 c0a6c504 00000000 c0a6c504 00000000 eb09de04 eb09dde8\n>    dde0: c0420a3c c05432f8 eb251a10 c0ac72c8 c0ac72d4 00000000 eb09de34 eb09de08\n>    de00: c041f320 c04209f0 00000000 eb251a10 eb251a44 c0a6c504 c0a50cf0 00000000\n>    de20: c096d224 00000000 eb09de54 eb09de38 c041f46c c041f11c 00000000 c0a6c504\n>    de40: c041f3e8 c0a50cf0 eb09de7c eb09de58 c041da08 c041f3f4 eb0eff58 eb2259b4\n>    de60: eb0eff6c c0a6c504 eaa55f80 00000000 eb09de8c eb09de80 c041f5bc c041d98c\n>    de80: eb09deb4 eb09de90 c041e190 c041f5a8 c0890798 eb09dea0 c0a6c504 ffffe000\n>    dea0: 000000cb c095883c eb09decc eb09deb8 c0420068 c041e02c c0935328 ffffe000\n>    dec0: eb09dedc eb09ded0 c04214b0 c041ffcc eb09deec eb09dee0 c0935340 c0421484\n>    dee0: eb09df5c eb09def0 c0900ecc c0935334 00000000 c08b0334 eb09df00 eb09df08\n>    df00: c013baa8 c09006a4 c010bf8c c08b0348 000000ca c08b0348 00000006 00000006\n>    df20: 000000cb c08af36c ebfffca1 ebfffca4 c0a8a700 00000007 c0a8a700 00000007\n>    df40: c0a8a700 000000cb c095883c c0a8a700 eb09df94 eb09df60 c0901080 c0900dac\n>    df60: 00000006 00000006 00000000 c0900698 00000000 c06eac54 00000000 00000000\n>    df80: 00000000 00000000 eb09dfac eb09df98 c06eac64 c0900f00 00000000 c06eac54\n>    dfa0: 00000000 eb09dfb0 c0106db8 c06eac60 00000000 00000000 00000000 00000000\n>    dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000\n>    dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 420113b0 60d05413\n>    Backtrace: \n>    [<c0545914>] (rvin_v4l2_probe) from [<c0543614>] (rvin_digital_notify_complete+0x10c/0x11c)\n>     r7:eaa56810 r6:eb1284c0 r5:00000000 r4:eaa56bd8\n>    [<c0543508>] (rvin_digital_notify_complete) from [<c0525164>] \n>    (v4l2_async_match_notify+0xe8/0xf0)\n>     r8:c0a5ff2c r7:eb1284c0 r6:ea9e2868 r5:c0543508 r4:eaa56bd8\n\nCould fixing the other issue fix this one as well?\n\nI'll see how the rest works at my end with CONFIG_OF_DYNAMIC enabled.\n\n>    [<c052507c>] (v4l2_async_match_notify) from [<c0525288>] (v4l2_async_notifier_register+0x11c/0x150)\n>     r7:eb3cda50 r6:ea9e2868 r5:c0a5ff18 r4:eaa56bd8\n>    [<c052516c>] (v4l2_async_notifier_register) from [<c05433f0>] (rcar_vin_probe+0x104/0x178)\n>     r9:eaa56bd8 r8:00000000 r7:eb251a10 r6:eb251a00 r5:00000000 r4:eaa56810\n>    [<c05432ec>] (rcar_vin_probe) from [<c0420a3c>] \n>    (platform_drv_probe+0x58/0xa4)\n>     r9:00000000 r8:c0a6c504 r7:00000000 r6:c0a6c504 r5:eb251a10 r4:c05432ec\n>    [<c04209e4>] (platform_drv_probe) from [<c041f320>] (driver_probe_device+0x210/0x2d8)\n>     r7:00000000 r6:c0ac72d4 r5:c0ac72c8 r4:eb251a10\n>    [<c041f110>] (driver_probe_device) from [<c041f46c>] (__driver_attach+0x84/0xb0)\n>     r10:00000000 r9:c096d224 r8:00000000 r7:c0a50cf0 r6:c0a6c504 r5:eb251a44\n>     r4:eb251a10 r3:00000000\n>    [<c041f3e8>] (__driver_attach) from [<c041da08>] (bus_for_each_dev+0x88/0x98)\n>     r7:c0a50cf0 r6:c041f3e8 r5:c0a6c504 r4:00000000\n>    [<c041d980>] (bus_for_each_dev) from [<c041f5bc>] (driver_attach+0x20/0x28)\n>     r6:00000000 r5:eaa55f80 r4:c0a6c504\n>    [<c041f59c>] (driver_attach) from [<c041e190>] (bus_add_driver+0x170/0x1e0)\n>    [<c041e020>] (bus_add_driver) from [<c0420068>] (driver_register+0xa8/0xe8)\n>     r7:c095883c r6:000000cb r5:ffffe000 r4:c0a6c504\n>    [<c041ffc0>] (driver_register) from [<c04214b0>] (__platform_driver_register+0x38/0x4c)\n>     r5:ffffe000 r4:c0935328\n>    [<c0421478>] (__platform_driver_register) from [<c0935340>] (rcar_vin_driver_init+0x18/0x20)\n>    [<c0935328>] (rcar_vin_driver_init) from [<c0900ecc>] (do_one_initcall+0x12c/0x154)\n>    [<c0900da0>] (do_one_initcall) from [<c0901080>] (kernel_init_freeable+0x18c/0x1d0)\n>     r8:c0a8a700 r7:c095883c r6:000000cb r5:c0a8a700 r4:00000007\n>    [<c0900ef4>] (kernel_init_freeable) from [<c06eac64>] (kernel_init+0x10/0x110)\n>     r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c06eac54 r4:00000000\n>    [<c06eac54>] (kernel_init) from [<c0106db8>] (ret_from_fork+0x14/0x3c)\n>     r5:c06eac54 r4:00000000\n>    Code: 03e05012 e5803368 0a00000a e5963068 (e593300c) \n>    ---[ end trace 82aa2a1c6173a5f6 ]---\n> \n> \n> Oddly enough setting CONFIG_OF_DYNAMIC=n or applying the patch\n> '[PATCH v2] device property: preserve usecount for node passed to \n> of_fwnode_graph_get_port_parent()' fixes _both_ issues. It obviously \n> would fix the 'Bad of_node_put() on ...' messages that it also fixes the \n> OOPS is strange, so I did some digging.\n> \n> The problem is introduced when rcar-vin in its complete callback calls \n> v4l2_device_register_subdev_nodes(). Before the call \n> vin->digital->subdev pointer is correct but after the call the \n> vin->digital->subdev pointer is changed to a for me random value. And \n> this is what is causing the OOPS in rvin_v4l2_probe() once it tries to \n> operate on the subdevice using v4l2_subdev_call() using this bad \n> pointer.\n> \n> I tried to track down the issue but I can't understand what is causing \n> it, but I managed to narrow it down. The callchain is:\n> \n> - rvin_digital_notify_complete\n>   - pr_dbg(\"sd: %p\\n\", vin->digital->subdev); # prints good pointer\n>   - v4l2_device_register_subdev_nodes()\n>     - __video_register_device()\n>       - cdev_alloc()         # Here the pointer gets corrupted\n>   - pr_dbg(\"sd: %p\\n\", vin->digital->subdev); # prints bad pointer\n> \n> I can't figure out why cdev_alloc() would corrupt it. I can even corrupt \n> the pointer by calling cdev_alloc() directly from the rcar-vin driver \n> itself. I added to following to the top  of the complete callback before \n> v4l2_device_register_subdev_nodes() is called.\n> \n>   pr_err(\"digital: %p sd: %p\\n\", vin->digital, vin->digital->subdev);\n>   cdev_alloc();\n>   pr_err(\"digital: %p sd: %p\\n\", vin->digital, vin->digital->subdev);\n> \n> And the result is:\n> \n> [    2.865306] digital: eb1284c0 sd: ea953068\n> [    2.869414] digital: eb1284c0 sd: c0a1e6dc\n> \n> If I set CONFIG_OF_DYNAMIC=n or apply the patch above the result is OK, \n> \n> [    1.961142] digital: ea8f8cc0 sd: ea8bac50\n> [    1.965240] digital: ea8f8cc0 sd: ea8bac50\n> \n> I can capture without issues so this patch in it self is good I think.  \n> So please add\n> \n> Acked-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> \n> \n> However I would like the issue that is revealed by this patch to be \n> sorted out before this patch is picked up as it causes problems with \n> CONFIG_OF_DYNAMIC=y which is enabled by using the shmobile_defconfig.\n> \n> On 2017-09-26 01:25:18 +0300, Sakari Ailus wrote:\n>> Instead of using a custom 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>>  drivers/media/platform/rcar-vin/rcar-core.c | 107 +++++++++-------------------\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, 46 insertions(+), 89 deletions(-)\n>>\n>> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c\n>> index 142de447aaaa..380288658601 100644\n>> --- a/drivers/media/platform/rcar-vin/rcar-core.c\n>> +++ b/drivers/media/platform/rcar-vin/rcar-core.c\n>> @@ -21,6 +21,7 @@\n>>  #include <linux/platform_device.h>\n>>  #include <linux/pm_runtime.h>\n>>  \n>> +#include <media/v4l2-async.h>\n>>  #include <media/v4l2-fwnode.h>\n>>  \n>>  #include \"rcar-vin.h\"\n>> @@ -77,14 +78,14 @@ static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)\n>>  \tint ret;\n>>  \n>>  \t/* Verify subdevices mbus format */\n>> -\tif (!rvin_mbus_supported(&vin->digital)) {\n>> +\tif (!rvin_mbus_supported(vin->digital)) {\n>>  \t\tvin_err(vin, \"Unsupported media bus format for %s\\n\",\n>> -\t\t\tvin->digital.subdev->name);\n>> +\t\t\tvin->digital->subdev->name);\n>>  \t\treturn -EINVAL;\n>>  \t}\n>>  \n>>  \tvin_dbg(vin, \"Found media bus format for %s: %d\\n\",\n>> -\t\tvin->digital.subdev->name, vin->digital.code);\n>> +\t\tvin->digital->subdev->name, vin->digital->code);\n>>  \n>>  \tret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);\n>>  \tif (ret < 0) {\n>> @@ -103,7 +104,7 @@ static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier,\n>>  \n>>  \tvin_dbg(vin, \"unbind digital subdev %s\\n\", subdev->name);\n>>  \trvin_v4l2_remove(vin);\n>> -\tvin->digital.subdev = NULL;\n>> +\tvin->digital->subdev = NULL;\n>>  }\n>>  \n>>  static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,\n>> @@ -120,117 +121,71 @@ static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,\n>>  \tret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);\n>>  \tif (ret < 0)\n>>  \t\treturn ret;\n>> -\tvin->digital.source_pad = ret;\n>> +\tvin->digital->source_pad = ret;\n>>  \n>>  \tret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);\n>> -\tvin->digital.sink_pad = ret < 0 ? 0 : ret;\n>> +\tvin->digital->sink_pad = ret < 0 ? 0 : ret;\n>>  \n>> -\tvin->digital.subdev = subdev;\n>> +\tvin->digital->subdev = subdev;\n>>  \n>>  \tvin_dbg(vin, \"bound subdev %s source pad: %u sink pad: %u\\n\",\n>> -\t\tsubdev->name, vin->digital.source_pad,\n>> -\t\tvin->digital.sink_pad);\n>> +\t\tsubdev->name, vin->digital->source_pad,\n>> +\t\tvin->digital->sink_pad);\n>>  \n>>  \treturn 0;\n>>  }\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>> +\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>> +\tif (!vin->digital)\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>> +\t\tto_of_node(vin->digital->asd.match.fwnode.fwnode));\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>> @@ -290,6 +245,8 @@ static int rcar_vin_probe(struct platform_device *pdev)\n>>  \tif (ret)\n>>  \t\treturn ret;\n>>  \n>> +\tplatform_set_drvdata(pdev, vin);\n>> +\n>>  \tret = rvin_digital_graph_init(vin);\n>>  \tif (ret < 0)\n>>  \t\tgoto error;\n>> @@ -297,11 +254,10 @@ static int rcar_vin_probe(struct platform_device *pdev)\n>>  \tpm_suspend_ignore_children(&pdev->dev, true);\n>>  \tpm_runtime_enable(&pdev->dev);\n>>  \n>> -\tplatform_set_drvdata(pdev, vin);\n>> -\n>>  \treturn 0;\n>>  error:\n>>  \trvin_dma_remove(vin);\n>> +\tv4l2_async_notifier_cleanup(&vin->notifier);\n>>  \n>>  \treturn ret;\n>>  }\n>> @@ -313,6 +269,7 @@ static int rcar_vin_remove(struct platform_device *pdev)\n>>  \tpm_runtime_disable(&pdev->dev);\n>>  \n>>  \tv4l2_async_notifier_unregister(&vin->notifier);\n>> +\tv4l2_async_notifier_cleanup(&vin->notifier);\n>>  \n>>  \trvin_dma_remove(vin);\n>>  \n>> diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c\n>> index b136844499f6..23fdff7a7370 100644\n>> --- a/drivers/media/platform/rcar-vin/rcar-dma.c\n>> +++ b/drivers/media/platform/rcar-vin/rcar-dma.c\n>> @@ -183,7 +183,7 @@ static int rvin_setup(struct rvin_dev *vin)\n>>  \t/*\n>>  \t * Input interface\n>>  \t */\n>> -\tswitch (vin->digital.code) {\n>> +\tswitch (vin->digital->code) {\n>>  \tcase MEDIA_BUS_FMT_YUYV8_1X16:\n>>  \t\t/* BT.601/BT.1358 16bit YCbCr422 */\n>>  \t\tvnmc |= VNMC_INF_YUV16;\n>> @@ -191,7 +191,7 @@ static int rvin_setup(struct rvin_dev *vin)\n>>  \t\tbreak;\n>>  \tcase MEDIA_BUS_FMT_UYVY8_2X8:\n>>  \t\t/* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */\n>> -\t\tvnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ?\n>> +\t\tvnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?\n>>  \t\t\tVNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;\n>>  \t\tinput_is_yuv = true;\n>>  \t\tbreak;\n>> @@ -200,7 +200,7 @@ static int rvin_setup(struct rvin_dev *vin)\n>>  \t\tbreak;\n>>  \tcase MEDIA_BUS_FMT_UYVY10_2X10:\n>>  \t\t/* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */\n>> -\t\tvnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ?\n>> +\t\tvnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?\n>>  \t\t\tVNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;\n>>  \t\tinput_is_yuv = true;\n>>  \t\tbreak;\n>> @@ -212,11 +212,11 @@ static int rvin_setup(struct rvin_dev *vin)\n>>  \tdmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);\n>>  \n>>  \t/* Hsync Signal Polarity Select */\n>> -\tif (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))\n>> +\tif (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))\n>>  \t\tdmr2 |= VNDMR2_HPS;\n>>  \n>>  \t/* Vsync Signal Polarity Select */\n>> -\tif (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))\n>> +\tif (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))\n>>  \t\tdmr2 |= VNDMR2_VPS;\n>>  \n>>  \t/*\n>> diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c\n>> index dd37ea811680..b479b882da12 100644\n>> --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c\n>> +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c\n>> @@ -111,7 +111,7 @@ static int rvin_reset_format(struct rvin_dev *vin)\n>>  \tstruct v4l2_mbus_framefmt *mf = &fmt.format;\n>>  \tint ret;\n>>  \n>> -\tfmt.pad = vin->digital.source_pad;\n>> +\tfmt.pad = vin->digital->source_pad;\n>>  \n>>  \tret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);\n>>  \tif (ret)\n>> @@ -172,13 +172,13 @@ static int __rvin_try_format_source(struct rvin_dev *vin,\n>>  \n>>  \tsd = vin_to_source(vin);\n>>  \n>> -\tv4l2_fill_mbus_format(&format.format, pix, vin->digital.code);\n>> +\tv4l2_fill_mbus_format(&format.format, pix, vin->digital->code);\n>>  \n>>  \tpad_cfg = v4l2_subdev_alloc_pad_config(sd);\n>>  \tif (pad_cfg == NULL)\n>>  \t\treturn -ENOMEM;\n>>  \n>> -\tformat.pad = vin->digital.source_pad;\n>> +\tformat.pad = vin->digital->source_pad;\n>>  \n>>  \tfield = pix->field;\n>>  \n>> @@ -555,7 +555,7 @@ static int rvin_enum_dv_timings(struct file *file, void *priv_fh,\n>>  \tif (timings->pad)\n>>  \t\treturn -EINVAL;\n>>  \n>> -\ttimings->pad = vin->digital.sink_pad;\n>> +\ttimings->pad = vin->digital->sink_pad;\n>>  \n>>  \tret = v4l2_subdev_call(sd, pad, enum_dv_timings, timings);\n>>  \n>> @@ -607,7 +607,7 @@ static int rvin_dv_timings_cap(struct file *file, void *priv_fh,\n>>  \tif (cap->pad)\n>>  \t\treturn -EINVAL;\n>>  \n>> -\tcap->pad = vin->digital.sink_pad;\n>> +\tcap->pad = vin->digital->sink_pad;\n>>  \n>>  \tret = v4l2_subdev_call(sd, pad, dv_timings_cap, cap);\n>>  \n>> @@ -625,7 +625,7 @@ static int rvin_g_edid(struct file *file, void *fh, struct v4l2_edid *edid)\n>>  \tif (edid->pad)\n>>  \t\treturn -EINVAL;\n>>  \n>> -\tedid->pad = vin->digital.sink_pad;\n>> +\tedid->pad = vin->digital->sink_pad;\n>>  \n>>  \tret = v4l2_subdev_call(sd, pad, get_edid, edid);\n>>  \n>> @@ -643,7 +643,7 @@ static int rvin_s_edid(struct file *file, void *fh, struct v4l2_edid *edid)\n>>  \tif (edid->pad)\n>>  \t\treturn -EINVAL;\n>>  \n>> -\tedid->pad = vin->digital.sink_pad;\n>> +\tedid->pad = vin->digital->sink_pad;\n>>  \n>>  \tret = v4l2_subdev_call(sd, pad, set_edid, edid);\n>>  \n>> diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h\n>> index 9bfb5a7c4dc4..5382078143fb 100644\n>> --- a/drivers/media/platform/rcar-vin/rcar-vin.h\n>> +++ b/drivers/media/platform/rcar-vin/rcar-vin.h\n>> @@ -126,7 +126,7 @@ struct rvin_dev {\n>>  \tstruct v4l2_device v4l2_dev;\n>>  \tstruct v4l2_ctrl_handler ctrl_handler;\n>>  \tstruct v4l2_async_notifier notifier;\n>> -\tstruct rvin_graph_entity digital;\n>> +\tstruct rvin_graph_entity *digital;\n>>  \n>>  \tstruct mutex lock;\n>>  \tstruct vb2_queue queue;\n>> @@ -145,7 +145,7 @@ struct rvin_dev {\n>>  \tstruct v4l2_rect compose;\n>>  };\n>>  \n>> -#define vin_to_source(vin)\t\tvin->digital.subdev\n>> +#define vin_to_source(vin)\t\t((vin)->digital->subdev)\n>>  \n>>  /* Debug */\n>>  #define vin_dbg(d, fmt, arg...)\t\tdev_dbg(d->dev, fmt, ##arg)\n>> -- \n>> 2.11.0\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 3y5LK65LtNz9t48\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tMon,  2 Oct 2017 22:58:18 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1750957AbdJBL6R (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tMon, 2 Oct 2017 07:58:17 -0400","from mga02.intel.com ([134.134.136.20]:37088 \"EHLO mga02.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1750878AbdJBL6P (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tMon, 2 Oct 2017 07:58:15 -0400","from fmsmga003.fm.intel.com ([10.253.24.29])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t02 Oct 2017 04:58:14 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby FMSMGA003.fm.intel.com with ESMTP; 02 Oct 2017 04:58:11 -0700","from [127.0.0.1] (localhost [127.0.0.1])\n\tby paasikivi.fi.intel.com (Postfix) with ESMTP id DFF16202F5;\n\tMon,  2 Oct 2017 14:58:10 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos;i=\"5.42,469,1500966000\"; d=\"scan'208\";a=\"905838190\"","Subject":"Re: [PATCH v14 07/28] rcar-vin: Use generic parser for parsing\n\tfwnode endpoints","To":"=?utf-8?q?Niklas_S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Cc":"linux-media@vger.kernel.org, maxime.ripard@free-electrons.com,\n\trobh@kernel.org, hverkuil@xs4all.nl,\n\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-8-sakari.ailus@linux.intel.com>\n\t<20170930131709.GP17182@bigcity.dyn.berto.se>","From":"Sakari Ailus <sakari.ailus@linux.intel.com>","Message-ID":"<3f940721-f190-4662-cfda-d99a0d97bf08@linux.intel.com>","Date":"Mon, 2 Oct 2017 14:58:10 +0300","User-Agent":"Mozilla/5.0 (X11; Linux i686 on x86_64; rv:51.0) Gecko/20100101\n\tSeaMonkey/2.48","MIME-Version":"1.0","In-Reply-To":"<20170930131709.GP17182@bigcity.dyn.berto.se>","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1778285,"web_url":"http://patchwork.ozlabs.org/comment/1778285/","msgid":"<20171002121422.GQ17182@bigcity.dyn.berto.se>","list_archive_url":null,"date":"2017-10-02T12:14:22","subject":"Re: [PATCH v14 07/28] rcar-vin: Use generic parser for parsing\n\tfwnode endpoints","submitter":{"id":67773,"url":"http://patchwork.ozlabs.org/api/people/67773/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Sakari,\n\nOn 2017-10-02 14:58:10 +0300, Sakari Ailus wrote:\n> Hi Niklas,\n> \n> On 09/30/17 16:17, Niklas Söderlund wrote:\n> > Hi Sakari,\n> > \n> > Thanks for your patch, I like it. Unfortunately it causes issues :-(\n> > \n> > I picked the first 7 patches of this series on top of media-next and it \n> > produce problems when tested on Koelsch with CONFIG_OF_DYNAMIC=y.\n> > \n> > 1. It print's 'OF: ERROR: Bad of_node_put() on /video@e6ef0000/port' \n> >    messages during boot.\n> \n> Do you have your own patch to fix fwnode_graph_get_port_parent()\n> applied? I noticed it doesn't seem to be in Rob's tree; let's continue\n> in the other thread.\n> \n> <URL:https://www.mail-archive.com/linux-media@vger.kernel.org/msg117450.html>\n\nTo produce this issue the fix is not applied. But as I try to describe \nat the end of my email applying it fixes both issues. So I think this \npatch is correct (and that is why I Acked it) but my concern is that if \nit's picked up before the fwnode_graph_get_port_parent() issue is sorted \nout there will be problems for rcar-vin, and if possible I would like to \navoid that.\n\n> \n> > \n> >    OF: ERROR: Bad of_node_put() on /video@e6ef0000/port\n> >    CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.13.0-rc4-00632-gfae12f9c98a8c567 #7\n> >    Hardware name: Generic R8A7791 (Flattened Device Tree)\n\n[snip]\n\n> \n> Could fixing the other issue fix this one as well?\n>\n> I'll see how the rest works at my end with CONFIG_OF_DYNAMIC enabled.\n\nYes, as I try to describe bellow, applying the fix for \nfwnode_graph_get_port_parent() solves both issues :-)\n\nWhat is troublesome for me is that I don't understand why cdev_alloc() \nwould change/corrupt the subdevice pointer if CONFIG_OF_DYNAMIC=y or the \nfix is _not_ applied.\n\n> \n> >    [<c052507c>] (v4l2_async_match_notify) from [<c0525288>] (v4l2_async_notifier_register+0x11c/0x150)\n> >     r7:eb3cda50 r6:ea9e2868 r5:c0a5ff18 r4:eaa56bd8\n> >    [<c052516c>] (v4l2_async_notifier_register) from [<c05433f0>] (rcar_vin_probe+0x104/0x178)\n> >     r9:eaa56bd8 r8:00000000 r7:eb251a10 r6:eb251a00 r5:00000000 r4:eaa56810\n> >    [<c05432ec>] (rcar_vin_probe) from [<c0420a3c>] \n> >    (platform_drv_probe+0x58/0xa4)\n> >     r9:00000000 r8:c0a6c504 r7:00000000 r6:c0a6c504 r5:eb251a10 r4:c05432ec\n> >    [<c04209e4>] (platform_drv_probe) from [<c041f320>] (driver_probe_device+0x210/0x2d8)\n> >     r7:00000000 r6:c0ac72d4 r5:c0ac72c8 r4:eb251a10\n> >    [<c041f110>] (driver_probe_device) from [<c041f46c>] (__driver_attach+0x84/0xb0)\n> >     r10:00000000 r9:c096d224 r8:00000000 r7:c0a50cf0 r6:c0a6c504 r5:eb251a44\n> >     r4:eb251a10 r3:00000000\n> >    [<c041f3e8>] (__driver_attach) from [<c041da08>] (bus_for_each_dev+0x88/0x98)\n> >     r7:c0a50cf0 r6:c041f3e8 r5:c0a6c504 r4:00000000\n> >    [<c041d980>] (bus_for_each_dev) from [<c041f5bc>] (driver_attach+0x20/0x28)\n> >     r6:00000000 r5:eaa55f80 r4:c0a6c504\n> >    [<c041f59c>] (driver_attach) from [<c041e190>] (bus_add_driver+0x170/0x1e0)\n> >    [<c041e020>] (bus_add_driver) from [<c0420068>] (driver_register+0xa8/0xe8)\n> >     r7:c095883c r6:000000cb r5:ffffe000 r4:c0a6c504\n> >    [<c041ffc0>] (driver_register) from [<c04214b0>] (__platform_driver_register+0x38/0x4c)\n> >     r5:ffffe000 r4:c0935328\n> >    [<c0421478>] (__platform_driver_register) from [<c0935340>] (rcar_vin_driver_init+0x18/0x20)\n> >    [<c0935328>] (rcar_vin_driver_init) from [<c0900ecc>] (do_one_initcall+0x12c/0x154)\n> >    [<c0900da0>] (do_one_initcall) from [<c0901080>] (kernel_init_freeable+0x18c/0x1d0)\n> >     r8:c0a8a700 r7:c095883c r6:000000cb r5:c0a8a700 r4:00000007\n> >    [<c0900ef4>] (kernel_init_freeable) from [<c06eac64>] (kernel_init+0x10/0x110)\n> >     r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c06eac54 r4:00000000\n> >    [<c06eac54>] (kernel_init) from [<c0106db8>] (ret_from_fork+0x14/0x3c)\n> >     r5:c06eac54 r4:00000000\n> >    Code: 03e05012 e5803368 0a00000a e5963068 (e593300c) \n> >    ---[ end trace 82aa2a1c6173a5f6 ]---\n> > \n> > \n> > Oddly enough setting CONFIG_OF_DYNAMIC=n or applying the patch\n> > '[PATCH v2] device property: preserve usecount for node passed to \n> > of_fwnode_graph_get_port_parent()' fixes _both_ issues. It obviously \n> > would fix the 'Bad of_node_put() on ...' messages that it also fixes the \n> > OOPS is strange, so I did some digging.\n> > \n> > The problem is introduced when rcar-vin in its complete callback calls \n> > v4l2_device_register_subdev_nodes(). Before the call \n> > vin->digital->subdev pointer is correct but after the call the \n> > vin->digital->subdev pointer is changed to a for me random value. And \n> > this is what is causing the OOPS in rvin_v4l2_probe() once it tries to \n> > operate on the subdevice using v4l2_subdev_call() using this bad \n> > pointer.\n> > \n> > I tried to track down the issue but I can't understand what is causing \n> > it, but I managed to narrow it down. The callchain is:\n> > \n> > - rvin_digital_notify_complete\n> >   - pr_dbg(\"sd: %p\\n\", vin->digital->subdev); # prints good pointer\n> >   - v4l2_device_register_subdev_nodes()\n> >     - __video_register_device()\n> >       - cdev_alloc()         # Here the pointer gets corrupted\n> >   - pr_dbg(\"sd: %p\\n\", vin->digital->subdev); # prints bad pointer\n> > \n> > I can't figure out why cdev_alloc() would corrupt it. I can even corrupt \n> > the pointer by calling cdev_alloc() directly from the rcar-vin driver \n> > itself. I added to following to the top  of the complete callback before \n> > v4l2_device_register_subdev_nodes() is called.\n> > \n> >   pr_err(\"digital: %p sd: %p\\n\", vin->digital, vin->digital->subdev);\n> >   cdev_alloc();\n> >   pr_err(\"digital: %p sd: %p\\n\", vin->digital, vin->digital->subdev);\n> > \n> > And the result is:\n> > \n> > [    2.865306] digital: eb1284c0 sd: ea953068\n> > [    2.869414] digital: eb1284c0 sd: c0a1e6dc\n> > \n> > If I set CONFIG_OF_DYNAMIC=n or apply the patch above the result is OK, \n> > \n> > [    1.961142] digital: ea8f8cc0 sd: ea8bac50\n> > [    1.965240] digital: ea8f8cc0 sd: ea8bac50\n> > \n> > I can capture without issues so this patch in it self is good I think.  \n> > So please add\n> > \n> > Acked-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> \n> > \n> > However I would like the issue that is revealed by this patch to be \n> > sorted out before this patch is picked up as it causes problems with \n> > CONFIG_OF_DYNAMIC=y which is enabled by using the shmobile_defconfig.\n> > \n> > On 2017-09-26 01:25:18 +0300, Sakari Ailus wrote:\n> >> Instead of using a custom 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> >>  drivers/media/platform/rcar-vin/rcar-core.c | 107 +++++++++-------------------\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, 46 insertions(+), 89 deletions(-)\n> >>\n> >> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c\n> >> index 142de447aaaa..380288658601 100644\n> >> --- a/drivers/media/platform/rcar-vin/rcar-core.c\n> >> +++ b/drivers/media/platform/rcar-vin/rcar-core.c\n> >> @@ -21,6 +21,7 @@\n> >>  #include <linux/platform_device.h>\n> >>  #include <linux/pm_runtime.h>\n> >>  \n> >> +#include <media/v4l2-async.h>\n> >>  #include <media/v4l2-fwnode.h>\n> >>  \n> >>  #include \"rcar-vin.h\"\n> >> @@ -77,14 +78,14 @@ static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)\n> >>  \tint ret;\n> >>  \n> >>  \t/* Verify subdevices mbus format */\n> >> -\tif (!rvin_mbus_supported(&vin->digital)) {\n> >> +\tif (!rvin_mbus_supported(vin->digital)) {\n> >>  \t\tvin_err(vin, \"Unsupported media bus format for %s\\n\",\n> >> -\t\t\tvin->digital.subdev->name);\n> >> +\t\t\tvin->digital->subdev->name);\n> >>  \t\treturn -EINVAL;\n> >>  \t}\n> >>  \n> >>  \tvin_dbg(vin, \"Found media bus format for %s: %d\\n\",\n> >> -\t\tvin->digital.subdev->name, vin->digital.code);\n> >> +\t\tvin->digital->subdev->name, vin->digital->code);\n> >>  \n> >>  \tret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);\n> >>  \tif (ret < 0) {\n> >> @@ -103,7 +104,7 @@ static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier,\n> >>  \n> >>  \tvin_dbg(vin, \"unbind digital subdev %s\\n\", subdev->name);\n> >>  \trvin_v4l2_remove(vin);\n> >> -\tvin->digital.subdev = NULL;\n> >> +\tvin->digital->subdev = NULL;\n> >>  }\n> >>  \n> >>  static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,\n> >> @@ -120,117 +121,71 @@ static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,\n> >>  \tret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);\n> >>  \tif (ret < 0)\n> >>  \t\treturn ret;\n> >> -\tvin->digital.source_pad = ret;\n> >> +\tvin->digital->source_pad = ret;\n> >>  \n> >>  \tret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);\n> >> -\tvin->digital.sink_pad = ret < 0 ? 0 : ret;\n> >> +\tvin->digital->sink_pad = ret < 0 ? 0 : ret;\n> >>  \n> >> -\tvin->digital.subdev = subdev;\n> >> +\tvin->digital->subdev = subdev;\n> >>  \n> >>  \tvin_dbg(vin, \"bound subdev %s source pad: %u sink pad: %u\\n\",\n> >> -\t\tsubdev->name, vin->digital.source_pad,\n> >> -\t\tvin->digital.sink_pad);\n> >> +\t\tsubdev->name, vin->digital->source_pad,\n> >> +\t\tvin->digital->sink_pad);\n> >>  \n> >>  \treturn 0;\n> >>  }\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> >> +\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> >> +\tif (!vin->digital)\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> >> +\t\tto_of_node(vin->digital->asd.match.fwnode.fwnode));\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> >> @@ -290,6 +245,8 @@ static int rcar_vin_probe(struct platform_device *pdev)\n> >>  \tif (ret)\n> >>  \t\treturn ret;\n> >>  \n> >> +\tplatform_set_drvdata(pdev, vin);\n> >> +\n> >>  \tret = rvin_digital_graph_init(vin);\n> >>  \tif (ret < 0)\n> >>  \t\tgoto error;\n> >> @@ -297,11 +254,10 @@ static int rcar_vin_probe(struct platform_device *pdev)\n> >>  \tpm_suspend_ignore_children(&pdev->dev, true);\n> >>  \tpm_runtime_enable(&pdev->dev);\n> >>  \n> >> -\tplatform_set_drvdata(pdev, vin);\n> >> -\n> >>  \treturn 0;\n> >>  error:\n> >>  \trvin_dma_remove(vin);\n> >> +\tv4l2_async_notifier_cleanup(&vin->notifier);\n> >>  \n> >>  \treturn ret;\n> >>  }\n> >> @@ -313,6 +269,7 @@ static int rcar_vin_remove(struct platform_device *pdev)\n> >>  \tpm_runtime_disable(&pdev->dev);\n> >>  \n> >>  \tv4l2_async_notifier_unregister(&vin->notifier);\n> >> +\tv4l2_async_notifier_cleanup(&vin->notifier);\n> >>  \n> >>  \trvin_dma_remove(vin);\n> >>  \n> >> diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c\n> >> index b136844499f6..23fdff7a7370 100644\n> >> --- a/drivers/media/platform/rcar-vin/rcar-dma.c\n> >> +++ b/drivers/media/platform/rcar-vin/rcar-dma.c\n> >> @@ -183,7 +183,7 @@ static int rvin_setup(struct rvin_dev *vin)\n> >>  \t/*\n> >>  \t * Input interface\n> >>  \t */\n> >> -\tswitch (vin->digital.code) {\n> >> +\tswitch (vin->digital->code) {\n> >>  \tcase MEDIA_BUS_FMT_YUYV8_1X16:\n> >>  \t\t/* BT.601/BT.1358 16bit YCbCr422 */\n> >>  \t\tvnmc |= VNMC_INF_YUV16;\n> >> @@ -191,7 +191,7 @@ static int rvin_setup(struct rvin_dev *vin)\n> >>  \t\tbreak;\n> >>  \tcase MEDIA_BUS_FMT_UYVY8_2X8:\n> >>  \t\t/* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */\n> >> -\t\tvnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ?\n> >> +\t\tvnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?\n> >>  \t\t\tVNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;\n> >>  \t\tinput_is_yuv = true;\n> >>  \t\tbreak;\n> >> @@ -200,7 +200,7 @@ static int rvin_setup(struct rvin_dev *vin)\n> >>  \t\tbreak;\n> >>  \tcase MEDIA_BUS_FMT_UYVY10_2X10:\n> >>  \t\t/* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */\n> >> -\t\tvnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ?\n> >> +\t\tvnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?\n> >>  \t\t\tVNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;\n> >>  \t\tinput_is_yuv = true;\n> >>  \t\tbreak;\n> >> @@ -212,11 +212,11 @@ static int rvin_setup(struct rvin_dev *vin)\n> >>  \tdmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);\n> >>  \n> >>  \t/* Hsync Signal Polarity Select */\n> >> -\tif (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))\n> >> +\tif (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))\n> >>  \t\tdmr2 |= VNDMR2_HPS;\n> >>  \n> >>  \t/* Vsync Signal Polarity Select */\n> >> -\tif (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))\n> >> +\tif (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))\n> >>  \t\tdmr2 |= VNDMR2_VPS;\n> >>  \n> >>  \t/*\n> >> diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c\n> >> index dd37ea811680..b479b882da12 100644\n> >> --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c\n> >> +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c\n> >> @@ -111,7 +111,7 @@ static int rvin_reset_format(struct rvin_dev *vin)\n> >>  \tstruct v4l2_mbus_framefmt *mf = &fmt.format;\n> >>  \tint ret;\n> >>  \n> >> -\tfmt.pad = vin->digital.source_pad;\n> >> +\tfmt.pad = vin->digital->source_pad;\n> >>  \n> >>  \tret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);\n> >>  \tif (ret)\n> >> @@ -172,13 +172,13 @@ static int __rvin_try_format_source(struct rvin_dev *vin,\n> >>  \n> >>  \tsd = vin_to_source(vin);\n> >>  \n> >> -\tv4l2_fill_mbus_format(&format.format, pix, vin->digital.code);\n> >> +\tv4l2_fill_mbus_format(&format.format, pix, vin->digital->code);\n> >>  \n> >>  \tpad_cfg = v4l2_subdev_alloc_pad_config(sd);\n> >>  \tif (pad_cfg == NULL)\n> >>  \t\treturn -ENOMEM;\n> >>  \n> >> -\tformat.pad = vin->digital.source_pad;\n> >> +\tformat.pad = vin->digital->source_pad;\n> >>  \n> >>  \tfield = pix->field;\n> >>  \n> >> @@ -555,7 +555,7 @@ static int rvin_enum_dv_timings(struct file *file, void *priv_fh,\n> >>  \tif (timings->pad)\n> >>  \t\treturn -EINVAL;\n> >>  \n> >> -\ttimings->pad = vin->digital.sink_pad;\n> >> +\ttimings->pad = vin->digital->sink_pad;\n> >>  \n> >>  \tret = v4l2_subdev_call(sd, pad, enum_dv_timings, timings);\n> >>  \n> >> @@ -607,7 +607,7 @@ static int rvin_dv_timings_cap(struct file *file, void *priv_fh,\n> >>  \tif (cap->pad)\n> >>  \t\treturn -EINVAL;\n> >>  \n> >> -\tcap->pad = vin->digital.sink_pad;\n> >> +\tcap->pad = vin->digital->sink_pad;\n> >>  \n> >>  \tret = v4l2_subdev_call(sd, pad, dv_timings_cap, cap);\n> >>  \n> >> @@ -625,7 +625,7 @@ static int rvin_g_edid(struct file *file, void *fh, struct v4l2_edid *edid)\n> >>  \tif (edid->pad)\n> >>  \t\treturn -EINVAL;\n> >>  \n> >> -\tedid->pad = vin->digital.sink_pad;\n> >> +\tedid->pad = vin->digital->sink_pad;\n> >>  \n> >>  \tret = v4l2_subdev_call(sd, pad, get_edid, edid);\n> >>  \n> >> @@ -643,7 +643,7 @@ static int rvin_s_edid(struct file *file, void *fh, struct v4l2_edid *edid)\n> >>  \tif (edid->pad)\n> >>  \t\treturn -EINVAL;\n> >>  \n> >> -\tedid->pad = vin->digital.sink_pad;\n> >> +\tedid->pad = vin->digital->sink_pad;\n> >>  \n> >>  \tret = v4l2_subdev_call(sd, pad, set_edid, edid);\n> >>  \n> >> diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h\n> >> index 9bfb5a7c4dc4..5382078143fb 100644\n> >> --- a/drivers/media/platform/rcar-vin/rcar-vin.h\n> >> +++ b/drivers/media/platform/rcar-vin/rcar-vin.h\n> >> @@ -126,7 +126,7 @@ struct rvin_dev {\n> >>  \tstruct v4l2_device v4l2_dev;\n> >>  \tstruct v4l2_ctrl_handler ctrl_handler;\n> >>  \tstruct v4l2_async_notifier notifier;\n> >> -\tstruct rvin_graph_entity digital;\n> >> +\tstruct rvin_graph_entity *digital;\n> >>  \n> >>  \tstruct mutex lock;\n> >>  \tstruct vb2_queue queue;\n> >> @@ -145,7 +145,7 @@ struct rvin_dev {\n> >>  \tstruct v4l2_rect compose;\n> >>  };\n> >>  \n> >> -#define vin_to_source(vin)\t\tvin->digital.subdev\n> >> +#define vin_to_source(vin)\t\t((vin)->digital->subdev)\n> >>  \n> >>  /* Debug */\n> >>  #define vin_dbg(d, fmt, arg...)\t\tdev_dbg(d->dev, fmt, ##arg)\n> >> -- \n> >> 2.11.0\n> >>\n> > \n> \n> \n> -- \n> Regards,\n> \n> Sakari Ailus\n> sakari.ailus@linux.intel.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>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com header.b=\"ckbzIZyS\"; \n\tdkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3y5Lgm3Wdxz9t48\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tMon,  2 Oct 2017 23:14:28 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751127AbdJBMO1 (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tMon, 2 Oct 2017 08:14:27 -0400","from mail-lf0-f43.google.com ([209.85.215.43]:54483 \"EHLO\n\tmail-lf0-f43.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751065AbdJBMO0 (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Mon, 2 Oct 2017 08:14:26 -0400","by mail-lf0-f43.google.com with SMTP id d10so3467468lfg.11\n\tfor <devicetree@vger.kernel.org>;\n\tMon, 02 Oct 2017 05:14:25 -0700 (PDT)","from localhost ([89.233.230.99]) by smtp.gmail.com with ESMTPSA id\n\tx4sm1576100lfa.55.2017.10.02.05.14.23\n\t(version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);\n\tMon, 02 Oct 2017 05:14:23 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to\n\t:user-agent; bh=xparjIdN5dqq1MPp776IbFWfuqL7gFI/xdAe7Urvhmw=;\n\tb=ckbzIZySka46tpTYKpJNxqtzwfZkEXWp+cQFzZe81I43RaAUNGTEeNAp1/MRMFcUO5\n\t+Ss5qbLI1Oksd+s2aGGKSJafNQQaOLXnmjvMI9c6/nTXiymCyXJAHXpT8PsokwrcOSE2\n\tPosr/GJuyIKr8VBfVi7PXdMnK6OkRYUhRpj8333a2YwX0T/D6ioce4v9aCgaRJ1lbhUB\n\tNaa34FXKZ20q0+GDR/QEnimVuu5whyQHHsVp4JJ41MGcV5TwJmwPs+m6NSmD4Ch0+wF6\n\tx30EotMo51Aka5YXknOeWUERqMd5FgpQEllmQ/YD5C6QHRjUT4Cto7Wt7e5pMqNjG/Zu\n\twFkQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to:user-agent;\n\tbh=xparjIdN5dqq1MPp776IbFWfuqL7gFI/xdAe7Urvhmw=;\n\tb=r2lZqljj3cPyFRP+66JEYeh+TYgmjXTUQVG8G2xaSewlcqyE+AhD7BucsxHujhvijh\n\ti8zHPOIy0fO1TCHqGRUFyMIs7T2lZ7RMn8pHUjKI5S1rg/fuEDgWtuPxYKZLWyRNeP0r\n\tGBSnkaRHEAZm/Gtoqvzh2Ajvs/3j79DLn2Zg8Li1ZoLrfNGtSrchDma5LZsTtuTn9sYY\n\tCmGdfOkODy6GOBKwgGV8poF+BrUmPC8HOprarDUuiy5/x4yaNmOPNjy/tQnp1QIYt+P2\n\tLGj0+GnC3aufH1UOyMo19Fmn+FTI7hj/N4IWtqjx/iLlW4p8R3ZD26W0IOYJI4NZ2zJi\n\tH1Ng==","X-Gm-Message-State":"AMCzsaU42IJzkpS0sDoca6l67YGCY/Mkq1GRnE+HCpLeqF763NmHh06Y\n\t1Kwml34icmzUJoohtQUSs7IBHQ==","X-Google-Smtp-Source":"AOwi7QDxE+5G8hMurZ33OiTppJ85JQIYq9es6lqMl7OJVs9i6+SttVMxcJBdYAWuwJbRNw7k2tSzLQ==","X-Received":"by 10.25.20.228 with SMTP id 97mr1410514lfu.211.1506946464160;\n\tMon, 02 Oct 2017 05:14:24 -0700 (PDT)","Date":"Mon, 2 Oct 2017 14:14:22 +0200","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","Cc":"linux-media@vger.kernel.org, maxime.ripard@free-electrons.com,\n\trobh@kernel.org, hverkuil@xs4all.nl,\n\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v14 07/28] rcar-vin: Use generic parser for parsing\n\tfwnode endpoints","Message-ID":"<20171002121422.GQ17182@bigcity.dyn.berto.se>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-8-sakari.ailus@linux.intel.com>\n\t<20170930131709.GP17182@bigcity.dyn.berto.se>\n\t<3f940721-f190-4662-cfda-d99a0d97bf08@linux.intel.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<3f940721-f190-4662-cfda-d99a0d97bf08@linux.intel.com>","User-Agent":"Mutt/1.9.0 (2017-09-02)","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1778286,"web_url":"http://patchwork.ozlabs.org/comment/1778286/","msgid":"<82a055f5-b0ad-bcd2-7d28-f256163a288c@linux.intel.com>","list_archive_url":null,"date":"2017-10-02T12:24:05","subject":"Re: [PATCH v14 07/28] rcar-vin: Use generic parser for parsing\n\tfwnode endpoints","submitter":{"id":65485,"url":"http://patchwork.ozlabs.org/api/people/65485/","name":"Sakari Ailus","email":"sakari.ailus@linux.intel.com"},"content":"Hejssan,\n\nOn 10/02/17 15:14, Niklas Söderlund wrote:\n> Hi Sakari,\n> \n> On 2017-10-02 14:58:10 +0300, Sakari Ailus wrote:\n>> Hi Niklas,\n>>\n>> On 09/30/17 16:17, Niklas Söderlund wrote:\n>>> Hi Sakari,\n>>>\n>>> Thanks for your patch, I like it. Unfortunately it causes issues :-(\n>>>\n>>> I picked the first 7 patches of this series on top of media-next and it \n>>> produce problems when tested on Koelsch with CONFIG_OF_DYNAMIC=y.\n>>>\n>>> 1. It print's 'OF: ERROR: Bad of_node_put() on /video@e6ef0000/port' \n>>>    messages during boot.\n>>\n>> Do you have your own patch to fix fwnode_graph_get_port_parent()\n>> applied? I noticed it doesn't seem to be in Rob's tree; let's continue\n>> in the other thread.\n>>\n>> <URL:https://www.mail-archive.com/linux-media@vger.kernel.org/msg117450.html>\n> \n> To produce this issue the fix is not applied. But as I try to describe \n> at the end of my email applying it fixes both issues. So I think this \n> patch is correct (and that is why I Acked it) but my concern is that if \n> it's picked up before the fwnode_graph_get_port_parent() issue is sorted \n> out there will be problems for rcar-vin, and if possible I would like to \n> avoid that.\n\nOops. I missed that between the oops log and the patch. X-)\n\nWell, good to hear that this isn't an actual bug in this set. I'll try\nto be careful in sending pull requests. :-) The same issue would be\npresent in any other driver using the new convenience functions.","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 3y5Lv015Kpz9s81\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tMon,  2 Oct 2017 23:24:12 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751082AbdJBMYK (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tMon, 2 Oct 2017 08:24:10 -0400","from mga03.intel.com ([134.134.136.65]:61548 \"EHLO mga03.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1751065AbdJBMYK (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tMon, 2 Oct 2017 08:24:10 -0400","from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t02 Oct 2017 05:24:09 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby fmsmga001.fm.intel.com with ESMTP; 02 Oct 2017 05:24:06 -0700","from [127.0.0.1] (localhost [127.0.0.1])\n\tby paasikivi.fi.intel.com (Postfix) with ESMTP id 11958202F5;\n\tMon,  2 Oct 2017 15:24:06 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos; i=\"5.42,469,1500966000\"; d=\"scan'208\";\n\ta=\"1201235233\"","Subject":"Re: [PATCH v14 07/28] rcar-vin: Use generic parser for parsing\n\tfwnode endpoints","To":"=?utf-8?q?Niklas_S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Cc":"linux-media@vger.kernel.org, maxime.ripard@free-electrons.com,\n\trobh@kernel.org, hverkuil@xs4all.nl,\n\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-8-sakari.ailus@linux.intel.com>\n\t<20170930131709.GP17182@bigcity.dyn.berto.se>\n\t<3f940721-f190-4662-cfda-d99a0d97bf08@linux.intel.com>\n\t<20171002121422.GQ17182@bigcity.dyn.berto.se>","From":"Sakari Ailus <sakari.ailus@linux.intel.com>","Message-ID":"<82a055f5-b0ad-bcd2-7d28-f256163a288c@linux.intel.com>","Date":"Mon, 2 Oct 2017 15:24:05 +0300","User-Agent":"Mozilla/5.0 (X11; Linux i686 on x86_64; rv:51.0) Gecko/20100101\n\tSeaMonkey/2.48","MIME-Version":"1.0","In-Reply-To":"<20171002121422.GQ17182@bigcity.dyn.berto.se>","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1782756,"web_url":"http://patchwork.ozlabs.org/comment/1782756/","msgid":"<4363f544-d1ec-68e4-1edf-9a16b3cdb1ea@xs4all.nl>","list_archive_url":null,"date":"2017-10-09T12:06:55","subject":"Re: [PATCH v14 20/28] 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\nMy reply here is also valid for v15.\n\nOn 26/09/17 13:30, Sakari Ailus wrote:\n> Hi Hans,\n> \n> Thanks for the review.\n> \n> On Tue, Sep 26, 2017 at 10:47:40AM +0200, Hans Verkuil wrote:\n>> On 26/09/17 00:25, 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>>> 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 f739dfd16cf7..f93049c361e4 100644\n>>> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n>>> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n>>> @@ -578,6 +578,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>>> + * 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>> \"at an index\". Still makes no sense to me. Which index?\n> \n> How about this:\n> \n> First find an fwnode referred to by the reference at @index in @prop.\n> \n> Then under that fwnode, @nprops times, for each property in @props,\n> iteratively follow child nodes starting from fwnode such that they have the\n> property in @props array at the index of the child node distance from the\n\ndistance? You mean 'instance'?\n\n> root node and the value of that property matching with the integer argument of\n> the reference, at the same index.\n\nYou've completely lost me. About halfway through this sentence my brain crashed :-)\n\n> \n>>\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>> I know I asked for this before, but can you change the example to one where\n>> nprops = 2? I think that will help understanding this.\n> \n> I could do that but then the example no longer corresponds to any actual\n> case that exists at the moment. LED nodes will use a single integer\n> argument and lens-focus nodes none.\n\nSo? The example is here to understand the code and it doesn't have to be\nrelated to actual hardware for a mainlined driver.\n\nIf you really don't want to do this here, then put the example in the commit\nlog. I don't see any reason why you can't put it here, though.\n\nI think that once I see an 'nprops = 2' example I can rephrase that\nbrain-crash sentence for you...\n\nBTW, where are the ACPI 'bindings' defined anyway? For DT they are in the\nbindings directory, but where does ACPI define such things? Just curious.\n\nRegards,\n\n\tHans\n\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>>\n>> corresponding -> corresponding to\n> \n> Fixed.\n> \n>>\n>>> +\t * integer arguments.\n>>> +\t */\n>>> +\tfwnode = fwnode_args.fwnode;\n>>> +\twhile (nprops--) {\n>>> +\t\tu32 val;\n>>> +\n>>> +\t\t/* Loop over all child nodes under fwnode. */\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>>\n>> Regards,\n>>\n>> \tHans\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 3y9f9w3cHFz9tY2\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tMon,  9 Oct 2017 23:07:00 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751896AbdJIMG6 (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tMon, 9 Oct 2017 08:06:58 -0400","from lb1-smtp-cloud8.xs4all.net ([194.109.24.21]:54412 \"EHLO\n\tlb1-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1751621AbdJIMG6 (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Mon, 9 Oct 2017 08:06:58 -0400","from [192.168.1.10] ([80.101.105.217])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid 1WpjeUe2yg5cR1WpkeHBU1; Mon, 09 Oct 2017 14:06:56 +0200"],"Subject":"Re: [PATCH v14 20/28] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","To":"Sakari Ailus <sakari.ailus@linux.intel.com>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-21-sakari.ailus@linux.intel.com>\n\t<fbd2f71d-aa6d-08ef-1723-132864bde27b@xs4all.nl>\n\t<20170926113029.eh5i4sp6we6lvgow@paasikivi.fi.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","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<4363f544-d1ec-68e4-1edf-9a16b3cdb1ea@xs4all.nl>","Date":"Mon, 9 Oct 2017 14:06:55 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101\n\tThunderbird/45.7.1","MIME-Version":"1.0","In-Reply-To":"<20170926113029.eh5i4sp6we6lvgow@paasikivi.fi.intel.com>","Content-Type":"text/plain; charset=windows-1252","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfB0tWCrd3lIClkXSwlkRmGgvOLiy/+0MquxP7Iw/GFD9i7xUz/IngfKcT7xjhsGa7adoc2BrT62/QNr4Uwl2taPO8aBa4N08sg3JpeLocwKv/Y3+6nBk\n\tLkRWputr4+h7FTeUjOtMngmWW6o/xhg0MziHuiG9i3t0LglLnu197GvPIzaJFdvaTaG2/3PRdE6pHB9JqcVSpTfu2YUpcBFNc3DvqcBVY18VJyJf18C7BOZD\n\tVvwTJAw8hXi2XDmwR4u5BcNHZVIU0Xut62Z3gEESxtJWgyHlMpGuKOhIvhPve2zgs+EIkXdDsCTAbBKgE+uKTblJduywFkrAAHanDCx/49YgsUloo7VjpNyq\n\tzxTe4014Pi9AFPfHJCtBoiH7sg3FCOJj+PXMkGlQ4dZG0Y4qCwETkqxnOdmMwstzA/iLtr7mqF1AxYisQCd2z3NmWsJ5fiTvVrlCK2Uoi6CPMRs8wGCvEo4y\n\tLY9Yg2GVP+IRWNZDu8RokRZMPMlb2XtZONEUW/g492dvbDb+G+ud1B8MKVg=","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1783649,"web_url":"http://patchwork.ozlabs.org/comment/1783649/","msgid":"<20171010112710.noq6a4ktjqzt5u22@valkosipuli.retiisi.org.uk>","list_archive_url":null,"date":"2017-10-10T11:27:10","subject":"Re: [PATCH v14 20/28] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","submitter":{"id":1593,"url":"http://patchwork.ozlabs.org/api/people/1593/","name":"Sakari Ailus","email":"sakari.ailus@iki.fi"},"content":"Hi Hans,\n\nOn Mon, Oct 09, 2017 at 02:06:55PM +0200, Hans Verkuil wrote:\n> Hi Sakari,\n> \n> My reply here is also valid for v15.\n> \n> On 26/09/17 13:30, Sakari Ailus wrote:\n> > Hi Hans,\n> > \n> > Thanks for the review.\n> > \n> > On Tue, Sep 26, 2017 at 10:47:40AM +0200, Hans Verkuil wrote:\n> >> On 26/09/17 00:25, 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> >>> 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 f739dfd16cf7..f93049c361e4 100644\n> >>> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> >>> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> >>> @@ -578,6 +578,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> >>> + * 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> >> \"at an index\". Still makes no sense to me. Which index?\n> > \n> > How about this:\n> > \n> > First find an fwnode referred to by the reference at @index in @prop.\n> > \n> > Then under that fwnode, @nprops times, for each property in @props,\n> > iteratively follow child nodes starting from fwnode such that they have the\n> > property in @props array at the index of the child node distance from the\n> \n> distance? You mean 'instance'?\n\nNo. It's a tree structure: this is the distance between a node in the tree\nand the root node (i.e. device's fwnode).\n\n> \n> > root node and the value of that property matching with the integer argument of\n> > the reference, at the same index.\n> \n> You've completely lost me. About halfway through this sentence my brain crashed :-)\n\n:-D\n\nDid keeping distance have any effect?\n\n> \n> > \n> >>\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> >> I know I asked for this before, but can you change the example to one where\n> >> nprops = 2? I think that will help understanding this.\n> > \n> > I could do that but then the example no longer corresponds to any actual\n> > case that exists at the moment. LED nodes will use a single integer\n> > argument and lens-focus nodes none.\n> \n> So? The example is here to understand the code and it doesn't have to be\n> related to actual hardware for a mainlined driver.\n\nThis isn't about hardware, the definitions being parsed currently aren't\nspecific to any single piece of hardware. I could add an example which does\nnot exist, that's certainly possible. But I fail to see how it'd help\nwhile the contrary could well be the case.\n\n> \n> If you really don't want to do this here, then put the example in the commit\n> log. I don't see any reason why you can't put it here, though.\n> \n> I think that once I see an 'nprops = 2' example I can rephrase that\n> brain-crash sentence for you...\n> \n> BTW, where are the ACPI 'bindings' defined anyway? For DT they are in the\n> bindings directory, but where does ACPI define such things? Just curious.\n\nAs the fwnode interface can be used to access information in both ACPI and\nDT, there is an incentive to maintain the interfaces effectively the same.\nIn other words where the interfaces are the same, there is no need to\ndefine bindings for ACPI as such. Where there are differences the bindings\nare defined in Documentation/acpi/dsd .\n\nThe so far only technical reason to that is related to the same is that\nACPI can only refer to device nodes (i.e. nodes that correspond to struct\ndevices), not sub-nodes under them.","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 3yBFFb4lFmz9t4V\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 10 Oct 2017 22:27:15 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1755805AbdJJL1O (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 10 Oct 2017 07:27:14 -0400","from nblzone-211-213.nblnetworks.fi ([83.145.211.213]:45202 \"EHLO\n\thillosipuli.retiisi.org.uk\" rhost-flags-OK-OK-OK-FAIL)\n\tby vger.kernel.org with ESMTP id S1755272AbdJJL1N (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 10 Oct 2017 07:27: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 E5730600FB;\n\tTue, 10 Oct 2017 14:27:10 +0300 (EEST)","from sakke by valkosipuli.localdomain with local (Exim 4.89)\n\t(envelope-from <sakari.ailus@retiisi.org.uk>)\n\tid 1e1sgo-0002Pn-JB; Tue, 10 Oct 2017 14:27:10 +0300"],"Date":"Tue, 10 Oct 2017 14:27:10 +0300","From":"Sakari Ailus <sakari.ailus@iki.fi>","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\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v14 20/28] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","Message-ID":"<20171010112710.noq6a4ktjqzt5u22@valkosipuli.retiisi.org.uk>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-21-sakari.ailus@linux.intel.com>\n\t<fbd2f71d-aa6d-08ef-1723-132864bde27b@xs4all.nl>\n\t<20170926113029.eh5i4sp6we6lvgow@paasikivi.fi.intel.com>\n\t<4363f544-d1ec-68e4-1edf-9a16b3cdb1ea@xs4all.nl>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<4363f544-d1ec-68e4-1edf-9a16b3cdb1ea@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":1783710,"web_url":"http://patchwork.ozlabs.org/comment/1783710/","msgid":"<d8a48273-7a19-0f83-4a4d-8058b7a59e0e@xs4all.nl>","list_archive_url":null,"date":"2017-10-10T13:07:29","subject":"Re: [PATCH v14 20/28] 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 10/10/2017 01:27 PM, Sakari Ailus wrote:\n> Hi Hans,\n> \n> On Mon, Oct 09, 2017 at 02:06:55PM +0200, Hans Verkuil wrote:\n>> Hi Sakari,\n>>\n>> My reply here is also valid for v15.\n>>\n>> On 26/09/17 13:30, Sakari Ailus wrote:\n>>> Hi Hans,\n>>>\n>>> Thanks for the review.\n>>>\n>>> On Tue, Sep 26, 2017 at 10:47:40AM +0200, Hans Verkuil wrote:\n>>>> On 26/09/17 00:25, 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>>>>> 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 f739dfd16cf7..f93049c361e4 100644\n>>>>> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n>>>>> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n>>>>> @@ -578,6 +578,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>>>>> + * 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>>>> \"at an index\". Still makes no sense to me. Which index?\n>>>\n>>> How about this:\n>>>\n>>> First find an fwnode referred to by the reference at @index in @prop.\n>>>\n>>> Then under that fwnode, @nprops times, for each property in @props,\n>>> iteratively follow child nodes starting from fwnode such that they have the\n>>> property in @props array at the index of the child node distance from the\n>>\n>> distance? You mean 'instance'?\n> \n> No. It's a tree structure: this is the distance between a node in the tree\n> and the root node (i.e. device's fwnode).\n> \n>>\n>>> root node and the value of that property matching with the integer argument of\n>>> the reference, at the same index.\n>>\n>> You've completely lost me. About halfway through this sentence my brain crashed :-)\n> \n> :-D\n> \n> Did keeping distance have any effect?\n\nNo :-)\n\n\"the index of the child node distance from the root node\": I have absolutely\nno idea how to interpret that.\n\n> \n>>\n>>>\n>>>>\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>>>> I know I asked for this before, but can you change the example to one where\n>>>> nprops = 2? I think that will help understanding this.\n>>>\n>>> I could do that but then the example no longer corresponds to any actual\n>>> case that exists at the moment. LED nodes will use a single integer\n>>> argument and lens-focus nodes none.\n>>\n>> So? The example is here to understand the code and it doesn't have to be\n>> related to actual hardware for a mainlined driver.\n> \n> This isn't about hardware, the definitions being parsed currently aren't\n> specific to any single piece of hardware. I could add an example which does\n> not exist, that's certainly possible. But I fail to see how it'd help\n> while the contrary could well be the case.\n\nIt helps to relate the code (and the comments for that matter) to what is in\nthe ACPI. In fact, if you can make such an example, then I can see if I can\ncome up with a better description.\n\nRegards,\n\n\tHans\n\n> \n>>\n>> If you really don't want to do this here, then put the example in the commit\n>> log. I don't see any reason why you can't put it here, though.\n>>\n>> I think that once I see an 'nprops = 2' example I can rephrase that\n>> brain-crash sentence for you...\n>>\n>> BTW, where are the ACPI 'bindings' defined anyway? For DT they are in the\n>> bindings directory, but where does ACPI define such things? Just curious.\n> \n> As the fwnode interface can be used to access information in both ACPI and\n> DT, there is an incentive to maintain the interfaces effectively the same.\n> In other words where the interfaces are the same, there is no need to\n> define bindings for ACPI as such. Where there are differences the bindings\n> are defined in Documentation/acpi/dsd .\n> \n> The so far only technical reason to that is related to the same is that\n> ACPI can only refer to device nodes (i.e. nodes that correspond to struct\n> devices), not sub-nodes under them.\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 3yBHTw3Bknz9s3w\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tWed, 11 Oct 2017 00:08:04 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1756045AbdJJNIC (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 10 Oct 2017 09:08:02 -0400","from lb1-smtp-cloud8.xs4all.net ([194.109.24.21]:42740 \"EHLO\n\tlb1-smtp-cloud8.xs4all.net\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1755272AbdJJNIC (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 10 Oct 2017 09:08:02 -0400","from [192.168.2.10] ([212.251.195.8])\n\tby smtp-cloud8.xs4all.net with ESMTPA\n\tid 1uFtecIE7g5cR1uFxeKpOD; Tue, 10 Oct 2017 15:08:00 +0200"],"Subject":"Re: [PATCH v14 20/28] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","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\tlaurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,\n\tpavel@ucw.cz, sre@kernel.org","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-21-sakari.ailus@linux.intel.com>\n\t<fbd2f71d-aa6d-08ef-1723-132864bde27b@xs4all.nl>\n\t<20170926113029.eh5i4sp6we6lvgow@paasikivi.fi.intel.com>\n\t<4363f544-d1ec-68e4-1edf-9a16b3cdb1ea@xs4all.nl>\n\t<20171010112710.noq6a4ktjqzt5u22@valkosipuli.retiisi.org.uk>","From":"Hans Verkuil <hverkuil@xs4all.nl>","Message-ID":"<d8a48273-7a19-0f83-4a4d-8058b7a59e0e@xs4all.nl>","Date":"Tue, 10 Oct 2017 15:07:29 +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":"<20171010112710.noq6a4ktjqzt5u22@valkosipuli.retiisi.org.uk>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","X-CMAE-Envelope":"MS4wfPprIwnYt8LKPHW0wZu6dhLCx4kyN0ZK/HjyigGtPN+GEXNka9uvYtQ53U3JGpJvNBrJnCmGetrONCe5/xMiZSCf12hh4HA38ELZJiXRLvHusdzC8o18\n\tr3hPDUD1jhcFc+Qcgu/ZpnM2R39l/GScY3i9cHs9TwCClxvCODpNS8PiUKOdpkzDx8DdK/O4FRNZTAocd49Sf+p+rN41MGvpXHUrKG13L7LuS4IRoUqtKOLt\n\tKTuA0yGsxMQR8TNzpdiDz1NvL7EpgpEAjXCZbdrch4hvVhVHn3qLrV0e5OTmSmBO4++F/WlIoMBWd31Fzp5LGe3G+Ke2LaGs2B7NaMf5Dgo3h9iOqK9om5AP\n\tcAVfLR3RYLd2w00aWfr2qGNgQFhsoLj+VZt5K1OVdbXuHoITOVu2v8gZSXLOE2RUz19mw6QGteFE2n2lxdF8uRPnRTaxXA==","Sender":"devicetree-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<devicetree.vger.kernel.org>","X-Mailing-List":"devicetree@vger.kernel.org"}},{"id":1787416,"web_url":"http://patchwork.ozlabs.org/comment/1787416/","msgid":"<20171016130244.stisr7g65hcbxwiz@paasikivi.fi.intel.com>","list_archive_url":null,"date":"2017-10-16T13:02:45","subject":"Re: [PATCH v14 20/28] 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, Oct 10, 2017 at 03:07:29PM +0200, Hans Verkuil wrote:\n> On 10/10/2017 01:27 PM, Sakari Ailus wrote:\n> > Hi Hans,\n> > \n> > On Mon, Oct 09, 2017 at 02:06:55PM +0200, Hans Verkuil wrote:\n> >> Hi Sakari,\n> >>\n> >> My reply here is also valid for v15.\n> >>\n> >> On 26/09/17 13:30, Sakari Ailus wrote:\n> >>> Hi Hans,\n> >>>\n> >>> Thanks for the review.\n> >>>\n> >>> On Tue, Sep 26, 2017 at 10:47:40AM +0200, Hans Verkuil wrote:\n> >>>> On 26/09/17 00:25, 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> >>>>> 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 f739dfd16cf7..f93049c361e4 100644\n> >>>>> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> >>>>> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> >>>>> @@ -578,6 +578,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> >>>>> + * 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> >>>> \"at an index\". Still makes no sense to me. Which index?\n> >>>\n> >>> How about this:\n> >>>\n> >>> First find an fwnode referred to by the reference at @index in @prop.\n> >>>\n> >>> Then under that fwnode, @nprops times, for each property in @props,\n> >>> iteratively follow child nodes starting from fwnode such that they have the\n> >>> property in @props array at the index of the child node distance from the\n> >>\n> >> distance? You mean 'instance'?\n> > \n> > No. It's a tree structure: this is the distance between a node in the tree\n> > and the root node (i.e. device's fwnode).\n> > \n> >>\n> >>> root node and the value of that property matching with the integer argument of\n> >>> the reference, at the same index.\n> >>\n> >> You've completely lost me. About halfway through this sentence my brain crashed :-)\n> > \n> > :-D\n> > \n> > Did keeping distance have any effect?\n> \n> No :-)\n> \n> \"the index of the child node distance from the root node\": I have absolutely\n> no idea how to interpret that.\n\nThis index is referring to the properties array and its value is the same\nas the distance of the child node from the device's root node.\n\n> \n> > \n> >>\n> >>>\n> >>>>\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> >>>> I know I asked for this before, but can you change the example to one where\n> >>>> nprops = 2? I think that will help understanding this.\n> >>>\n> >>> I could do that but then the example no longer corresponds to any actual\n> >>> case that exists at the moment. LED nodes will use a single integer\n> >>> argument and lens-focus nodes none.\n> >>\n> >> So? The example is here to understand the code and it doesn't have to be\n> >> related to actual hardware for a mainlined driver.\n> > \n> > This isn't about hardware, the definitions being parsed currently aren't\n> > specific to any single piece of hardware. I could add an example which does\n> > not exist, that's certainly possible. But I fail to see how it'd help\n> > while the contrary could well be the case.\n> \n> It helps to relate the code (and the comments for that matter) to what is in\n> the ACPI. In fact, if you can make such an example, then I can see if I can\n> come up with a better description.\n\nHmm. I thought about the example, and figured out the graph data structure\ncould be parsed using this function as well. From\nDocumentation/acpi/dsd/graph.txt:\n\n    Scope (\\_SB.PCI0.I2C2)\n    {\n\tDevice (CAM0)\n\t{\n\t    Name (_DSD, Package () {\n\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n\t\tPackage () {\n\t\t    Package () { \"compatible\", Package () { \"nokia,smia\" } },\n\t\t},\n\t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n\t\tPackage () {\n\t\t    Package () { \"port0\", \"PRT0\" },\n\t\t}\n\t    })\n\t    Name (PRT0, Package() {\n\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n\t\tPackage () {\n\t\t    Package () { \"port\", 0 },\n\t\t},\n\t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n\t\tPackage () {\n\t\t    Package () { \"endpoint0\", \"EP00\" },\n\t\t}\n\t    })\n\t    Name (EP00, Package() {\n\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n\t\tPackage () {\n\t\t    Package () { \"endpoint\", 0 },\n\t\t    Package () { \"remote-endpoint\", Package() { \\_SB.PCI0.ISP, 4, 0 } },\n\t\t}\n\t    })\n\t}\n    }\n\n    Scope (\\_SB.PCI0)\n    {\n\tDevice (ISP)\n\t{\n\t    Name (_DSD, Package () {\n\t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n\t\tPackage () {\n\t\t    Package () { \"port4\", \"PRT4\" },\n\t\t}\n\t    })\n\n\t    Name (PRT4, Package() {\n\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n\t\tPackage () {\n\t\t    Package () { \"port\", 4 }, /* CSI-2 port number */\n\t\t},\n\t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n\t\tPackage () {\n\t\t    Package () { \"endpoint0\", \"EP40\" },\n\t\t}\n\t    })\n\n\t    Name (EP40, Package() {\n\t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n\t\tPackage () {\n\t\t    Package () { \"endpoint\", 0 },\n\t\t    Package () { \"remote-endpoint\", Package () { \\_SB.PCI0.I2C2.CAM0, 0, 0 } },\n\t\t}\n\t    })\n\t}\n    }\n\n>From the EP40 node under ISP device, you could parse the graph remote\nendpoint using v4l2_fwnode_reference_get_int_prop with these arguments (the\nargument dev changed to fwnode in an earlier version of the patch, I'll\naddress that soon as well):\n\n @fwnode: fwnode referring to EP40 under ISP.\n @prop: \"remote-endpoint\"\n @index: 0\n @props: \"port\", \"endpoint\"\n @nprops: 2\n\nAnd you'd get back fwnode referring to EP00 under CAM0.\n\nThe same works the other way around: if you use EP00 under CAM0 as the\nfwnode, you'll get fwnode referring to EP40 under ISP.\n\nIf the remote-endpoint property would have additional references beyond the\nfirst one, then incrementing index could be used to obtain them. The graph\nbindings don't allow this though.\n\nThis function can be eventually moved to the ACPI framework, but doing that\nright now would probably one kernel release delay for the functionality.","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 3yFz576Btpz9t3Z\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 17 Oct 2017 00:02:51 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752004AbdJPNCu (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tMon, 16 Oct 2017 09:02:50 -0400","from mga04.intel.com ([192.55.52.120]:25354 \"EHLO mga04.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1751389AbdJPNCt (ORCPT <rfc822;devicetree@vger.kernel.org>);\n\tMon, 16 Oct 2017 09:02:49 -0400","from fmsmga002.fm.intel.com ([10.253.24.26])\n\tby fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t16 Oct 2017 06:02:48 -0700","from paasikivi.fi.intel.com ([10.237.72.42])\n\tby fmsmga002.fm.intel.com with ESMTP; 16 Oct 2017 06:02:45 -0700","by paasikivi.fi.intel.com (Postfix, from userid 1000)\n\tid 257A92048B; Mon, 16 Oct 2017 16:02:45 +0300 (EEST)"],"X-ExtLoop1":"1","X-IronPort-AV":"E=Sophos; i=\"5.43,387,1503385200\"; d=\"scan'208\";\n\ta=\"1231320100\"","Date":"Mon, 16 Oct 2017 16:02:45 +0300","From":"Sakari Ailus <sakari.ailus@linux.intel.com>","To":"Hans Verkuil <hverkuil@xs4all.nl>","Cc":"Sakari Ailus <sakari.ailus@iki.fi>, linux-media@vger.kernel.org,\n\tniklas.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","Subject":"Re: [PATCH v14 20/28] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","Message-ID":"<20171016130244.stisr7g65hcbxwiz@paasikivi.fi.intel.com>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-21-sakari.ailus@linux.intel.com>\n\t<fbd2f71d-aa6d-08ef-1723-132864bde27b@xs4all.nl>\n\t<20170926113029.eh5i4sp6we6lvgow@paasikivi.fi.intel.com>\n\t<4363f544-d1ec-68e4-1edf-9a16b3cdb1ea@xs4all.nl>\n\t<20171010112710.noq6a4ktjqzt5u22@valkosipuli.retiisi.org.uk>\n\t<d8a48273-7a19-0f83-4a4d-8058b7a59e0e@xs4all.nl>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<d8a48273-7a19-0f83-4a4d-8058b7a59e0e@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":1788356,"web_url":"http://patchwork.ozlabs.org/comment/1788356/","msgid":"<20171017124258.3epvbqzou3jjyv7y@valkosipuli.retiisi.org.uk>","list_archive_url":null,"date":"2017-10-17T12:42:58","subject":"Re: [PATCH v14 20/28] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","submitter":{"id":1593,"url":"http://patchwork.ozlabs.org/api/people/1593/","name":"Sakari Ailus","email":"sakari.ailus@iki.fi"},"content":"On Mon, Oct 16, 2017 at 04:02:45PM +0300, Sakari Ailus wrote:\n> Hi Hans,\n> \n> On Tue, Oct 10, 2017 at 03:07:29PM +0200, Hans Verkuil wrote:\n> > On 10/10/2017 01:27 PM, Sakari Ailus wrote:\n> > > Hi Hans,\n> > > \n> > > On Mon, Oct 09, 2017 at 02:06:55PM +0200, Hans Verkuil wrote:\n> > >> Hi Sakari,\n> > >>\n> > >> My reply here is also valid for v15.\n> > >>\n> > >> On 26/09/17 13:30, Sakari Ailus wrote:\n> > >>> Hi Hans,\n> > >>>\n> > >>> Thanks for the review.\n> > >>>\n> > >>> On Tue, Sep 26, 2017 at 10:47:40AM +0200, Hans Verkuil wrote:\n> > >>>> On 26/09/17 00:25, 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> > >>>>> 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 f739dfd16cf7..f93049c361e4 100644\n> > >>>>> --- a/drivers/media/v4l2-core/v4l2-fwnode.c\n> > >>>>> +++ b/drivers/media/v4l2-core/v4l2-fwnode.c\n> > >>>>> @@ -578,6 +578,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> > >>>>> + * 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> > >>>> \"at an index\". Still makes no sense to me. Which index?\n> > >>>\n> > >>> How about this:\n> > >>>\n> > >>> First find an fwnode referred to by the reference at @index in @prop.\n> > >>>\n> > >>> Then under that fwnode, @nprops times, for each property in @props,\n> > >>> iteratively follow child nodes starting from fwnode such that they have the\n> > >>> property in @props array at the index of the child node distance from the\n> > >>\n> > >> distance? You mean 'instance'?\n> > > \n> > > No. It's a tree structure: this is the distance between a node in the tree\n> > > and the root node (i.e. device's fwnode).\n> > > \n> > >>\n> > >>> root node and the value of that property matching with the integer argument of\n> > >>> the reference, at the same index.\n> > >>\n> > >> You've completely lost me. About halfway through this sentence my brain crashed :-)\n> > > \n> > > :-D\n> > > \n> > > Did keeping distance have any effect?\n> > \n> > No :-)\n> > \n> > \"the index of the child node distance from the root node\": I have absolutely\n> > no idea how to interpret that.\n> \n> This index is referring to the properties array and its value is the same\n> as the distance of the child node from the device's root node.\n> \n> > \n> > > \n> > >>\n> > >>>\n> > >>>>\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> > >>>> I know I asked for this before, but can you change the example to one where\n> > >>>> nprops = 2? I think that will help understanding this.\n> > >>>\n> > >>> I could do that but then the example no longer corresponds to any actual\n> > >>> case that exists at the moment. LED nodes will use a single integer\n> > >>> argument and lens-focus nodes none.\n> > >>\n> > >> So? The example is here to understand the code and it doesn't have to be\n> > >> related to actual hardware for a mainlined driver.\n> > > \n> > > This isn't about hardware, the definitions being parsed currently aren't\n> > > specific to any single piece of hardware. I could add an example which does\n> > > not exist, that's certainly possible. But I fail to see how it'd help\n> > > while the contrary could well be the case.\n> > \n> > It helps to relate the code (and the comments for that matter) to what is in\n> > the ACPI. In fact, if you can make such an example, then I can see if I can\n> > come up with a better description.\n> \n> Hmm. I thought about the example, and figured out the graph data structure\n> could be parsed using this function as well. From\n> Documentation/acpi/dsd/graph.txt:\n> \n>     Scope (\\_SB.PCI0.I2C2)\n>     {\n> \tDevice (CAM0)\n> \t{\n> \t    Name (_DSD, Package () {\n> \t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> \t\tPackage () {\n> \t\t    Package () { \"compatible\", Package () { \"nokia,smia\" } },\n> \t\t},\n> \t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n> \t\tPackage () {\n> \t\t    Package () { \"port0\", \"PRT0\" },\n> \t\t}\n> \t    })\n> \t    Name (PRT0, Package() {\n> \t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> \t\tPackage () {\n> \t\t    Package () { \"port\", 0 },\n> \t\t},\n> \t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n> \t\tPackage () {\n> \t\t    Package () { \"endpoint0\", \"EP00\" },\n> \t\t}\n> \t    })\n> \t    Name (EP00, Package() {\n> \t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> \t\tPackage () {\n> \t\t    Package () { \"endpoint\", 0 },\n> \t\t    Package () { \"remote-endpoint\", Package() { \\_SB.PCI0.ISP, 4, 0 } },\n> \t\t}\n> \t    })\n> \t}\n>     }\n> \n>     Scope (\\_SB.PCI0)\n>     {\n> \tDevice (ISP)\n> \t{\n> \t    Name (_DSD, Package () {\n> \t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n> \t\tPackage () {\n> \t\t    Package () { \"port4\", \"PRT4\" },\n> \t\t}\n> \t    })\n> \n> \t    Name (PRT4, Package() {\n> \t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> \t\tPackage () {\n> \t\t    Package () { \"port\", 4 }, /* CSI-2 port number */\n> \t\t},\n> \t\tToUUID(\"dbb8e3e6-5886-4ba6-8795-1319f52a966b\"),\n> \t\tPackage () {\n> \t\t    Package () { \"endpoint0\", \"EP40\" },\n> \t\t}\n> \t    })\n> \n> \t    Name (EP40, Package() {\n> \t\tToUUID(\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\"),\n> \t\tPackage () {\n> \t\t    Package () { \"endpoint\", 0 },\n> \t\t    Package () { \"remote-endpoint\", Package () { \\_SB.PCI0.I2C2.CAM0, 0, 0 } },\n> \t\t}\n> \t    })\n> \t}\n>     }\n\nIf you did this with DT it'd look roughly like:\n\ncam0 {\n\tcompatible = \"nokia,smia\";\n\n\tport {\n\t\tcam0_ep: endpoint {\n\t\t\tremote-endpoint = <&isp_port4_ep>;\n\t\t};\n\t};\n};\n\nisp {\n\tports {\n\t\tport@4 {\n\t\t\treg = <4>;\n\t\t\tisp_port4_ep: endpoint {\n\t\t\t\tremote-endpoint = <&cam0_ep>;\n\t\t\t};\t\n\t\t};\n\t};\n};\n\nAnd in ACPI style, i.e. with explicit \"port\" and \"endpoint\" properties as\nwell as integers to point the ports and endpoints:\n\ncam: cam0 {\n\tcompatible = \"nokia,smia\";\n\n\tport {\n\t\tport = <0>;\n\t\tcam0_ep: endpoint {\n\t\t\tendpoint = <0>;\n\t\t\tremote-endpoint = <&isp 4 0>;\n\t\t};\n\t};\n};\n\nisp: isp {\n\tports {\n\t\tport@4 {\n\t\t\tport = <4>;\n\t\t\tisp_port4_ep: endpoint {\n\t\t\t\tendpoint = <0>;\n\t\t\t\tremote-endpoint = <&cam 0 0>;\n\t\t\t};\t\n\t\t};\n\t};\n};\n\n\n> \n> From the EP40 node under ISP device, you could parse the graph remote\n> endpoint using v4l2_fwnode_reference_get_int_prop with these arguments (the\n> argument dev changed to fwnode in an earlier version of the patch, I'll\n> address that soon as well):\n> \n>  @fwnode: fwnode referring to EP40 under ISP.\n>  @prop: \"remote-endpoint\"\n>  @index: 0\n>  @props: \"port\", \"endpoint\"\n>  @nprops: 2\n> \n> And you'd get back fwnode referring to EP00 under CAM0.\n> \n> The same works the other way around: if you use EP00 under CAM0 as the\n> fwnode, you'll get fwnode referring to EP40 under ISP.\n> \n> If the remote-endpoint property would have additional references beyond the\n> first one, then incrementing index could be used to obtain them. The graph\n> bindings don't allow this though.\n> \n> This function can be eventually moved to the ACPI framework, but doing that\n> right now would probably one kernel release delay for the functionality.\n> \n> -- \n> Regards,\n> \n> Sakari Ailus\n> sakari.ailus@linux.intel.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 3yGZbq6zjLz9sBW\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 17 Oct 2017 23:43:03 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1757345AbdJQMnC (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 17 Oct 2017 08:43:02 -0400","from nblzone-211-213.nblnetworks.fi ([83.145.211.213]:39760 \"EHLO\n\thillosipuli.retiisi.org.uk\" rhost-flags-OK-OK-OK-FAIL)\n\tby vger.kernel.org with ESMTP id S1754784AbdJQMnB (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 17 Oct 2017 08:43:01 -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 392CE600EC;\n\tTue, 17 Oct 2017 15:42:59 +0300 (EEST)","from sakke by valkosipuli.localdomain with local (Exim 4.89)\n\t(envelope-from <sakari.ailus@retiisi.org.uk>)\n\tid 1e4RD0-0001Sz-QN; Tue, 17 Oct 2017 15:42:58 +0300"],"Date":"Tue, 17 Oct 2017 15:42:58 +0300","From":"Sakari Ailus <sakari.ailus@iki.fi>","To":"Sakari Ailus <sakari.ailus@linux.intel.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, laurent.pinchart@ideasonboard.com,\n\tdevicetree@vger.kernel.org, pavel@ucw.cz, sre@kernel.org","Subject":"Re: [PATCH v14 20/28] v4l: fwnode: Add a helper function to obtain\n\tdevice / integer references","Message-ID":"<20171017124258.3epvbqzou3jjyv7y@valkosipuli.retiisi.org.uk>","References":"<20170925222540.371-1-sakari.ailus@linux.intel.com>\n\t<20170925222540.371-21-sakari.ailus@linux.intel.com>\n\t<fbd2f71d-aa6d-08ef-1723-132864bde27b@xs4all.nl>\n\t<20170926113029.eh5i4sp6we6lvgow@paasikivi.fi.intel.com>\n\t<4363f544-d1ec-68e4-1edf-9a16b3cdb1ea@xs4all.nl>\n\t<20171010112710.noq6a4ktjqzt5u22@valkosipuli.retiisi.org.uk>\n\t<d8a48273-7a19-0f83-4a4d-8058b7a59e0e@xs4all.nl>\n\t<20171016130244.stisr7g65hcbxwiz@paasikivi.fi.intel.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20171016130244.stisr7g65hcbxwiz@paasikivi.fi.intel.com>","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"}}]