diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2015-09-14 10:37:35 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-09-24 20:00:19 -0400 |
commit | 3f5c8d3187852b1cbed8546169e6293d6d421751 (patch) | |
tree | 72bde461108542c7afb05753288a442c80d03e4c | |
parent | 504a33749971c36c54ba5ccb1364872dee1f17a7 (diff) |
device property: Add fwnode_property_match_string()
Sometimes it is useful to be able to extract an index of certain string
value from an array of strings. A typical use case is to give a name to a
DMA channel, PWM, clock and so on.
Provide an implementation using unified device property accessors that
follows of_property_match_string() but works for all supported fwnodes.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/base/property.c | 68 | ||||
-rw-r--r-- | include/linux/property.h | 4 |
2 files changed, 72 insertions, 0 deletions
diff --git a/drivers/base/property.c b/drivers/base/property.c index 660ecec60bdf..de40623bbd8a 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c | |||
@@ -287,6 +287,28 @@ int device_property_read_string(struct device *dev, const char *propname, | |||
287 | } | 287 | } |
288 | EXPORT_SYMBOL_GPL(device_property_read_string); | 288 | EXPORT_SYMBOL_GPL(device_property_read_string); |
289 | 289 | ||
290 | /** | ||
291 | * device_property_match_string - find a string in an array and return index | ||
292 | * @dev: Device to get the property of | ||
293 | * @propname: Name of the property holding the array | ||
294 | * @string: String to look for | ||
295 | * | ||
296 | * Find a given string in a string array and if it is found return the | ||
297 | * index back. | ||
298 | * | ||
299 | * Return: %0 if the property was found (success), | ||
300 | * %-EINVAL if given arguments are not valid, | ||
301 | * %-ENODATA if the property does not have a value, | ||
302 | * %-EPROTO if the property is not an array of strings, | ||
303 | * %-ENXIO if no suitable firmware interface is present. | ||
304 | */ | ||
305 | int device_property_match_string(struct device *dev, const char *propname, | ||
306 | const char *string) | ||
307 | { | ||
308 | return fwnode_property_match_string(dev_fwnode(dev), propname, string); | ||
309 | } | ||
310 | EXPORT_SYMBOL_GPL(device_property_match_string); | ||
311 | |||
290 | #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ | 312 | #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ |
291 | (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ | 313 | (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ |
292 | : of_property_count_elems_of_size((node), (propname), sizeof(type)) | 314 | : of_property_count_elems_of_size((node), (propname), sizeof(type)) |
@@ -479,6 +501,52 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode, | |||
479 | EXPORT_SYMBOL_GPL(fwnode_property_read_string); | 501 | EXPORT_SYMBOL_GPL(fwnode_property_read_string); |
480 | 502 | ||
481 | /** | 503 | /** |
504 | * fwnode_property_match_string - find a string in an array and return index | ||
505 | * @fwnode: Firmware node to get the property of | ||
506 | * @propname: Name of the property holding the array | ||
507 | * @string: String to look for | ||
508 | * | ||
509 | * Find a given string in a string array and if it is found return the | ||
510 | * index back. | ||
511 | * | ||
512 | * Return: %0 if the property was found (success), | ||
513 | * %-EINVAL if given arguments are not valid, | ||
514 | * %-ENODATA if the property does not have a value, | ||
515 | * %-EPROTO if the property is not an array of strings, | ||
516 | * %-ENXIO if no suitable firmware interface is present. | ||
517 | */ | ||
518 | int fwnode_property_match_string(struct fwnode_handle *fwnode, | ||
519 | const char *propname, const char *string) | ||
520 | { | ||
521 | const char **values; | ||
522 | int nval, ret, i; | ||
523 | |||
524 | nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0); | ||
525 | if (nval < 0) | ||
526 | return nval; | ||
527 | |||
528 | values = kcalloc(nval, sizeof(*values), GFP_KERNEL); | ||
529 | if (!values) | ||
530 | return -ENOMEM; | ||
531 | |||
532 | ret = fwnode_property_read_string_array(fwnode, propname, values, nval); | ||
533 | if (ret < 0) | ||
534 | goto out; | ||
535 | |||
536 | ret = -ENODATA; | ||
537 | for (i = 0; i < nval; i++) { | ||
538 | if (!strcmp(values[i], string)) { | ||
539 | ret = i; | ||
540 | break; | ||
541 | } | ||
542 | } | ||
543 | out: | ||
544 | kfree(values); | ||
545 | return ret; | ||
546 | } | ||
547 | EXPORT_SYMBOL_GPL(fwnode_property_match_string); | ||
548 | |||
549 | /** | ||
482 | * device_get_next_child_node - Return the next child node handle for a device | 550 | * device_get_next_child_node - Return the next child node handle for a device |
483 | * @dev: Device to find the next child node for. | 551 | * @dev: Device to find the next child node for. |
484 | * @child: Handle to one of the device's child nodes or a null handle. | 552 | * @child: Handle to one of the device's child nodes or a null handle. |
diff --git a/include/linux/property.h b/include/linux/property.h index a59c6ee566c2..463de52fe891 100644 --- a/include/linux/property.h +++ b/include/linux/property.h | |||
@@ -40,6 +40,8 @@ int device_property_read_string_array(struct device *dev, const char *propname, | |||
40 | const char **val, size_t nval); | 40 | const char **val, size_t nval); |
41 | int device_property_read_string(struct device *dev, const char *propname, | 41 | int device_property_read_string(struct device *dev, const char *propname, |
42 | const char **val); | 42 | const char **val); |
43 | int device_property_match_string(struct device *dev, | ||
44 | const char *propname, const char *string); | ||
43 | 45 | ||
44 | bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname); | 46 | bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname); |
45 | int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, | 47 | int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, |
@@ -59,6 +61,8 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode, | |||
59 | size_t nval); | 61 | size_t nval); |
60 | int fwnode_property_read_string(struct fwnode_handle *fwnode, | 62 | int fwnode_property_read_string(struct fwnode_handle *fwnode, |
61 | const char *propname, const char **val); | 63 | const char *propname, const char **val); |
64 | int fwnode_property_match_string(struct fwnode_handle *fwnode, | ||
65 | const char *propname, const char *string); | ||
62 | 66 | ||
63 | struct fwnode_handle *device_get_next_child_node(struct device *dev, | 67 | struct fwnode_handle *device_get_next_child_node(struct device *dev, |
64 | struct fwnode_handle *child); | 68 | struct fwnode_handle *child); |