linux/drivers/acpi/acpica/hwacpi.c

148 lines
3.8 KiB
C

// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/******************************************************************************
*
* Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
*
* Copyright (C) 2000 - 2021, Intel Corp.
*
*****************************************************************************/
#include <acpi/acpi.h>
#include "accommon.h"
#define _COMPONENT ACPI_HARDWARE
ACPI_MODULE_NAME("hwacpi")
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
/******************************************************************************
*
* FUNCTION: acpi_hw_set_mode
*
* PARAMETERS: mode - SYS_MODE_ACPI or SYS_MODE_LEGACY
*
* RETURN: Status
*
* DESCRIPTION: Transitions the system into the requested mode.
*
******************************************************************************/
acpi_status acpi_hw_set_mode(u32 mode)
{
acpi_status status;
ACPI_FUNCTION_TRACE(hw_set_mode);
/* If the Hardware Reduced flag is set, machine is always in acpi mode */
if (acpi_gbl_reduced_hardware) {
return_ACPI_STATUS(AE_OK);
}
/*
* ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
* system does not support mode transition.
*/
if (!acpi_gbl_FADT.smi_command) {
ACPI_ERROR((AE_INFO,
"No SMI_CMD in FADT, mode transition failed"));
return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
}
/*
* ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE
* in FADT: If it is zero, enabling or disabling is not supported.
* As old systems may have used zero for mode transition,
* we make sure both the numbers are zero to determine these
* transitions are not supported.
*/
if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
ACPI_ERROR((AE_INFO,
"No ACPI mode transition supported in this system "
"(enable/disable both zero)"));
return_ACPI_STATUS(AE_OK);
}
switch (mode) {
case ACPI_SYS_MODE_ACPI:
/* BIOS should have disabled ALL fixed and GP events */
status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.acpi_enable, 8);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Attempting to enable ACPI mode\n"));
break;
case ACPI_SYS_MODE_LEGACY:
/*
* BIOS should clear all fixed status bits and restore fixed event
* enable bits to default
*/
status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32)acpi_gbl_FADT.acpi_disable, 8);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Attempting to enable Legacy (non-ACPI) mode\n"));
break;
default:
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not write ACPI mode change"));
return_ACPI_STATUS(status);
}
return_ACPI_STATUS(AE_OK);
}
/*******************************************************************************
*
* FUNCTION: acpi_hw_get_mode
*
* PARAMETERS: none
*
* RETURN: SYS_MODE_ACPI or SYS_MODE_LEGACY
*
* DESCRIPTION: Return current operating state of system. Determined by
* querying the SCI_EN bit.
*
******************************************************************************/
u32 acpi_hw_get_mode(void)
{
acpi_status status;
u32 value;
ACPI_FUNCTION_TRACE(hw_get_mode);
/* If the Hardware Reduced flag is set, machine is always in acpi mode */
if (acpi_gbl_reduced_hardware) {
return_UINT32(ACPI_SYS_MODE_ACPI);
}
/*
* ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
* system does not support mode transition.
*/
if (!acpi_gbl_FADT.smi_command) {
return_UINT32(ACPI_SYS_MODE_ACPI);
}
status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
if (ACPI_FAILURE(status)) {
return_UINT32(ACPI_SYS_MODE_LEGACY);
}
if (value) {
return_UINT32(ACPI_SYS_MODE_ACPI);
} else {
return_UINT32(ACPI_SYS_MODE_LEGACY);
}
}
#endif /* !ACPI_REDUCED_HARDWARE */