Re: [PATCH] of: Create function for counting number of phandles ina property

From: Andreas Larsson
Date: Mon Feb 11 2013 - 06:26:31 EST


On 2013-02-11 00:58, Grant Likely wrote:
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 2390ddb..e1120a2 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1025,12 +1025,13 @@ EXPORT_SYMBOL(of_parse_phandle);
* To get a device_node of the `node2' node you may call this:
* of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
*/
-int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
- const char *cells_name, int index,
- struct of_phandle_args *out_args)
+static int __of_parse_phandle_with_args(const struct device_node *np,
+ const char *list_name,
+ const char *cells_name, int index,
+ struct of_phandle_args *out_args)
{
const __be32 *list, *list_end;
- int size, cur_index = 0;
+ int rc = 0, size, cur_index = 0;
uint32_t count = 0;
struct device_node *node = NULL;
phandle phandle;
@@ -1059,12 +1060,14 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
if (!node) {
pr_err("%s: could not find phandle\n",
np->full_name);
+ rc = -EINVAL;
break;
}
if (of_property_read_u32(node, cells_name, &count)) {
pr_err("%s: could not get %s for %s\n",
np->full_name, cells_name,
node->full_name);
+ rc = -EINVAL;
break;
}

@@ -1075,6 +1078,7 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
if (list + count > list_end) {
pr_err("%s: arguments longer than property\n",
np->full_name);
+ rc = -EINVAL;
break;
}
}
@@ -1086,8 +1090,10 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
* or return -ENOENT for an empty entry.
*/
if (cur_index == index) {
- if (!phandle)
- return -ENOENT;
+ if (!phandle) {
+ rc = -ENOENT;
+ break;
+ }

if (out_args) {
int i;
@@ -1098,22 +1104,54 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
for (i = 0; i < count; i++)
out_args->args[i] = be32_to_cpup(list++);
}
- return 0;
+
+ rc = 0;
+ break;
}

of_node_put(node);
node = NULL;
list += count;
cur_index++;
+ rc = cur_index;
}

/* Loop exited without finding a valid entry; return an error */
if (node)
of_node_put(node);
- return -EINVAL;
+ return rc;
+}
+
+int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
+ const char *cells_name, int index,
+ struct of_phandle_args *out_args)
+{
+ return __of_parse_phandle_with_args(np, list_name, cells_name, index, out_args);
}
EXPORT_SYMBOL(of_parse_phandle_with_args);

Will this not result in a situation where a call to of_parse_phandle_with_args with an out of bounds index returns the number of tuples instead of an error code and possibly some caller that uses the this count as a phandle instead of handling an error?

Of course of_count_phandle_with_args can be used to make sure that no such call is made in the first place, but that is another story.

Related to this is that Case 7 in of_selftest_parse_phandle_with_args never gets exercised as far as I can see.


diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index c454f57..bdbe0f3 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -50,8 +50,28 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)
extern int of_get_named_gpio_flags(struct device_node *np,
const char *list_name, int index, enum of_gpio_flags *flags);

-extern unsigned int of_gpio_named_count(struct device_node *np,
- const char* propname);
+/**
+ * of_gpio_named_count - Count GPIOs for a device
+ * @np: device node to count GPIOs for
+ * @propname: property name containing gpio specifier(s)
+ *
+ * The function returns the count of GPIOs specified for a node.
+ *
+ * Note that the empty GPIO specifiers counts too. For example,
+ *
+ * gpios = <0
+ * &pio1 1 2
+ * 0
+ * &pio2 3 4>;
+ *
+ * defines four GPIOs (so this function will return 4), two of which
+ * are not specified. Returns -EINVAL for an incorrectly formed gpios
+ * property.
+ */
+static int of_gpio_named_count(struct device_node *np, const char* propname)
+{
+ return of_count_phandle_with_args(np, propname, "#gpio-cells");
+}

Should this be static inline int?

I think it would be good to also document that it also returns -ENOENT when the propname property is missing, which might be an important case to distinguish from the -EINVAL case.


Cheers,
Andreas Larsson

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/