aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Fitzgerald <rf@opensource.wolfsonmicro.com>2016-09-12 09:01:29 -0400
committerRob Herring <robh@kernel.org>2016-09-15 09:33:01 -0400
commita67e9472da423ec47a3586920b526ebaedf25fc3 (patch)
tree0e6b3da989b014b7eece1b4222f189de76c43bae
parent79ac5d31df7011e2b60dba4bd1e2f9a9f65e5e1e (diff)
of: Add array read functions with min/max size limits
Add a new set of array reading functions that take a minimum and maximum size limit and will fail if the property size is not within the size limits. This makes it more convenient for drivers that use variable-size DT arrays which must be bounded at both ends - data must be at least N entries but must not overflow the array it is being copied into. It is also more efficient than making this functionality out of existing public functions and avoids duplication. The existing array functions have been left in the API, since there are a very large number of clients of those functions and their existing functionality is still useful. This avoids turning a small API improvement into a major kernel rework. The old functions have been turned into mininmal static inlines calling the new functions. The old functions had no upper limit on the actual size of the dts entry, to preserve this functionality rather than keeping two near-identical implementations, if the new function is called with max=0 there is no limit on the size of the dts entry but only the min number of elements are read. Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com> Signed-off-by: Rob Herring <robh@kernel.org>
-rw-r--r--drivers/of/base.c156
-rw-r--r--include/linux/of.h144
2 files changed, 234 insertions, 66 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index b85373768ce1..a0bccb54a9bd 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1209,108 +1209,145 @@ int of_property_read_u32_index(const struct device_node *np,
1209EXPORT_SYMBOL_GPL(of_property_read_u32_index); 1209EXPORT_SYMBOL_GPL(of_property_read_u32_index);
1210 1210
1211/** 1211/**
1212 * of_property_read_u8_array - Find and read an array of u8 from a property. 1212 * of_property_read_variable_u8_array - Find and read an array of u8 from a
1213 * property, with bounds on the minimum and maximum array size.
1213 * 1214 *
1214 * @np: device node from which the property value is to be read. 1215 * @np: device node from which the property value is to be read.
1215 * @propname: name of the property to be searched. 1216 * @propname: name of the property to be searched.
1216 * @out_values: pointer to return value, modified only if return value is 0. 1217 * @out_values: pointer to return value, modified only if return value is 0.
1217 * @sz: number of array elements to read 1218 * @sz_min: minimum number of array elements to read
1219 * @sz_max: maximum number of array elements to read, if zero there is no
1220 * upper limit on the number of elements in the dts entry but only
1221 * sz_min will be read.
1218 * 1222 *
1219 * Search for a property in a device node and read 8-bit value(s) from 1223 * Search for a property in a device node and read 8-bit value(s) from
1220 * it. Returns 0 on success, -EINVAL if the property does not exist, 1224 * it. Returns number of elements read on success, -EINVAL if the property
1221 * -ENODATA if property does not have a value, and -EOVERFLOW if the 1225 * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
1222 * property data isn't large enough. 1226 * if the property data is smaller than sz_min or longer than sz_max.
1223 * 1227 *
1224 * dts entry of array should be like: 1228 * dts entry of array should be like:
1225 * property = /bits/ 8 <0x50 0x60 0x70>; 1229 * property = /bits/ 8 <0x50 0x60 0x70>;
1226 * 1230 *
1227 * The out_values is modified only if a valid u8 value can be decoded. 1231 * The out_values is modified only if a valid u8 value can be decoded.
1228 */ 1232 */
1229int of_property_read_u8_array(const struct device_node *np, 1233int of_property_read_variable_u8_array(const struct device_node *np,
1230 const char *propname, u8 *out_values, size_t sz) 1234 const char *propname, u8 *out_values,
1235 size_t sz_min, size_t sz_max)
1231{ 1236{
1237 size_t sz, count;
1232 const u8 *val = of_find_property_value_of_size(np, propname, 1238 const u8 *val = of_find_property_value_of_size(np, propname,
1233 (sz * sizeof(*out_values)), 1239 (sz_min * sizeof(*out_values)),
1234 0, 1240 (sz_max * sizeof(*out_values)),
1235 NULL); 1241 &sz);
1236 1242
1237 if (IS_ERR(val)) 1243 if (IS_ERR(val))
1238 return PTR_ERR(val); 1244 return PTR_ERR(val);
1239 1245
1240 while (sz--) 1246 if (!sz_max)
1247 sz = sz_min;
1248 else
1249 sz /= sizeof(*out_values);
1250
1251 count = sz;
1252 while (count--)
1241 *out_values++ = *val++; 1253 *out_values++ = *val++;
1242 return 0; 1254
1255 return sz;
1243} 1256}
1244EXPORT_SYMBOL_GPL(of_property_read_u8_array); 1257EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array);
1245 1258
1246/** 1259/**
1247 * of_property_read_u16_array - Find and read an array of u16 from a property. 1260 * of_property_read_variable_u16_array - Find and read an array of u16 from a
1261 * property, with bounds on the minimum and maximum array size.
1248 * 1262 *
1249 * @np: device node from which the property value is to be read. 1263 * @np: device node from which the property value is to be read.
1250 * @propname: name of the property to be searched. 1264 * @propname: name of the property to be searched.
1251 * @out_values: pointer to return value, modified only if return value is 0. 1265 * @out_values: pointer to return value, modified only if return value is 0.
1252 * @sz: number of array elements to read 1266 * @sz_min: minimum number of array elements to read
1267 * @sz_max: maximum number of array elements to read, if zero there is no
1268 * upper limit on the number of elements in the dts entry but only
1269 * sz_min will be read.
1253 * 1270 *
1254 * Search for a property in a device node and read 16-bit value(s) from 1271 * Search for a property in a device node and read 16-bit value(s) from
1255 * it. Returns 0 on success, -EINVAL if the property does not exist, 1272 * it. Returns number of elements read on success, -EINVAL if the property
1256 * -ENODATA if property does not have a value, and -EOVERFLOW if the 1273 * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
1257 * property data isn't large enough. 1274 * if the property data is smaller than sz_min or longer than sz_max.
1258 * 1275 *
1259 * dts entry of array should be like: 1276 * dts entry of array should be like:
1260 * property = /bits/ 16 <0x5000 0x6000 0x7000>; 1277 * property = /bits/ 16 <0x5000 0x6000 0x7000>;
1261 * 1278 *
1262 * The out_values is modified only if a valid u16 value can be decoded. 1279 * The out_values is modified only if a valid u16 value can be decoded.
1263 */ 1280 */
1264int of_property_read_u16_array(const struct device_node *np, 1281int of_property_read_variable_u16_array(const struct device_node *np,
1265 const char *propname, u16 *out_values, size_t sz) 1282 const char *propname, u16 *out_values,
1283 size_t sz_min, size_t sz_max)
1266{ 1284{
1285 size_t sz, count;
1267 const __be16 *val = of_find_property_value_of_size(np, propname, 1286 const __be16 *val = of_find_property_value_of_size(np, propname,
1268 (sz * sizeof(*out_values)), 1287 (sz_min * sizeof(*out_values)),
1269 0, 1288 (sz_max * sizeof(*out_values)),
1270 NULL); 1289 &sz);
1271 1290
1272 if (IS_ERR(val)) 1291 if (IS_ERR(val))
1273 return PTR_ERR(val); 1292 return PTR_ERR(val);
1274 1293
1275 while (sz--) 1294 if (!sz_max)
1295 sz = sz_min;
1296 else
1297 sz /= sizeof(*out_values);
1298
1299 count = sz;
1300 while (count--)
1276 *out_values++ = be16_to_cpup(val++); 1301 *out_values++ = be16_to_cpup(val++);
1277 return 0; 1302
1303 return sz;
1278} 1304}
1279EXPORT_SYMBOL_GPL(of_property_read_u16_array); 1305EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array);
1280 1306
1281/** 1307/**
1282 * of_property_read_u32_array - Find and read an array of 32 bit integers 1308 * of_property_read_variable_u32_array - Find and read an array of 32 bit
1283 * from a property. 1309 * integers from a property, with bounds on the minimum and maximum array size.
1284 * 1310 *
1285 * @np: device node from which the property value is to be read. 1311 * @np: device node from which the property value is to be read.
1286 * @propname: name of the property to be searched. 1312 * @propname: name of the property to be searched.
1287 * @out_values: pointer to return value, modified only if return value is 0. 1313 * @out_values: pointer to return value, modified only if return value is 0.
1288 * @sz: number of array elements to read 1314 * @sz_min: minimum number of array elements to read
1315 * @sz_max: maximum number of array elements to read, if zero there is no
1316 * upper limit on the number of elements in the dts entry but only
1317 * sz_min will be read.
1289 * 1318 *
1290 * Search for a property in a device node and read 32-bit value(s) from 1319 * Search for a property in a device node and read 32-bit value(s) from
1291 * it. Returns 0 on success, -EINVAL if the property does not exist, 1320 * it. Returns number of elements read on success, -EINVAL if the property
1292 * -ENODATA if property does not have a value, and -EOVERFLOW if the 1321 * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
1293 * property data isn't large enough. 1322 * if the property data is smaller than sz_min or longer than sz_max.
1294 * 1323 *
1295 * The out_values is modified only if a valid u32 value can be decoded. 1324 * The out_values is modified only if a valid u32 value can be decoded.
1296 */ 1325 */
1297int of_property_read_u32_array(const struct device_node *np, 1326int of_property_read_variable_u32_array(const struct device_node *np,
1298 const char *propname, u32 *out_values, 1327 const char *propname, u32 *out_values,
1299 size_t sz) 1328 size_t sz_min, size_t sz_max)
1300{ 1329{
1330 size_t sz, count;
1301 const __be32 *val = of_find_property_value_of_size(np, propname, 1331 const __be32 *val = of_find_property_value_of_size(np, propname,
1302 (sz * sizeof(*out_values)), 1332 (sz_min * sizeof(*out_values)),
1303 0, 1333 (sz_max * sizeof(*out_values)),
1304 NULL); 1334 &sz);
1305 1335
1306 if (IS_ERR(val)) 1336 if (IS_ERR(val))
1307 return PTR_ERR(val); 1337 return PTR_ERR(val);
1308 1338
1309 while (sz--) 1339 if (!sz_max)
1340 sz = sz_min;
1341 else
1342 sz /= sizeof(*out_values);
1343
1344 count = sz;
1345 while (count--)
1310 *out_values++ = be32_to_cpup(val++); 1346 *out_values++ = be32_to_cpup(val++);
1311 return 0; 1347
1348 return sz;
1312} 1349}
1313EXPORT_SYMBOL_GPL(of_property_read_u32_array); 1350EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array);
1314 1351
1315/** 1352/**
1316 * of_property_read_u64 - Find and read a 64 bit integer from a property 1353 * of_property_read_u64 - Find and read a 64 bit integer from a property
@@ -1342,40 +1379,51 @@ int of_property_read_u64(const struct device_node *np, const char *propname,
1342EXPORT_SYMBOL_GPL(of_property_read_u64); 1379EXPORT_SYMBOL_GPL(of_property_read_u64);
1343 1380
1344/** 1381/**
1345 * of_property_read_u64_array - Find and read an array of 64 bit integers 1382 * of_property_read_variable_u64_array - Find and read an array of 64 bit
1346 * from a property. 1383 * integers from a property, with bounds on the minimum and maximum array size.
1347 * 1384 *
1348 * @np: device node from which the property value is to be read. 1385 * @np: device node from which the property value is to be read.
1349 * @propname: name of the property to be searched. 1386 * @propname: name of the property to be searched.
1350 * @out_values: pointer to return value, modified only if return value is 0. 1387 * @out_values: pointer to return value, modified only if return value is 0.
1351 * @sz: number of array elements to read 1388 * @sz_min: minimum number of array elements to read
1389 * @sz_max: maximum number of array elements to read, if zero there is no
1390 * upper limit on the number of elements in the dts entry but only
1391 * sz_min will be read.
1352 * 1392 *
1353 * Search for a property in a device node and read 64-bit value(s) from 1393 * Search for a property in a device node and read 64-bit value(s) from
1354 * it. Returns 0 on success, -EINVAL if the property does not exist, 1394 * it. Returns number of elements read on success, -EINVAL if the property
1355 * -ENODATA if property does not have a value, and -EOVERFLOW if the 1395 * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
1356 * property data isn't large enough. 1396 * if the property data is smaller than sz_min or longer than sz_max.
1357 * 1397 *
1358 * The out_values is modified only if a valid u64 value can be decoded. 1398 * The out_values is modified only if a valid u64 value can be decoded.
1359 */ 1399 */
1360int of_property_read_u64_array(const struct device_node *np, 1400int of_property_read_variable_u64_array(const struct device_node *np,
1361 const char *propname, u64 *out_values, 1401 const char *propname, u64 *out_values,
1362 size_t sz) 1402 size_t sz_min, size_t sz_max)
1363{ 1403{
1404 size_t sz, count;
1364 const __be32 *val = of_find_property_value_of_size(np, propname, 1405 const __be32 *val = of_find_property_value_of_size(np, propname,
1365 (sz * sizeof(*out_values)), 1406 (sz_min * sizeof(*out_values)),
1366 0, 1407 (sz_max * sizeof(*out_values)),
1367 NULL); 1408 &sz);
1368 1409
1369 if (IS_ERR(val)) 1410 if (IS_ERR(val))
1370 return PTR_ERR(val); 1411 return PTR_ERR(val);
1371 1412
1372 while (sz--) { 1413 if (!sz_max)
1414 sz = sz_min;
1415 else
1416 sz /= sizeof(*out_values);
1417
1418 count = sz;
1419 while (count--) {
1373 *out_values++ = of_read_number(val, 2); 1420 *out_values++ = of_read_number(val, 2);
1374 val += 2; 1421 val += 2;
1375 } 1422 }
1376 return 0; 1423
1424 return sz;
1377} 1425}
1378EXPORT_SYMBOL_GPL(of_property_read_u64_array); 1426EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array);
1379 1427
1380/** 1428/**
1381 * of_property_read_string - Find and read a string from a property 1429 * of_property_read_string - Find and read a string from a property
diff --git a/include/linux/of.h b/include/linux/of.h
index 3d9ff8e9d803..299aeb192727 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -291,20 +291,24 @@ extern int of_property_count_elems_of_size(const struct device_node *np,
291extern int of_property_read_u32_index(const struct device_node *np, 291extern int of_property_read_u32_index(const struct device_node *np,
292 const char *propname, 292 const char *propname,
293 u32 index, u32 *out_value); 293 u32 index, u32 *out_value);
294extern int of_property_read_u8_array(const struct device_node *np, 294extern int of_property_read_variable_u8_array(const struct device_node *np,
295 const char *propname, u8 *out_values, size_t sz); 295 const char *propname, u8 *out_values,
296extern int of_property_read_u16_array(const struct device_node *np, 296 size_t sz_min, size_t sz_max);
297 const char *propname, u16 *out_values, size_t sz); 297extern int of_property_read_variable_u16_array(const struct device_node *np,
298extern int of_property_read_u32_array(const struct device_node *np, 298 const char *propname, u16 *out_values,
299 const char *propname, 299 size_t sz_min, size_t sz_max);
300 u32 *out_values, 300extern int of_property_read_variable_u32_array(const struct device_node *np,
301 size_t sz); 301 const char *propname,
302 u32 *out_values,
303 size_t sz_min,
304 size_t sz_max);
302extern int of_property_read_u64(const struct device_node *np, 305extern int of_property_read_u64(const struct device_node *np,
303 const char *propname, u64 *out_value); 306 const char *propname, u64 *out_value);
304extern int of_property_read_u64_array(const struct device_node *np, 307extern int of_property_read_variable_u64_array(const struct device_node *np,
305 const char *propname, 308 const char *propname,
306 u64 *out_values, 309 u64 *out_values,
307 size_t sz); 310 size_t sz_min,
311 size_t sz_max);
308 312
309extern int of_property_read_string(const struct device_node *np, 313extern int of_property_read_string(const struct device_node *np,
310 const char *propname, 314 const char *propname,
@@ -380,6 +384,122 @@ extern int of_detach_node(struct device_node *);
380 384
381#define of_match_ptr(_ptr) (_ptr) 385#define of_match_ptr(_ptr) (_ptr)
382 386
387/**
388 * of_property_read_u8_array - Find and read an array of u8 from a property.
389 *
390 * @np: device node from which the property value is to be read.
391 * @propname: name of the property to be searched.
392 * @out_values: pointer to return value, modified only if return value is 0.
393 * @sz: number of array elements to read
394 *
395 * Search for a property in a device node and read 8-bit value(s) from
396 * it. Returns 0 on success, -EINVAL if the property does not exist,
397 * -ENODATA if property does not have a value, and -EOVERFLOW if the
398 * property data isn't large enough.
399 *
400 * dts entry of array should be like:
401 * property = /bits/ 8 <0x50 0x60 0x70>;
402 *
403 * The out_values is modified only if a valid u8 value can be decoded.
404 */
405static inline int of_property_read_u8_array(const struct device_node *np,
406 const char *propname,
407 u8 *out_values, size_t sz)
408{
409 int ret = of_property_read_variable_u8_array(np, propname, out_values,
410 sz, 0);
411 if (ret >= 0)
412 return 0;
413 else
414 return ret;
415}
416
417/**
418 * of_property_read_u16_array - Find and read an array of u16 from a property.
419 *
420 * @np: device node from which the property value is to be read.
421 * @propname: name of the property to be searched.
422 * @out_values: pointer to return value, modified only if return value is 0.
423 * @sz: number of array elements to read
424 *
425 * Search for a property in a device node and read 16-bit value(s) from
426 * it. Returns 0 on success, -EINVAL if the property does not exist,
427 * -ENODATA if property does not have a value, and -EOVERFLOW if the
428 * property data isn't large enough.
429 *
430 * dts entry of array should be like:
431 * property = /bits/ 16 <0x5000 0x6000 0x7000>;
432 *
433 * The out_values is modified only if a valid u16 value can be decoded.
434 */
435static inline int of_property_read_u16_array(const struct device_node *np,
436 const char *propname,
437 u16 *out_values, size_t sz)
438{
439 int ret = of_property_read_variable_u16_array(np, propname, out_values,
440 sz, 0);
441 if (ret >= 0)
442 return 0;
443 else
444 return ret;
445}
446
447/**
448 * of_property_read_u32_array - Find and read an array of 32 bit integers
449 * from a property.
450 *
451 * @np: device node from which the property value is to be read.
452 * @propname: name of the property to be searched.
453 * @out_values: pointer to return value, modified only if return value is 0.
454 * @sz: number of array elements to read
455 *
456 * Search for a property in a device node and read 32-bit value(s) from
457 * it. Returns 0 on success, -EINVAL if the property does not exist,
458 * -ENODATA if property does not have a value, and -EOVERFLOW if the
459 * property data isn't large enough.
460 *
461 * The out_values is modified only if a valid u32 value can be decoded.
462 */
463static inline int of_property_read_u32_array(const struct device_node *np,
464 const char *propname,
465 u32 *out_values, size_t sz)
466{
467 int ret = of_property_read_variable_u32_array(np, propname, out_values,
468 sz, 0);
469 if (ret >= 0)
470 return 0;
471 else
472 return ret;
473}
474
475/**
476 * of_property_read_u64_array - Find and read an array of 64 bit integers
477 * from a property.
478 *
479 * @np: device node from which the property value is to be read.
480 * @propname: name of the property to be searched.
481 * @out_values: pointer to return value, modified only if return value is 0.
482 * @sz: number of array elements to read
483 *
484 * Search for a property in a device node and read 64-bit value(s) from
485 * it. Returns 0 on success, -EINVAL if the property does not exist,
486 * -ENODATA if property does not have a value, and -EOVERFLOW if the
487 * property data isn't large enough.
488 *
489 * The out_values is modified only if a valid u64 value can be decoded.
490 */
491static inline int of_property_read_u64_array(const struct device_node *np,
492 const char *propname,
493 u64 *out_values, size_t sz)
494{
495 int ret = of_property_read_variable_u64_array(np, propname, out_values,
496 sz, 0);
497 if (ret >= 0)
498 return 0;
499 else
500 return ret;
501}
502
383/* 503/*
384 * struct property *prop; 504 * struct property *prop;
385 * const __be32 *p; 505 * const __be32 *p;