diff --git a/drivers/acpi/acpi_tad.c b/drivers/acpi/acpi_tad.c index fc43df083738..45459a4cafae 100644 --- a/drivers/acpi/acpi_tad.c +++ b/drivers/acpi/acpi_tad.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +87,8 @@ static bool acpi_tad_rt_is_invalid(struct acpi_tad_rt *rt) rt->daylight > 3; } +static DEFINE_MUTEX(acpi_tad_aml_lock); + static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt) { acpi_handle handle = ACPI_HANDLE(dev); @@ -113,6 +116,8 @@ static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt) if (PM_RUNTIME_ACQUIRE_ERR(&pm)) return -ENXIO; + guard(mutex)(&acpi_tad_aml_lock); + status = acpi_evaluate_integer(handle, "_SRT", &arg_list, &retval); if (ACPI_FAILURE(status) || retval) return -EIO; @@ -124,30 +129,27 @@ static int acpi_tad_evaluate_grt(struct device *dev, struct acpi_tad_rt *rt) { acpi_handle handle = ACPI_HANDLE(dev); struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER }; - union acpi_object *out_obj; - struct acpi_tad_rt *data; acpi_status status; int ret = -EIO; + guard(mutex)(&acpi_tad_aml_lock); + status = acpi_evaluate_object(handle, "_GRT", NULL, &output); - if (ACPI_FAILURE(status)) - goto out_free; + if (ACPI_SUCCESS(status)) { + union acpi_object *out_obj; - out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_BUFFER) - goto out_free; + out_obj = output.pointer; + if (out_obj->type == ACPI_TYPE_BUFFER && + out_obj->buffer.length == sizeof(*rt)) { + struct acpi_tad_rt *data; - if (out_obj->buffer.length != sizeof(*rt)) - goto out_free; - - data = (struct acpi_tad_rt *)(out_obj->buffer.pointer); - if (!data->valid) - goto out_free; - - memcpy(rt, data, sizeof(*rt)); - ret = 0; - -out_free: + data = (struct acpi_tad_rt *)(out_obj->buffer.pointer); + if (data->valid) { + memcpy(rt, data, sizeof(*rt)); + ret = 0; + } + } + } ACPI_FREE(output.pointer); return ret; } @@ -193,6 +195,8 @@ static int __acpi_tad_wake_set(struct device *dev, char *method, u32 timer_id, args[0].integer.value = timer_id; args[1].integer.value = value; + guard(mutex)(&acpi_tad_aml_lock); + status = acpi_evaluate_integer(handle, method, &arg_list, &retval); if (ACPI_FAILURE(status) || retval) return -EIO; @@ -215,6 +219,8 @@ static int __acpi_tad_wake_read(struct device *dev, char *method, u32 timer_id, args[0].integer.value = timer_id; + guard(mutex)(&acpi_tad_aml_lock); + status = acpi_evaluate_integer(handle, method, &arg_list, retval); if (ACPI_FAILURE(status)) return -EIO; @@ -416,6 +422,8 @@ static int acpi_tad_clear_status(struct device *dev, u32 timer_id) if (PM_RUNTIME_ACQUIRE_ERR(&pm)) return -ENXIO; + guard(mutex)(&acpi_tad_aml_lock); + status = acpi_evaluate_integer(handle, "_CWS", &arg_list, &retval); if (ACPI_FAILURE(status) || retval) return -EIO; @@ -456,6 +464,8 @@ static ssize_t acpi_tad_status_read(struct device *dev, char *buf, u32 timer_id) if (PM_RUNTIME_ACQUIRE_ERR(&pm)) return -ENXIO; + guard(mutex)(&acpi_tad_aml_lock); + status = acpi_evaluate_integer(handle, "_GWS", &arg_list, &retval); if (ACPI_FAILURE(status)) return -EIO;