mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
ACPI support fixes for 7.4-rc1
- Separate handler locking from sysfs lifetime in the ACPI platform
profile driver to avoid possible deadlocks due to sysfs accesses
during driver removal (Daniel Lezcano)
- Introduce additional locking around the evaluation of selected ACPI
control methods in a few places to work around issues related to
concurrency in AML on some platforms (Ali Ahmet Memiş)
- Address two issues reported by Sashiko in the ACPI table data sysfs
interface (Jamie Nguyen)
- Initialize parser_state.aml_end in acpi_install_method() properly to
avoid out-of-bounds accesses during control method installation (Ivan
Hu)
-----BEGIN PGP SIGNATURE-----
iQFGBAABCAAwFiEEcM8Aw/RY0dgsiRUR7l+9nS/U47UFAmrk+i0SHHJqd0Byand5
c29ja2kubmV0AAoJEO5fvZ0v1OO1BKUIAIvsvGOzWnUBWGY2GN9umZfNbEFnYrXH
7mbAzDTP5lDjyqnrod7eSjXAATxWISxupR7qVPSbqjqGURwzMCZsPeX4ZRd5pUTZ
THA0KTeE57hMKj/dvzvFQKIswGUkruQ09NZ3J6KZ514CJJ7SgSOilbUDf+7xzbLZ
yLDDBc0POqhZaKIuAYSFsoRw+D7PB2q/k5Hvv8VVhumDgl2YcCLcpQSG4lftqdxn
R6bjVAQaKJj/nArxwdQRt/LdNSQu1WQgnLkq57Ewwd4tORBlgMsGP9GrR/9QaQqY
E6VINShueGRnDNIMAzb4imbXVsfE+gtoyYdAffCTV3HXy8aoJ95OwGA=
=04kC
-----END PGP SIGNATURE-----
Merge tag 'acpi-7.4-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI support fixes from Rafael Wysocki:
"These address assorted issues in ACPI support code and work around
concurrency-related issues in AML on some platforms:
- Separate handler locking from sysfs lifetime in the ACPI platform
profile driver to avoid possible deadlocks due to sysfs accesses
during driver removal (Daniel Lezcano)
- Introduce additional locking around the evaluation of selected ACPI
control methods in a few places to work around issues related to
concurrency in AML on some platforms (Ali Ahmet Memiş)
- Address two issues reported by Sashiko in the ACPI table data sysfs
interface (Jamie Nguyen)
- Initialize parser_state.aml_end in acpi_install_method() properly
to avoid out-of-bounds accesses during control method installation
(Ivan Hu)"
* tag 'acpi-7.4-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
ACPI: sysfs: Finish sysfs init when creating a table file fails
ACPI: sysfs: Map only the requested range in acpi_data_show()
ACPICA: Initialize parser_state.aml_end in acpi_install_method()
ACPI: platform_profile: Separate handler locking from sysfs lifetime
platform/x86: ideapad-laptop: Evaluate ACPI methods exclusively
thermal: intel: int340x: Evaluate _TMP exclusively
ACPI: battery: Evaluate battery methods exclusively
ACPI: utils: Add exclusive AML evaluation helpers
This commit is contained in:
commit
e3e15872e7
|
|
@ -503,6 +503,7 @@ acpi_status acpi_install_method(u8 *buffer)
|
|||
/* First AML opcode in the table must be a control method */
|
||||
|
||||
parser_state.aml = buffer + sizeof(struct acpi_table_header);
|
||||
parser_state.aml_end = buffer + table->length;
|
||||
opcode = acpi_ps_peek_opcode(&parser_state);
|
||||
if (opcode != AML_METHOD_OP) {
|
||||
return (AE_BAD_PARAMETER);
|
||||
|
|
|
|||
|
|
@ -647,9 +647,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
|
|||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
acpi_status status = AE_ERROR;
|
||||
|
||||
status = acpi_evaluate_object(battery->device->handle,
|
||||
use_bix ? "_BIX":"_BIF",
|
||||
NULL, &buffer);
|
||||
status = acpi_evaluate_object_exclusive(battery->device->handle,
|
||||
use_bix ? "_BIX" : "_BIF", NULL, &buffer);
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_handle_info(battery->device->handle,
|
||||
|
|
@ -688,8 +687,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
|
|||
msecs_to_jiffies(cache_time)))
|
||||
return 0;
|
||||
|
||||
status = acpi_evaluate_object(battery->device->handle, "_BST",
|
||||
NULL, &buffer);
|
||||
status = acpi_evaluate_object_exclusive(battery->device->handle, "_BST", NULL, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_handle_info(battery->device->handle,
|
||||
"_BST evaluation failed: %s",
|
||||
|
|
@ -739,8 +737,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
|
|||
!test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
|
||||
return -ENODEV;
|
||||
|
||||
status = acpi_execute_simple_method(battery->device->handle, "_BTP",
|
||||
battery->alarm);
|
||||
status = acpi_execute_simple_method_exclusive(battery->device->handle, "_BTP",
|
||||
battery->alarm);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,15 +8,25 @@
|
|||
#include <linux/bits.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_profile.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#define to_pprof_handler(d) (container_of(d, struct platform_profile_handler, dev))
|
||||
|
||||
/*
|
||||
* Protects profile_handlers membership and serializes profile operations
|
||||
* against each other and handler removal. Never held across sysfs teardown,
|
||||
* which can wait for callbacks that acquire this lock.
|
||||
*/
|
||||
static DEFINE_MUTEX(profile_lock);
|
||||
/* Serialize registration and sysfs updates without blocking sysfs callbacks. */
|
||||
static DEFINE_MUTEX(profile_registration_lock);
|
||||
static LIST_HEAD(profile_handlers);
|
||||
|
||||
struct platform_profile_handler {
|
||||
struct list_head node;
|
||||
const char *name;
|
||||
struct device dev;
|
||||
int minor;
|
||||
|
|
@ -44,6 +54,23 @@ static_assert(ARRAY_SIZE(profile_names) == PLATFORM_PROFILE_LAST);
|
|||
|
||||
static DEFINE_IDA(platform_profile_ida);
|
||||
|
||||
static int profile_for_each_handler(void *data,
|
||||
int (*fn)(struct device *dev, void *data))
|
||||
{
|
||||
struct platform_profile_handler *handler;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&profile_lock);
|
||||
|
||||
list_for_each_entry(handler, &profile_handlers, node) {
|
||||
ret = fn(&handler->dev, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* _commmon_choices_show - Show the available profile choices
|
||||
* @choices: The available profile choices
|
||||
|
|
@ -306,20 +333,18 @@ static ssize_t platform_profile_choices_show(struct kobject *kobj,
|
|||
int err;
|
||||
|
||||
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
|
||||
err = class_for_each_device(&platform_profile_class, NULL,
|
||||
&data, _aggregate_choices);
|
||||
err = profile_for_each_handler(&data, _aggregate_choices);
|
||||
if (err)
|
||||
return err;
|
||||
if (data.count == 1) {
|
||||
err = class_for_each_device(&platform_profile_class, NULL,
|
||||
&data, _remove_hidden_choices);
|
||||
err = profile_for_each_handler(&data, _remove_hidden_choices);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* no profile handler registered any more */
|
||||
if (bitmap_empty(data.aggregate, PLATFORM_PROFILE_LAST))
|
||||
if (!data.count || bitmap_empty(data.aggregate, PLATFORM_PROFILE_LAST))
|
||||
return -EINVAL;
|
||||
|
||||
return _commmon_choices_show(data.aggregate, buf);
|
||||
|
|
@ -384,8 +409,7 @@ static ssize_t platform_profile_show(struct kobject *kobj,
|
|||
int err;
|
||||
|
||||
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
|
||||
err = class_for_each_device(&platform_profile_class, NULL,
|
||||
&profile, _aggregate_profiles);
|
||||
err = profile_for_each_handler(&profile, _aggregate_profiles);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
|
@ -423,15 +447,13 @@ static ssize_t platform_profile_store(struct kobject *kobj,
|
|||
return -EINVAL;
|
||||
|
||||
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
|
||||
ret = class_for_each_device(&platform_profile_class, NULL,
|
||||
&data, _aggregate_choices);
|
||||
ret = profile_for_each_handler(&data, _aggregate_choices);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!test_bit(i, data.aggregate))
|
||||
if (!data.count || !test_bit(i, data.aggregate))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = class_for_each_device(&platform_profile_class, NULL, &i,
|
||||
_store_and_notify);
|
||||
ret = profile_for_each_handler(&i, _store_and_notify);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -450,22 +472,11 @@ static struct attribute *platform_profile_attrs[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static int profile_class_registered(struct device *dev, const void *data)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static umode_t profile_class_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
|
||||
{
|
||||
struct device *dev;
|
||||
guard(mutex)(&profile_lock);
|
||||
|
||||
dev = class_find_device(&platform_profile_class, NULL, NULL, profile_class_registered);
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
put_device(dev);
|
||||
|
||||
return attr->mode;
|
||||
return list_empty(&profile_handlers) ? 0 : attr->mode;
|
||||
}
|
||||
|
||||
static const struct attribute_group platform_profile_group = {
|
||||
|
|
@ -502,8 +513,7 @@ int platform_profile_cycle(void)
|
|||
int err;
|
||||
|
||||
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
|
||||
err = class_for_each_device(&platform_profile_class, NULL,
|
||||
&profile, _aggregate_profiles);
|
||||
err = profile_for_each_handler(&profile, _aggregate_profiles);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -512,8 +522,7 @@ int platform_profile_cycle(void)
|
|||
profile == PLATFORM_PROFILE_LAST)
|
||||
return -EINVAL;
|
||||
|
||||
err = class_for_each_device(&platform_profile_class, NULL,
|
||||
&data, _aggregate_choices);
|
||||
err = profile_for_each_handler(&data, _aggregate_choices);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -525,8 +534,7 @@ int platform_profile_cycle(void)
|
|||
PLATFORM_PROFILE_LAST,
|
||||
profile + 1);
|
||||
|
||||
err = class_for_each_device(&platform_profile_class, NULL, &next,
|
||||
_store_and_notify);
|
||||
err = profile_for_each_handler(&next, _store_and_notify);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
|
@ -583,7 +591,7 @@ struct device *platform_profile_register(struct device *dev, const char *name,
|
|||
}
|
||||
}
|
||||
|
||||
guard(mutex)(&profile_lock);
|
||||
guard(mutex)(&profile_registration_lock);
|
||||
|
||||
/* create class interface for individual handler */
|
||||
minor = ida_alloc(&platform_profile_ida, GFP_KERNEL);
|
||||
|
|
@ -604,6 +612,8 @@ struct device *platform_profile_register(struct device *dev, const char *name,
|
|||
put_device(ppdev);
|
||||
goto cleanup_ida;
|
||||
}
|
||||
scoped_guard(mutex, &profile_lock)
|
||||
list_add_tail(&to_pprof_handler(ppdev)->node, &profile_handlers);
|
||||
|
||||
sysfs_notify(acpi_kobj, NULL, "platform_profile");
|
||||
|
||||
|
|
@ -614,6 +624,9 @@ struct device *platform_profile_register(struct device *dev, const char *name,
|
|||
return ppdev;
|
||||
|
||||
cleanup_cur:
|
||||
scoped_guard(mutex, &profile_lock)
|
||||
list_del(&to_pprof_handler(ppdev)->node);
|
||||
|
||||
device_unregister(ppdev);
|
||||
|
||||
cleanup_ida:
|
||||
|
|
@ -636,7 +649,10 @@ void platform_profile_remove(struct device *dev)
|
|||
|
||||
pprof = to_pprof_handler(dev);
|
||||
|
||||
guard(mutex)(&profile_lock);
|
||||
guard(mutex)(&profile_registration_lock);
|
||||
|
||||
scoped_guard(mutex, &profile_lock)
|
||||
list_del(&pprof->node);
|
||||
|
||||
ida_free(&platform_profile_ida, pprof->minor);
|
||||
device_unregister(&pprof->dev);
|
||||
|
|
|
|||
|
|
@ -420,6 +420,7 @@ static ssize_t acpi_data_show(struct file *filp, struct kobject *kobj,
|
|||
struct acpi_data_attr *data_attr;
|
||||
void __iomem *base;
|
||||
ssize_t size;
|
||||
u64 end;
|
||||
|
||||
data_attr = container_of(bin_attr, struct acpi_data_attr, attr);
|
||||
size = data_attr->attr.size;
|
||||
|
|
@ -433,13 +434,17 @@ static ssize_t acpi_data_show(struct file *filp, struct kobject *kobj,
|
|||
if (count > size - offset)
|
||||
count = size - offset;
|
||||
|
||||
base = acpi_os_map_iomem(data_attr->addr, size);
|
||||
/* acpi_os_map_iomem() can't handle a range that wraps around */
|
||||
if (check_add_overflow(data_attr->addr, size, &end))
|
||||
return -EINVAL;
|
||||
|
||||
base = acpi_os_map_iomem(data_attr->addr + offset, count);
|
||||
if (!base)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy_fromio(buf, base + offset, count);
|
||||
memcpy_fromio(buf, base, count);
|
||||
|
||||
acpi_os_unmap_iomem(base, size);
|
||||
acpi_os_unmap_iomem(base, count);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
@ -511,7 +516,6 @@ static int acpi_tables_sysfs_init(void)
|
|||
struct acpi_table_header *table_header = NULL;
|
||||
int table_index;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
tables_kobj = kobject_create_and_add("tables", acpi_kobj);
|
||||
if (!tables_kobj)
|
||||
|
|
@ -536,13 +540,11 @@ static int acpi_tables_sysfs_init(void)
|
|||
|
||||
table_attr = kzalloc_obj(*table_attr);
|
||||
if (!table_attr)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
|
||||
ret = acpi_table_attr_init(tables_kobj,
|
||||
table_attr, table_header);
|
||||
if (ret) {
|
||||
if (acpi_table_attr_init(tables_kobj, table_attr, table_header)) {
|
||||
kfree(table_attr);
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
list_add_tail(&table_attr->node, &acpi_table_attr_list);
|
||||
acpi_table_data_init(table_header, table_attr);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
|
|
@ -243,6 +244,28 @@ acpi_extract_package(union acpi_object *package,
|
|||
|
||||
EXPORT_SYMBOL(acpi_extract_package);
|
||||
|
||||
static DEFINE_MUTEX(acpi_exclusive_eval_lock);
|
||||
|
||||
/**
|
||||
* acpi_evaluate_object_exclusive - Evaluate an object without interleaving
|
||||
* @handle: ACPI handle of the object or its scope.
|
||||
* @pathname: Path of the object relative to @handle.
|
||||
* @arguments: Arguments to pass, or NULL.
|
||||
* @buffer: Buffer for the return value, or NULL.
|
||||
*
|
||||
* Same as acpi_evaluate_object(), but serialized with other exclusive
|
||||
* evaluations. Use it only for methods known to break when interleaved.
|
||||
*/
|
||||
acpi_status acpi_evaluate_object_exclusive(acpi_handle handle, acpi_string pathname,
|
||||
struct acpi_object_list *arguments,
|
||||
struct acpi_buffer *buffer)
|
||||
{
|
||||
guard(mutex)(&acpi_exclusive_eval_lock);
|
||||
|
||||
return acpi_evaluate_object(handle, pathname, arguments, buffer);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_evaluate_object_exclusive);
|
||||
|
||||
acpi_status
|
||||
acpi_evaluate_integer(acpi_handle handle,
|
||||
acpi_string pathname,
|
||||
|
|
@ -277,6 +300,16 @@ acpi_evaluate_integer(acpi_handle handle,
|
|||
|
||||
EXPORT_SYMBOL(acpi_evaluate_integer);
|
||||
|
||||
acpi_status acpi_evaluate_integer_exclusive(acpi_handle handle, acpi_string pathname,
|
||||
struct acpi_object_list *arguments,
|
||||
unsigned long long *data)
|
||||
{
|
||||
guard(mutex)(&acpi_exclusive_eval_lock);
|
||||
|
||||
return acpi_evaluate_integer(handle, pathname, arguments, data);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_evaluate_integer_exclusive);
|
||||
|
||||
int acpi_get_local_u64_address(acpi_handle handle, u64 *addr)
|
||||
{
|
||||
acpi_status status;
|
||||
|
|
@ -685,6 +718,14 @@ acpi_status acpi_execute_simple_method(acpi_handle handle, char *method,
|
|||
}
|
||||
EXPORT_SYMBOL(acpi_execute_simple_method);
|
||||
|
||||
acpi_status acpi_execute_simple_method_exclusive(acpi_handle handle, char *method, u64 arg)
|
||||
{
|
||||
guard(mutex)(&acpi_exclusive_eval_lock);
|
||||
|
||||
return acpi_execute_simple_method(handle, method, arg);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_execute_simple_method_exclusive);
|
||||
|
||||
/**
|
||||
* acpi_evaluate_ej0: Evaluate _EJ0 method for hotplug operations
|
||||
* @handle: ACPI device handle
|
||||
|
|
|
|||
|
|
@ -297,12 +297,16 @@ static void ideapad_shared_exit(struct ideapad_private *priv)
|
|||
#define IDEAPAD_EC_POLL_MIN_US 150
|
||||
#define IDEAPAD_EC_POLL_MAX_US 300
|
||||
|
||||
/*
|
||||
* On some models GBMD and the battery _BIX take the EC mutex and a
|
||||
* serialized method in opposite order, so evaluate all methods exclusively.
|
||||
*/
|
||||
static int eval_int(acpi_handle handle, const char *name, unsigned long *res)
|
||||
{
|
||||
unsigned long long result;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(handle, (char *)name, NULL, &result);
|
||||
status = acpi_evaluate_integer_exclusive(handle, (char *)name, NULL, &result);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
|
||||
|
|
@ -324,7 +328,7 @@ static int eval_int_with_arg(acpi_handle handle, const char *name, unsigned long
|
|||
in_obj.type = ACPI_TYPE_INTEGER;
|
||||
in_obj.integer.value = arg;
|
||||
|
||||
status = acpi_evaluate_integer(handle, (char *)name, ¶ms, &result);
|
||||
status = acpi_evaluate_integer_exclusive(handle, (char *)name, ¶ms, &result);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
|
||||
|
|
@ -336,7 +340,7 @@ static int eval_int_with_arg(acpi_handle handle, const char *name, unsigned long
|
|||
|
||||
static int exec_simple_method(acpi_handle handle, const char *name, unsigned long arg)
|
||||
{
|
||||
acpi_status status = acpi_execute_simple_method(handle, (char *)name, arg);
|
||||
acpi_status status = acpi_execute_simple_method_exclusive(handle, (char *)name, arg);
|
||||
|
||||
return ACPI_FAILURE(status) ? -EIO : 0;
|
||||
}
|
||||
|
|
@ -394,7 +398,7 @@ static int eval_vpcw(acpi_handle handle, unsigned long cmd, unsigned long data)
|
|||
in_obj[1].type = ACPI_TYPE_INTEGER;
|
||||
in_obj[1].integer.value = data;
|
||||
|
||||
status = acpi_evaluate_object(handle, "VPCW", ¶ms, NULL);
|
||||
status = acpi_evaluate_object_exclusive(handle, "VPCW", ¶ms, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
|
||||
|
|
|
|||
|
|
@ -217,8 +217,7 @@ static int int3403_add(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
|
||||
status = acpi_evaluate_integer(priv->adev->handle, "_TMP",
|
||||
NULL, &tmp);
|
||||
status = acpi_evaluate_integer_exclusive(priv->adev->handle, "_TMP", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
status = acpi_evaluate_integer(priv->adev->handle, "PTYP",
|
||||
NULL, &priv->type);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,11 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone,
|
|||
unsigned long long tmp;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(d->adev->handle, "_TMP", NULL, &tmp);
|
||||
/*
|
||||
* On some ThinkPads _TMP switches the EC page selector without
|
||||
* taking the mutex the battery methods use.
|
||||
*/
|
||||
status = acpi_evaluate_integer_exclusive(d->adev->handle, "_TMP", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
status = acpi_evaluate_integer(adev->handle, "_TMP", NULL, &tmp);
|
||||
status = acpi_evaluate_integer_exclusive(adev->handle, "_TMP", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
/* there is no _TMP method, add local method */
|
||||
if (intel_tcc_get_tjmax(-1) > 0)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ acpi_status
|
|||
acpi_evaluate_integer(acpi_handle handle,
|
||||
acpi_string pathname,
|
||||
struct acpi_object_list *arguments, unsigned long long *data);
|
||||
acpi_status acpi_evaluate_object_exclusive(acpi_handle handle, acpi_string pathname,
|
||||
struct acpi_object_list *arguments,
|
||||
struct acpi_buffer *buffer);
|
||||
acpi_status acpi_evaluate_integer_exclusive(acpi_handle handle, acpi_string pathname,
|
||||
struct acpi_object_list *arguments,
|
||||
unsigned long long *data);
|
||||
bool acpi_evaluate_reference(acpi_handle handle, acpi_string pathname,
|
||||
struct acpi_object_list *arguments,
|
||||
struct acpi_handle_list *list);
|
||||
|
|
@ -50,6 +56,7 @@ acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code,
|
|||
bool acpi_has_method(acpi_handle handle, char *name);
|
||||
acpi_status acpi_execute_simple_method(acpi_handle handle, char *method,
|
||||
u64 arg);
|
||||
acpi_status acpi_execute_simple_method_exclusive(acpi_handle handle, char *method, u64 arg);
|
||||
acpi_status acpi_evaluate_ej0(acpi_handle handle);
|
||||
acpi_status acpi_evaluate_lck(acpi_handle handle, int lock);
|
||||
acpi_status acpi_evaluate_reg(acpi_handle handle, u8 space_id, u32 function);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user