device property: keep single value inplace
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Mon, 30 Nov 2015 15:11:32 +0000 (17:11 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 7 Dec 2015 01:29:22 +0000 (02:29 +0100)
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>
drivers/base/property.c
include/linux/property.h

index 86834bd..ad3cb09 100644 (file)
@@ -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);
index c29460a..69a8a08 100644 (file)
@@ -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;
+       };
 };
 
 /**