linux/drivers/acpi/acpica/exsystem.c
Rafael J. Wysocki c244dc1bc9 Revert "ACPICA: executer/exsystem: Warn about sleeps greater than 10 ms"
Commit 6eaf08770e ("ACPICA: executer/exsystem: Warn about sleeps
greater than 10 ms") made acpi_ex_system_do_sleep() log a warning for
sleep times greater than 10 ms, but such sleep times are used in
power management AML because of the PCI specification requirements.

This results with logging warnings that cannot really be acted on in
any useful way which is annoying and these warnings show up in the logs
on many production systems, so revert commit 6eaf08770e.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-05-21 18:02:26 +02:00

280 lines
7.5 KiB
C

// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/******************************************************************************
*
* Module Name: exsystem - Interface to OS services
*
* Copyright (C) 2000 - 2022, Intel Corp.
*
*****************************************************************************/
#include <acpi/acpi.h>
#include "accommon.h"
#include "acinterp.h"
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME("exsystem")
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_wait_semaphore
*
* PARAMETERS: semaphore - Semaphore to wait on
* timeout - Max time to wait
*
* RETURN: Status
*
* DESCRIPTION: Implements a semaphore wait with a check to see if the
* semaphore is available immediately. If it is not, the
* interpreter is released before waiting.
*
******************************************************************************/
acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
{
acpi_status status;
ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);
status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT);
if (ACPI_SUCCESS(status)) {
return_ACPI_STATUS(status);
}
if (status == AE_TIME) {
/* We must wait, so unlock the interpreter */
acpi_ex_exit_interpreter();
status = acpi_os_wait_semaphore(semaphore, 1, timeout);
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"*** Thread awake after blocking, %s\n",
acpi_format_exception(status)));
/* Reacquire the interpreter */
acpi_ex_enter_interpreter();
}
return_ACPI_STATUS(status);
}
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_wait_mutex
*
* PARAMETERS: mutex - Mutex to wait on
* timeout - Max time to wait
*
* RETURN: Status
*
* DESCRIPTION: Implements a mutex wait with a check to see if the
* mutex is available immediately. If it is not, the
* interpreter is released before waiting.
*
******************************************************************************/
acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
{
acpi_status status;
ACPI_FUNCTION_TRACE(ex_system_wait_mutex);
status = acpi_os_acquire_mutex(mutex, ACPI_DO_NOT_WAIT);
if (ACPI_SUCCESS(status)) {
return_ACPI_STATUS(status);
}
if (status == AE_TIME) {
/* We must wait, so unlock the interpreter */
acpi_ex_exit_interpreter();
status = acpi_os_acquire_mutex(mutex, timeout);
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"*** Thread awake after blocking, %s\n",
acpi_format_exception(status)));
/* Reacquire the interpreter */
acpi_ex_enter_interpreter();
}
return_ACPI_STATUS(status);
}
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_do_stall
*
* PARAMETERS: how_long_us - The amount of time to stall,
* in microseconds
*
* RETURN: Status
*
* DESCRIPTION: Suspend running thread for specified amount of time.
* Note: ACPI specification requires that Stall() does not
* relinquish the processor, and delays longer than 100 usec
* should use Sleep() instead. We allow stalls up to 255 usec
* for compatibility with other interpreters and existing BIOSs.
*
******************************************************************************/
acpi_status acpi_ex_system_do_stall(u32 how_long_us)
{
acpi_status status = AE_OK;
ACPI_FUNCTION_ENTRY();
if (how_long_us > 255) {
/*
* Longer than 255 microseconds, this is an error
*
* (ACPI specifies 100 usec as max, but this gives some slack in
* order to support existing BIOSs)
*/
ACPI_ERROR((AE_INFO,
"Time parameter is too large (%u)", how_long_us));
status = AE_AML_OPERAND_VALUE;
} else {
if (how_long_us > 100) {
ACPI_WARNING((AE_INFO,
"Time parameter %u us > 100 us violating ACPI spec, please fix the firmware.",
how_long_us));
}
acpi_os_stall(how_long_us);
}
return (status);
}
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_do_sleep
*
* PARAMETERS: how_long_ms - The amount of time to sleep,
* in milliseconds
*
* RETURN: None
*
* DESCRIPTION: Sleep the running thread for specified amount of time.
*
******************************************************************************/
acpi_status acpi_ex_system_do_sleep(u64 how_long_ms)
{
ACPI_FUNCTION_ENTRY();
/* Since this thread will sleep, we must release the interpreter */
acpi_ex_exit_interpreter();
/*
* For compatibility with other ACPI implementations and to prevent
* accidental deep sleeps, limit the sleep time to something reasonable.
*/
if (how_long_ms > ACPI_MAX_SLEEP) {
how_long_ms = ACPI_MAX_SLEEP;
}
acpi_os_sleep(how_long_ms);
/* And now we must get the interpreter again */
acpi_ex_enter_interpreter();
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_signal_event
*
* PARAMETERS: obj_desc - The object descriptor for this op
*
* RETURN: Status
*
* DESCRIPTION: Provides an access point to perform synchronization operations
* within the AML.
*
******************************************************************************/
acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
{
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE(ex_system_signal_event);
if (obj_desc) {
status =
acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1);
}
return_ACPI_STATUS(status);
}
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_wait_event
*
* PARAMETERS: time_desc - The 'time to delay' object descriptor
* obj_desc - The object descriptor for this op
*
* RETURN: Status
*
* DESCRIPTION: Provides an access point to perform synchronization operations
* within the AML. This operation is a request to wait for an
* event.
*
******************************************************************************/
acpi_status
acpi_ex_system_wait_event(union acpi_operand_object *time_desc,
union acpi_operand_object *obj_desc)
{
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE(ex_system_wait_event);
if (obj_desc) {
status =
acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore,
(u16) time_desc->integer.
value);
}
return_ACPI_STATUS(status);
}
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_reset_event
*
* PARAMETERS: obj_desc - The object descriptor for this op
*
* RETURN: Status
*
* DESCRIPTION: Reset an event to a known state.
*
******************************************************************************/
acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc)
{
acpi_status status = AE_OK;
acpi_semaphore temp_semaphore;
ACPI_FUNCTION_ENTRY();
/*
* We are going to simply delete the existing semaphore and
* create a new one!
*/
status =
acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
if (ACPI_SUCCESS(status)) {
(void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore);
obj_desc->event.os_semaphore = temp_semaphore;
}
return (status);
}