summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2015-11-30 17:11:32 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-12-07 02:29:22 +0100
commit66586baba56679baa2da1a10a96ccf15b1e96b95 (patch)
treee3d941455d6478cb071edc6ef307ba3f7b45fcf3
parent318a1971826103ecf560875b17236dd4a93e8c88 (diff)
device property: keep single value inplace
We may save a lot of lines of code and space by keeping single values inside the struct property_entry. Refactor the implementation to do so. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/base/property.c33
-rw-r--r--include/linux/property.h31
2 files changed, 53 insertions, 11 deletions
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 86834bde4585..ad3cb0982363 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -72,7 +72,10 @@ static void *pset_prop_find(struct property_set *pset, const char *propname,
prop = pset_prop_get(pset, propname);
if (!prop)
return ERR_PTR(-EINVAL);
- pointer = prop->value.raw_data;
+ if (prop->is_array)
+ pointer = prop->pointer.raw_data;
+ else
+ pointer = &prop->value.raw_data;
if (!pointer)
return ERR_PTR(-ENODATA);
if (length > prop->length)
@@ -167,6 +170,31 @@ static int pset_prop_read_string_array(struct property_set *pset,
return 0;
}
+static int pset_prop_read_string(struct property_set *pset,
+ const char *propname, const char **strings)
+{
+ struct property_entry *prop;
+ const char **pointer;
+
+ prop = pset_prop_get(pset, propname);
+ if (!prop)
+ return -EINVAL;
+ if (!prop->is_string)
+ return -EILSEQ;
+ if (prop->is_array) {
+ pointer = prop->pointer.str;
+ if (!pointer)
+ return -ENODATA;
+ } else {
+ pointer = &prop->value.str;
+ if (*pointer && strnlen(*pointer, prop->length) >= prop->length)
+ return -EILSEQ;
+ }
+
+ *strings = *pointer;
+ return 0;
+}
+
static inline struct fwnode_handle *dev_fwnode(struct device *dev)
{
return IS_ENABLED(CONFIG_OF) && dev->of_node ?
@@ -566,8 +594,7 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode,
return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
val, 1);
else if (is_pset_node(fwnode))
- return pset_prop_read_string_array(to_pset_node(fwnode),
- propname, val, 1);
+ return pset_prop_read_string(to_pset_node(fwnode), propname, val);
return -ENXIO;
}
EXPORT_SYMBOL_GPL(fwnode_property_read_string);
diff --git a/include/linux/property.h b/include/linux/property.h
index c29460a0e521..69a8a0817fd3 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -145,19 +145,34 @@ static inline int fwnode_property_read_u64(struct fwnode_handle *fwnode,
* struct property_entry - "Built-in" device property representation.
* @name: Name of the property.
* @length: Length of data making up the value.
- * @value: Value of the property (an array of items of the given type).
+ * @is_array: True when the property is an array.
+ * @is_string: True when property is a string.
+ * @pointer: Pointer to the property (an array of items of the given type).
+ * @value: Value of the property (when it is a single item of the given type).
*/
struct property_entry {
const char *name;
size_t length;
+ bool is_array;
+ bool is_string;
union {
- void *raw_data;
- u8 *u8_data;
- u16 *u16_data;
- u32 *u32_data;
- u64 *u64_data;
- const char **str;
- } value;
+ union {
+ void *raw_data;
+ u8 *u8_data;
+ u16 *u16_data;
+ u32 *u32_data;
+ u64 *u64_data;
+ const char **str;
+ } pointer;
+ union {
+ unsigned long long raw_data;
+ u8 u8_data;
+ u16 u16_data;
+ u32 u32_data;
+ u64 u64_data;
+ const char *str;
+ } value;
+ };
};
/**