diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-14 15:50:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-14 15:50:05 -0400 |
commit | b41d037a1fd32d6535a2eef877b10f8deefeaf70 (patch) | |
tree | daecbd26a3e80545f9d3bab99e07395aaf1b9678 | |
parent | ef98988ba369da88bab8a4d457407e71bbe160fa (diff) | |
parent | 522533f338f38e15106d5f58901f38fe7bd6a7d8 (diff) |
Merge tag 'acpi-extra-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more ACPI updates from Rafael Wysocki:
"This includes a couple of fixes needed after recent changes, two ACPI
driver fixes (fan and "Processor Aggregator"), an update of the ACPI
device properties handling code and a new MAINTAINERS entry for ACPI
on ARM64.
Specifics:
- Fix an unused function warning that started to appear after recent
changes in the ACPI EC driver (Eric Biggers).
- Fix the KERN_CONT usage in acpi_os_vprintf() that has become
(particularly) annoying recently (Joe Perches).
- Fix the fan status checking in the ACPI fan driver to avoid
returning incorrect error codes sometimes (Srinivas Pandruvada).
- Fix the ACPI Processor Aggregator driver (PAD) to always let the
special processor_aggregator driver from Xen take over when running
as Xen dom0 (Juergen Gross).
- Update the handling of reference device properties in ACPI by
allowing empty rows ("holes") to appear in reference property lists
(Mika Westerberg).
- Add a new MAINTAINERS entry for ACPI on ARM64 (Lorenzo Pieralisi)"
* tag 'acpi-extra-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
acpi_os_vprintf: Use printk_get_level() to avoid unnecessary KERN_CONT
ACPI / PAD: don't register acpi_pad driver if running as Xen dom0
ACPI / property: Allow holes in reference properties
MAINTAINERS: Add ARM64-specific ACPI maintainers entry
ACPI / EC: Fix unused function warning when CONFIG_PM_SLEEP=n
ACPI / fan: Fix error reading cur_state
-rw-r--r-- | MAINTAINERS | 8 | ||||
-rw-r--r-- | drivers/acpi/acpi_pad.c | 5 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 2 | ||||
-rw-r--r-- | drivers/acpi/fan.c | 12 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 13 | ||||
-rw-r--r-- | drivers/acpi/property.c | 117 | ||||
-rw-r--r-- | include/linux/acpi.h | 22 |
7 files changed, 123 insertions, 56 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index fc849cabf99e..146d1498aa01 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -316,6 +316,14 @@ W: https://01.org/linux-acpi | |||
316 | S: Supported | 316 | S: Supported |
317 | F: drivers/acpi/fan.c | 317 | F: drivers/acpi/fan.c |
318 | 318 | ||
319 | ACPI FOR ARM64 (ACPI/arm64) | ||
320 | M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> | ||
321 | M: Hanjun Guo <hanjun.guo@linaro.org> | ||
322 | M: Sudeep Holla <sudeep.holla@arm.com> | ||
323 | L: linux-acpi@vger.kernel.org | ||
324 | S: Maintained | ||
325 | F: drivers/acpi/arm64 | ||
326 | |||
319 | ACPI THERMAL DRIVER | 327 | ACPI THERMAL DRIVER |
320 | M: Zhang Rui <rui.zhang@intel.com> | 328 | M: Zhang Rui <rui.zhang@intel.com> |
321 | L: linux-acpi@vger.kernel.org | 329 | L: linux-acpi@vger.kernel.org |
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 8ea8211b2d58..eb76a4c10dbf 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/acpi.h> | 27 | #include <linux/acpi.h> |
28 | #include <asm/mwait.h> | 28 | #include <asm/mwait.h> |
29 | #include <xen/xen.h> | ||
29 | 30 | ||
30 | #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" | 31 | #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" |
31 | #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" | 32 | #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" |
@@ -477,6 +478,10 @@ static struct acpi_driver acpi_pad_driver = { | |||
477 | 478 | ||
478 | static int __init acpi_pad_init(void) | 479 | static int __init acpi_pad_init(void) |
479 | { | 480 | { |
481 | /* Xen ACPI PAD is used when running as Xen Dom0. */ | ||
482 | if (xen_initial_domain()) | ||
483 | return -ENODEV; | ||
484 | |||
480 | power_saving_mwait_init(); | 485 | power_saving_mwait_init(); |
481 | if (power_saving_mwait_eax == 0) | 486 | if (power_saving_mwait_eax == 0) |
482 | return -EINVAL; | 487 | return -EINVAL; |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 680531062160..48e19d013170 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -526,6 +526,7 @@ static void acpi_ec_enable_event(struct acpi_ec *ec) | |||
526 | acpi_ec_clear(ec); | 526 | acpi_ec_clear(ec); |
527 | } | 527 | } |
528 | 528 | ||
529 | #ifdef CONFIG_PM_SLEEP | ||
529 | static bool acpi_ec_query_flushed(struct acpi_ec *ec) | 530 | static bool acpi_ec_query_flushed(struct acpi_ec *ec) |
530 | { | 531 | { |
531 | bool flushed; | 532 | bool flushed; |
@@ -557,6 +558,7 @@ static void acpi_ec_disable_event(struct acpi_ec *ec) | |||
557 | spin_unlock_irqrestore(&ec->lock, flags); | 558 | spin_unlock_irqrestore(&ec->lock, flags); |
558 | __acpi_ec_flush_event(ec); | 559 | __acpi_ec_flush_event(ec); |
559 | } | 560 | } |
561 | #endif /* CONFIG_PM_SLEEP */ | ||
560 | 562 | ||
561 | static bool acpi_ec_guard_event(struct acpi_ec *ec) | 563 | static bool acpi_ec_guard_event(struct acpi_ec *ec) |
562 | { | 564 | { |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 384cfc3083e1..6cf4988206f2 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -129,8 +129,18 @@ static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state) | |||
129 | 129 | ||
130 | control = obj->package.elements[1].integer.value; | 130 | control = obj->package.elements[1].integer.value; |
131 | for (i = 0; i < fan->fps_count; i++) { | 131 | for (i = 0; i < fan->fps_count; i++) { |
132 | if (control == fan->fps[i].control) | 132 | /* |
133 | * When Fine Grain Control is set, return the state | ||
134 | * corresponding to maximum fan->fps[i].control | ||
135 | * value compared to the current speed. Here the | ||
136 | * fan->fps[] is sorted array with increasing speed. | ||
137 | */ | ||
138 | if (fan->fif.fine_grain_ctrl && control < fan->fps[i].control) { | ||
139 | i = (i > 0) ? i - 1 : 0; | ||
133 | break; | 140 | break; |
141 | } else if (control == fan->fps[i].control) { | ||
142 | break; | ||
143 | } | ||
134 | } | 144 | } |
135 | if (i == fan->fps_count) { | 145 | if (i == fan->fps_count) { |
136 | dev_dbg(&device->dev, "Invalid control value returned\n"); | 146 | dev_dbg(&device->dev, "Invalid control value returned\n"); |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 4305ee9db4b2..416953a42510 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -162,11 +162,18 @@ void acpi_os_vprintf(const char *fmt, va_list args) | |||
162 | if (acpi_in_debugger) { | 162 | if (acpi_in_debugger) { |
163 | kdb_printf("%s", buffer); | 163 | kdb_printf("%s", buffer); |
164 | } else { | 164 | } else { |
165 | printk(KERN_CONT "%s", buffer); | 165 | if (printk_get_level(buffer)) |
166 | printk("%s", buffer); | ||
167 | else | ||
168 | printk(KERN_CONT "%s", buffer); | ||
166 | } | 169 | } |
167 | #else | 170 | #else |
168 | if (acpi_debugger_write_log(buffer) < 0) | 171 | if (acpi_debugger_write_log(buffer) < 0) { |
169 | printk(KERN_CONT "%s", buffer); | 172 | if (printk_get_level(buffer)) |
173 | printk("%s", buffer); | ||
174 | else | ||
175 | printk(KERN_CONT "%s", buffer); | ||
176 | } | ||
170 | #endif | 177 | #endif |
171 | } | 178 | } |
172 | 179 | ||
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index f2fd3fee588a..03f5ec11ab31 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c | |||
@@ -468,10 +468,11 @@ static int acpi_data_get_property_array(struct acpi_device_data *data, | |||
468 | } | 468 | } |
469 | 469 | ||
470 | /** | 470 | /** |
471 | * acpi_data_get_property_reference - returns handle to the referenced object | 471 | * __acpi_node_get_property_reference - returns handle to the referenced object |
472 | * @data: ACPI device data object containing the property | 472 | * @fwnode: Firmware node to get the property from |
473 | * @propname: Name of the property | 473 | * @propname: Name of the property |
474 | * @index: Index of the reference to return | 474 | * @index: Index of the reference to return |
475 | * @num_args: Maximum number of arguments after each reference | ||
475 | * @args: Location to store the returned reference with optional arguments | 476 | * @args: Location to store the returned reference with optional arguments |
476 | * | 477 | * |
477 | * Find property with @name, verifify that it is a package containing at least | 478 | * Find property with @name, verifify that it is a package containing at least |
@@ -482,17 +483,40 @@ static int acpi_data_get_property_array(struct acpi_device_data *data, | |||
482 | * If there's more than one reference in the property value package, @index is | 483 | * If there's more than one reference in the property value package, @index is |
483 | * used to select the one to return. | 484 | * used to select the one to return. |
484 | * | 485 | * |
486 | * It is possible to leave holes in the property value set like in the | ||
487 | * example below: | ||
488 | * | ||
489 | * Package () { | ||
490 | * "cs-gpios", | ||
491 | * Package () { | ||
492 | * ^GPIO, 19, 0, 0, | ||
493 | * ^GPIO, 20, 0, 0, | ||
494 | * 0, | ||
495 | * ^GPIO, 21, 0, 0, | ||
496 | * } | ||
497 | * } | ||
498 | * | ||
499 | * Calling this function with index %2 return %-ENOENT and with index %3 | ||
500 | * returns the last entry. If the property does not contain any more values | ||
501 | * %-ENODATA is returned. The NULL entry must be single integer and | ||
502 | * preferably contain value %0. | ||
503 | * | ||
485 | * Return: %0 on success, negative error code on failure. | 504 | * Return: %0 on success, negative error code on failure. |
486 | */ | 505 | */ |
487 | static int acpi_data_get_property_reference(struct acpi_device_data *data, | 506 | int __acpi_node_get_property_reference(struct fwnode_handle *fwnode, |
488 | const char *propname, size_t index, | 507 | const char *propname, size_t index, size_t num_args, |
489 | struct acpi_reference_args *args) | 508 | struct acpi_reference_args *args) |
490 | { | 509 | { |
491 | const union acpi_object *element, *end; | 510 | const union acpi_object *element, *end; |
492 | const union acpi_object *obj; | 511 | const union acpi_object *obj; |
512 | struct acpi_device_data *data; | ||
493 | struct acpi_device *device; | 513 | struct acpi_device *device; |
494 | int ret, idx = 0; | 514 | int ret, idx = 0; |
495 | 515 | ||
516 | data = acpi_device_data_of_node(fwnode); | ||
517 | if (!data) | ||
518 | return -EINVAL; | ||
519 | |||
496 | ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); | 520 | ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); |
497 | if (ret) | 521 | if (ret) |
498 | return ret; | 522 | return ret; |
@@ -532,59 +556,54 @@ static int acpi_data_get_property_reference(struct acpi_device_data *data, | |||
532 | while (element < end) { | 556 | while (element < end) { |
533 | u32 nargs, i; | 557 | u32 nargs, i; |
534 | 558 | ||
535 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) | 559 | if (element->type == ACPI_TYPE_LOCAL_REFERENCE) { |
536 | return -EPROTO; | 560 | ret = acpi_bus_get_device(element->reference.handle, |
537 | 561 | &device); | |
538 | ret = acpi_bus_get_device(element->reference.handle, &device); | 562 | if (ret) |
539 | if (ret) | 563 | return -ENODEV; |
540 | return -ENODEV; | 564 | |
541 | 565 | nargs = 0; | |
542 | element++; | 566 | element++; |
543 | nargs = 0; | 567 | |
544 | 568 | /* assume following integer elements are all args */ | |
545 | /* assume following integer elements are all args */ | 569 | for (i = 0; element + i < end && i < num_args; i++) { |
546 | for (i = 0; element + i < end; i++) { | 570 | int type = element[i].type; |
547 | int type = element[i].type; | 571 | |
572 | if (type == ACPI_TYPE_INTEGER) | ||
573 | nargs++; | ||
574 | else if (type == ACPI_TYPE_LOCAL_REFERENCE) | ||
575 | break; | ||
576 | else | ||
577 | return -EPROTO; | ||
578 | } | ||
548 | 579 | ||
549 | if (type == ACPI_TYPE_INTEGER) | 580 | if (nargs > MAX_ACPI_REFERENCE_ARGS) |
550 | nargs++; | ||
551 | else if (type == ACPI_TYPE_LOCAL_REFERENCE) | ||
552 | break; | ||
553 | else | ||
554 | return -EPROTO; | 581 | return -EPROTO; |
555 | } | ||
556 | 582 | ||
557 | if (idx++ == index) { | 583 | if (idx == index) { |
558 | args->adev = device; | 584 | args->adev = device; |
559 | args->nargs = nargs; | 585 | args->nargs = nargs; |
560 | for (i = 0; i < nargs; i++) | 586 | for (i = 0; i < nargs; i++) |
561 | args->args[i] = element[i].integer.value; | 587 | args->args[i] = element[i].integer.value; |
562 | 588 | ||
563 | return 0; | 589 | return 0; |
590 | } | ||
591 | |||
592 | element += nargs; | ||
593 | } else if (element->type == ACPI_TYPE_INTEGER) { | ||
594 | if (idx == index) | ||
595 | return -ENOENT; | ||
596 | element++; | ||
597 | } else { | ||
598 | return -EPROTO; | ||
564 | } | 599 | } |
565 | 600 | ||
566 | element += nargs; | 601 | idx++; |
567 | } | 602 | } |
568 | 603 | ||
569 | return -EPROTO; | 604 | return -ENODATA; |
570 | } | ||
571 | |||
572 | /** | ||
573 | * acpi_node_get_property_reference - get a handle to the referenced object. | ||
574 | * @fwnode: Firmware node to get the property from. | ||
575 | * @propname: Name of the property. | ||
576 | * @index: Index of the reference to return. | ||
577 | * @args: Location to store the returned reference with optional arguments. | ||
578 | */ | ||
579 | int acpi_node_get_property_reference(struct fwnode_handle *fwnode, | ||
580 | const char *name, size_t index, | ||
581 | struct acpi_reference_args *args) | ||
582 | { | ||
583 | struct acpi_device_data *data = acpi_device_data_of_node(fwnode); | ||
584 | |||
585 | return data ? acpi_data_get_property_reference(data, name, index, args) : -EINVAL; | ||
586 | } | 605 | } |
587 | EXPORT_SYMBOL_GPL(acpi_node_get_property_reference); | 606 | EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference); |
588 | 607 | ||
589 | static int acpi_data_prop_read_single(struct acpi_device_data *data, | 608 | static int acpi_data_prop_read_single(struct acpi_device_data *data, |
590 | const char *propname, | 609 | const char *propname, |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 94afcb2c384c..ddbeda6dbdc8 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -946,9 +946,17 @@ struct acpi_reference_args { | |||
946 | #ifdef CONFIG_ACPI | 946 | #ifdef CONFIG_ACPI |
947 | int acpi_dev_get_property(struct acpi_device *adev, const char *name, | 947 | int acpi_dev_get_property(struct acpi_device *adev, const char *name, |
948 | acpi_object_type type, const union acpi_object **obj); | 948 | acpi_object_type type, const union acpi_object **obj); |
949 | int acpi_node_get_property_reference(struct fwnode_handle *fwnode, | 949 | int __acpi_node_get_property_reference(struct fwnode_handle *fwnode, |
950 | const char *name, size_t index, | 950 | const char *name, size_t index, size_t num_args, |
951 | struct acpi_reference_args *args); | 951 | struct acpi_reference_args *args); |
952 | |||
953 | static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode, | ||
954 | const char *name, size_t index, | ||
955 | struct acpi_reference_args *args) | ||
956 | { | ||
957 | return __acpi_node_get_property_reference(fwnode, name, index, | ||
958 | MAX_ACPI_REFERENCE_ARGS, args); | ||
959 | } | ||
952 | 960 | ||
953 | int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname, | 961 | int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname, |
954 | void **valptr); | 962 | void **valptr); |
@@ -1024,6 +1032,14 @@ static inline int acpi_dev_get_property(struct acpi_device *adev, | |||
1024 | return -ENXIO; | 1032 | return -ENXIO; |
1025 | } | 1033 | } |
1026 | 1034 | ||
1035 | static inline int | ||
1036 | __acpi_node_get_property_reference(struct fwnode_handle *fwnode, | ||
1037 | const char *name, size_t index, size_t num_args, | ||
1038 | struct acpi_reference_args *args) | ||
1039 | { | ||
1040 | return -ENXIO; | ||
1041 | } | ||
1042 | |||
1027 | static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode, | 1043 | static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode, |
1028 | const char *name, size_t index, | 1044 | const char *name, size_t index, |
1029 | struct acpi_reference_args *args) | 1045 | struct acpi_reference_args *args) |