aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r--drivers/of/base.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index f7a87ce1b480..c5572cb87a88 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1096,7 +1096,7 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
1096 struct of_phandle_args *out_args) 1096 struct of_phandle_args *out_args)
1097{ 1097{
1098 const __be32 *list, *list_end; 1098 const __be32 *list, *list_end;
1099 int size, cur_index = 0; 1099 int rc = 0, size, cur_index = 0;
1100 uint32_t count = 0; 1100 uint32_t count = 0;
1101 struct device_node *node = NULL; 1101 struct device_node *node = NULL;
1102 phandle phandle; 1102 phandle phandle;
@@ -1109,6 +1109,7 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
1109 1109
1110 /* Loop over the phandles until all the requested entry is found */ 1110 /* Loop over the phandles until all the requested entry is found */
1111 while (list < list_end) { 1111 while (list < list_end) {
1112 rc = -EINVAL;
1112 count = 0; 1113 count = 0;
1113 1114
1114 /* 1115 /*
@@ -1125,13 +1126,13 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
1125 if (!node) { 1126 if (!node) {
1126 pr_err("%s: could not find phandle\n", 1127 pr_err("%s: could not find phandle\n",
1127 np->full_name); 1128 np->full_name);
1128 break; 1129 goto err;
1129 } 1130 }
1130 if (of_property_read_u32(node, cells_name, &count)) { 1131 if (of_property_read_u32(node, cells_name, &count)) {
1131 pr_err("%s: could not get %s for %s\n", 1132 pr_err("%s: could not get %s for %s\n",
1132 np->full_name, cells_name, 1133 np->full_name, cells_name,
1133 node->full_name); 1134 node->full_name);
1134 break; 1135 goto err;
1135 } 1136 }
1136 1137
1137 /* 1138 /*
@@ -1141,7 +1142,7 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
1141 if (list + count > list_end) { 1142 if (list + count > list_end) {
1142 pr_err("%s: arguments longer than property\n", 1143 pr_err("%s: arguments longer than property\n",
1143 np->full_name); 1144 np->full_name);
1144 break; 1145 goto err;
1145 } 1146 }
1146 } 1147 }
1147 1148
@@ -1151,9 +1152,10 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
1151 * index matches, then fill the out_args structure and return, 1152 * index matches, then fill the out_args structure and return,
1152 * or return -ENOENT for an empty entry. 1153 * or return -ENOENT for an empty entry.
1153 */ 1154 */
1155 rc = -ENOENT;
1154 if (cur_index == index) { 1156 if (cur_index == index) {
1155 if (!phandle) 1157 if (!phandle)
1156 return -ENOENT; 1158 goto err;
1157 1159
1158 if (out_args) { 1160 if (out_args) {
1159 int i; 1161 int i;
@@ -1164,6 +1166,10 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
1164 for (i = 0; i < count; i++) 1166 for (i = 0; i < count; i++)
1165 out_args->args[i] = be32_to_cpup(list++); 1167 out_args->args[i] = be32_to_cpup(list++);
1166 } 1168 }
1169
1170 /* Found it! return success */
1171 if (node)
1172 of_node_put(node);
1167 return 0; 1173 return 0;
1168 } 1174 }
1169 1175
@@ -1173,10 +1179,16 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
1173 cur_index++; 1179 cur_index++;
1174 } 1180 }
1175 1181
1176 /* Loop exited without finding a valid entry; return an error */ 1182 /*
1183 * Unlock node before returning result; will be one of:
1184 * -ENOENT : index is for empty phandle
1185 * -EINVAL : parsing error on data
1186 */
1187 rc = -ENOENT;
1188 err:
1177 if (node) 1189 if (node)
1178 of_node_put(node); 1190 of_node_put(node);
1179 return -EINVAL; 1191 return rc;
1180} 1192}
1181EXPORT_SYMBOL(of_parse_phandle_with_args); 1193EXPORT_SYMBOL(of_parse_phandle_with_args);
1182 1194