瀏覽代碼

of: of_parse_phandles_with_args() learns to differentiate 'hole' cells

Given this list (contains three gpio specifiers, one of which is a hole):

gpios = <&phandle1 1 2 3
         0 /* a hole */
         &phandle2 4 5 6>;

of_parse_phandles_with_args() would report -ENOENT for the `hole'
specifier item, the same error value is used to report the end of the
list, for example.

Sometimes we want to differentiate holes from real errors -- for
example when we want to count all the [syntax correct] specifiers.

With this patch of_parse_phandles_with_args() will report -EEXITS when
somebody requested to parse a hole.

Also, make the out_{node,args} arguments optional, when counting we
don't really need the out values.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Anton Vorontsov 16 年之前
父節點
當前提交
7736a3db98
共有 1 個文件被更改,包括 16 次插入6 次删除
  1. 16 6
      drivers/of/base.c

+ 16 - 6
drivers/of/base.c

@@ -499,8 +499,8 @@ EXPORT_SYMBOL_GPL(of_modalias_node);
  * @list_name:	property name that contains a list
  * @list_name:	property name that contains a list
  * @cells_name:	property name that specifies phandles' arguments count
  * @cells_name:	property name that specifies phandles' arguments count
  * @index:	index of a phandle to parse out
  * @index:	index of a phandle to parse out
- * @out_node:	pointer to device_node struct pointer (will be filled)
- * @out_args:	pointer to arguments pointer (will be filled)
+ * @out_node:	optional pointer to device_node struct pointer (will be filled)
+ * @out_args:	optional pointer to arguments pointer (will be filled)
  *
  *
  * This function is useful to parse lists of phandles and their arguments.
  * This function is useful to parse lists of phandles and their arguments.
  * Returns 0 on success and fills out_node and out_args, on error returns
  * Returns 0 on success and fills out_node and out_args, on error returns
@@ -534,7 +534,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
 	int size;
 	int size;
 	int cur_index = 0;
 	int cur_index = 0;
 	struct device_node *node = NULL;
 	struct device_node *node = NULL;
-	const void *args;
+	const void *args = NULL;
 
 
 	list = of_get_property(np, list_name, &size);
 	list = of_get_property(np, list_name, &size);
 	if (!list) {
 	if (!list) {
@@ -580,16 +580,26 @@ next:
 
 
 		of_node_put(node);
 		of_node_put(node);
 		node = NULL;
 		node = NULL;
+		args = NULL;
 		cur_index++;
 		cur_index++;
 	}
 	}
 
 
 	if (!node) {
 	if (!node) {
-		ret = -ENOENT;
+		/*
+		 * args w/o node indicates that the loop above has stopped at
+		 * the 'hole' cell. Report this differently.
+		 */
+		if (args)
+			ret = -EEXIST;
+		else
+			ret = -ENOENT;
 		goto err0;
 		goto err0;
 	}
 	}
 
 
-	*out_node = node;
-	*out_args = args;
+	if (out_node)
+		*out_node = node;
+	if (out_args)
+		*out_args = args;
 
 
 	return 0;
 	return 0;
 err1:
 err1: