mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-20 05:31:15 +00:00
Device properties framework update for 4.18-rc1
Modify the device properties framework to remove union aliasing from it (Andy Shevchenko). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJbFR5eAAoJEILEb/54YlRxLYIP/2WQ/h1q3UQwnaKNuaWvLUE0 SlLoczpNZ40QENliBg/q9DwGf0ivq7ewO+J7kvZl4CLHbAXJCSPMPtOhKpZqCC/+ bteNHfPRMBOMYwKdduXgVAQLGkti20VyW5q5+ya7mfK2sLHGAcvxZnUY/0QmGM9m YRk19Kzy8bsDQJLkzW6dsUhXdiiT8J0zw8AqcCi/T1t9rrpRO1N1CQ3WOCe8EIpo PPR5+dTDWydnCXf25POXrD3RAkDqM9VErv8kRn9frwg/8OcEvmUWF6jYvIzQEjEZ zixIIKR57xlGJVwTsKz4tHxoJvb3pwRc2fYolwNeWJT3kw3ZLwHmtu8rEU5fD775 B9n5gazJ+bYbkTPVK+gk9x9EyV+83nqSGjDvg0qLwTKjC3kKdrbPQbGSyKS922Hh Zuuum25B6RiRRtRwz64FbImGl1tfV+HhwUurK6rmowoeLoTEgd0OXUF+uXN822oW hiZEqQgr2FmoQkb8zqJfQnos7K88kDAcijBEYBVM+kcyoy/zr6wSM71wO+X6D5eY qL8dc4ycSAD9jhPqOjMpphvC8aTT606VLaTlz8lCmFO7eRVfEBGZdS8CPupGCEML kaC3OHMh+J+gF8b3v5c5rCwOfNM4Yp8FyCQ7RrGBradjNrrdWAKgLLa+70AqOv6B mkMDLVmXn61AKbBycgdw =snbq -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
a74e0c4c9c
3 changed files with 117 additions and 47 deletions
|
@ -56,6 +56,72 @@ pset_prop_get(const struct property_set *pset, const char *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const void *property_get_pointer(const struct property_entry *prop)
|
||||||
|
{
|
||||||
|
switch (prop->type) {
|
||||||
|
case DEV_PROP_U8:
|
||||||
|
if (prop->is_array)
|
||||||
|
return prop->pointer.u8_data;
|
||||||
|
return &prop->value.u8_data;
|
||||||
|
case DEV_PROP_U16:
|
||||||
|
if (prop->is_array)
|
||||||
|
return prop->pointer.u16_data;
|
||||||
|
return &prop->value.u16_data;
|
||||||
|
case DEV_PROP_U32:
|
||||||
|
if (prop->is_array)
|
||||||
|
return prop->pointer.u32_data;
|
||||||
|
return &prop->value.u32_data;
|
||||||
|
case DEV_PROP_U64:
|
||||||
|
if (prop->is_array)
|
||||||
|
return prop->pointer.u64_data;
|
||||||
|
return &prop->value.u64_data;
|
||||||
|
case DEV_PROP_STRING:
|
||||||
|
if (prop->is_array)
|
||||||
|
return prop->pointer.str;
|
||||||
|
return &prop->value.str;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void property_set_pointer(struct property_entry *prop, const void *pointer)
|
||||||
|
{
|
||||||
|
switch (prop->type) {
|
||||||
|
case DEV_PROP_U8:
|
||||||
|
if (prop->is_array)
|
||||||
|
prop->pointer.u8_data = pointer;
|
||||||
|
else
|
||||||
|
prop->value.u8_data = *((u8 *)pointer);
|
||||||
|
break;
|
||||||
|
case DEV_PROP_U16:
|
||||||
|
if (prop->is_array)
|
||||||
|
prop->pointer.u16_data = pointer;
|
||||||
|
else
|
||||||
|
prop->value.u16_data = *((u16 *)pointer);
|
||||||
|
break;
|
||||||
|
case DEV_PROP_U32:
|
||||||
|
if (prop->is_array)
|
||||||
|
prop->pointer.u32_data = pointer;
|
||||||
|
else
|
||||||
|
prop->value.u32_data = *((u32 *)pointer);
|
||||||
|
break;
|
||||||
|
case DEV_PROP_U64:
|
||||||
|
if (prop->is_array)
|
||||||
|
prop->pointer.u64_data = pointer;
|
||||||
|
else
|
||||||
|
prop->value.u64_data = *((u64 *)pointer);
|
||||||
|
break;
|
||||||
|
case DEV_PROP_STRING:
|
||||||
|
if (prop->is_array)
|
||||||
|
prop->pointer.str = pointer;
|
||||||
|
else
|
||||||
|
prop->value.str = pointer;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const void *pset_prop_find(const struct property_set *pset,
|
static const void *pset_prop_find(const struct property_set *pset,
|
||||||
const char *propname, size_t length)
|
const char *propname, size_t length)
|
||||||
{
|
{
|
||||||
|
@ -65,10 +131,7 @@ static const void *pset_prop_find(const struct property_set *pset,
|
||||||
prop = pset_prop_get(pset, propname);
|
prop = pset_prop_get(pset, propname);
|
||||||
if (!prop)
|
if (!prop)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
if (prop->is_array)
|
pointer = property_get_pointer(prop);
|
||||||
pointer = prop->pointer.raw_data;
|
|
||||||
else
|
|
||||||
pointer = &prop->value.raw_data;
|
|
||||||
if (!pointer)
|
if (!pointer)
|
||||||
return ERR_PTR(-ENODATA);
|
return ERR_PTR(-ENODATA);
|
||||||
if (length > prop->length)
|
if (length > prop->length)
|
||||||
|
@ -698,16 +761,17 @@ EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args);
|
||||||
|
|
||||||
static void property_entry_free_data(const struct property_entry *p)
|
static void property_entry_free_data(const struct property_entry *p)
|
||||||
{
|
{
|
||||||
|
const void *pointer = property_get_pointer(p);
|
||||||
size_t i, nval;
|
size_t i, nval;
|
||||||
|
|
||||||
if (p->is_array) {
|
if (p->is_array) {
|
||||||
if (p->is_string && p->pointer.str) {
|
if (p->type == DEV_PROP_STRING && p->pointer.str) {
|
||||||
nval = p->length / sizeof(const char *);
|
nval = p->length / sizeof(const char *);
|
||||||
for (i = 0; i < nval; i++)
|
for (i = 0; i < nval; i++)
|
||||||
kfree(p->pointer.str[i]);
|
kfree(p->pointer.str[i]);
|
||||||
}
|
}
|
||||||
kfree(p->pointer.raw_data);
|
kfree(pointer);
|
||||||
} else if (p->is_string) {
|
} else if (p->type == DEV_PROP_STRING) {
|
||||||
kfree(p->value.str);
|
kfree(p->value.str);
|
||||||
}
|
}
|
||||||
kfree(p->name);
|
kfree(p->name);
|
||||||
|
@ -716,7 +780,7 @@ static void property_entry_free_data(const struct property_entry *p)
|
||||||
static int property_copy_string_array(struct property_entry *dst,
|
static int property_copy_string_array(struct property_entry *dst,
|
||||||
const struct property_entry *src)
|
const struct property_entry *src)
|
||||||
{
|
{
|
||||||
char **d;
|
const char **d;
|
||||||
size_t nval = src->length / sizeof(*d);
|
size_t nval = src->length / sizeof(*d);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -734,40 +798,44 @@ static int property_copy_string_array(struct property_entry *dst,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dst->pointer.raw_data = d;
|
dst->pointer.str = d;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int property_entry_copy_data(struct property_entry *dst,
|
static int property_entry_copy_data(struct property_entry *dst,
|
||||||
const struct property_entry *src)
|
const struct property_entry *src)
|
||||||
{
|
{
|
||||||
|
const void *pointer = property_get_pointer(src);
|
||||||
|
const void *new;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (src->is_array) {
|
if (src->is_array) {
|
||||||
if (!src->length)
|
if (!src->length)
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
|
|
||||||
if (src->is_string) {
|
if (src->type == DEV_PROP_STRING) {
|
||||||
error = property_copy_string_array(dst, src);
|
error = property_copy_string_array(dst, src);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
new = dst->pointer.str;
|
||||||
} else {
|
} else {
|
||||||
dst->pointer.raw_data = kmemdup(src->pointer.raw_data,
|
new = kmemdup(pointer, src->length, GFP_KERNEL);
|
||||||
src->length, GFP_KERNEL);
|
if (!new)
|
||||||
if (!dst->pointer.raw_data)
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
} else if (src->is_string) {
|
} else if (src->type == DEV_PROP_STRING) {
|
||||||
dst->value.str = kstrdup(src->value.str, GFP_KERNEL);
|
new = kstrdup(src->value.str, GFP_KERNEL);
|
||||||
if (!dst->value.str && src->value.str)
|
if (!new && src->value.str)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
} else {
|
} else {
|
||||||
dst->value.raw_data = src->value.raw_data;
|
new = pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst->length = src->length;
|
dst->length = src->length;
|
||||||
dst->is_array = src->is_array;
|
dst->is_array = src->is_array;
|
||||||
dst->is_string = src->is_string;
|
dst->type = src->type;
|
||||||
|
|
||||||
|
property_set_pointer(dst, new);
|
||||||
|
|
||||||
dst->name = kstrdup(src->name, GFP_KERNEL);
|
dst->name = kstrdup(src->name, GFP_KERNEL);
|
||||||
if (!dst->name)
|
if (!dst->name)
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Note, all properties are considered as u8 arrays.
|
||||||
|
* To get a value of any of them the caller must use device_property_read_u8_array().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) "apple-properties: " fmt
|
#define pr_fmt(fmt) "apple-properties: " fmt
|
||||||
|
@ -96,12 +99,13 @@ static void __init unmarshal_key_value_pairs(struct dev_header *dev_header,
|
||||||
entry[i].name = key;
|
entry[i].name = key;
|
||||||
entry[i].length = val_len - sizeof(val_len);
|
entry[i].length = val_len - sizeof(val_len);
|
||||||
entry[i].is_array = !!entry[i].length;
|
entry[i].is_array = !!entry[i].length;
|
||||||
entry[i].pointer.raw_data = ptr + key_len + sizeof(val_len);
|
entry[i].type = DEV_PROP_U8;
|
||||||
|
entry[i].pointer.u8_data = ptr + key_len + sizeof(val_len);
|
||||||
|
|
||||||
if (dump_properties) {
|
if (dump_properties) {
|
||||||
dev_info(dev, "property: %s\n", entry[i].name);
|
dev_info(dev, "property: %s\n", entry[i].name);
|
||||||
print_hex_dump(KERN_INFO, pr_fmt(), DUMP_PREFIX_OFFSET,
|
print_hex_dump(KERN_INFO, pr_fmt(), DUMP_PREFIX_OFFSET,
|
||||||
16, 1, entry[i].pointer.raw_data,
|
16, 1, entry[i].pointer.u8_data,
|
||||||
entry[i].length, true);
|
entry[i].length, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,7 @@ static inline int fwnode_property_read_u64(const struct fwnode_handle *fwnode,
|
||||||
* @name: Name of the property.
|
* @name: Name of the property.
|
||||||
* @length: Length of data making up the value.
|
* @length: Length of data making up the value.
|
||||||
* @is_array: True when the property is an array.
|
* @is_array: True when the property is an array.
|
||||||
* @is_string: True when property is a string.
|
* @type: Type of the data in unions.
|
||||||
* @pointer: Pointer to the property (an array of items of the given type).
|
* @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).
|
* @value: Value of the property (when it is a single item of the given type).
|
||||||
*/
|
*/
|
||||||
|
@ -186,10 +186,9 @@ struct property_entry {
|
||||||
const char *name;
|
const char *name;
|
||||||
size_t length;
|
size_t length;
|
||||||
bool is_array;
|
bool is_array;
|
||||||
bool is_string;
|
enum dev_prop_type type;
|
||||||
union {
|
union {
|
||||||
union {
|
union {
|
||||||
const void *raw_data;
|
|
||||||
const u8 *u8_data;
|
const u8 *u8_data;
|
||||||
const u16 *u16_data;
|
const u16 *u16_data;
|
||||||
const u32 *u32_data;
|
const u32 *u32_data;
|
||||||
|
@ -197,7 +196,6 @@ struct property_entry {
|
||||||
const char * const *str;
|
const char * const *str;
|
||||||
} pointer;
|
} pointer;
|
||||||
union {
|
union {
|
||||||
unsigned long long raw_data;
|
|
||||||
u8 u8_data;
|
u8 u8_data;
|
||||||
u16 u16_data;
|
u16 u16_data;
|
||||||
u32 u32_data;
|
u32 u32_data;
|
||||||
|
@ -213,55 +211,55 @@ struct property_entry {
|
||||||
* and structs.
|
* and structs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PROPERTY_ENTRY_INTEGER_ARRAY(_name_, _type_, _val_) \
|
#define PROPERTY_ENTRY_INTEGER_ARRAY(_name_, _type_, _Type_, _val_) \
|
||||||
(struct property_entry) { \
|
(struct property_entry) { \
|
||||||
.name = _name_, \
|
.name = _name_, \
|
||||||
.length = ARRAY_SIZE(_val_) * sizeof(_type_), \
|
.length = ARRAY_SIZE(_val_) * sizeof(_type_), \
|
||||||
.is_array = true, \
|
.is_array = true, \
|
||||||
.is_string = false, \
|
.type = DEV_PROP_##_Type_, \
|
||||||
{ .pointer = { ._type_##_data = _val_ } }, \
|
{ .pointer = { ._type_##_data = _val_ } }, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROPERTY_ENTRY_U8_ARRAY(_name_, _val_) \
|
#define PROPERTY_ENTRY_U8_ARRAY(_name_, _val_) \
|
||||||
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u8, _val_)
|
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u8, U8, _val_)
|
||||||
#define PROPERTY_ENTRY_U16_ARRAY(_name_, _val_) \
|
#define PROPERTY_ENTRY_U16_ARRAY(_name_, _val_) \
|
||||||
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u16, _val_)
|
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u16, U16, _val_)
|
||||||
#define PROPERTY_ENTRY_U32_ARRAY(_name_, _val_) \
|
#define PROPERTY_ENTRY_U32_ARRAY(_name_, _val_) \
|
||||||
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u32, _val_)
|
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u32, U32, _val_)
|
||||||
#define PROPERTY_ENTRY_U64_ARRAY(_name_, _val_) \
|
#define PROPERTY_ENTRY_U64_ARRAY(_name_, _val_) \
|
||||||
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u64, _val_)
|
PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u64, U64, _val_)
|
||||||
|
|
||||||
#define PROPERTY_ENTRY_STRING_ARRAY(_name_, _val_) \
|
#define PROPERTY_ENTRY_STRING_ARRAY(_name_, _val_) \
|
||||||
(struct property_entry) { \
|
(struct property_entry) { \
|
||||||
.name = _name_, \
|
.name = _name_, \
|
||||||
.length = ARRAY_SIZE(_val_) * sizeof(const char *), \
|
.length = ARRAY_SIZE(_val_) * sizeof(const char *), \
|
||||||
.is_array = true, \
|
.is_array = true, \
|
||||||
.is_string = true, \
|
.type = DEV_PROP_STRING, \
|
||||||
{ .pointer = { .str = _val_ } }, \
|
{ .pointer = { .str = _val_ } }, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROPERTY_ENTRY_INTEGER(_name_, _type_, _val_) \
|
#define PROPERTY_ENTRY_INTEGER(_name_, _type_, _Type_, _val_) \
|
||||||
(struct property_entry) { \
|
(struct property_entry) { \
|
||||||
.name = _name_, \
|
.name = _name_, \
|
||||||
.length = sizeof(_type_), \
|
.length = sizeof(_type_), \
|
||||||
.is_string = false, \
|
.type = DEV_PROP_##_Type_, \
|
||||||
{ .value = { ._type_##_data = _val_ } }, \
|
{ .value = { ._type_##_data = _val_ } }, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PROPERTY_ENTRY_U8(_name_, _val_) \
|
#define PROPERTY_ENTRY_U8(_name_, _val_) \
|
||||||
PROPERTY_ENTRY_INTEGER(_name_, u8, _val_)
|
PROPERTY_ENTRY_INTEGER(_name_, u8, U8, _val_)
|
||||||
#define PROPERTY_ENTRY_U16(_name_, _val_) \
|
#define PROPERTY_ENTRY_U16(_name_, _val_) \
|
||||||
PROPERTY_ENTRY_INTEGER(_name_, u16, _val_)
|
PROPERTY_ENTRY_INTEGER(_name_, u16, U16, _val_)
|
||||||
#define PROPERTY_ENTRY_U32(_name_, _val_) \
|
#define PROPERTY_ENTRY_U32(_name_, _val_) \
|
||||||
PROPERTY_ENTRY_INTEGER(_name_, u32, _val_)
|
PROPERTY_ENTRY_INTEGER(_name_, u32, U32, _val_)
|
||||||
#define PROPERTY_ENTRY_U64(_name_, _val_) \
|
#define PROPERTY_ENTRY_U64(_name_, _val_) \
|
||||||
PROPERTY_ENTRY_INTEGER(_name_, u64, _val_)
|
PROPERTY_ENTRY_INTEGER(_name_, u64, U64, _val_)
|
||||||
|
|
||||||
#define PROPERTY_ENTRY_STRING(_name_, _val_) \
|
#define PROPERTY_ENTRY_STRING(_name_, _val_) \
|
||||||
(struct property_entry) { \
|
(struct property_entry) { \
|
||||||
.name = _name_, \
|
.name = _name_, \
|
||||||
.length = sizeof(_val_), \
|
.length = sizeof(_val_), \
|
||||||
.is_string = true, \
|
.type = DEV_PROP_STRING, \
|
||||||
{ .value = { .str = _val_ } }, \
|
{ .value = { .str = _val_ } }, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue