diff options
-rw-r--r-- | drivers/acpi/property.c | 178 | ||||
-rw-r--r-- | drivers/base/Makefile | 2 | ||||
-rw-r--r-- | drivers/base/property.c | 185 | ||||
-rw-r--r-- | drivers/of/base.c | 33 | ||||
-rw-r--r-- | include/linux/acpi.h | 32 | ||||
-rw-r--r-- | include/linux/of.h | 12 | ||||
-rw-r--r-- | include/linux/property.h | 73 |
7 files changed, 514 insertions, 1 deletions
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index c4a3e800e82c..2541b1fd1fa5 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c | |||
@@ -362,3 +362,181 @@ int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, | |||
362 | return -EPROTO; | 362 | return -EPROTO; |
363 | } | 363 | } |
364 | EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference); | 364 | EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference); |
365 | |||
366 | int acpi_dev_prop_get(struct acpi_device *adev, const char *propname, | ||
367 | void **valptr) | ||
368 | { | ||
369 | return acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY, | ||
370 | (const union acpi_object **)valptr); | ||
371 | } | ||
372 | |||
373 | int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, | ||
374 | enum dev_prop_type proptype, void *val) | ||
375 | { | ||
376 | const union acpi_object *obj; | ||
377 | int ret; | ||
378 | |||
379 | if (!val) | ||
380 | return -EINVAL; | ||
381 | |||
382 | if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) { | ||
383 | ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_INTEGER, &obj); | ||
384 | if (ret) | ||
385 | return ret; | ||
386 | |||
387 | switch (proptype) { | ||
388 | case DEV_PROP_U8: | ||
389 | if (obj->integer.value > U8_MAX) | ||
390 | return -EOVERFLOW; | ||
391 | *(u8 *)val = obj->integer.value; | ||
392 | break; | ||
393 | case DEV_PROP_U16: | ||
394 | if (obj->integer.value > U16_MAX) | ||
395 | return -EOVERFLOW; | ||
396 | *(u16 *)val = obj->integer.value; | ||
397 | break; | ||
398 | case DEV_PROP_U32: | ||
399 | if (obj->integer.value > U32_MAX) | ||
400 | return -EOVERFLOW; | ||
401 | *(u32 *)val = obj->integer.value; | ||
402 | break; | ||
403 | default: | ||
404 | *(u64 *)val = obj->integer.value; | ||
405 | break; | ||
406 | } | ||
407 | } else if (proptype == DEV_PROP_STRING) { | ||
408 | ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_STRING, &obj); | ||
409 | if (ret) | ||
410 | return ret; | ||
411 | |||
412 | *(char **)val = obj->string.pointer; | ||
413 | } else { | ||
414 | ret = -EINVAL; | ||
415 | } | ||
416 | return ret; | ||
417 | } | ||
418 | |||
419 | static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val, | ||
420 | size_t nval) | ||
421 | { | ||
422 | int i; | ||
423 | |||
424 | for (i = 0; i < nval; i++) { | ||
425 | if (items[i].type != ACPI_TYPE_INTEGER) | ||
426 | return -EPROTO; | ||
427 | if (items[i].integer.value > U8_MAX) | ||
428 | return -EOVERFLOW; | ||
429 | |||
430 | val[i] = items[i].integer.value; | ||
431 | } | ||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | static int acpi_copy_property_array_u16(const union acpi_object *items, | ||
436 | u16 *val, size_t nval) | ||
437 | { | ||
438 | int i; | ||
439 | |||
440 | for (i = 0; i < nval; i++) { | ||
441 | if (items[i].type != ACPI_TYPE_INTEGER) | ||
442 | return -EPROTO; | ||
443 | if (items[i].integer.value > U16_MAX) | ||
444 | return -EOVERFLOW; | ||
445 | |||
446 | val[i] = items[i].integer.value; | ||
447 | } | ||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static int acpi_copy_property_array_u32(const union acpi_object *items, | ||
452 | u32 *val, size_t nval) | ||
453 | { | ||
454 | int i; | ||
455 | |||
456 | for (i = 0; i < nval; i++) { | ||
457 | if (items[i].type != ACPI_TYPE_INTEGER) | ||
458 | return -EPROTO; | ||
459 | if (items[i].integer.value > U32_MAX) | ||
460 | return -EOVERFLOW; | ||
461 | |||
462 | val[i] = items[i].integer.value; | ||
463 | } | ||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | static int acpi_copy_property_array_u64(const union acpi_object *items, | ||
468 | u64 *val, size_t nval) | ||
469 | { | ||
470 | int i; | ||
471 | |||
472 | for (i = 0; i < nval; i++) { | ||
473 | if (items[i].type != ACPI_TYPE_INTEGER) | ||
474 | return -EPROTO; | ||
475 | |||
476 | val[i] = items[i].integer.value; | ||
477 | } | ||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | static int acpi_copy_property_array_string(const union acpi_object *items, | ||
482 | char **val, size_t nval) | ||
483 | { | ||
484 | int i; | ||
485 | |||
486 | for (i = 0; i < nval; i++) { | ||
487 | if (items[i].type != ACPI_TYPE_STRING) | ||
488 | return -EPROTO; | ||
489 | |||
490 | val[i] = items[i].string.pointer; | ||
491 | } | ||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, | ||
496 | enum dev_prop_type proptype, void *val, size_t nval) | ||
497 | { | ||
498 | const union acpi_object *obj; | ||
499 | const union acpi_object *items; | ||
500 | int ret; | ||
501 | |||
502 | if (val && nval == 1) { | ||
503 | ret = acpi_dev_prop_read_single(adev, propname, proptype, val); | ||
504 | if (!ret) | ||
505 | return ret; | ||
506 | } | ||
507 | |||
508 | ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj); | ||
509 | if (ret) | ||
510 | return ret; | ||
511 | |||
512 | if (!val) | ||
513 | return obj->package.count; | ||
514 | else if (nval <= 0) | ||
515 | return -EINVAL; | ||
516 | |||
517 | if (nval > obj->package.count) | ||
518 | return -EOVERFLOW; | ||
519 | |||
520 | items = obj->package.elements; | ||
521 | switch (proptype) { | ||
522 | case DEV_PROP_U8: | ||
523 | ret = acpi_copy_property_array_u8(items, (u8 *)val, nval); | ||
524 | break; | ||
525 | case DEV_PROP_U16: | ||
526 | ret = acpi_copy_property_array_u16(items, (u16 *)val, nval); | ||
527 | break; | ||
528 | case DEV_PROP_U32: | ||
529 | ret = acpi_copy_property_array_u32(items, (u32 *)val, nval); | ||
530 | break; | ||
531 | case DEV_PROP_U64: | ||
532 | ret = acpi_copy_property_array_u64(items, (u64 *)val, nval); | ||
533 | break; | ||
534 | case DEV_PROP_STRING: | ||
535 | ret = acpi_copy_property_array_string(items, (char **)val, nval); | ||
536 | break; | ||
537 | default: | ||
538 | ret = -EINVAL; | ||
539 | break; | ||
540 | } | ||
541 | return ret; | ||
542 | } | ||
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 6922cd6850a2..53c3fe1aeb29 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -4,7 +4,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \ | |||
4 | driver.o class.o platform.o \ | 4 | driver.o class.o platform.o \ |
5 | cpu.o firmware.o init.o map.o devres.o \ | 5 | cpu.o firmware.o init.o map.o devres.o \ |
6 | attribute_container.o transport_class.o \ | 6 | attribute_container.o transport_class.o \ |
7 | topology.o container.o | 7 | topology.o container.o property.o |
8 | obj-$(CONFIG_DEVTMPFS) += devtmpfs.o | 8 | obj-$(CONFIG_DEVTMPFS) += devtmpfs.o |
9 | obj-$(CONFIG_DMA_CMA) += dma-contiguous.o | 9 | obj-$(CONFIG_DMA_CMA) += dma-contiguous.o |
10 | obj-y += power/ | 10 | obj-y += power/ |
diff --git a/drivers/base/property.c b/drivers/base/property.c new file mode 100644 index 000000000000..6a94ef6e83c9 --- /dev/null +++ b/drivers/base/property.c | |||
@@ -0,0 +1,185 @@ | |||
1 | /* | ||
2 | * property.c - Unified device property interface. | ||
3 | * | ||
4 | * Copyright (C) 2014, Intel Corporation | ||
5 | * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||
6 | * Mika Westerberg <mika.westerberg@linux.intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/property.h> | ||
14 | #include <linux/export.h> | ||
15 | #include <linux/acpi.h> | ||
16 | #include <linux/of.h> | ||
17 | |||
18 | /** | ||
19 | * device_property_present - check if a property of a device is present | ||
20 | * @dev: Device whose property is being checked | ||
21 | * @propname: Name of the property | ||
22 | * | ||
23 | * Check if property @propname is present in the device firmware description. | ||
24 | */ | ||
25 | bool device_property_present(struct device *dev, const char *propname) | ||
26 | { | ||
27 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) | ||
28 | return of_property_read_bool(dev->of_node, propname); | ||
29 | |||
30 | return !acpi_dev_prop_get(ACPI_COMPANION(dev), propname, NULL); | ||
31 | } | ||
32 | EXPORT_SYMBOL_GPL(device_property_present); | ||
33 | |||
34 | #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ | ||
35 | (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ | ||
36 | : of_property_count_elems_of_size((node), (propname), sizeof(type)) | ||
37 | |||
38 | #define DEV_PROP_READ_ARRAY(_dev_, _propname_, _type_, _proptype_, _val_, _nval_) \ | ||
39 | IS_ENABLED(CONFIG_OF) && _dev_->of_node ? \ | ||
40 | (OF_DEV_PROP_READ_ARRAY(_dev_->of_node, _propname_, _type_, \ | ||
41 | _val_, _nval_)) : \ | ||
42 | acpi_dev_prop_read(ACPI_COMPANION(_dev_), _propname_, \ | ||
43 | _proptype_, _val_, _nval_) | ||
44 | |||
45 | /** | ||
46 | * device_property_read_u8_array - return a u8 array property of a device | ||
47 | * @dev: Device to get the property of | ||
48 | * @propname: Name of the property | ||
49 | * @val: The values are stored here | ||
50 | * @nval: Size of the @val array | ||
51 | * | ||
52 | * Function reads an array of u8 properties with @propname from the device | ||
53 | * firmware description and stores them to @val if found. | ||
54 | * | ||
55 | * Return: %0 if the property was found (success), | ||
56 | * %-EINVAL if given arguments are not valid, | ||
57 | * %-ENODATA if the property does not have a value, | ||
58 | * %-EPROTO if the property is not an array of numbers, | ||
59 | * %-EOVERFLOW if the size of the property is not as expected. | ||
60 | */ | ||
61 | int device_property_read_u8_array(struct device *dev, const char *propname, | ||
62 | u8 *val, size_t nval) | ||
63 | { | ||
64 | return DEV_PROP_READ_ARRAY(dev, propname, u8, DEV_PROP_U8, val, nval); | ||
65 | } | ||
66 | EXPORT_SYMBOL_GPL(device_property_read_u8_array); | ||
67 | |||
68 | /** | ||
69 | * device_property_read_u16_array - return a u16 array property of a device | ||
70 | * @dev: Device to get the property of | ||
71 | * @propname: Name of the property | ||
72 | * @val: The values are stored here | ||
73 | * @nval: Size of the @val array | ||
74 | * | ||
75 | * Function reads an array of u16 properties with @propname from the device | ||
76 | * firmware description and stores them to @val if found. | ||
77 | * | ||
78 | * Return: %0 if the property was found (success), | ||
79 | * %-EINVAL if given arguments are not valid, | ||
80 | * %-ENODATA if the property does not have a value, | ||
81 | * %-EPROTO if the property is not an array of numbers, | ||
82 | * %-EOVERFLOW if the size of the property is not as expected. | ||
83 | */ | ||
84 | int device_property_read_u16_array(struct device *dev, const char *propname, | ||
85 | u16 *val, size_t nval) | ||
86 | { | ||
87 | return DEV_PROP_READ_ARRAY(dev, propname, u16, DEV_PROP_U16, val, nval); | ||
88 | } | ||
89 | EXPORT_SYMBOL_GPL(device_property_read_u16_array); | ||
90 | |||
91 | /** | ||
92 | * device_property_read_u32_array - return a u32 array property of a device | ||
93 | * @dev: Device to get the property of | ||
94 | * @propname: Name of the property | ||
95 | * @val: The values are stored here | ||
96 | * @nval: Size of the @val array | ||
97 | * | ||
98 | * Function reads an array of u32 properties with @propname from the device | ||
99 | * firmware description and stores them to @val if found. | ||
100 | * | ||
101 | * Return: %0 if the property was found (success), | ||
102 | * %-EINVAL if given arguments are not valid, | ||
103 | * %-ENODATA if the property does not have a value, | ||
104 | * %-EPROTO if the property is not an array of numbers, | ||
105 | * %-EOVERFLOW if the size of the property is not as expected. | ||
106 | */ | ||
107 | int device_property_read_u32_array(struct device *dev, const char *propname, | ||
108 | u32 *val, size_t nval) | ||
109 | { | ||
110 | return DEV_PROP_READ_ARRAY(dev, propname, u32, DEV_PROP_U32, val, nval); | ||
111 | } | ||
112 | EXPORT_SYMBOL_GPL(device_property_read_u32_array); | ||
113 | |||
114 | /** | ||
115 | * device_property_read_u64_array - return a u64 array property of a device | ||
116 | * @dev: Device to get the property of | ||
117 | * @propname: Name of the property | ||
118 | * @val: The values are stored here | ||
119 | * @nval: Size of the @val array | ||
120 | * | ||
121 | * Function reads an array of u64 properties with @propname from the device | ||
122 | * firmware description and stores them to @val if found. | ||
123 | * | ||
124 | * Return: %0 if the property was found (success), | ||
125 | * %-EINVAL if given arguments are not valid, | ||
126 | * %-ENODATA if the property does not have a value, | ||
127 | * %-EPROTO if the property is not an array of numbers, | ||
128 | * %-EOVERFLOW if the size of the property is not as expected. | ||
129 | */ | ||
130 | int device_property_read_u64_array(struct device *dev, const char *propname, | ||
131 | u64 *val, size_t nval) | ||
132 | { | ||
133 | return DEV_PROP_READ_ARRAY(dev, propname, u64, DEV_PROP_U64, val, nval); | ||
134 | } | ||
135 | EXPORT_SYMBOL_GPL(device_property_read_u64_array); | ||
136 | |||
137 | /** | ||
138 | * device_property_read_string_array - return a string array property of device | ||
139 | * @dev: Device to get the property of | ||
140 | * @propname: Name of the property | ||
141 | * @val: The values are stored here | ||
142 | * @nval: Size of the @val array | ||
143 | * | ||
144 | * Function reads an array of string properties with @propname from the device | ||
145 | * firmware description and stores them to @val if found. | ||
146 | * | ||
147 | * Return: %0 if the property was found (success), | ||
148 | * %-EINVAL if given arguments are not valid, | ||
149 | * %-ENODATA if the property does not have a value, | ||
150 | * %-EPROTO or %-EILSEQ if the property is not an array of strings, | ||
151 | * %-EOVERFLOW if the size of the property is not as expected. | ||
152 | */ | ||
153 | int device_property_read_string_array(struct device *dev, const char *propname, | ||
154 | const char **val, size_t nval) | ||
155 | { | ||
156 | return IS_ENABLED(CONFIG_OF) && dev->of_node ? | ||
157 | of_property_read_string_array(dev->of_node, propname, val, nval) : | ||
158 | acpi_dev_prop_read(ACPI_COMPANION(dev), propname, | ||
159 | DEV_PROP_STRING, val, nval); | ||
160 | } | ||
161 | EXPORT_SYMBOL_GPL(device_property_read_string_array); | ||
162 | |||
163 | /** | ||
164 | * device_property_read_string - return a string property of a device | ||
165 | * @dev: Device to get the property of | ||
166 | * @propname: Name of the property | ||
167 | * @val: The value is stored here | ||
168 | * | ||
169 | * Function reads property @propname from the device firmware description and | ||
170 | * stores the value into @val if found. The value is checked to be a string. | ||
171 | * | ||
172 | * Return: %0 if the property was found (success), | ||
173 | * %-EINVAL if given arguments are not valid, | ||
174 | * %-ENODATA if the property does not have a value, | ||
175 | * %-EPROTO or %-EILSEQ if the property type is not a string. | ||
176 | */ | ||
177 | int device_property_read_string(struct device *dev, const char *propname, | ||
178 | const char **val) | ||
179 | { | ||
180 | return IS_ENABLED(CONFIG_OF) && dev->of_node ? | ||
181 | of_property_read_string(dev->of_node, propname, val) : | ||
182 | acpi_dev_prop_read(ACPI_COMPANION(dev), propname, | ||
183 | DEV_PROP_STRING, val, 1); | ||
184 | } | ||
185 | EXPORT_SYMBOL_GPL(device_property_read_string); | ||
diff --git a/drivers/of/base.c b/drivers/of/base.c index 3823edf2d012..4c2ccde42427 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -1250,6 +1250,39 @@ int of_property_read_u64(const struct device_node *np, const char *propname, | |||
1250 | EXPORT_SYMBOL_GPL(of_property_read_u64); | 1250 | EXPORT_SYMBOL_GPL(of_property_read_u64); |
1251 | 1251 | ||
1252 | /** | 1252 | /** |
1253 | * of_property_read_u64_array - Find and read an array of 64 bit integers | ||
1254 | * from a property. | ||
1255 | * | ||
1256 | * @np: device node from which the property value is to be read. | ||
1257 | * @propname: name of the property to be searched. | ||
1258 | * @out_values: pointer to return value, modified only if return value is 0. | ||
1259 | * @sz: number of array elements to read | ||
1260 | * | ||
1261 | * Search for a property in a device node and read 64-bit value(s) from | ||
1262 | * it. Returns 0 on success, -EINVAL if the property does not exist, | ||
1263 | * -ENODATA if property does not have a value, and -EOVERFLOW if the | ||
1264 | * property data isn't large enough. | ||
1265 | * | ||
1266 | * The out_values is modified only if a valid u64 value can be decoded. | ||
1267 | */ | ||
1268 | int of_property_read_u64_array(const struct device_node *np, | ||
1269 | const char *propname, u64 *out_values, | ||
1270 | size_t sz) | ||
1271 | { | ||
1272 | const __be32 *val = of_find_property_value_of_size(np, propname, | ||
1273 | (sz * sizeof(*out_values))); | ||
1274 | |||
1275 | if (IS_ERR(val)) | ||
1276 | return PTR_ERR(val); | ||
1277 | |||
1278 | while (sz--) { | ||
1279 | *out_values++ = of_read_number(val, 2); | ||
1280 | val += 2; | ||
1281 | } | ||
1282 | return 0; | ||
1283 | } | ||
1284 | |||
1285 | /** | ||
1253 | * of_property_read_string - Find and read a string from a property | 1286 | * of_property_read_string - Find and read a string from a property |
1254 | * @np: device node from which the property value is to be read. | 1287 | * @np: device node from which the property value is to be read. |
1255 | * @propname: name of the property to be searched. | 1288 | * @propname: name of the property to be searched. |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index dcdf8738898c..76d64d6a903a 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/ioport.h> /* for struct resource */ | 29 | #include <linux/ioport.h> /* for struct resource */ |
30 | #include <linux/device.h> | 30 | #include <linux/device.h> |
31 | #include <linux/property.h> | ||
31 | 32 | ||
32 | #ifndef _LINUX | 33 | #ifndef _LINUX |
33 | #define _LINUX | 34 | #define _LINUX |
@@ -677,6 +678,13 @@ int acpi_dev_get_property_array(struct acpi_device *adev, const char *name, | |||
677 | int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, | 678 | int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name, |
678 | const char *cells_name, size_t index, | 679 | const char *cells_name, size_t index, |
679 | struct acpi_reference_args *args); | 680 | struct acpi_reference_args *args); |
681 | |||
682 | int acpi_dev_prop_get(struct acpi_device *adev, const char *propname, | ||
683 | void **valptr); | ||
684 | int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, | ||
685 | enum dev_prop_type proptype, void *val); | ||
686 | int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, | ||
687 | enum dev_prop_type proptype, void *val, size_t nval); | ||
680 | #else | 688 | #else |
681 | static inline int acpi_dev_get_property(struct acpi_device *adev, | 689 | static inline int acpi_dev_get_property(struct acpi_device *adev, |
682 | const char *name, acpi_object_type type, | 690 | const char *name, acpi_object_type type, |
@@ -697,6 +705,30 @@ static inline int acpi_dev_get_property_reference(struct acpi_device *adev, | |||
697 | { | 705 | { |
698 | return -ENXIO; | 706 | return -ENXIO; |
699 | } | 707 | } |
708 | |||
709 | static inline int acpi_dev_prop_get(struct acpi_device *adev, | ||
710 | const char *propname, | ||
711 | void **valptr) | ||
712 | { | ||
713 | return -ENXIO; | ||
714 | } | ||
715 | |||
716 | static inline int acpi_dev_prop_read_single(struct acpi_device *adev, | ||
717 | const char *propname, | ||
718 | enum dev_prop_type proptype, | ||
719 | void *val) | ||
720 | { | ||
721 | return -ENXIO; | ||
722 | } | ||
723 | |||
724 | static inline int acpi_dev_prop_read(struct acpi_device *adev, | ||
725 | const char *propname, | ||
726 | enum dev_prop_type proptype, | ||
727 | void *val, size_t nval) | ||
728 | { | ||
729 | return -ENXIO; | ||
730 | } | ||
731 | |||
700 | #endif | 732 | #endif |
701 | 733 | ||
702 | #endif /*_LINUX_ACPI_H*/ | 734 | #endif /*_LINUX_ACPI_H*/ |
diff --git a/include/linux/of.h b/include/linux/of.h index 29f0adc5f3e4..ce9f6a2b3532 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/topology.h> | 24 | #include <linux/topology.h> |
25 | #include <linux/notifier.h> | 25 | #include <linux/notifier.h> |
26 | #include <linux/property.h> | ||
26 | 27 | ||
27 | #include <asm/byteorder.h> | 28 | #include <asm/byteorder.h> |
28 | #include <asm/errno.h> | 29 | #include <asm/errno.h> |
@@ -263,6 +264,10 @@ extern int of_property_read_u32_array(const struct device_node *np, | |||
263 | size_t sz); | 264 | size_t sz); |
264 | extern int of_property_read_u64(const struct device_node *np, | 265 | extern int of_property_read_u64(const struct device_node *np, |
265 | const char *propname, u64 *out_value); | 266 | const char *propname, u64 *out_value); |
267 | extern int of_property_read_u64_array(const struct device_node *np, | ||
268 | const char *propname, | ||
269 | u64 *out_values, | ||
270 | size_t sz); | ||
266 | 271 | ||
267 | extern int of_property_read_string(struct device_node *np, | 272 | extern int of_property_read_string(struct device_node *np, |
268 | const char *propname, | 273 | const char *propname, |
@@ -477,6 +482,13 @@ static inline int of_property_read_u32_array(const struct device_node *np, | |||
477 | return -ENOSYS; | 482 | return -ENOSYS; |
478 | } | 483 | } |
479 | 484 | ||
485 | static inline int of_property_read_u64_array(const struct device_node *np, | ||
486 | const char *propname, | ||
487 | u64 *out_values, size_t sz) | ||
488 | { | ||
489 | return -ENOSYS; | ||
490 | } | ||
491 | |||
480 | static inline int of_property_read_string(struct device_node *np, | 492 | static inline int of_property_read_string(struct device_node *np, |
481 | const char *propname, | 493 | const char *propname, |
482 | const char **out_string) | 494 | const char **out_string) |
diff --git a/include/linux/property.h b/include/linux/property.h new file mode 100644 index 000000000000..9242fb0221ba --- /dev/null +++ b/include/linux/property.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * property.h - Unified device property interface. | ||
3 | * | ||
4 | * Copyright (C) 2014, Intel Corporation | ||
5 | * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||
6 | * Mika Westerberg <mika.westerberg@linux.intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef _LINUX_PROPERTY_H_ | ||
14 | #define _LINUX_PROPERTY_H_ | ||
15 | |||
16 | #include <linux/types.h> | ||
17 | |||
18 | struct device; | ||
19 | |||
20 | enum dev_prop_type { | ||
21 | DEV_PROP_U8, | ||
22 | DEV_PROP_U16, | ||
23 | DEV_PROP_U32, | ||
24 | DEV_PROP_U64, | ||
25 | DEV_PROP_STRING, | ||
26 | DEV_PROP_MAX, | ||
27 | }; | ||
28 | |||
29 | bool device_property_present(struct device *dev, const char *propname); | ||
30 | int device_property_read_u8_array(struct device *dev, const char *propname, | ||
31 | u8 *val, size_t nval); | ||
32 | int device_property_read_u16_array(struct device *dev, const char *propname, | ||
33 | u16 *val, size_t nval); | ||
34 | int device_property_read_u32_array(struct device *dev, const char *propname, | ||
35 | u32 *val, size_t nval); | ||
36 | int device_property_read_u64_array(struct device *dev, const char *propname, | ||
37 | u64 *val, size_t nval); | ||
38 | int device_property_read_string_array(struct device *dev, const char *propname, | ||
39 | const char **val, size_t nval); | ||
40 | int device_property_read_string(struct device *dev, const char *propname, | ||
41 | const char **val); | ||
42 | |||
43 | static inline bool device_property_read_bool(struct device *dev, | ||
44 | const char *propname) | ||
45 | { | ||
46 | return device_property_present(dev, propname); | ||
47 | } | ||
48 | |||
49 | static inline int device_property_read_u8(struct device *dev, | ||
50 | const char *propname, u8 *val) | ||
51 | { | ||
52 | return device_property_read_u8_array(dev, propname, val, 1); | ||
53 | } | ||
54 | |||
55 | static inline int device_property_read_u16(struct device *dev, | ||
56 | const char *propname, u16 *val) | ||
57 | { | ||
58 | return device_property_read_u16_array(dev, propname, val, 1); | ||
59 | } | ||
60 | |||
61 | static inline int device_property_read_u32(struct device *dev, | ||
62 | const char *propname, u32 *val) | ||
63 | { | ||
64 | return device_property_read_u32_array(dev, propname, val, 1); | ||
65 | } | ||
66 | |||
67 | static inline int device_property_read_u64(struct device *dev, | ||
68 | const char *propname, u64 *val) | ||
69 | { | ||
70 | return device_property_read_u64_array(dev, propname, val, 1); | ||
71 | } | ||
72 | |||
73 | #endif /* _LINUX_PROPERTY_H_ */ | ||