diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2015-09-14 16:37:35 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-09-25 02:00:19 +0200 |
commit | 3f5c8d3187852b1cbed8546169e6293d6d421751 (patch) | |
tree | 72bde461108542c7afb05753288a442c80d03e4c /drivers/base/property.c | |
parent | ACPI / property: Extend device_get_next_child_node() to data-only nodes (diff) | |
download | linux-3f5c8d3187852b1cbed8546169e6293d6d421751.tar.xz linux-3f5c8d3187852b1cbed8546169e6293d6d421751.zip |
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>
Diffstat (limited to 'drivers/base/property.c')
-rw-r--r-- | drivers/base/property.c | 68 |
1 files changed, 68 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, } EXPORT_SYMBOL_GPL(device_property_read_string); +/** + * device_property_match_string - find a string in an array and return index + * @dev: Device to get the property of + * @propname: Name of the property holding the array + * @string: String to look for + * + * Find a given string in a string array and if it is found return the + * index back. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO if the property is not an array of strings, + * %-ENXIO if no suitable firmware interface is present. + */ +int device_property_match_string(struct device *dev, const char *propname, + const char *string) +{ + return fwnode_property_match_string(dev_fwnode(dev), propname, string); +} +EXPORT_SYMBOL_GPL(device_property_match_string); + #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ : of_property_count_elems_of_size((node), (propname), sizeof(type)) @@ -479,6 +501,52 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode, EXPORT_SYMBOL_GPL(fwnode_property_read_string); /** + * fwnode_property_match_string - find a string in an array and return index + * @fwnode: Firmware node to get the property of + * @propname: Name of the property holding the array + * @string: String to look for + * + * Find a given string in a string array and if it is found return the + * index back. + * + * Return: %0 if the property was found (success), + * %-EINVAL if given arguments are not valid, + * %-ENODATA if the property does not have a value, + * %-EPROTO if the property is not an array of strings, + * %-ENXIO if no suitable firmware interface is present. + */ +int fwnode_property_match_string(struct fwnode_handle *fwnode, + const char *propname, const char *string) +{ + const char **values; + int nval, ret, i; + + nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0); + if (nval < 0) + return nval; + + values = kcalloc(nval, sizeof(*values), GFP_KERNEL); + if (!values) + return -ENOMEM; + + ret = fwnode_property_read_string_array(fwnode, propname, values, nval); + if (ret < 0) + goto out; + + ret = -ENODATA; + for (i = 0; i < nval; i++) { + if (!strcmp(values[i], string)) { + ret = i; + break; + } + } +out: + kfree(values); + return ret; +} +EXPORT_SYMBOL_GPL(fwnode_property_match_string); + +/** * device_get_next_child_node - Return the next child node handle for a device * @dev: Device to find the next child node for. * @child: Handle to one of the device's child nodes or a null handle. |