All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sakari Ailus <sakari.ailus@linux.intel.com>
To: linux-media@vger.kernel.org
Cc: niklas.soderlund@ragnatech.se, maxime.ripard@free-electrons.com,
	hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com,
	pavel@ucw.cz, sre@kernel.org
Subject: [PATCH v15.2 24/32] v4l: fwnode: Add a helper function to obtain device / integer references
Date: Tue, 24 Oct 2017 23:32:54 +0300	[thread overview]
Message-ID: <20171024203254.19993-1-sakari.ailus@linux.intel.com> (raw)
In-Reply-To: <ffc57dfd-e798-d532-e029-dc91989e285c@xs4all.nl>

v4l2_fwnode_reference_parse_int_prop() will find an fwnode such that under
the device's own fwnode, it will follow child fwnodes with the given
property-value pair and return the resulting fwnode.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/v4l2-core/v4l2-fwnode.c | 286 ++++++++++++++++++++++++++++++++++
 1 file changed, 286 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index edd2e8d983a1..ed7e363a8a6a 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -578,6 +578,292 @@ static int v4l2_fwnode_reference_parse(
 	return ret;
 }
 
+/*
+ * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
+ *					arguments
+ * @fwnode: fwnode to read @prop from
+ * @notifier: notifier for @dev
+ * @prop: the name of the property
+ * @index: the index of the reference to get
+ * @props: the array of integer property names
+ * @nprops: the number of integer property names in @nprops
+ *
+ * First find an fwnode referred to by the reference at @index in @prop.
+ *
+ * Then under that fwnode, @nprops times, for each property in @props,
+ * iteratively follow child nodes starting from fwnode such that they have the
+ * property in @props array at the index of the child node distance from the
+ * root node and the value of that property matching with the integer argument
+ * of the reference, at the same index.
+ *
+ * The child fwnode reched at the end of the iteration is then returned to the
+ * caller.
+ *
+ * The core reason for this is that you cannot refer to just any node in ACPI.
+ * So to refer to an endpoint (easy in DT) you need to refer to a device, then
+ * provide a list of (property name, property value) tuples where each tuple
+ * uniquely identifies a child node. The first tuple identifies a child directly
+ * underneath the device fwnode, the next tuple identifies a child node
+ * underneath the fwnode identified by the previous tuple, etc. until you
+ * reached the fwnode you need.
+ *
+ * An example with a graph, as defined in Documentation/acpi/dsd/graph.txt:
+ *
+ *	Scope (\_SB.PCI0.I2C2)
+ *	{
+ *		Device (CAM0)
+ *		{
+ *			Name (_DSD, Package () {
+ *				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ *				Package () {
+ *					Package () {
+ *						"compatible",
+ *						Package () { "nokia,smia" }
+ *					},
+ *				},
+ *				ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ *				Package () {
+ *					Package () { "port0", "PRT0" },
+ *				}
+ *			})
+ *			Name (PRT0, Package() {
+ *				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ *				Package () {
+ *					Package () { "port", 0 },
+ *				},
+ *				ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ *				Package () {
+ *					Package () { "endpoint0", "EP00" },
+ *				}
+ *			})
+ *			Name (EP00, Package() {
+ *				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ *				Package () {
+ *					Package () { "endpoint", 0 },
+ *					Package () {
+ *						"remote-endpoint",
+ *						Package() {
+ *							\_SB.PCI0.ISP, 4, 0
+ *						}
+ *					},
+ *				}
+ *			})
+ *		}
+ *	}
+ *
+ *	Scope (\_SB.PCI0)
+ *	{
+ *		Device (ISP)
+ *		{
+ *			Name (_DSD, Package () {
+ *				ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ *				Package () {
+ *					Package () { "port4", "PRT4" },
+ *				}
+ *			})
+ *
+ *			Name (PRT4, Package() {
+ *				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ *				Package () {
+ *					Package () { "port", 4 },
+ *				},
+ *				ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ *				Package () {
+ *					Package () { "endpoint0", "EP40" },
+ *				}
+ *			})
+ *
+ *			Name (EP40, Package() {
+ *				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ *				Package () {
+ *					Package () { "endpoint", 0 },
+ *					Package () {
+ *						"remote-endpoint",
+ *						Package () {
+ *							\_SB.PCI0.I2C2.CAM0,
+ *							0, 0
+ *						}
+ *					},
+ *				}
+ *			})
+ *		}
+ *	}
+ *
+ * From the EP40 node under ISP device, you could parse the graph remote
+ * endpoint using v4l2_fwnode_reference_get_int_prop with these arguments:
+ *
+ *  @fwnode: fwnode referring to EP40 under ISP.
+ *  @prop: "remote-endpoint"
+ *  @index: 0
+ *  @props: "port", "endpoint"
+ *  @nprops: 2
+ *
+ * And you'd get back fwnode referring to EP00 under CAM0.
+ *
+ * The same works the other way around: if you use EP00 under CAM0 as the
+ * fwnode, you'll get fwnode referring to EP40 under ISP.
+ *
+ * The same example in DT syntax would look like this:
+ *
+ * cam: cam0 {
+ *	compatible = "nokia,smia";
+ *
+ *	port {
+ *		port = <0>;
+ *		endpoint {
+ *			endpoint = <0>;
+ *			remote-endpoint = <&isp 4 0>;
+ *		};
+ *	};
+ * };
+ *
+ * isp: isp {
+ *	ports {
+ *		port@4 {
+ *			port = <4>;
+ *			endpoint {
+ *				endpoint = <0>;
+ *				remote-endpoint = <&cam 0 0>;
+ *			};
+ *		};
+ *	};
+ * };
+ *
+ * Return: 0 on success
+ *	   -ENOENT if no entries (or the property itself) were found
+ *	   -EINVAL if property parsing otherwise failed
+ *	   -ENOMEM if memory allocation failed
+ */
+static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(
+	struct fwnode_handle *fwnode, const char *prop, unsigned int index,
+	const char **props, unsigned int nprops)
+{
+	struct fwnode_reference_args fwnode_args;
+	unsigned int *args = fwnode_args.args;
+	struct fwnode_handle *child;
+	int ret;
+
+	/*
+	 * Obtain remote fwnode as well as the integer arguments.
+	 *
+	 * Note that right now both -ENODATA and -ENOENT may signal
+	 * out-of-bounds access. Return -ENOENT in that case.
+	 */
+	ret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops,
+						 index, &fwnode_args);
+	if (ret)
+		return ERR_PTR(ret == -ENODATA ? -ENOENT : ret);
+
+	/*
+	 * Find a node in the tree under the referred fwnode corresponding to
+	 * the integer arguments.
+	 */
+	fwnode = fwnode_args.fwnode;
+	while (nprops--) {
+		u32 val;
+
+		/* Loop over all child nodes under fwnode. */
+		fwnode_for_each_child_node(fwnode, child) {
+			if (fwnode_property_read_u32(child, *props, &val))
+				continue;
+
+			/* Found property, see if its value matches. */
+			if (val == *args)
+				break;
+		}
+
+		fwnode_handle_put(fwnode);
+
+		/* No property found; return an error here. */
+		if (!child) {
+			fwnode = ERR_PTR(-ENOENT);
+			break;
+		}
+
+		props++;
+		args++;
+		fwnode = child;
+	}
+
+	return fwnode;
+}
+
+/*
+ * v4l2_fwnode_reference_parse_int_props - parse references for async sub-devices
+ * @dev: struct device pointer
+ * @notifier: notifier for @dev
+ * @prop: the name of the property
+ * @props: the array of integer property names
+ * @nprops: the number of integer properties
+ *
+ * Use v4l2_fwnode_reference_get_int_prop to find fwnodes through reference in
+ * property @prop with integer arguments with child nodes matching in properties
+ * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier
+ * accordingly.
+ *
+ * While it is technically possible to use this function on DT, it is only
+ * meaningful on ACPI. On Device tree you can refer to any node in the tree but
+ * on ACPI the references are limited to devices.
+ *
+ * Return: 0 on success
+ *	   -ENOENT if no entries (or the property itself) were found
+ *	   -EINVAL if property parsing otherwisefailed
+ *	   -ENOMEM if memory allocation failed
+ */
+static int v4l2_fwnode_reference_parse_int_props(
+	struct device *dev, struct v4l2_async_notifier *notifier,
+	const char *prop, const char **props, unsigned int nprops)
+{
+	struct fwnode_handle *fwnode;
+	unsigned int index;
+	int ret;
+
+	for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(
+					 dev_fwnode(dev), prop, index, props,
+					 nprops))); index++)
+		fwnode_handle_put(fwnode);
+
+	/*
+	 * Note that right now both -ENODATA and -ENOENT may signal
+	 * out-of-bounds access. Return the error in cases other than that.
+	 */
+	if (PTR_ERR(fwnode) != -ENOENT && PTR_ERR(fwnode) != -ENODATA)
+		return PTR_ERR(fwnode);
+
+	ret = v4l2_async_notifier_realloc(notifier,
+					  notifier->num_subdevs + index);
+	if (ret)
+		return -ENOMEM;
+
+	for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(
+					 dev_fwnode(dev), prop, index, props,
+					 nprops))); index++) {
+		struct v4l2_async_subdev *asd;
+
+		if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {
+			ret = -EINVAL;
+			goto error;
+		}
+
+		asd = kzalloc(sizeof(struct v4l2_async_subdev), GFP_KERNEL);
+		if (!asd) {
+			ret = -ENOMEM;
+			goto error;
+		}
+
+		notifier->subdevs[notifier->num_subdevs] = asd;
+		asd->match.fwnode.fwnode = fwnode;
+		asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
+		notifier->num_subdevs++;
+	}
+
+	return PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode);
+
+error:
+	fwnode_handle_put(fwnode);
+	return ret;
+}
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-- 
2.11.0

  parent reply	other threads:[~2017-10-24 20:32 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-04 21:50 [PATCH v15 00/32] Unified fwnode endpoint parser, async sub-device notifier support, N9 flash DTS Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 01/32] v4l: async: Remove re-probing support Sakari Ailus
2017-10-08 21:50   ` Sebastian Reichel
2017-10-09 11:22   ` Mauro Carvalho Chehab
2017-10-09 14:06     ` Sakari Ailus
2017-10-09 14:08       ` Hans Verkuil
2017-10-09 14:18         ` Sakari Ailus
2017-10-09 14:20           ` Hans Verkuil
2017-10-09 15:27             ` Mauro Carvalho Chehab
     [not found]           ` <CGME20171009164457epcas1p3c5e134e4bb5d85498fe8d4f00332f2fc@epcas1p3.samsung.com>
2017-10-09 16:44             ` Sylwester Nawrocki
2017-10-09 19:18               ` Laurent Pinchart
2017-10-10 12:18               ` Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 02/32] v4l: async: Don't set sd->dev NULL in v4l2_async_cleanup Sakari Ailus
2017-10-08 21:50   ` Sebastian Reichel
2017-10-09 11:21   ` Hans Verkuil
2017-10-04 21:50 ` [PATCH v15 03/32] v4l: async: fix unbind error in v4l2_async_notifier_unregister() Sakari Ailus
2017-10-08 21:50   ` Sebastian Reichel
2017-10-09 11:23   ` Hans Verkuil
2017-10-04 21:50 ` [PATCH v15 04/32] v4l: async: Fix notifier complete callback error handling Sakari Ailus
2017-10-09 11:45   ` Hans Verkuil
2017-10-10 12:57     ` Sakari Ailus
2017-10-10 13:18       ` Hans Verkuil
2017-10-10 14:21         ` Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 05/32] v4l: async: Correctly serialise async sub-device unregistration Sakari Ailus
2017-10-08 21:52   ` Sebastian Reichel
2017-10-09 11:45   ` Hans Verkuil
2017-10-04 21:50 ` [PATCH v15 06/32] v4l: async: Use more intuitive names for internal functions Sakari Ailus
2017-10-08 21:53   ` Sebastian Reichel
2017-10-04 21:50 ` [PATCH v15 07/32] v4l: async: Add V4L2 async documentation to the documentation build Sakari Ailus
2017-10-08 21:54   ` Sebastian Reichel
2017-10-09 11:31   ` Mauro Carvalho Chehab
2017-10-04 21:50 ` [PATCH v15 08/32] v4l: fwnode: Support generic parsing of graph endpoints in a device Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 09/32] omap3isp: Use generic parser for parsing fwnode endpoints Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 10/32] rcar-vin: " Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 11/32] omap3isp: Fix check for our own sub-devices Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 12/32] omap3isp: Print the name of the entity where no source pads could be found Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 13/32] v4l: async: Move async subdev notifier operations to a separate structure Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 14/32] v4l: async: Introduce helpers for calling async ops callbacks Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 15/32] v4l: async: Register sub-devices before calling bound callback Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 16/32] v4l: async: Allow async notifier register call succeed with no subdevs Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 17/32] v4l: async: Prepare for async sub-device notifiers Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 18/32] v4l: async: Allow binding notifiers to sub-devices Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 19/32] v4l: async: Ensure only unique fwnodes are registered to notifiers Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 20/32] dt: bindings: Add a binding for flash LED devices associated to a sensor Sakari Ailus
     [not found]   ` <20171004215051.13385-21-sakari.ailus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2017-10-13 13:41     ` Rob Herring
2017-10-13 13:41       ` Rob Herring
2017-10-04 21:50 ` [PATCH v15 21/32] dt: bindings: Add lens-focus binding for image sensors Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 22/32] v4l: fwnode: Move KernelDoc documentation to the header Sakari Ailus
2017-10-05 12:03   ` [PATCH v15.1 " Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 23/32] v4l: fwnode: Add a helper function for parsing generic references Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 24/32] v4l: fwnode: Add a helper function to obtain device / integer references Sakari Ailus
2017-10-18 13:56   ` [PATCH v15.1 " Sakari Ailus
2017-10-18 15:32     ` Sakari Ailus
2017-10-19  6:52       ` Hans Verkuil
2017-10-20 11:35         ` Sakari Ailus
2017-10-24 20:32         ` Sakari Ailus [this message]
2017-10-24 20:36           ` [PATCH v15.2 " Sakari Ailus
2017-10-25  7:28           ` Hans Verkuil
2017-10-04 21:50 ` [PATCH v15 25/32] v4l: fwnode: Add convenience function for parsing common external refs Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 26/32] v4l: fwnode: Add a convenience function for registering sensors Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 27/32] dt: bindings: smiapp: Document lens-focus and flash-leds properties Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 28/32] smiapp: Add support for flash and lens devices Sakari Ailus
2017-10-06 11:21   ` Pavel Machek
2017-10-04 21:50 ` [PATCH v15 29/32] et8ek8: " Sakari Ailus
2017-10-06 11:21   ` Pavel Machek
2017-10-04 21:50 ` [PATCH v15 30/32] ov5670: " Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 31/32] ov13858: " Sakari Ailus
2017-10-04 21:50 ` [PATCH v15 32/32] arm: dts: omap3: N9/N950: Add flash references to the camera Sakari Ailus
2017-10-05  6:11 ` [PATCH v15 00/32] Unified fwnode endpoint parser, async sub-device notifier support, N9 flash DTS Sakari Ailus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171024203254.19993-1-sakari.ailus@linux.intel.com \
    --to=sakari.ailus@linux.intel.com \
    --cc=hverkuil@xs4all.nl \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-media@vger.kernel.org \
    --cc=maxime.ripard@free-electrons.com \
    --cc=niklas.soderlund@ragnatech.se \
    --cc=pavel@ucw.cz \
    --cc=sre@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.