aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-05 13:13:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-05 13:13:13 -0400
commita74e0c4c9cb02d44bc5ec1a70a6ba599366fb130 (patch)
tree5c55e103af8770a8b9dcfff48e8bac0074ecd083 /drivers
parentf4fe74cc909bf811cd9cc7fd84f5a7514e06a7e1 (diff)
parent63dcc7090137a893322432e156d66be3ce104615 (diff)
Merge tag 'dp-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull device properties framework update from Rafael Wysocki: "Modify the device properties framework to remove union aliasing from it (Andy Shevchenko)" * tag 'dp-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: device property: Get rid of union aliasing
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/property.c104
-rw-r--r--drivers/firmware/efi/apple-properties.c8
2 files changed, 92 insertions, 20 deletions
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 8f205f6461ed..240ab5230ff6 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -56,6 +56,72 @@ pset_prop_get(const struct property_set *pset, const char *name)
56 return NULL; 56 return NULL;
57} 57}
58 58
59static const void *property_get_pointer(const struct property_entry *prop)
60{
61 switch (prop->type) {
62 case DEV_PROP_U8:
63 if (prop->is_array)
64 return prop->pointer.u8_data;
65 return &prop->value.u8_data;
66 case DEV_PROP_U16:
67 if (prop->is_array)
68 return prop->pointer.u16_data;
69 return &prop->value.u16_data;
70 case DEV_PROP_U32:
71 if (prop->is_array)
72 return prop->pointer.u32_data;
73 return &prop->value.u32_data;
74 case DEV_PROP_U64:
75 if (prop->is_array)
76 return prop->pointer.u64_data;
77 return &prop->value.u64_data;
78 case DEV_PROP_STRING:
79 if (prop->is_array)
80 return prop->pointer.str;
81 return &prop->value.str;
82 default:
83 return NULL;
84 }
85}
86
87static void property_set_pointer(struct property_entry *prop, const void *pointer)
88{
89 switch (prop->type) {
90 case DEV_PROP_U8:
91 if (prop->is_array)
92 prop->pointer.u8_data = pointer;
93 else
94 prop->value.u8_data = *((u8 *)pointer);
95 break;
96 case DEV_PROP_U16:
97 if (prop->is_array)
98 prop->pointer.u16_data = pointer;
99 else
100 prop->value.u16_data = *((u16 *)pointer);
101 break;
102 case DEV_PROP_U32:
103 if (prop->is_array)
104 prop->pointer.u32_data = pointer;
105 else
106 prop->value.u32_data = *((u32 *)pointer);
107 break;
108 case DEV_PROP_U64:
109 if (prop->is_array)
110 prop->pointer.u64_data = pointer;
111 else
112 prop->value.u64_data = *((u64 *)pointer);
113 break;
114 case DEV_PROP_STRING:
115 if (prop->is_array)
116 prop->pointer.str = pointer;
117 else
118 prop->value.str = pointer;
119 break;
120 default:
121 break;
122 }
123}
124
59static const void *pset_prop_find(const struct property_set *pset, 125static const void *pset_prop_find(const struct property_set *pset,
60 const char *propname, size_t length) 126 const char *propname, size_t length)
61{ 127{
@@ -65,10 +131,7 @@ static const void *pset_prop_find(const struct property_set *pset,
65 prop = pset_prop_get(pset, propname); 131 prop = pset_prop_get(pset, propname);
66 if (!prop) 132 if (!prop)
67 return ERR_PTR(-EINVAL); 133 return ERR_PTR(-EINVAL);
68 if (prop->is_array) 134 pointer = property_get_pointer(prop);
69 pointer = prop->pointer.raw_data;
70 else
71 pointer = &prop->value.raw_data;
72 if (!pointer) 135 if (!pointer)
73 return ERR_PTR(-ENODATA); 136 return ERR_PTR(-ENODATA);
74 if (length > prop->length) 137 if (length > prop->length)
@@ -698,16 +761,17 @@ EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args);
698 761
699static void property_entry_free_data(const struct property_entry *p) 762static void property_entry_free_data(const struct property_entry *p)
700{ 763{
764 const void *pointer = property_get_pointer(p);
701 size_t i, nval; 765 size_t i, nval;
702 766
703 if (p->is_array) { 767 if (p->is_array) {
704 if (p->is_string && p->pointer.str) { 768 if (p->type == DEV_PROP_STRING && p->pointer.str) {
705 nval = p->length / sizeof(const char *); 769 nval = p->length / sizeof(const char *);
706 for (i = 0; i < nval; i++) 770 for (i = 0; i < nval; i++)
707 kfree(p->pointer.str[i]); 771 kfree(p->pointer.str[i]);
708 } 772 }
709 kfree(p->pointer.raw_data); 773 kfree(pointer);
710 } else if (p->is_string) { 774 } else if (p->type == DEV_PROP_STRING) {
711 kfree(p->value.str); 775 kfree(p->value.str);
712 } 776 }
713 kfree(p->name); 777 kfree(p->name);
@@ -716,7 +780,7 @@ static void property_entry_free_data(const struct property_entry *p)
716static int property_copy_string_array(struct property_entry *dst, 780static int property_copy_string_array(struct property_entry *dst,
717 const struct property_entry *src) 781 const struct property_entry *src)
718{ 782{
719 char **d; 783 const char **d;
720 size_t nval = src->length / sizeof(*d); 784 size_t nval = src->length / sizeof(*d);
721 int i; 785 int i;
722 786
@@ -734,40 +798,44 @@ static int property_copy_string_array(struct property_entry *dst,
734 } 798 }
735 } 799 }
736 800
737 dst->pointer.raw_data = d; 801 dst->pointer.str = d;
738 return 0; 802 return 0;
739} 803}
740 804
741static int property_entry_copy_data(struct property_entry *dst, 805static int property_entry_copy_data(struct property_entry *dst,
742 const struct property_entry *src) 806 const struct property_entry *src)
743{ 807{
808 const void *pointer = property_get_pointer(src);
809 const void *new;
744 int error; 810 int error;
745 811
746 if (src->is_array) { 812 if (src->is_array) {
747 if (!src->length) 813 if (!src->length)
748 return -ENODATA; 814 return -ENODATA;
749 815
750 if (src->is_string) { 816 if (src->type == DEV_PROP_STRING) {
751 error = property_copy_string_array(dst, src); 817 error = property_copy_string_array(dst, src);
752 if (error) 818 if (error)
753 return error; 819 return error;
820 new = dst->pointer.str;
754 } else { 821 } else {
755 dst->pointer.raw_data = kmemdup(src->pointer.raw_data, 822 new = kmemdup(pointer, src->length, GFP_KERNEL);
756 src->length, GFP_KERNEL); 823 if (!new)
757 if (!dst->pointer.raw_data)
758 return -ENOMEM; 824 return -ENOMEM;
759 } 825 }
760 } else if (src->is_string) { 826 } else if (src->type == DEV_PROP_STRING) {
761 dst->value.str = kstrdup(src->value.str, GFP_KERNEL); 827 new = kstrdup(src->value.str, GFP_KERNEL);
762 if (!dst->value.str && src->value.str) 828 if (!new && src->value.str)
763 return -ENOMEM; 829 return -ENOMEM;
764 } else { 830 } else {
765 dst->value.raw_data = src->value.raw_data; 831 new = pointer;
766 } 832 }
767 833
768 dst->length = src->length; 834 dst->length = src->length;
769 dst->is_array = src->is_array; 835 dst->is_array = src->is_array;
770 dst->is_string = src->is_string; 836 dst->type = src->type;
837
838 property_set_pointer(dst, new);
771 839
772 dst->name = kstrdup(src->name, GFP_KERNEL); 840 dst->name = kstrdup(src->name, GFP_KERNEL);
773 if (!dst->name) 841 if (!dst->name)
diff --git a/drivers/firmware/efi/apple-properties.c b/drivers/firmware/efi/apple-properties.c
index adaa9a3714b9..60a95719ecb8 100644
--- a/drivers/firmware/efi/apple-properties.c
+++ b/drivers/firmware/efi/apple-properties.c
@@ -13,6 +13,9 @@
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 *
17 * Note, all properties are considered as u8 arrays.
18 * To get a value of any of them the caller must use device_property_read_u8_array().
16 */ 19 */
17 20
18#define pr_fmt(fmt) "apple-properties: " fmt 21#define pr_fmt(fmt) "apple-properties: " fmt
@@ -96,12 +99,13 @@ static void __init unmarshal_key_value_pairs(struct dev_header *dev_header,
96 entry[i].name = key; 99 entry[i].name = key;
97 entry[i].length = val_len - sizeof(val_len); 100 entry[i].length = val_len - sizeof(val_len);
98 entry[i].is_array = !!entry[i].length; 101 entry[i].is_array = !!entry[i].length;
99 entry[i].pointer.raw_data = ptr + key_len + sizeof(val_len); 102 entry[i].type = DEV_PROP_U8;
103 entry[i].pointer.u8_data = ptr + key_len + sizeof(val_len);
100 104
101 if (dump_properties) { 105 if (dump_properties) {
102 dev_info(dev, "property: %s\n", entry[i].name); 106 dev_info(dev, "property: %s\n", entry[i].name);
103 print_hex_dump(KERN_INFO, pr_fmt(), DUMP_PREFIX_OFFSET, 107 print_hex_dump(KERN_INFO, pr_fmt(), DUMP_PREFIX_OFFSET,
104 16, 1, entry[i].pointer.raw_data, 108 16, 1, entry[i].pointer.u8_data,
105 entry[i].length, true); 109 entry[i].length, true);
106 } 110 }
107 111