Re: [PATCH v10 18/24] v4l: fwnode: Add a helper function to obtain device / interger references
From: Sakari Ailus <sakari.ailus@iki.fi>
Date: 2017-09-11 12:28:20
Also in:
linux-acpi, linux-media
Hi Hans, Thanks for the review. On Mon, Sep 11, 2017 at 11:38:58AM +0200, Hans Verkuil wrote:
Typo in subject: interger -> integer On 09/11/2017 10:00 AM, Sakari Ailus wrote:quoted
v4l2_fwnode_reference_parse_int_prop() will find an fwnode such that under the device's own fwnode,Sorry, you lost me here. Which device are we talking about?
The fwnode related a struct device, in other words what dev_fwnode(dev) gives you. This is either struct device.fwnode or struct device.of_node.fwnode, depending on which firmware interface was used to create the device. I'll add a note of this.
quoted
it will follow child fwnodes with the given property -- value pair and return the resulting fwnode.property-value pair (easier readable that way). You only describe v4l2_fwnode_reference_parse_int_prop(), not v4l2_fwnode_reference_parse_int_props().
Yes, I think I changed the naming but forgot to update the commit. I'll do that now.
quoted
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> --- drivers/media/v4l2-core/v4l2-fwnode.c | 93 +++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+)diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 4821c4989119..56eee5bbd3b5 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c@@ -496,6 +496,99 @@ static int v4l2_fwnode_reference_parse( return ret; } +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)Need comments describing what this does.
Yes. I'll also rename it (get -> read) for consistency with the async changes.
quoted
+{ + struct fwnode_reference_args fwnode_args; + unsigned int *args = fwnode_args.args; + struct fwnode_handle *child; + int ret; + + ret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops, + index, &fwnode_args); + if (ret) + return ERR_PTR(ret == -EINVAL ? -ENOENT : ret);Why map EINVAL to ENOENT? Needs a comment, either here or in the function description.
fwnode_property_get_reference_args() returns currently a little bit different error codes in ACPI / DT. This is worth documenting there and fixing as well.
quoted
+ + for (fwnode = fwnode_args.fwnode; + nprops; nprops--, fwnode = child, props++, args++) {I think you cram too much in this for-loop: fwnode, nprops, fwnode, props, args... It's hard to parse.
Hmm. I'm not sure if that really helps; the function is just handling each entry in the array and related array pointers are changed accordingly. The fwnode = child assignment is there to move to the child node. I.e. what you need for handling the loop itself. I can change this though if you think it really makes a difference for better.
I would make this a 'while (nprops)' and write out all the other assignments, increments and decrements.quoted
+ u32 val; + + fwnode_for_each_child_node(fwnode, child) { + if (fwnode_property_read_u32(child, *props, &val)) + continue; + + if (val == *args) + break;I'm lost. This really needs comments and perhaps even an DT or ACPI example so you can see what exactly it is we're doing here.
I'll add comments to the code. A good example will be ACPI documentation for LEDs, see 17th patch in v9. That will go through the linux-pm tree so it won't be available in the same tree for a while.
quoted
+ } + + fwnode_handle_put(fwnode); + + if (!child) { + fwnode = ERR_PTR(-ENOENT); + break; + } + } + + return fwnode; +} + +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)Needs comments describing what this does.
Will add.
quoted
+{ + struct fwnode_handle *fwnode; + unsigned int index = 0; + int ret; + + while (!IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop( + dev_fwnode(dev), prop, index, props, + nprops)))) { + fwnode_handle_put(fwnode); + index++; + } + + if (PTR_ERR(fwnode) != -ENOENT) + return PTR_ERR(fwnode);Missing 'if (index == 0)'?
Yes, will add.
quoted
+ + 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))); ) {I'd add 'index++' in this for-loop. It's weird that it is missing.
Agreed, I'll move it there.
quoted
+ 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++; + + fwnode_handle_put(fwnode); + + index++; + } + + return PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode); + +error: + fwnode_handle_put(fwnode); + return ret; +} + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Sakari Ailus [off-list ref]"); MODULE_AUTHOR("Sylwester Nawrocki [off-list ref]");
-- Regards, Sakari Ailus e-mail: sakari.ailus@iki.fi