diff options
author | Rob Herring <robh@kernel.org> | 2017-07-05 09:31:52 -0400 |
---|---|---|
committer | Rob Herring <robh@kernel.org> | 2017-07-05 09:31:52 -0400 |
commit | a4485b545e2fad4d65732cb7c60089bf4246de5c (patch) | |
tree | 452caf921257d924d9d7b2b1efbf6f80a03d6a52 /drivers/of | |
parent | 5e1743c0af9d5179cf575c0bc2777af02a79b911 (diff) | |
parent | b8ba92b101e82b82a5359dc2dfbd772eb46780d4 (diff) |
Merge branch 'dt/property-move' into dt/next
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/Makefile | 2 | ||||
-rw-r--r-- | drivers/of/base.c | 735 | ||||
-rw-r--r-- | drivers/of/property.c | 806 |
3 files changed, 809 insertions, 734 deletions
diff --git a/drivers/of/Makefile b/drivers/of/Makefile index d7efd9d458aa..97dc01c81438 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y = base.o device.o platform.o | 1 | obj-y = base.o device.o platform.o property.o |
2 | obj-$(CONFIG_OF_DYNAMIC) += dynamic.o | 2 | obj-$(CONFIG_OF_DYNAMIC) += dynamic.o |
3 | obj-$(CONFIG_OF_FLATTREE) += fdt.o | 3 | obj-$(CONFIG_OF_FLATTREE) += fdt.o |
4 | obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o | 4 | obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 87b4968f3d8f..686628d1dfa6 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -1119,458 +1119,6 @@ struct device_node *of_find_node_by_phandle(phandle handle) | |||
1119 | } | 1119 | } |
1120 | EXPORT_SYMBOL(of_find_node_by_phandle); | 1120 | EXPORT_SYMBOL(of_find_node_by_phandle); |
1121 | 1121 | ||
1122 | /** | ||
1123 | * of_property_count_elems_of_size - Count the number of elements in a property | ||
1124 | * | ||
1125 | * @np: device node from which the property value is to be read. | ||
1126 | * @propname: name of the property to be searched. | ||
1127 | * @elem_size: size of the individual element | ||
1128 | * | ||
1129 | * Search for a property in a device node and count the number of elements of | ||
1130 | * size elem_size in it. Returns number of elements on sucess, -EINVAL if the | ||
1131 | * property does not exist or its length does not match a multiple of elem_size | ||
1132 | * and -ENODATA if the property does not have a value. | ||
1133 | */ | ||
1134 | int of_property_count_elems_of_size(const struct device_node *np, | ||
1135 | const char *propname, int elem_size) | ||
1136 | { | ||
1137 | struct property *prop = of_find_property(np, propname, NULL); | ||
1138 | |||
1139 | if (!prop) | ||
1140 | return -EINVAL; | ||
1141 | if (!prop->value) | ||
1142 | return -ENODATA; | ||
1143 | |||
1144 | if (prop->length % elem_size != 0) { | ||
1145 | pr_err("size of %s in node %s is not a multiple of %d\n", | ||
1146 | propname, np->full_name, elem_size); | ||
1147 | return -EINVAL; | ||
1148 | } | ||
1149 | |||
1150 | return prop->length / elem_size; | ||
1151 | } | ||
1152 | EXPORT_SYMBOL_GPL(of_property_count_elems_of_size); | ||
1153 | |||
1154 | /** | ||
1155 | * of_find_property_value_of_size | ||
1156 | * | ||
1157 | * @np: device node from which the property value is to be read. | ||
1158 | * @propname: name of the property to be searched. | ||
1159 | * @min: minimum allowed length of property value | ||
1160 | * @max: maximum allowed length of property value (0 means unlimited) | ||
1161 | * @len: if !=NULL, actual length is written to here | ||
1162 | * | ||
1163 | * Search for a property in a device node and valid the requested size. | ||
1164 | * Returns the property value on success, -EINVAL if the property does not | ||
1165 | * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
1166 | * property data is too small or too large. | ||
1167 | * | ||
1168 | */ | ||
1169 | static void *of_find_property_value_of_size(const struct device_node *np, | ||
1170 | const char *propname, u32 min, u32 max, size_t *len) | ||
1171 | { | ||
1172 | struct property *prop = of_find_property(np, propname, NULL); | ||
1173 | |||
1174 | if (!prop) | ||
1175 | return ERR_PTR(-EINVAL); | ||
1176 | if (!prop->value) | ||
1177 | return ERR_PTR(-ENODATA); | ||
1178 | if (prop->length < min) | ||
1179 | return ERR_PTR(-EOVERFLOW); | ||
1180 | if (max && prop->length > max) | ||
1181 | return ERR_PTR(-EOVERFLOW); | ||
1182 | |||
1183 | if (len) | ||
1184 | *len = prop->length; | ||
1185 | |||
1186 | return prop->value; | ||
1187 | } | ||
1188 | |||
1189 | /** | ||
1190 | * of_property_read_u32_index - Find and read a u32 from a multi-value property. | ||
1191 | * | ||
1192 | * @np: device node from which the property value is to be read. | ||
1193 | * @propname: name of the property to be searched. | ||
1194 | * @index: index of the u32 in the list of values | ||
1195 | * @out_value: pointer to return value, modified only if no error. | ||
1196 | * | ||
1197 | * Search for a property in a device node and read nth 32-bit value from | ||
1198 | * it. Returns 0 on success, -EINVAL if the property does not exist, | ||
1199 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
1200 | * property data isn't large enough. | ||
1201 | * | ||
1202 | * The out_value is modified only if a valid u32 value can be decoded. | ||
1203 | */ | ||
1204 | int of_property_read_u32_index(const struct device_node *np, | ||
1205 | const char *propname, | ||
1206 | u32 index, u32 *out_value) | ||
1207 | { | ||
1208 | const u32 *val = of_find_property_value_of_size(np, propname, | ||
1209 | ((index + 1) * sizeof(*out_value)), | ||
1210 | 0, | ||
1211 | NULL); | ||
1212 | |||
1213 | if (IS_ERR(val)) | ||
1214 | return PTR_ERR(val); | ||
1215 | |||
1216 | *out_value = be32_to_cpup(((__be32 *)val) + index); | ||
1217 | return 0; | ||
1218 | } | ||
1219 | EXPORT_SYMBOL_GPL(of_property_read_u32_index); | ||
1220 | |||
1221 | /** | ||
1222 | * of_property_read_u64_index - Find and read a u64 from a multi-value property. | ||
1223 | * | ||
1224 | * @np: device node from which the property value is to be read. | ||
1225 | * @propname: name of the property to be searched. | ||
1226 | * @index: index of the u64 in the list of values | ||
1227 | * @out_value: pointer to return value, modified only if no error. | ||
1228 | * | ||
1229 | * Search for a property in a device node and read nth 64-bit value from | ||
1230 | * it. Returns 0 on success, -EINVAL if the property does not exist, | ||
1231 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
1232 | * property data isn't large enough. | ||
1233 | * | ||
1234 | * The out_value is modified only if a valid u64 value can be decoded. | ||
1235 | */ | ||
1236 | int of_property_read_u64_index(const struct device_node *np, | ||
1237 | const char *propname, | ||
1238 | u32 index, u64 *out_value) | ||
1239 | { | ||
1240 | const u64 *val = of_find_property_value_of_size(np, propname, | ||
1241 | ((index + 1) * sizeof(*out_value)), | ||
1242 | 0, NULL); | ||
1243 | |||
1244 | if (IS_ERR(val)) | ||
1245 | return PTR_ERR(val); | ||
1246 | |||
1247 | *out_value = be64_to_cpup(((__be64 *)val) + index); | ||
1248 | return 0; | ||
1249 | } | ||
1250 | EXPORT_SYMBOL_GPL(of_property_read_u64_index); | ||
1251 | |||
1252 | /** | ||
1253 | * of_property_read_variable_u8_array - Find and read an array of u8 from a | ||
1254 | * property, with bounds on the minimum and maximum array size. | ||
1255 | * | ||
1256 | * @np: device node from which the property value is to be read. | ||
1257 | * @propname: name of the property to be searched. | ||
1258 | * @out_values: pointer to return value, modified only if return value is 0. | ||
1259 | * @sz_min: minimum number of array elements to read | ||
1260 | * @sz_max: maximum number of array elements to read, if zero there is no | ||
1261 | * upper limit on the number of elements in the dts entry but only | ||
1262 | * sz_min will be read. | ||
1263 | * | ||
1264 | * Search for a property in a device node and read 8-bit value(s) from | ||
1265 | * it. Returns number of elements read on success, -EINVAL if the property | ||
1266 | * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | ||
1267 | * if the property data is smaller than sz_min or longer than sz_max. | ||
1268 | * | ||
1269 | * dts entry of array should be like: | ||
1270 | * property = /bits/ 8 <0x50 0x60 0x70>; | ||
1271 | * | ||
1272 | * The out_values is modified only if a valid u8 value can be decoded. | ||
1273 | */ | ||
1274 | int of_property_read_variable_u8_array(const struct device_node *np, | ||
1275 | const char *propname, u8 *out_values, | ||
1276 | size_t sz_min, size_t sz_max) | ||
1277 | { | ||
1278 | size_t sz, count; | ||
1279 | const u8 *val = of_find_property_value_of_size(np, propname, | ||
1280 | (sz_min * sizeof(*out_values)), | ||
1281 | (sz_max * sizeof(*out_values)), | ||
1282 | &sz); | ||
1283 | |||
1284 | if (IS_ERR(val)) | ||
1285 | return PTR_ERR(val); | ||
1286 | |||
1287 | if (!sz_max) | ||
1288 | sz = sz_min; | ||
1289 | else | ||
1290 | sz /= sizeof(*out_values); | ||
1291 | |||
1292 | count = sz; | ||
1293 | while (count--) | ||
1294 | *out_values++ = *val++; | ||
1295 | |||
1296 | return sz; | ||
1297 | } | ||
1298 | EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array); | ||
1299 | |||
1300 | /** | ||
1301 | * of_property_read_variable_u16_array - Find and read an array of u16 from a | ||
1302 | * property, with bounds on the minimum and maximum array size. | ||
1303 | * | ||
1304 | * @np: device node from which the property value is to be read. | ||
1305 | * @propname: name of the property to be searched. | ||
1306 | * @out_values: pointer to return value, modified only if return value is 0. | ||
1307 | * @sz_min: minimum number of array elements to read | ||
1308 | * @sz_max: maximum number of array elements to read, if zero there is no | ||
1309 | * upper limit on the number of elements in the dts entry but only | ||
1310 | * sz_min will be read. | ||
1311 | * | ||
1312 | * Search for a property in a device node and read 16-bit value(s) from | ||
1313 | * it. Returns number of elements read on success, -EINVAL if the property | ||
1314 | * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | ||
1315 | * if the property data is smaller than sz_min or longer than sz_max. | ||
1316 | * | ||
1317 | * dts entry of array should be like: | ||
1318 | * property = /bits/ 16 <0x5000 0x6000 0x7000>; | ||
1319 | * | ||
1320 | * The out_values is modified only if a valid u16 value can be decoded. | ||
1321 | */ | ||
1322 | int of_property_read_variable_u16_array(const struct device_node *np, | ||
1323 | const char *propname, u16 *out_values, | ||
1324 | size_t sz_min, size_t sz_max) | ||
1325 | { | ||
1326 | size_t sz, count; | ||
1327 | const __be16 *val = of_find_property_value_of_size(np, propname, | ||
1328 | (sz_min * sizeof(*out_values)), | ||
1329 | (sz_max * sizeof(*out_values)), | ||
1330 | &sz); | ||
1331 | |||
1332 | if (IS_ERR(val)) | ||
1333 | return PTR_ERR(val); | ||
1334 | |||
1335 | if (!sz_max) | ||
1336 | sz = sz_min; | ||
1337 | else | ||
1338 | sz /= sizeof(*out_values); | ||
1339 | |||
1340 | count = sz; | ||
1341 | while (count--) | ||
1342 | *out_values++ = be16_to_cpup(val++); | ||
1343 | |||
1344 | return sz; | ||
1345 | } | ||
1346 | EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array); | ||
1347 | |||
1348 | /** | ||
1349 | * of_property_read_variable_u32_array - Find and read an array of 32 bit | ||
1350 | * integers from a property, with bounds on the minimum and maximum array size. | ||
1351 | * | ||
1352 | * @np: device node from which the property value is to be read. | ||
1353 | * @propname: name of the property to be searched. | ||
1354 | * @out_values: pointer to return value, modified only if return value is 0. | ||
1355 | * @sz_min: minimum number of array elements to read | ||
1356 | * @sz_max: maximum number of array elements to read, if zero there is no | ||
1357 | * upper limit on the number of elements in the dts entry but only | ||
1358 | * sz_min will be read. | ||
1359 | * | ||
1360 | * Search for a property in a device node and read 32-bit value(s) from | ||
1361 | * it. Returns number of elements read on success, -EINVAL if the property | ||
1362 | * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | ||
1363 | * if the property data is smaller than sz_min or longer than sz_max. | ||
1364 | * | ||
1365 | * The out_values is modified only if a valid u32 value can be decoded. | ||
1366 | */ | ||
1367 | int of_property_read_variable_u32_array(const struct device_node *np, | ||
1368 | const char *propname, u32 *out_values, | ||
1369 | size_t sz_min, size_t sz_max) | ||
1370 | { | ||
1371 | size_t sz, count; | ||
1372 | const __be32 *val = of_find_property_value_of_size(np, propname, | ||
1373 | (sz_min * sizeof(*out_values)), | ||
1374 | (sz_max * sizeof(*out_values)), | ||
1375 | &sz); | ||
1376 | |||
1377 | if (IS_ERR(val)) | ||
1378 | return PTR_ERR(val); | ||
1379 | |||
1380 | if (!sz_max) | ||
1381 | sz = sz_min; | ||
1382 | else | ||
1383 | sz /= sizeof(*out_values); | ||
1384 | |||
1385 | count = sz; | ||
1386 | while (count--) | ||
1387 | *out_values++ = be32_to_cpup(val++); | ||
1388 | |||
1389 | return sz; | ||
1390 | } | ||
1391 | EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array); | ||
1392 | |||
1393 | /** | ||
1394 | * of_property_read_u64 - Find and read a 64 bit integer from a property | ||
1395 | * @np: device node from which the property value is to be read. | ||
1396 | * @propname: name of the property to be searched. | ||
1397 | * @out_value: pointer to return value, modified only if return value is 0. | ||
1398 | * | ||
1399 | * Search for a property in a device node and read a 64-bit value from | ||
1400 | * it. Returns 0 on success, -EINVAL if the property does not exist, | ||
1401 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
1402 | * property data isn't large enough. | ||
1403 | * | ||
1404 | * The out_value is modified only if a valid u64 value can be decoded. | ||
1405 | */ | ||
1406 | int of_property_read_u64(const struct device_node *np, const char *propname, | ||
1407 | u64 *out_value) | ||
1408 | { | ||
1409 | const __be32 *val = of_find_property_value_of_size(np, propname, | ||
1410 | sizeof(*out_value), | ||
1411 | 0, | ||
1412 | NULL); | ||
1413 | |||
1414 | if (IS_ERR(val)) | ||
1415 | return PTR_ERR(val); | ||
1416 | |||
1417 | *out_value = of_read_number(val, 2); | ||
1418 | return 0; | ||
1419 | } | ||
1420 | EXPORT_SYMBOL_GPL(of_property_read_u64); | ||
1421 | |||
1422 | /** | ||
1423 | * of_property_read_variable_u64_array - Find and read an array of 64 bit | ||
1424 | * integers from a property, with bounds on the minimum and maximum array size. | ||
1425 | * | ||
1426 | * @np: device node from which the property value is to be read. | ||
1427 | * @propname: name of the property to be searched. | ||
1428 | * @out_values: pointer to return value, modified only if return value is 0. | ||
1429 | * @sz_min: minimum number of array elements to read | ||
1430 | * @sz_max: maximum number of array elements to read, if zero there is no | ||
1431 | * upper limit on the number of elements in the dts entry but only | ||
1432 | * sz_min will be read. | ||
1433 | * | ||
1434 | * Search for a property in a device node and read 64-bit value(s) from | ||
1435 | * it. Returns number of elements read on success, -EINVAL if the property | ||
1436 | * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | ||
1437 | * if the property data is smaller than sz_min or longer than sz_max. | ||
1438 | * | ||
1439 | * The out_values is modified only if a valid u64 value can be decoded. | ||
1440 | */ | ||
1441 | int of_property_read_variable_u64_array(const struct device_node *np, | ||
1442 | const char *propname, u64 *out_values, | ||
1443 | size_t sz_min, size_t sz_max) | ||
1444 | { | ||
1445 | size_t sz, count; | ||
1446 | const __be32 *val = of_find_property_value_of_size(np, propname, | ||
1447 | (sz_min * sizeof(*out_values)), | ||
1448 | (sz_max * sizeof(*out_values)), | ||
1449 | &sz); | ||
1450 | |||
1451 | if (IS_ERR(val)) | ||
1452 | return PTR_ERR(val); | ||
1453 | |||
1454 | if (!sz_max) | ||
1455 | sz = sz_min; | ||
1456 | else | ||
1457 | sz /= sizeof(*out_values); | ||
1458 | |||
1459 | count = sz; | ||
1460 | while (count--) { | ||
1461 | *out_values++ = of_read_number(val, 2); | ||
1462 | val += 2; | ||
1463 | } | ||
1464 | |||
1465 | return sz; | ||
1466 | } | ||
1467 | EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array); | ||
1468 | |||
1469 | /** | ||
1470 | * of_property_read_string - Find and read a string from a property | ||
1471 | * @np: device node from which the property value is to be read. | ||
1472 | * @propname: name of the property to be searched. | ||
1473 | * @out_string: pointer to null terminated return string, modified only if | ||
1474 | * return value is 0. | ||
1475 | * | ||
1476 | * Search for a property in a device tree node and retrieve a null | ||
1477 | * terminated string value (pointer to data, not a copy). Returns 0 on | ||
1478 | * success, -EINVAL if the property does not exist, -ENODATA if property | ||
1479 | * does not have a value, and -EILSEQ if the string is not null-terminated | ||
1480 | * within the length of the property data. | ||
1481 | * | ||
1482 | * The out_string pointer is modified only if a valid string can be decoded. | ||
1483 | */ | ||
1484 | int of_property_read_string(const struct device_node *np, const char *propname, | ||
1485 | const char **out_string) | ||
1486 | { | ||
1487 | const struct property *prop = of_find_property(np, propname, NULL); | ||
1488 | if (!prop) | ||
1489 | return -EINVAL; | ||
1490 | if (!prop->value) | ||
1491 | return -ENODATA; | ||
1492 | if (strnlen(prop->value, prop->length) >= prop->length) | ||
1493 | return -EILSEQ; | ||
1494 | *out_string = prop->value; | ||
1495 | return 0; | ||
1496 | } | ||
1497 | EXPORT_SYMBOL_GPL(of_property_read_string); | ||
1498 | |||
1499 | /** | ||
1500 | * of_property_match_string() - Find string in a list and return index | ||
1501 | * @np: pointer to node containing string list property | ||
1502 | * @propname: string list property name | ||
1503 | * @string: pointer to string to search for in string list | ||
1504 | * | ||
1505 | * This function searches a string list property and returns the index | ||
1506 | * of a specific string value. | ||
1507 | */ | ||
1508 | int of_property_match_string(const struct device_node *np, const char *propname, | ||
1509 | const char *string) | ||
1510 | { | ||
1511 | const struct property *prop = of_find_property(np, propname, NULL); | ||
1512 | size_t l; | ||
1513 | int i; | ||
1514 | const char *p, *end; | ||
1515 | |||
1516 | if (!prop) | ||
1517 | return -EINVAL; | ||
1518 | if (!prop->value) | ||
1519 | return -ENODATA; | ||
1520 | |||
1521 | p = prop->value; | ||
1522 | end = p + prop->length; | ||
1523 | |||
1524 | for (i = 0; p < end; i++, p += l) { | ||
1525 | l = strnlen(p, end - p) + 1; | ||
1526 | if (p + l > end) | ||
1527 | return -EILSEQ; | ||
1528 | pr_debug("comparing %s with %s\n", string, p); | ||
1529 | if (strcmp(string, p) == 0) | ||
1530 | return i; /* Found it; return index */ | ||
1531 | } | ||
1532 | return -ENODATA; | ||
1533 | } | ||
1534 | EXPORT_SYMBOL_GPL(of_property_match_string); | ||
1535 | |||
1536 | /** | ||
1537 | * of_property_read_string_helper() - Utility helper for parsing string properties | ||
1538 | * @np: device node from which the property value is to be read. | ||
1539 | * @propname: name of the property to be searched. | ||
1540 | * @out_strs: output array of string pointers. | ||
1541 | * @sz: number of array elements to read. | ||
1542 | * @skip: Number of strings to skip over at beginning of list. | ||
1543 | * | ||
1544 | * Don't call this function directly. It is a utility helper for the | ||
1545 | * of_property_read_string*() family of functions. | ||
1546 | */ | ||
1547 | int of_property_read_string_helper(const struct device_node *np, | ||
1548 | const char *propname, const char **out_strs, | ||
1549 | size_t sz, int skip) | ||
1550 | { | ||
1551 | const struct property *prop = of_find_property(np, propname, NULL); | ||
1552 | int l = 0, i = 0; | ||
1553 | const char *p, *end; | ||
1554 | |||
1555 | if (!prop) | ||
1556 | return -EINVAL; | ||
1557 | if (!prop->value) | ||
1558 | return -ENODATA; | ||
1559 | p = prop->value; | ||
1560 | end = p + prop->length; | ||
1561 | |||
1562 | for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) { | ||
1563 | l = strnlen(p, end - p) + 1; | ||
1564 | if (p + l > end) | ||
1565 | return -EILSEQ; | ||
1566 | if (out_strs && i >= skip) | ||
1567 | *out_strs++ = p; | ||
1568 | } | ||
1569 | i -= skip; | ||
1570 | return i <= 0 ? -ENODATA : i; | ||
1571 | } | ||
1572 | EXPORT_SYMBOL_GPL(of_property_read_string_helper); | ||
1573 | |||
1574 | void of_print_phandle_args(const char *msg, const struct of_phandle_args *args) | 1122 | void of_print_phandle_args(const char *msg, const struct of_phandle_args *args) |
1575 | { | 1123 | { |
1576 | int i; | 1124 | int i; |
@@ -1607,6 +1155,7 @@ int of_phandle_iterator_init(struct of_phandle_iterator *it, | |||
1607 | 1155 | ||
1608 | return 0; | 1156 | return 0; |
1609 | } | 1157 | } |
1158 | EXPORT_SYMBOL_GPL(of_phandle_iterator_init); | ||
1610 | 1159 | ||
1611 | int of_phandle_iterator_next(struct of_phandle_iterator *it) | 1160 | int of_phandle_iterator_next(struct of_phandle_iterator *it) |
1612 | { | 1161 | { |
@@ -1676,6 +1225,7 @@ err: | |||
1676 | 1225 | ||
1677 | return -EINVAL; | 1226 | return -EINVAL; |
1678 | } | 1227 | } |
1228 | EXPORT_SYMBOL_GPL(of_phandle_iterator_next); | ||
1679 | 1229 | ||
1680 | int of_phandle_iterator_args(struct of_phandle_iterator *it, | 1230 | int of_phandle_iterator_args(struct of_phandle_iterator *it, |
1681 | uint32_t *args, | 1231 | uint32_t *args, |
@@ -2217,47 +1767,6 @@ int of_alias_get_highest_id(const char *stem) | |||
2217 | } | 1767 | } |
2218 | EXPORT_SYMBOL_GPL(of_alias_get_highest_id); | 1768 | EXPORT_SYMBOL_GPL(of_alias_get_highest_id); |
2219 | 1769 | ||
2220 | const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, | ||
2221 | u32 *pu) | ||
2222 | { | ||
2223 | const void *curv = cur; | ||
2224 | |||
2225 | if (!prop) | ||
2226 | return NULL; | ||
2227 | |||
2228 | if (!cur) { | ||
2229 | curv = prop->value; | ||
2230 | goto out_val; | ||
2231 | } | ||
2232 | |||
2233 | curv += sizeof(*cur); | ||
2234 | if (curv >= prop->value + prop->length) | ||
2235 | return NULL; | ||
2236 | |||
2237 | out_val: | ||
2238 | *pu = be32_to_cpup(curv); | ||
2239 | return curv; | ||
2240 | } | ||
2241 | EXPORT_SYMBOL_GPL(of_prop_next_u32); | ||
2242 | |||
2243 | const char *of_prop_next_string(struct property *prop, const char *cur) | ||
2244 | { | ||
2245 | const void *curv = cur; | ||
2246 | |||
2247 | if (!prop) | ||
2248 | return NULL; | ||
2249 | |||
2250 | if (!cur) | ||
2251 | return prop->value; | ||
2252 | |||
2253 | curv += strlen(cur) + 1; | ||
2254 | if (curv >= prop->value + prop->length) | ||
2255 | return NULL; | ||
2256 | |||
2257 | return curv; | ||
2258 | } | ||
2259 | EXPORT_SYMBOL_GPL(of_prop_next_string); | ||
2260 | |||
2261 | /** | 1770 | /** |
2262 | * of_console_check() - Test and setup console for DT setup | 1771 | * of_console_check() - Test and setup console for DT setup |
2263 | * @dn - Pointer to device node | 1772 | * @dn - Pointer to device node |
@@ -2331,243 +1840,3 @@ int of_find_last_cache_level(unsigned int cpu) | |||
2331 | 1840 | ||
2332 | return cache_level; | 1841 | return cache_level; |
2333 | } | 1842 | } |
2334 | |||
2335 | /** | ||
2336 | * of_graph_parse_endpoint() - parse common endpoint node properties | ||
2337 | * @node: pointer to endpoint device_node | ||
2338 | * @endpoint: pointer to the OF endpoint data structure | ||
2339 | * | ||
2340 | * The caller should hold a reference to @node. | ||
2341 | */ | ||
2342 | int of_graph_parse_endpoint(const struct device_node *node, | ||
2343 | struct of_endpoint *endpoint) | ||
2344 | { | ||
2345 | struct device_node *port_node = of_get_parent(node); | ||
2346 | |||
2347 | WARN_ONCE(!port_node, "%s(): endpoint %s has no parent node\n", | ||
2348 | __func__, node->full_name); | ||
2349 | |||
2350 | memset(endpoint, 0, sizeof(*endpoint)); | ||
2351 | |||
2352 | endpoint->local_node = node; | ||
2353 | /* | ||
2354 | * It doesn't matter whether the two calls below succeed. | ||
2355 | * If they don't then the default value 0 is used. | ||
2356 | */ | ||
2357 | of_property_read_u32(port_node, "reg", &endpoint->port); | ||
2358 | of_property_read_u32(node, "reg", &endpoint->id); | ||
2359 | |||
2360 | of_node_put(port_node); | ||
2361 | |||
2362 | return 0; | ||
2363 | } | ||
2364 | EXPORT_SYMBOL(of_graph_parse_endpoint); | ||
2365 | |||
2366 | /** | ||
2367 | * of_graph_get_port_by_id() - get the port matching a given id | ||
2368 | * @parent: pointer to the parent device node | ||
2369 | * @id: id of the port | ||
2370 | * | ||
2371 | * Return: A 'port' node pointer with refcount incremented. The caller | ||
2372 | * has to use of_node_put() on it when done. | ||
2373 | */ | ||
2374 | struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id) | ||
2375 | { | ||
2376 | struct device_node *node, *port; | ||
2377 | |||
2378 | node = of_get_child_by_name(parent, "ports"); | ||
2379 | if (node) | ||
2380 | parent = node; | ||
2381 | |||
2382 | for_each_child_of_node(parent, port) { | ||
2383 | u32 port_id = 0; | ||
2384 | |||
2385 | if (of_node_cmp(port->name, "port") != 0) | ||
2386 | continue; | ||
2387 | of_property_read_u32(port, "reg", &port_id); | ||
2388 | if (id == port_id) | ||
2389 | break; | ||
2390 | } | ||
2391 | |||
2392 | of_node_put(node); | ||
2393 | |||
2394 | return port; | ||
2395 | } | ||
2396 | EXPORT_SYMBOL(of_graph_get_port_by_id); | ||
2397 | |||
2398 | /** | ||
2399 | * of_graph_get_next_endpoint() - get next endpoint node | ||
2400 | * @parent: pointer to the parent device node | ||
2401 | * @prev: previous endpoint node, or NULL to get first | ||
2402 | * | ||
2403 | * Return: An 'endpoint' node pointer with refcount incremented. Refcount | ||
2404 | * of the passed @prev node is decremented. | ||
2405 | */ | ||
2406 | struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, | ||
2407 | struct device_node *prev) | ||
2408 | { | ||
2409 | struct device_node *endpoint; | ||
2410 | struct device_node *port; | ||
2411 | |||
2412 | if (!parent) | ||
2413 | return NULL; | ||
2414 | |||
2415 | /* | ||
2416 | * Start by locating the port node. If no previous endpoint is specified | ||
2417 | * search for the first port node, otherwise get the previous endpoint | ||
2418 | * parent port node. | ||
2419 | */ | ||
2420 | if (!prev) { | ||
2421 | struct device_node *node; | ||
2422 | |||
2423 | node = of_get_child_by_name(parent, "ports"); | ||
2424 | if (node) | ||
2425 | parent = node; | ||
2426 | |||
2427 | port = of_get_child_by_name(parent, "port"); | ||
2428 | of_node_put(node); | ||
2429 | |||
2430 | if (!port) { | ||
2431 | pr_err("graph: no port node found in %s\n", | ||
2432 | parent->full_name); | ||
2433 | return NULL; | ||
2434 | } | ||
2435 | } else { | ||
2436 | port = of_get_parent(prev); | ||
2437 | if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n", | ||
2438 | __func__, prev->full_name)) | ||
2439 | return NULL; | ||
2440 | } | ||
2441 | |||
2442 | while (1) { | ||
2443 | /* | ||
2444 | * Now that we have a port node, get the next endpoint by | ||
2445 | * getting the next child. If the previous endpoint is NULL this | ||
2446 | * will return the first child. | ||
2447 | */ | ||
2448 | endpoint = of_get_next_child(port, prev); | ||
2449 | if (endpoint) { | ||
2450 | of_node_put(port); | ||
2451 | return endpoint; | ||
2452 | } | ||
2453 | |||
2454 | /* No more endpoints under this port, try the next one. */ | ||
2455 | prev = NULL; | ||
2456 | |||
2457 | do { | ||
2458 | port = of_get_next_child(parent, port); | ||
2459 | if (!port) | ||
2460 | return NULL; | ||
2461 | } while (of_node_cmp(port->name, "port")); | ||
2462 | } | ||
2463 | } | ||
2464 | EXPORT_SYMBOL(of_graph_get_next_endpoint); | ||
2465 | |||
2466 | /** | ||
2467 | * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers | ||
2468 | * @parent: pointer to the parent device node | ||
2469 | * @port_reg: identifier (value of reg property) of the parent port node | ||
2470 | * @reg: identifier (value of reg property) of the endpoint node | ||
2471 | * | ||
2472 | * Return: An 'endpoint' node pointer which is identified by reg and at the same | ||
2473 | * is the child of a port node identified by port_reg. reg and port_reg are | ||
2474 | * ignored when they are -1. | ||
2475 | */ | ||
2476 | struct device_node *of_graph_get_endpoint_by_regs( | ||
2477 | const struct device_node *parent, int port_reg, int reg) | ||
2478 | { | ||
2479 | struct of_endpoint endpoint; | ||
2480 | struct device_node *node = NULL; | ||
2481 | |||
2482 | for_each_endpoint_of_node(parent, node) { | ||
2483 | of_graph_parse_endpoint(node, &endpoint); | ||
2484 | if (((port_reg == -1) || (endpoint.port == port_reg)) && | ||
2485 | ((reg == -1) || (endpoint.id == reg))) | ||
2486 | return node; | ||
2487 | } | ||
2488 | |||
2489 | return NULL; | ||
2490 | } | ||
2491 | EXPORT_SYMBOL(of_graph_get_endpoint_by_regs); | ||
2492 | |||
2493 | /** | ||
2494 | * of_graph_get_remote_port_parent() - get remote port's parent node | ||
2495 | * @node: pointer to a local endpoint device_node | ||
2496 | * | ||
2497 | * Return: Remote device node associated with remote endpoint node linked | ||
2498 | * to @node. Use of_node_put() on it when done. | ||
2499 | */ | ||
2500 | struct device_node *of_graph_get_remote_port_parent( | ||
2501 | const struct device_node *node) | ||
2502 | { | ||
2503 | struct device_node *np; | ||
2504 | unsigned int depth; | ||
2505 | |||
2506 | /* Get remote endpoint node. */ | ||
2507 | np = of_parse_phandle(node, "remote-endpoint", 0); | ||
2508 | |||
2509 | /* Walk 3 levels up only if there is 'ports' node. */ | ||
2510 | for (depth = 3; depth && np; depth--) { | ||
2511 | np = of_get_next_parent(np); | ||
2512 | if (depth == 2 && of_node_cmp(np->name, "ports")) | ||
2513 | break; | ||
2514 | } | ||
2515 | return np; | ||
2516 | } | ||
2517 | EXPORT_SYMBOL(of_graph_get_remote_port_parent); | ||
2518 | |||
2519 | /** | ||
2520 | * of_graph_get_remote_port() - get remote port node | ||
2521 | * @node: pointer to a local endpoint device_node | ||
2522 | * | ||
2523 | * Return: Remote port node associated with remote endpoint node linked | ||
2524 | * to @node. Use of_node_put() on it when done. | ||
2525 | */ | ||
2526 | struct device_node *of_graph_get_remote_port(const struct device_node *node) | ||
2527 | { | ||
2528 | struct device_node *np; | ||
2529 | |||
2530 | /* Get remote endpoint node. */ | ||
2531 | np = of_parse_phandle(node, "remote-endpoint", 0); | ||
2532 | if (!np) | ||
2533 | return NULL; | ||
2534 | return of_get_next_parent(np); | ||
2535 | } | ||
2536 | EXPORT_SYMBOL(of_graph_get_remote_port); | ||
2537 | |||
2538 | /** | ||
2539 | * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint | ||
2540 | * @node: pointer to parent device_node containing graph port/endpoint | ||
2541 | * @port: identifier (value of reg property) of the parent port node | ||
2542 | * @endpoint: identifier (value of reg property) of the endpoint node | ||
2543 | * | ||
2544 | * Return: Remote device node associated with remote endpoint node linked | ||
2545 | * to @node. Use of_node_put() on it when done. | ||
2546 | */ | ||
2547 | struct device_node *of_graph_get_remote_node(const struct device_node *node, | ||
2548 | u32 port, u32 endpoint) | ||
2549 | { | ||
2550 | struct device_node *endpoint_node, *remote; | ||
2551 | |||
2552 | endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint); | ||
2553 | if (!endpoint_node) { | ||
2554 | pr_debug("no valid endpoint (%d, %d) for node %s\n", | ||
2555 | port, endpoint, node->full_name); | ||
2556 | return NULL; | ||
2557 | } | ||
2558 | |||
2559 | remote = of_graph_get_remote_port_parent(endpoint_node); | ||
2560 | of_node_put(endpoint_node); | ||
2561 | if (!remote) { | ||
2562 | pr_debug("no valid remote node\n"); | ||
2563 | return NULL; | ||
2564 | } | ||
2565 | |||
2566 | if (!of_device_is_available(remote)) { | ||
2567 | pr_debug("not available for remote node\n"); | ||
2568 | return NULL; | ||
2569 | } | ||
2570 | |||
2571 | return remote; | ||
2572 | } | ||
2573 | EXPORT_SYMBOL(of_graph_get_remote_node); | ||
diff --git a/drivers/of/property.c b/drivers/of/property.c new file mode 100644 index 000000000000..07c7c36c5ca8 --- /dev/null +++ b/drivers/of/property.c | |||
@@ -0,0 +1,806 @@ | |||
1 | /* | ||
2 | * drivers/of/property.c - Procedures for accessing and interpreting | ||
3 | * Devicetree properties and graphs. | ||
4 | * | ||
5 | * Initially created by copying procedures from drivers/of/base.c. This | ||
6 | * file contains the OF property as well as the OF graph interface | ||
7 | * functions. | ||
8 | * | ||
9 | * Paul Mackerras August 1996. | ||
10 | * Copyright (C) 1996-2005 Paul Mackerras. | ||
11 | * | ||
12 | * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. | ||
13 | * {engebret|bergner}@us.ibm.com | ||
14 | * | ||
15 | * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net | ||
16 | * | ||
17 | * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and | ||
18 | * Grant Likely. | ||
19 | * | ||
20 | * This program is free software; you can redistribute it and/or | ||
21 | * modify it under the terms of the GNU General Public License | ||
22 | * as published by the Free Software Foundation; either version | ||
23 | * 2 of the License, or (at your option) any later version. | ||
24 | */ | ||
25 | |||
26 | #define pr_fmt(fmt) "OF: " fmt | ||
27 | |||
28 | #include <linux/of.h> | ||
29 | #include <linux/of_device.h> | ||
30 | #include <linux/of_graph.h> | ||
31 | #include <linux/string.h> | ||
32 | |||
33 | #include "of_private.h" | ||
34 | |||
35 | /** | ||
36 | * of_property_count_elems_of_size - Count the number of elements in a property | ||
37 | * | ||
38 | * @np: device node from which the property value is to be read. | ||
39 | * @propname: name of the property to be searched. | ||
40 | * @elem_size: size of the individual element | ||
41 | * | ||
42 | * Search for a property in a device node and count the number of elements of | ||
43 | * size elem_size in it. Returns number of elements on sucess, -EINVAL if the | ||
44 | * property does not exist or its length does not match a multiple of elem_size | ||
45 | * and -ENODATA if the property does not have a value. | ||
46 | */ | ||
47 | int of_property_count_elems_of_size(const struct device_node *np, | ||
48 | const char *propname, int elem_size) | ||
49 | { | ||
50 | struct property *prop = of_find_property(np, propname, NULL); | ||
51 | |||
52 | if (!prop) | ||
53 | return -EINVAL; | ||
54 | if (!prop->value) | ||
55 | return -ENODATA; | ||
56 | |||
57 | if (prop->length % elem_size != 0) { | ||
58 | pr_err("size of %s in node %s is not a multiple of %d\n", | ||
59 | propname, np->full_name, elem_size); | ||
60 | return -EINVAL; | ||
61 | } | ||
62 | |||
63 | return prop->length / elem_size; | ||
64 | } | ||
65 | EXPORT_SYMBOL_GPL(of_property_count_elems_of_size); | ||
66 | |||
67 | /** | ||
68 | * of_find_property_value_of_size | ||
69 | * | ||
70 | * @np: device node from which the property value is to be read. | ||
71 | * @propname: name of the property to be searched. | ||
72 | * @min: minimum allowed length of property value | ||
73 | * @max: maximum allowed length of property value (0 means unlimited) | ||
74 | * @len: if !=NULL, actual length is written to here | ||
75 | * | ||
76 | * Search for a property in a device node and valid the requested size. | ||
77 | * Returns the property value on success, -EINVAL if the property does not | ||
78 | * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
79 | * property data is too small or too large. | ||
80 | * | ||
81 | */ | ||
82 | static void *of_find_property_value_of_size(const struct device_node *np, | ||
83 | const char *propname, u32 min, u32 max, size_t *len) | ||
84 | { | ||
85 | struct property *prop = of_find_property(np, propname, NULL); | ||
86 | |||
87 | if (!prop) | ||
88 | return ERR_PTR(-EINVAL); | ||
89 | if (!prop->value) | ||
90 | return ERR_PTR(-ENODATA); | ||
91 | if (prop->length < min) | ||
92 | return ERR_PTR(-EOVERFLOW); | ||
93 | if (max && prop->length > max) | ||
94 | return ERR_PTR(-EOVERFLOW); | ||
95 | |||
96 | if (len) | ||
97 | *len = prop->length; | ||
98 | |||
99 | return prop->value; | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * of_property_read_u32_index - Find and read a u32 from a multi-value property. | ||
104 | * | ||
105 | * @np: device node from which the property value is to be read. | ||
106 | * @propname: name of the property to be searched. | ||
107 | * @index: index of the u32 in the list of values | ||
108 | * @out_value: pointer to return value, modified only if no error. | ||
109 | * | ||
110 | * Search for a property in a device node and read nth 32-bit value from | ||
111 | * it. Returns 0 on success, -EINVAL if the property does not exist, | ||
112 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
113 | * property data isn't large enough. | ||
114 | * | ||
115 | * The out_value is modified only if a valid u32 value can be decoded. | ||
116 | */ | ||
117 | int of_property_read_u32_index(const struct device_node *np, | ||
118 | const char *propname, | ||
119 | u32 index, u32 *out_value) | ||
120 | { | ||
121 | const u32 *val = of_find_property_value_of_size(np, propname, | ||
122 | ((index + 1) * sizeof(*out_value)), | ||
123 | 0, | ||
124 | NULL); | ||
125 | |||
126 | if (IS_ERR(val)) | ||
127 | return PTR_ERR(val); | ||
128 | |||
129 | *out_value = be32_to_cpup(((__be32 *)val) + index); | ||
130 | return 0; | ||
131 | } | ||
132 | EXPORT_SYMBOL_GPL(of_property_read_u32_index); | ||
133 | |||
134 | /** | ||
135 | * of_property_read_u64_index - Find and read a u64 from a multi-value property. | ||
136 | * | ||
137 | * @np: device node from which the property value is to be read. | ||
138 | * @propname: name of the property to be searched. | ||
139 | * @index: index of the u64 in the list of values | ||
140 | * @out_value: pointer to return value, modified only if no error. | ||
141 | * | ||
142 | * Search for a property in a device node and read nth 64-bit value from | ||
143 | * it. Returns 0 on success, -EINVAL if the property does not exist, | ||
144 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
145 | * property data isn't large enough. | ||
146 | * | ||
147 | * The out_value is modified only if a valid u64 value can be decoded. | ||
148 | */ | ||
149 | int of_property_read_u64_index(const struct device_node *np, | ||
150 | const char *propname, | ||
151 | u32 index, u64 *out_value) | ||
152 | { | ||
153 | const u64 *val = of_find_property_value_of_size(np, propname, | ||
154 | ((index + 1) * sizeof(*out_value)), | ||
155 | 0, NULL); | ||
156 | |||
157 | if (IS_ERR(val)) | ||
158 | return PTR_ERR(val); | ||
159 | |||
160 | *out_value = be64_to_cpup(((__be64 *)val) + index); | ||
161 | return 0; | ||
162 | } | ||
163 | EXPORT_SYMBOL_GPL(of_property_read_u64_index); | ||
164 | |||
165 | /** | ||
166 | * of_property_read_variable_u8_array - Find and read an array of u8 from a | ||
167 | * property, with bounds on the minimum and maximum array size. | ||
168 | * | ||
169 | * @np: device node from which the property value is to be read. | ||
170 | * @propname: name of the property to be searched. | ||
171 | * @out_values: pointer to return value, modified only if return value is 0. | ||
172 | * @sz_min: minimum number of array elements to read | ||
173 | * @sz_max: maximum number of array elements to read, if zero there is no | ||
174 | * upper limit on the number of elements in the dts entry but only | ||
175 | * sz_min will be read. | ||
176 | * | ||
177 | * Search for a property in a device node and read 8-bit value(s) from | ||
178 | * it. Returns number of elements read on success, -EINVAL if the property | ||
179 | * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | ||
180 | * if the property data is smaller than sz_min or longer than sz_max. | ||
181 | * | ||
182 | * dts entry of array should be like: | ||
183 | * property = /bits/ 8 <0x50 0x60 0x70>; | ||
184 | * | ||
185 | * The out_values is modified only if a valid u8 value can be decoded. | ||
186 | */ | ||
187 | int of_property_read_variable_u8_array(const struct device_node *np, | ||
188 | const char *propname, u8 *out_values, | ||
189 | size_t sz_min, size_t sz_max) | ||
190 | { | ||
191 | size_t sz, count; | ||
192 | const u8 *val = of_find_property_value_of_size(np, propname, | ||
193 | (sz_min * sizeof(*out_values)), | ||
194 | (sz_max * sizeof(*out_values)), | ||
195 | &sz); | ||
196 | |||
197 | if (IS_ERR(val)) | ||
198 | return PTR_ERR(val); | ||
199 | |||
200 | if (!sz_max) | ||
201 | sz = sz_min; | ||
202 | else | ||
203 | sz /= sizeof(*out_values); | ||
204 | |||
205 | count = sz; | ||
206 | while (count--) | ||
207 | *out_values++ = *val++; | ||
208 | |||
209 | return sz; | ||
210 | } | ||
211 | EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array); | ||
212 | |||
213 | /** | ||
214 | * of_property_read_variable_u16_array - Find and read an array of u16 from a | ||
215 | * property, with bounds on the minimum and maximum array size. | ||
216 | * | ||
217 | * @np: device node from which the property value is to be read. | ||
218 | * @propname: name of the property to be searched. | ||
219 | * @out_values: pointer to return value, modified only if return value is 0. | ||
220 | * @sz_min: minimum number of array elements to read | ||
221 | * @sz_max: maximum number of array elements to read, if zero there is no | ||
222 | * upper limit on the number of elements in the dts entry but only | ||
223 | * sz_min will be read. | ||
224 | * | ||
225 | * Search for a property in a device node and read 16-bit value(s) from | ||
226 | * it. Returns number of elements read on success, -EINVAL if the property | ||
227 | * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | ||
228 | * if the property data is smaller than sz_min or longer than sz_max. | ||
229 | * | ||
230 | * dts entry of array should be like: | ||
231 | * property = /bits/ 16 <0x5000 0x6000 0x7000>; | ||
232 | * | ||
233 | * The out_values is modified only if a valid u16 value can be decoded. | ||
234 | */ | ||
235 | int of_property_read_variable_u16_array(const struct device_node *np, | ||
236 | const char *propname, u16 *out_values, | ||
237 | size_t sz_min, size_t sz_max) | ||
238 | { | ||
239 | size_t sz, count; | ||
240 | const __be16 *val = of_find_property_value_of_size(np, propname, | ||
241 | (sz_min * sizeof(*out_values)), | ||
242 | (sz_max * sizeof(*out_values)), | ||
243 | &sz); | ||
244 | |||
245 | if (IS_ERR(val)) | ||
246 | return PTR_ERR(val); | ||
247 | |||
248 | if (!sz_max) | ||
249 | sz = sz_min; | ||
250 | else | ||
251 | sz /= sizeof(*out_values); | ||
252 | |||
253 | count = sz; | ||
254 | while (count--) | ||
255 | *out_values++ = be16_to_cpup(val++); | ||
256 | |||
257 | return sz; | ||
258 | } | ||
259 | EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array); | ||
260 | |||
261 | /** | ||
262 | * of_property_read_variable_u32_array - Find and read an array of 32 bit | ||
263 | * integers from a property, with bounds on the minimum and maximum array size. | ||
264 | * | ||
265 | * @np: device node from which the property value is to be read. | ||
266 | * @propname: name of the property to be searched. | ||
267 | * @out_values: pointer to return value, modified only if return value is 0. | ||
268 | * @sz_min: minimum number of array elements to read | ||
269 | * @sz_max: maximum number of array elements to read, if zero there is no | ||
270 | * upper limit on the number of elements in the dts entry but only | ||
271 | * sz_min will be read. | ||
272 | * | ||
273 | * Search for a property in a device node and read 32-bit value(s) from | ||
274 | * it. Returns number of elements read on success, -EINVAL if the property | ||
275 | * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | ||
276 | * if the property data is smaller than sz_min or longer than sz_max. | ||
277 | * | ||
278 | * The out_values is modified only if a valid u32 value can be decoded. | ||
279 | */ | ||
280 | int of_property_read_variable_u32_array(const struct device_node *np, | ||
281 | const char *propname, u32 *out_values, | ||
282 | size_t sz_min, size_t sz_max) | ||
283 | { | ||
284 | size_t sz, count; | ||
285 | const __be32 *val = of_find_property_value_of_size(np, propname, | ||
286 | (sz_min * sizeof(*out_values)), | ||
287 | (sz_max * sizeof(*out_values)), | ||
288 | &sz); | ||
289 | |||
290 | if (IS_ERR(val)) | ||
291 | return PTR_ERR(val); | ||
292 | |||
293 | if (!sz_max) | ||
294 | sz = sz_min; | ||
295 | else | ||
296 | sz /= sizeof(*out_values); | ||
297 | |||
298 | count = sz; | ||
299 | while (count--) | ||
300 | *out_values++ = be32_to_cpup(val++); | ||
301 | |||
302 | return sz; | ||
303 | } | ||
304 | EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array); | ||
305 | |||
306 | /** | ||
307 | * of_property_read_u64 - Find and read a 64 bit integer from a property | ||
308 | * @np: device node from which the property value is to be read. | ||
309 | * @propname: name of the property to be searched. | ||
310 | * @out_value: pointer to return value, modified only if return value is 0. | ||
311 | * | ||
312 | * Search for a property in a device node and read a 64-bit value from | ||
313 | * it. Returns 0 on success, -EINVAL if the property does not exist, | ||
314 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
315 | * property data isn't large enough. | ||
316 | * | ||
317 | * The out_value is modified only if a valid u64 value can be decoded. | ||
318 | */ | ||
319 | int of_property_read_u64(const struct device_node *np, const char *propname, | ||
320 | u64 *out_value) | ||
321 | { | ||
322 | const __be32 *val = of_find_property_value_of_size(np, propname, | ||
323 | sizeof(*out_value), | ||
324 | 0, | ||
325 | NULL); | ||
326 | |||
327 | if (IS_ERR(val)) | ||
328 | return PTR_ERR(val); | ||
329 | |||
330 | *out_value = of_read_number(val, 2); | ||
331 | return 0; | ||
332 | } | ||
333 | EXPORT_SYMBOL_GPL(of_property_read_u64); | ||
334 | |||
335 | /** | ||
336 | * of_property_read_variable_u64_array - Find and read an array of 64 bit | ||
337 | * integers from a property, with bounds on the minimum and maximum array size. | ||
338 | * | ||
339 | * @np: device node from which the property value is to be read. | ||
340 | * @propname: name of the property to be searched. | ||
341 | * @out_values: pointer to return value, modified only if return value is 0. | ||
342 | * @sz_min: minimum number of array elements to read | ||
343 | * @sz_max: maximum number of array elements to read, if zero there is no | ||
344 | * upper limit on the number of elements in the dts entry but only | ||
345 | * sz_min will be read. | ||
346 | * | ||
347 | * Search for a property in a device node and read 64-bit value(s) from | ||
348 | * it. Returns number of elements read on success, -EINVAL if the property | ||
349 | * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | ||
350 | * if the property data is smaller than sz_min or longer than sz_max. | ||
351 | * | ||
352 | * The out_values is modified only if a valid u64 value can be decoded. | ||
353 | */ | ||
354 | int of_property_read_variable_u64_array(const struct device_node *np, | ||
355 | const char *propname, u64 *out_values, | ||
356 | size_t sz_min, size_t sz_max) | ||
357 | { | ||
358 | size_t sz, count; | ||
359 | const __be32 *val = of_find_property_value_of_size(np, propname, | ||
360 | (sz_min * sizeof(*out_values)), | ||
361 | (sz_max * sizeof(*out_values)), | ||
362 | &sz); | ||
363 | |||
364 | if (IS_ERR(val)) | ||
365 | return PTR_ERR(val); | ||
366 | |||
367 | if (!sz_max) | ||
368 | sz = sz_min; | ||
369 | else | ||
370 | sz /= sizeof(*out_values); | ||
371 | |||
372 | count = sz; | ||
373 | while (count--) { | ||
374 | *out_values++ = of_read_number(val, 2); | ||
375 | val += 2; | ||
376 | } | ||
377 | |||
378 | return sz; | ||
379 | } | ||
380 | EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array); | ||
381 | |||
382 | /** | ||
383 | * of_property_read_string - Find and read a string from a property | ||
384 | * @np: device node from which the property value is to be read. | ||
385 | * @propname: name of the property to be searched. | ||
386 | * @out_string: pointer to null terminated return string, modified only if | ||
387 | * return value is 0. | ||
388 | * | ||
389 | * Search for a property in a device tree node and retrieve a null | ||
390 | * terminated string value (pointer to data, not a copy). Returns 0 on | ||
391 | * success, -EINVAL if the property does not exist, -ENODATA if property | ||
392 | * does not have a value, and -EILSEQ if the string is not null-terminated | ||
393 | * within the length of the property data. | ||
394 | * | ||
395 | * The out_string pointer is modified only if a valid string can be decoded. | ||
396 | */ | ||
397 | int of_property_read_string(const struct device_node *np, const char *propname, | ||
398 | const char **out_string) | ||
399 | { | ||
400 | const struct property *prop = of_find_property(np, propname, NULL); | ||
401 | if (!prop) | ||
402 | return -EINVAL; | ||
403 | if (!prop->value) | ||
404 | return -ENODATA; | ||
405 | if (strnlen(prop->value, prop->length) >= prop->length) | ||
406 | return -EILSEQ; | ||
407 | *out_string = prop->value; | ||
408 | return 0; | ||
409 | } | ||
410 | EXPORT_SYMBOL_GPL(of_property_read_string); | ||
411 | |||
412 | /** | ||
413 | * of_property_match_string() - Find string in a list and return index | ||
414 | * @np: pointer to node containing string list property | ||
415 | * @propname: string list property name | ||
416 | * @string: pointer to string to search for in string list | ||
417 | * | ||
418 | * This function searches a string list property and returns the index | ||
419 | * of a specific string value. | ||
420 | */ | ||
421 | int of_property_match_string(const struct device_node *np, const char *propname, | ||
422 | const char *string) | ||
423 | { | ||
424 | const struct property *prop = of_find_property(np, propname, NULL); | ||
425 | size_t l; | ||
426 | int i; | ||
427 | const char *p, *end; | ||
428 | |||
429 | if (!prop) | ||
430 | return -EINVAL; | ||
431 | if (!prop->value) | ||
432 | return -ENODATA; | ||
433 | |||
434 | p = prop->value; | ||
435 | end = p + prop->length; | ||
436 | |||
437 | for (i = 0; p < end; i++, p += l) { | ||
438 | l = strnlen(p, end - p) + 1; | ||
439 | if (p + l > end) | ||
440 | return -EILSEQ; | ||
441 | pr_debug("comparing %s with %s\n", string, p); | ||
442 | if (strcmp(string, p) == 0) | ||
443 | return i; /* Found it; return index */ | ||
444 | } | ||
445 | return -ENODATA; | ||
446 | } | ||
447 | EXPORT_SYMBOL_GPL(of_property_match_string); | ||
448 | |||
449 | /** | ||
450 | * of_property_read_string_helper() - Utility helper for parsing string properties | ||
451 | * @np: device node from which the property value is to be read. | ||
452 | * @propname: name of the property to be searched. | ||
453 | * @out_strs: output array of string pointers. | ||
454 | * @sz: number of array elements to read. | ||
455 | * @skip: Number of strings to skip over at beginning of list. | ||
456 | * | ||
457 | * Don't call this function directly. It is a utility helper for the | ||
458 | * of_property_read_string*() family of functions. | ||
459 | */ | ||
460 | int of_property_read_string_helper(const struct device_node *np, | ||
461 | const char *propname, const char **out_strs, | ||
462 | size_t sz, int skip) | ||
463 | { | ||
464 | const struct property *prop = of_find_property(np, propname, NULL); | ||
465 | int l = 0, i = 0; | ||
466 | const char *p, *end; | ||
467 | |||
468 | if (!prop) | ||
469 | return -EINVAL; | ||
470 | if (!prop->value) | ||
471 | return -ENODATA; | ||
472 | p = prop->value; | ||
473 | end = p + prop->length; | ||
474 | |||
475 | for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) { | ||
476 | l = strnlen(p, end - p) + 1; | ||
477 | if (p + l > end) | ||
478 | return -EILSEQ; | ||
479 | if (out_strs && i >= skip) | ||
480 | *out_strs++ = p; | ||
481 | } | ||
482 | i -= skip; | ||
483 | return i <= 0 ? -ENODATA : i; | ||
484 | } | ||
485 | EXPORT_SYMBOL_GPL(of_property_read_string_helper); | ||
486 | |||
487 | const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, | ||
488 | u32 *pu) | ||
489 | { | ||
490 | const void *curv = cur; | ||
491 | |||
492 | if (!prop) | ||
493 | return NULL; | ||
494 | |||
495 | if (!cur) { | ||
496 | curv = prop->value; | ||
497 | goto out_val; | ||
498 | } | ||
499 | |||
500 | curv += sizeof(*cur); | ||
501 | if (curv >= prop->value + prop->length) | ||
502 | return NULL; | ||
503 | |||
504 | out_val: | ||
505 | *pu = be32_to_cpup(curv); | ||
506 | return curv; | ||
507 | } | ||
508 | EXPORT_SYMBOL_GPL(of_prop_next_u32); | ||
509 | |||
510 | const char *of_prop_next_string(struct property *prop, const char *cur) | ||
511 | { | ||
512 | const void *curv = cur; | ||
513 | |||
514 | if (!prop) | ||
515 | return NULL; | ||
516 | |||
517 | if (!cur) | ||
518 | return prop->value; | ||
519 | |||
520 | curv += strlen(cur) + 1; | ||
521 | if (curv >= prop->value + prop->length) | ||
522 | return NULL; | ||
523 | |||
524 | return curv; | ||
525 | } | ||
526 | EXPORT_SYMBOL_GPL(of_prop_next_string); | ||
527 | |||
528 | /** | ||
529 | * of_graph_parse_endpoint() - parse common endpoint node properties | ||
530 | * @node: pointer to endpoint device_node | ||
531 | * @endpoint: pointer to the OF endpoint data structure | ||
532 | * | ||
533 | * The caller should hold a reference to @node. | ||
534 | */ | ||
535 | int of_graph_parse_endpoint(const struct device_node *node, | ||
536 | struct of_endpoint *endpoint) | ||
537 | { | ||
538 | struct device_node *port_node = of_get_parent(node); | ||
539 | |||
540 | WARN_ONCE(!port_node, "%s(): endpoint %s has no parent node\n", | ||
541 | __func__, node->full_name); | ||
542 | |||
543 | memset(endpoint, 0, sizeof(*endpoint)); | ||
544 | |||
545 | endpoint->local_node = node; | ||
546 | /* | ||
547 | * It doesn't matter whether the two calls below succeed. | ||
548 | * If they don't then the default value 0 is used. | ||
549 | */ | ||
550 | of_property_read_u32(port_node, "reg", &endpoint->port); | ||
551 | of_property_read_u32(node, "reg", &endpoint->id); | ||
552 | |||
553 | of_node_put(port_node); | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | EXPORT_SYMBOL(of_graph_parse_endpoint); | ||
558 | |||
559 | /** | ||
560 | * of_graph_get_port_by_id() - get the port matching a given id | ||
561 | * @parent: pointer to the parent device node | ||
562 | * @id: id of the port | ||
563 | * | ||
564 | * Return: A 'port' node pointer with refcount incremented. The caller | ||
565 | * has to use of_node_put() on it when done. | ||
566 | */ | ||
567 | struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id) | ||
568 | { | ||
569 | struct device_node *node, *port; | ||
570 | |||
571 | node = of_get_child_by_name(parent, "ports"); | ||
572 | if (node) | ||
573 | parent = node; | ||
574 | |||
575 | for_each_child_of_node(parent, port) { | ||
576 | u32 port_id = 0; | ||
577 | |||
578 | if (of_node_cmp(port->name, "port") != 0) | ||
579 | continue; | ||
580 | of_property_read_u32(port, "reg", &port_id); | ||
581 | if (id == port_id) | ||
582 | break; | ||
583 | } | ||
584 | |||
585 | of_node_put(node); | ||
586 | |||
587 | return port; | ||
588 | } | ||
589 | EXPORT_SYMBOL(of_graph_get_port_by_id); | ||
590 | |||
591 | /** | ||
592 | * of_graph_get_next_endpoint() - get next endpoint node | ||
593 | * @parent: pointer to the parent device node | ||
594 | * @prev: previous endpoint node, or NULL to get first | ||
595 | * | ||
596 | * Return: An 'endpoint' node pointer with refcount incremented. Refcount | ||
597 | * of the passed @prev node is decremented. | ||
598 | */ | ||
599 | struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, | ||
600 | struct device_node *prev) | ||
601 | { | ||
602 | struct device_node *endpoint; | ||
603 | struct device_node *port; | ||
604 | |||
605 | if (!parent) | ||
606 | return NULL; | ||
607 | |||
608 | /* | ||
609 | * Start by locating the port node. If no previous endpoint is specified | ||
610 | * search for the first port node, otherwise get the previous endpoint | ||
611 | * parent port node. | ||
612 | */ | ||
613 | if (!prev) { | ||
614 | struct device_node *node; | ||
615 | |||
616 | node = of_get_child_by_name(parent, "ports"); | ||
617 | if (node) | ||
618 | parent = node; | ||
619 | |||
620 | port = of_get_child_by_name(parent, "port"); | ||
621 | of_node_put(node); | ||
622 | |||
623 | if (!port) { | ||
624 | pr_err("graph: no port node found in %s\n", | ||
625 | parent->full_name); | ||
626 | return NULL; | ||
627 | } | ||
628 | } else { | ||
629 | port = of_get_parent(prev); | ||
630 | if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n", | ||
631 | __func__, prev->full_name)) | ||
632 | return NULL; | ||
633 | } | ||
634 | |||
635 | while (1) { | ||
636 | /* | ||
637 | * Now that we have a port node, get the next endpoint by | ||
638 | * getting the next child. If the previous endpoint is NULL this | ||
639 | * will return the first child. | ||
640 | */ | ||
641 | endpoint = of_get_next_child(port, prev); | ||
642 | if (endpoint) { | ||
643 | of_node_put(port); | ||
644 | return endpoint; | ||
645 | } | ||
646 | |||
647 | /* No more endpoints under this port, try the next one. */ | ||
648 | prev = NULL; | ||
649 | |||
650 | do { | ||
651 | port = of_get_next_child(parent, port); | ||
652 | if (!port) | ||
653 | return NULL; | ||
654 | } while (of_node_cmp(port->name, "port")); | ||
655 | } | ||
656 | } | ||
657 | EXPORT_SYMBOL(of_graph_get_next_endpoint); | ||
658 | |||
659 | /** | ||
660 | * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers | ||
661 | * @parent: pointer to the parent device node | ||
662 | * @port_reg: identifier (value of reg property) of the parent port node | ||
663 | * @reg: identifier (value of reg property) of the endpoint node | ||
664 | * | ||
665 | * Return: An 'endpoint' node pointer which is identified by reg and at the same | ||
666 | * is the child of a port node identified by port_reg. reg and port_reg are | ||
667 | * ignored when they are -1. | ||
668 | */ | ||
669 | struct device_node *of_graph_get_endpoint_by_regs( | ||
670 | const struct device_node *parent, int port_reg, int reg) | ||
671 | { | ||
672 | struct of_endpoint endpoint; | ||
673 | struct device_node *node = NULL; | ||
674 | |||
675 | for_each_endpoint_of_node(parent, node) { | ||
676 | of_graph_parse_endpoint(node, &endpoint); | ||
677 | if (((port_reg == -1) || (endpoint.port == port_reg)) && | ||
678 | ((reg == -1) || (endpoint.id == reg))) | ||
679 | return node; | ||
680 | } | ||
681 | |||
682 | return NULL; | ||
683 | } | ||
684 | EXPORT_SYMBOL(of_graph_get_endpoint_by_regs); | ||
685 | |||
686 | /** | ||
687 | * of_graph_get_remote_endpoint() - get remote endpoint node | ||
688 | * @node: pointer to a local endpoint device_node | ||
689 | * | ||
690 | * Return: Remote endpoint node associated with remote endpoint node linked | ||
691 | * to @node. Use of_node_put() on it when done. | ||
692 | */ | ||
693 | struct device_node *of_graph_get_remote_endpoint(const struct device_node *node) | ||
694 | { | ||
695 | /* Get remote endpoint node. */ | ||
696 | return of_parse_phandle(node, "remote-endpoint", 0); | ||
697 | } | ||
698 | EXPORT_SYMBOL(of_graph_get_remote_endpoint); | ||
699 | |||
700 | /** | ||
701 | * of_graph_get_port_parent() - get port's parent node | ||
702 | * @node: pointer to a local endpoint device_node | ||
703 | * | ||
704 | * Return: device node associated with endpoint node linked | ||
705 | * to @node. Use of_node_put() on it when done. | ||
706 | */ | ||
707 | struct device_node *of_graph_get_port_parent(struct device_node *node) | ||
708 | { | ||
709 | unsigned int depth; | ||
710 | |||
711 | /* Walk 3 levels up only if there is 'ports' node. */ | ||
712 | for (depth = 3; depth && node; depth--) { | ||
713 | node = of_get_next_parent(node); | ||
714 | if (depth == 2 && of_node_cmp(node->name, "ports")) | ||
715 | break; | ||
716 | } | ||
717 | return node; | ||
718 | } | ||
719 | EXPORT_SYMBOL(of_graph_get_port_parent); | ||
720 | |||
721 | /** | ||
722 | * of_graph_get_remote_port_parent() - get remote port's parent node | ||
723 | * @node: pointer to a local endpoint device_node | ||
724 | * | ||
725 | * Return: Remote device node associated with remote endpoint node linked | ||
726 | * to @node. Use of_node_put() on it when done. | ||
727 | */ | ||
728 | struct device_node *of_graph_get_remote_port_parent( | ||
729 | const struct device_node *node) | ||
730 | { | ||
731 | struct device_node *np; | ||
732 | |||
733 | /* Get remote endpoint node. */ | ||
734 | np = of_graph_get_remote_endpoint(node); | ||
735 | |||
736 | return of_graph_get_port_parent(np); | ||
737 | } | ||
738 | EXPORT_SYMBOL(of_graph_get_remote_port_parent); | ||
739 | |||
740 | /** | ||
741 | * of_graph_get_remote_port() - get remote port node | ||
742 | * @node: pointer to a local endpoint device_node | ||
743 | * | ||
744 | * Return: Remote port node associated with remote endpoint node linked | ||
745 | * to @node. Use of_node_put() on it when done. | ||
746 | */ | ||
747 | struct device_node *of_graph_get_remote_port(const struct device_node *node) | ||
748 | { | ||
749 | struct device_node *np; | ||
750 | |||
751 | /* Get remote endpoint node. */ | ||
752 | np = of_graph_get_remote_endpoint(node); | ||
753 | if (!np) | ||
754 | return NULL; | ||
755 | return of_get_next_parent(np); | ||
756 | } | ||
757 | EXPORT_SYMBOL(of_graph_get_remote_port); | ||
758 | |||
759 | int of_graph_get_endpoint_count(const struct device_node *np) | ||
760 | { | ||
761 | struct device_node *endpoint; | ||
762 | int num = 0; | ||
763 | |||
764 | for_each_endpoint_of_node(np, endpoint) | ||
765 | num++; | ||
766 | |||
767 | return num; | ||
768 | } | ||
769 | EXPORT_SYMBOL(of_graph_get_endpoint_count); | ||
770 | |||
771 | /** | ||
772 | * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint | ||
773 | * @node: pointer to parent device_node containing graph port/endpoint | ||
774 | * @port: identifier (value of reg property) of the parent port node | ||
775 | * @endpoint: identifier (value of reg property) of the endpoint node | ||
776 | * | ||
777 | * Return: Remote device node associated with remote endpoint node linked | ||
778 | * to @node. Use of_node_put() on it when done. | ||
779 | */ | ||
780 | struct device_node *of_graph_get_remote_node(const struct device_node *node, | ||
781 | u32 port, u32 endpoint) | ||
782 | { | ||
783 | struct device_node *endpoint_node, *remote; | ||
784 | |||
785 | endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint); | ||
786 | if (!endpoint_node) { | ||
787 | pr_debug("no valid endpoint (%d, %d) for node %s\n", | ||
788 | port, endpoint, node->full_name); | ||
789 | return NULL; | ||
790 | } | ||
791 | |||
792 | remote = of_graph_get_remote_port_parent(endpoint_node); | ||
793 | of_node_put(endpoint_node); | ||
794 | if (!remote) { | ||
795 | pr_debug("no valid remote node\n"); | ||
796 | return NULL; | ||
797 | } | ||
798 | |||
799 | if (!of_device_is_available(remote)) { | ||
800 | pr_debug("not available for remote node\n"); | ||
801 | return NULL; | ||
802 | } | ||
803 | |||
804 | return remote; | ||
805 | } | ||
806 | EXPORT_SYMBOL(of_graph_get_remote_node); | ||