aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2013-02-10 17:57:21 -0500
committerGrant Likely <grant.likely@secretlab.ca>2013-02-13 05:09:31 -0500
commitbd69f73f2c81eed9a398708b8c4bb3409ba1b0f9 (patch)
tree0be6f0ee561d13d01b6c44478b693cc60453ff6d /drivers/of
parent23ce04c0734e33b1042273b0ed11a8e4f7f988ca (diff)
of: Create function for counting number of phandles in a property
This patch creates of_count_phandle_with_args(), a new function for counting the number of phandle+argument tuples in a given property. This is better than the existing method of parsing each phandle individually until parsing fails which is a horribly slow way to do the count. Tested on ARM using the selftest code. v3: - Rebased on top of selftest code cleanup patch v2: - fix bug where of_parse_phandle_with_args() could behave like _count_. - made of_gpio_named_count() into a static inline regardless of CONFIG_OF_GPIO Tested-by: Andreas Larsson <andreas@gaisler.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Cc: Linus Walleij <linus.walleij@linaro.org> Cc: Rob Herring <rob.herring@calxeda.com>
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/base.c41
-rw-r--r--drivers/of/selftest.c15
2 files changed, 52 insertions, 4 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index c5572cb87a88..321d3ef05006 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1091,9 +1091,10 @@ EXPORT_SYMBOL(of_parse_phandle);
1091 * To get a device_node of the `node2' node you may call this: 1091 * To get a device_node of the `node2' node you may call this:
1092 * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); 1092 * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
1093 */ 1093 */
1094int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, 1094static int __of_parse_phandle_with_args(const struct device_node *np,
1095 const char *cells_name, int index, 1095 const char *list_name,
1096 struct of_phandle_args *out_args) 1096 const char *cells_name, int index,
1097 struct of_phandle_args *out_args)
1097{ 1098{
1098 const __be32 *list, *list_end; 1099 const __be32 *list, *list_end;
1099 int rc = 0, size, cur_index = 0; 1100 int rc = 0, size, cur_index = 0;
@@ -1183,15 +1184,47 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
1183 * Unlock node before returning result; will be one of: 1184 * Unlock node before returning result; will be one of:
1184 * -ENOENT : index is for empty phandle 1185 * -ENOENT : index is for empty phandle
1185 * -EINVAL : parsing error on data 1186 * -EINVAL : parsing error on data
1187 * [1..n] : Number of phandle (count mode; when index = -1)
1186 */ 1188 */
1187 rc = -ENOENT; 1189 rc = index < 0 ? cur_index : -ENOENT;
1188 err: 1190 err:
1189 if (node) 1191 if (node)
1190 of_node_put(node); 1192 of_node_put(node);
1191 return rc; 1193 return rc;
1192} 1194}
1195
1196int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
1197 const char *cells_name, int index,
1198 struct of_phandle_args *out_args)
1199{
1200 if (index < 0)
1201 return -EINVAL;
1202 return __of_parse_phandle_with_args(np, list_name, cells_name, index, out_args);
1203}
1193EXPORT_SYMBOL(of_parse_phandle_with_args); 1204EXPORT_SYMBOL(of_parse_phandle_with_args);
1194 1205
1206/**
1207 * of_count_phandle_with_args() - Find the number of phandles references in a property
1208 * @np: pointer to a device tree node containing a list
1209 * @list_name: property name that contains a list
1210 * @cells_name: property name that specifies phandles' arguments count
1211 *
1212 * Returns the number of phandle + argument tuples within a property. It
1213 * is a typical pattern to encode a list of phandle and variable
1214 * arguments into a single property. The number of arguments is encoded
1215 * by a property in the phandle-target node. For example, a gpios
1216 * property would contain a list of GPIO specifies consisting of a
1217 * phandle and 1 or more arguments. The number of arguments are
1218 * determined by the #gpio-cells property in the node pointed to by the
1219 * phandle.
1220 */
1221int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
1222 const char *cells_name)
1223{
1224 return __of_parse_phandle_with_args(np, list_name, cells_name, -1, NULL);
1225}
1226EXPORT_SYMBOL(of_count_phandle_with_args);
1227
1195#if defined(CONFIG_OF_DYNAMIC) 1228#if defined(CONFIG_OF_DYNAMIC)
1196static int of_property_notify(int action, struct device_node *np, 1229static int of_property_notify(int action, struct device_node *np,
1197 struct property *prop) 1230 struct property *prop)
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
index 01b4174a3b46..0eb5c38b4e07 100644
--- a/drivers/of/selftest.c
+++ b/drivers/of/selftest.c
@@ -36,6 +36,9 @@ static void __init of_selftest_parse_phandle_with_args(void)
36 return; 36 return;
37 } 37 }
38 38
39 rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells");
40 selftest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc);
41
39 for (i = 0; i < 8; i++) { 42 for (i = 0; i < 8; i++) {
40 bool passed = true; 43 bool passed = true;
41 rc = of_parse_phandle_with_args(np, "phandle-list", 44 rc = of_parse_phandle_with_args(np, "phandle-list",
@@ -94,21 +97,33 @@ static void __init of_selftest_parse_phandle_with_args(void)
94 rc = of_parse_phandle_with_args(np, "phandle-list-missing", 97 rc = of_parse_phandle_with_args(np, "phandle-list-missing",
95 "#phandle-cells", 0, &args); 98 "#phandle-cells", 0, &args);
96 selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc); 99 selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
100 rc = of_count_phandle_with_args(np, "phandle-list-missing",
101 "#phandle-cells");
102 selftest(rc == -ENOENT, "expected:%i got:%i\n", -ENOENT, rc);
97 103
98 /* Check for missing cells property */ 104 /* Check for missing cells property */
99 rc = of_parse_phandle_with_args(np, "phandle-list", 105 rc = of_parse_phandle_with_args(np, "phandle-list",
100 "#phandle-cells-missing", 0, &args); 106 "#phandle-cells-missing", 0, &args);
101 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); 107 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
108 rc = of_count_phandle_with_args(np, "phandle-list",
109 "#phandle-cells-missing");
110 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
102 111
103 /* Check for bad phandle in list */ 112 /* Check for bad phandle in list */
104 rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle", 113 rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle",
105 "#phandle-cells", 0, &args); 114 "#phandle-cells", 0, &args);
106 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); 115 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
116 rc = of_count_phandle_with_args(np, "phandle-list-bad-phandle",
117 "#phandle-cells");
118 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
107 119
108 /* Check for incorrectly formed argument list */ 120 /* Check for incorrectly formed argument list */
109 rc = of_parse_phandle_with_args(np, "phandle-list-bad-args", 121 rc = of_parse_phandle_with_args(np, "phandle-list-bad-args",
110 "#phandle-cells", 1, &args); 122 "#phandle-cells", 1, &args);
111 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); 123 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
124 rc = of_count_phandle_with_args(np, "phandle-list-bad-args",
125 "#phandle-cells");
126 selftest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc);
112} 127}
113 128
114static void __init of_selftest_property_match_string(void) 129static void __init of_selftest_property_match_string(void)