Commit 318a1971 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Rafael J. Wysocki
Browse files

device property: refactor built-in properties support



Instead of using the type and nval fields we will use length (in bytes) of the
value. The sanity check is done in the accessors.

The built-in property accessors are split in the same way such as device tree.

Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 61f5e294
Loading
Loading
Loading
Loading
+110 −40
Original line number Original line Diff line number Diff line
@@ -63,45 +63,107 @@ static struct property_entry *pset_prop_get(struct property_set *pset,
	return NULL;
	return NULL;
}
}


static int pset_prop_read_array(struct property_set *pset, const char *name,
static void *pset_prop_find(struct property_set *pset, const char *propname,
				enum dev_prop_type type, void *val, size_t nval)
			    size_t length)
{
{
	struct property_entry *prop;
	struct property_entry *prop;
	unsigned int item_size;
	void *pointer;


	prop = pset_prop_get(pset, name);
	prop = pset_prop_get(pset, propname);
	if (!prop)
	if (!prop)
		return -ENODATA;
		return ERR_PTR(-EINVAL);
	pointer = prop->value.raw_data;
	if (!pointer)
		return ERR_PTR(-ENODATA);
	if (length > prop->length)
		return ERR_PTR(-EOVERFLOW);
	return pointer;
}

static int pset_prop_read_u8_array(struct property_set *pset,
				   const char *propname,
				   u8 *values, size_t nval)
{
	void *pointer;
	size_t length = nval * sizeof(*values);


	if (prop->type != type)
	pointer = pset_prop_find(pset, propname, length);
		return -EPROTO;
	if (IS_ERR(pointer))
		return PTR_ERR(pointer);


	if (!val)
	memcpy(values, pointer, length);
		return prop->nval;
	return 0;
}


	if (prop->nval < nval)
static int pset_prop_read_u16_array(struct property_set *pset,
		return -EOVERFLOW;
				    const char *propname,
				    u16 *values, size_t nval)
{
	void *pointer;
	size_t length = nval * sizeof(*values);


	switch (type) {
	pointer = pset_prop_find(pset, propname, length);
	case DEV_PROP_U8:
	if (IS_ERR(pointer))
		item_size = sizeof(u8);
		return PTR_ERR(pointer);
		break;

	case DEV_PROP_U16:
	memcpy(values, pointer, length);
		item_size = sizeof(u16);
	return 0;
		break;
}
	case DEV_PROP_U32:

		item_size = sizeof(u32);
static int pset_prop_read_u32_array(struct property_set *pset,
		break;
				    const char *propname,
	case DEV_PROP_U64:
				    u32 *values, size_t nval)
		item_size = sizeof(u64);
{
		break;
	void *pointer;
	case DEV_PROP_STRING:
	size_t length = nval * sizeof(*values);
		item_size = sizeof(const char *);

		break;
	pointer = pset_prop_find(pset, propname, length);
	default:
	if (IS_ERR(pointer))
		return PTR_ERR(pointer);

	memcpy(values, pointer, length);
	return 0;
}

static int pset_prop_read_u64_array(struct property_set *pset,
				    const char *propname,
				    u64 *values, size_t nval)
{
	void *pointer;
	size_t length = nval * sizeof(*values);

	pointer = pset_prop_find(pset, propname, length);
	if (IS_ERR(pointer))
		return PTR_ERR(pointer);

	memcpy(values, pointer, length);
	return 0;
}

static int pset_prop_count_elems_of_size(struct property_set *pset,
					 const char *propname, size_t length)
{
	struct property_entry *prop;

	prop = pset_prop_get(pset, propname);
	if (!prop)
		return -EINVAL;
		return -EINVAL;

	return prop->length / length;
}
}
	memcpy(val, prop->value.raw_data, nval * item_size);

static int pset_prop_read_string_array(struct property_set *pset,
				       const char *propname,
				       const char **strings, size_t nval)
{
	void *pointer;
	size_t length = nval * sizeof(*strings);

	pointer = pset_prop_find(pset, propname, length);
	if (IS_ERR(pointer))
		return PTR_ERR(pointer);

	memcpy(strings, pointer, length);
	return 0;
	return 0;
}
}


@@ -314,6 +376,10 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
	(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))


#define PSET_PROP_READ_ARRAY(node, propname, type, val, nval)				\
	(val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval))	\
	      : pset_prop_count_elems_of_size((node), (propname), sizeof(type))

#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
({ \
({ \
	int _ret_; \
	int _ret_; \
@@ -324,8 +390,8 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
		_ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \
		_ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \
					    _val_, _nval_); \
					    _val_, _nval_); \
	else if (is_pset_node(_fwnode_)) 						\
	else if (is_pset_node(_fwnode_)) 						\
		_ret_ = pset_prop_read_array(to_pset_node(_fwnode_), _propname_,	\
		_ret_ = PSET_PROP_READ_ARRAY(to_pset_node(_fwnode_), _propname_,	\
					     _proptype_, _val_, _nval_); \
					     _type_, _val_, _nval_);			\
	else \
	else \
		_ret_ = -ENXIO; \
		_ret_ = -ENXIO; \
	_ret_; \
	_ret_; \
@@ -466,8 +532,12 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
					   val, nval);
					   val, nval);
	else if (is_pset_node(fwnode))
	else if (is_pset_node(fwnode))
		return pset_prop_read_array(to_pset_node(fwnode), propname,
		return val ?
					    DEV_PROP_STRING, val, nval);
			pset_prop_read_string_array(to_pset_node(fwnode),
						    propname, val, nval) :
			pset_prop_count_elems_of_size(to_pset_node(fwnode),
						      propname,
						      sizeof(const char *));
	return -ENXIO;
	return -ENXIO;
}
}
EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
@@ -496,8 +566,8 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode,
		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
					   val, 1);
					   val, 1);
	else if (is_pset_node(fwnode))
	else if (is_pset_node(fwnode))
		return pset_prop_read_array(to_pset_node(fwnode), propname,
		return pset_prop_read_string_array(to_pset_node(fwnode),
					    DEV_PROP_STRING, val, 1);
						   propname, val, 1);
	return -ENXIO;
	return -ENXIO;
}
}
EXPORT_SYMBOL_GPL(fwnode_property_read_string);
EXPORT_SYMBOL_GPL(fwnode_property_read_string);
+3 −5
Original line number Original line Diff line number Diff line
@@ -144,14 +144,12 @@ static inline int fwnode_property_read_u64(struct fwnode_handle *fwnode,
/**
/**
 * struct property_entry - "Built-in" device property representation.
 * struct property_entry - "Built-in" device property representation.
 * @name: Name of the property.
 * @name: Name of the property.
 * @type: Type of the property.
 * @length: Length of data making up the value.
 * @nval: Number of items of type @type making up the value.
 * @value: Value of the property (an array of items of the given type).
 * @value: Value of the property (an array of @nval items of type @type).
 */
 */
struct property_entry {
struct property_entry {
	const char *name;
	const char *name;
	enum dev_prop_type type;
	size_t length;
	size_t nval;
	union {
	union {
		void *raw_data;
		void *raw_data;
		u8 *u8_data;
		u8 *u8_data;