Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f5c8d31 authored by Mika Westerberg's avatar Mika Westerberg Committed by Rafael J. Wysocki
Browse files

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: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 504a3374
Loading
Loading
Loading
Loading
+68 −0
Original line number Original line Diff line number Diff line
@@ -287,6 +287,28 @@ int device_property_read_string(struct device *dev, const char *propname,
}
}
EXPORT_SYMBOL_GPL(device_property_read_string);
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) \
#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
	(val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
	(val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
	      : of_property_count_elems_of_size((node), (propname), sizeof(type))
	      : of_property_count_elems_of_size((node), (propname), sizeof(type))
@@ -478,6 +500,52 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode,
}
}
EXPORT_SYMBOL_GPL(fwnode_property_read_string);
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
 * device_get_next_child_node - Return the next child node handle for a device
 * @dev: Device to find the next child node for.
 * @dev: Device to find the next child node for.
+4 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,8 @@ int device_property_read_string_array(struct device *dev, const char *propname,
				      const char **val, size_t nval);
				      const char **val, size_t nval);
int device_property_read_string(struct device *dev, const char *propname,
int device_property_read_string(struct device *dev, const char *propname,
				const char **val);
				const char **val);
int device_property_match_string(struct device *dev,
				 const char *propname, const char *string);


bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname);
bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname);
int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
@@ -59,6 +61,8 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
				      size_t nval);
				      size_t nval);
int fwnode_property_read_string(struct fwnode_handle *fwnode,
int fwnode_property_read_string(struct fwnode_handle *fwnode,
				const char *propname, const char **val);
				const char *propname, const char **val);
int fwnode_property_match_string(struct fwnode_handle *fwnode,
				 const char *propname, const char *string);


struct fwnode_handle *device_get_next_child_node(struct device *dev,
struct fwnode_handle *device_get_next_child_node(struct device *dev,
						 struct fwnode_handle *child);
						 struct fwnode_handle *child);