1324 lines · 41.4 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0/* * property.c - Unified device property interface. * * Copyright (C) 2014, Intel Corporation * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com> *          Mika Westerberg <mika.westerberg@linux.intel.com> */ #include <linux/acpi.h>#include <linux/export.h>#include <linux/kernel.h>#include <linux/of.h>#include <linux/of_address.h>#include <linux/of_graph.h>#include <linux/of_irq.h>#include <linux/property.h>#include <linux/etherdevice.h>#include <linux/phy.h> struct fwnode_handle *dev_fwnode(struct device *dev){	return IS_ENABLED(CONFIG_OF) && dev->of_node ?		&dev->of_node->fwnode : dev->fwnode;}EXPORT_SYMBOL_GPL(dev_fwnode); /** * device_property_present - check if a property of a device is present * @dev: Device whose property is being checked * @propname: Name of the property * * Check if property @propname is present in the device firmware description. */bool device_property_present(struct device *dev, const char *propname){	return fwnode_property_present(dev_fwnode(dev), propname);}EXPORT_SYMBOL_GPL(device_property_present); /** * fwnode_property_present - check if a property of a firmware node is present * @fwnode: Firmware node whose property to check * @propname: Name of the property */bool fwnode_property_present(const struct fwnode_handle *fwnode,			     const char *propname){	bool ret; 	ret = fwnode_call_bool_op(fwnode, property_present, propname);	if (ret == false && !IS_ERR_OR_NULL(fwnode) &&	    !IS_ERR_OR_NULL(fwnode->secondary))		ret = fwnode_call_bool_op(fwnode->secondary, property_present,					 propname);	return ret;}EXPORT_SYMBOL_GPL(fwnode_property_present); /** * device_property_read_u8_array - return a u8 array property of a device * @dev: Device to get the property of * @propname: Name of the property * @val: The values are stored here or %NULL to return the number of values * @nval: Size of the @val array * * Function reads an array of u8 properties with @propname from the device * firmware description and stores them to @val if found. * * Return: number of values if @val was %NULL, *         %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 numbers, *	   %-EOVERFLOW if the size of the property is not as expected. *	   %-ENXIO if no suitable firmware interface is present. */int device_property_read_u8_array(struct device *dev, const char *propname,				  u8 *val, size_t nval){	return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval);}EXPORT_SYMBOL_GPL(device_property_read_u8_array); /** * device_property_read_u16_array - return a u16 array property of a device * @dev: Device to get the property of * @propname: Name of the property * @val: The values are stored here or %NULL to return the number of values * @nval: Size of the @val array * * Function reads an array of u16 properties with @propname from the device * firmware description and stores them to @val if found. * * Return: number of values if @val was %NULL, *         %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 numbers, *	   %-EOVERFLOW if the size of the property is not as expected. *	   %-ENXIO if no suitable firmware interface is present. */int device_property_read_u16_array(struct device *dev, const char *propname,				   u16 *val, size_t nval){	return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval);}EXPORT_SYMBOL_GPL(device_property_read_u16_array); /** * device_property_read_u32_array - return a u32 array property of a device * @dev: Device to get the property of * @propname: Name of the property * @val: The values are stored here or %NULL to return the number of values * @nval: Size of the @val array * * Function reads an array of u32 properties with @propname from the device * firmware description and stores them to @val if found. * * Return: number of values if @val was %NULL, *         %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 numbers, *	   %-EOVERFLOW if the size of the property is not as expected. *	   %-ENXIO if no suitable firmware interface is present. */int device_property_read_u32_array(struct device *dev, const char *propname,				   u32 *val, size_t nval){	return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval);}EXPORT_SYMBOL_GPL(device_property_read_u32_array); /** * device_property_read_u64_array - return a u64 array property of a device * @dev: Device to get the property of * @propname: Name of the property * @val: The values are stored here or %NULL to return the number of values * @nval: Size of the @val array * * Function reads an array of u64 properties with @propname from the device * firmware description and stores them to @val if found. * * Return: number of values if @val was %NULL, *         %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 numbers, *	   %-EOVERFLOW if the size of the property is not as expected. *	   %-ENXIO if no suitable firmware interface is present. */int device_property_read_u64_array(struct device *dev, const char *propname,				   u64 *val, size_t nval){	return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval);}EXPORT_SYMBOL_GPL(device_property_read_u64_array); /** * device_property_read_string_array - return a string array property of device * @dev: Device to get the property of * @propname: Name of the property * @val: The values are stored here or %NULL to return the number of values * @nval: Size of the @val array * * Function reads an array of string properties with @propname from the device * firmware description and stores them to @val if found. * * Return: number of values read on success if @val is non-NULL, *	   number of values available on success if @val is NULL, *	   %-EINVAL if given arguments are not valid, *	   %-ENODATA if the property does not have a value, *	   %-EPROTO or %-EILSEQ if the property is not an array of strings, *	   %-EOVERFLOW if the size of the property is not as expected. *	   %-ENXIO if no suitable firmware interface is present. */int device_property_read_string_array(struct device *dev, const char *propname,				      const char **val, size_t nval){	return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval);}EXPORT_SYMBOL_GPL(device_property_read_string_array); /** * device_property_read_string - return a string property of a device * @dev: Device to get the property of * @propname: Name of the property * @val: The value is stored here * * Function reads property @propname from the device firmware description and * stores the value into @val if found. The value is checked to be a string. * * 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 or %-EILSEQ if the property type is not a string. *	   %-ENXIO if no suitable firmware interface is present. */int device_property_read_string(struct device *dev, const char *propname,				const char **val){	return fwnode_property_read_string(dev_fwnode(dev), propname, val);}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); static int fwnode_property_read_int_array(const struct fwnode_handle *fwnode,					  const char *propname,					  unsigned int elem_size, void *val,					  size_t nval){	int ret; 	ret = fwnode_call_int_op(fwnode, property_read_int_array, propname,				 elem_size, val, nval);	if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&	    !IS_ERR_OR_NULL(fwnode->secondary))		ret = fwnode_call_int_op(			fwnode->secondary, property_read_int_array, propname,			elem_size, val, nval); 	return ret;} /** * fwnode_property_read_u8_array - return a u8 array property of firmware node * @fwnode: Firmware node to get the property of * @propname: Name of the property * @val: The values are stored here or %NULL to return the number of values * @nval: Size of the @val array * * Read an array of u8 properties with @propname from @fwnode and stores them to * @val if found. * * Return: number of values if @val was %NULL, *         %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 numbers, *	   %-EOVERFLOW if the size of the property is not as expected, *	   %-ENXIO if no suitable firmware interface is present. */int fwnode_property_read_u8_array(const struct fwnode_handle *fwnode,				  const char *propname, u8 *val, size_t nval){	return fwnode_property_read_int_array(fwnode, propname, sizeof(u8),					      val, nval);}EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array); /** * fwnode_property_read_u16_array - return a u16 array property of firmware node * @fwnode: Firmware node to get the property of * @propname: Name of the property * @val: The values are stored here or %NULL to return the number of values * @nval: Size of the @val array * * Read an array of u16 properties with @propname from @fwnode and store them to * @val if found. * * Return: number of values if @val was %NULL, *         %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 numbers, *	   %-EOVERFLOW if the size of the property is not as expected, *	   %-ENXIO if no suitable firmware interface is present. */int fwnode_property_read_u16_array(const struct fwnode_handle *fwnode,				   const char *propname, u16 *val, size_t nval){	return fwnode_property_read_int_array(fwnode, propname, sizeof(u16),					      val, nval);}EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array); /** * fwnode_property_read_u32_array - return a u32 array property of firmware node * @fwnode: Firmware node to get the property of * @propname: Name of the property * @val: The values are stored here or %NULL to return the number of values * @nval: Size of the @val array * * Read an array of u32 properties with @propname from @fwnode store them to * @val if found. * * Return: number of values if @val was %NULL, *         %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 numbers, *	   %-EOVERFLOW if the size of the property is not as expected, *	   %-ENXIO if no suitable firmware interface is present. */int fwnode_property_read_u32_array(const struct fwnode_handle *fwnode,				   const char *propname, u32 *val, size_t nval){	return fwnode_property_read_int_array(fwnode, propname, sizeof(u32),					      val, nval);}EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array); /** * fwnode_property_read_u64_array - return a u64 array property firmware node * @fwnode: Firmware node to get the property of * @propname: Name of the property * @val: The values are stored here or %NULL to return the number of values * @nval: Size of the @val array * * Read an array of u64 properties with @propname from @fwnode and store them to * @val if found. * * Return: number of values if @val was %NULL, *         %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 numbers, *	   %-EOVERFLOW if the size of the property is not as expected, *	   %-ENXIO if no suitable firmware interface is present. */int fwnode_property_read_u64_array(const struct fwnode_handle *fwnode,				   const char *propname, u64 *val, size_t nval){	return fwnode_property_read_int_array(fwnode, propname, sizeof(u64),					      val, nval);}EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array); /** * fwnode_property_read_string_array - return string array property of a node * @fwnode: Firmware node to get the property of * @propname: Name of the property * @val: The values are stored here or %NULL to return the number of values * @nval: Size of the @val array * * Read an string list property @propname from the given firmware node and store * them to @val if found. * * Return: number of values read on success if @val is non-NULL, *	   number of values available on success if @val is NULL, *	   %-EINVAL if given arguments are not valid, *	   %-ENODATA if the property does not have a value, *	   %-EPROTO or %-EILSEQ if the property is not an array of strings, *	   %-EOVERFLOW if the size of the property is not as expected, *	   %-ENXIO if no suitable firmware interface is present. */int fwnode_property_read_string_array(const struct fwnode_handle *fwnode,				      const char *propname, const char **val,				      size_t nval){	int ret; 	ret = fwnode_call_int_op(fwnode, property_read_string_array, propname,				 val, nval);	if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&	    !IS_ERR_OR_NULL(fwnode->secondary))		ret = fwnode_call_int_op(fwnode->secondary,					 property_read_string_array, propname,					 val, nval);	return ret;}EXPORT_SYMBOL_GPL(fwnode_property_read_string_array); /** * fwnode_property_read_string - return a string property of a firmware node * @fwnode: Firmware node to get the property of * @propname: Name of the property * @val: The value is stored here * * Read property @propname from the given firmware node and store the value into * @val if found.  The value is checked to be a string. * * 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 or %-EILSEQ if the property is not a string, *	   %-ENXIO if no suitable firmware interface is present. */int fwnode_property_read_string(const struct fwnode_handle *fwnode,				const char *propname, const char **val){	int ret = fwnode_property_read_string_array(fwnode, propname, val, 1); 	return ret < 0 ? ret : 0;}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(const struct fwnode_handle *fwnode,	const char *propname, const char *string){	const char **values;	int nval, ret; 	nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0);	if (nval < 0)		return nval; 	if (nval == 0)		return -ENODATA; 	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 = match_string(values, nval, string);	if (ret < 0)		ret = -ENODATA;out:	kfree(values);	return ret;}EXPORT_SYMBOL_GPL(fwnode_property_match_string); /** * fwnode_property_get_reference_args() - Find a reference with arguments * @fwnode:	Firmware node where to look for the reference * @prop:	The name of the property * @nargs_prop:	The name of the property telling the number of *		arguments in the referred node. NULL if @nargs is known, *		otherwise @nargs is ignored. Only relevant on OF. * @nargs:	Number of arguments. Ignored if @nargs_prop is non-NULL. * @index:	Index of the reference, from zero onwards. * @args:	Result structure with reference and integer arguments. * * Obtain a reference based on a named property in an fwnode, with * integer arguments. * * Caller is responsible to call fwnode_handle_put() on the returned * args->fwnode pointer. * * Returns: %0 on success *	    %-ENOENT when the index is out of bounds, the index has an empty *		     reference or the property was not found *	    %-EINVAL on parse error */int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,				       const char *prop, const char *nargs_prop,				       unsigned int nargs, unsigned int index,				       struct fwnode_reference_args *args){	return fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop,				  nargs, index, args);}EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args); /** * fwnode_find_reference - Find named reference to a fwnode_handle * @fwnode: Firmware node where to look for the reference * @name: The name of the reference * @index: Index of the reference * * @index can be used when the named reference holds a table of references. * * Returns pointer to the reference fwnode, or ERR_PTR. Caller is responsible to * call fwnode_handle_put() on the returned fwnode pointer. */struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode,					    const char *name,					    unsigned int index)

Lines 1–500 of 1324.