xref: /linux/drivers/acpi/acpica/hwacpi.c (revision 58f6259b7a08f8d47d4629609703d358b042f0fd)
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
5  *
6  * Copyright (C) 2000 - 2023, Intel Corp.
7  *
8  *****************************************************************************/
9 
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 
13 #define _COMPONENT          ACPI_HARDWARE
14 ACPI_MODULE_NAME("hwacpi")
15 
16 #if (!ACPI_REDUCED_HARDWARE)	/* Entire module */
17 /******************************************************************************
18  *
19  * FUNCTION:    acpi_hw_set_mode
20  *
21  * PARAMETERS:  mode            - SYS_MODE_ACPI or SYS_MODE_LEGACY
22  *
23  * RETURN:      Status
24  *
25  * DESCRIPTION: Transitions the system into the requested mode.
26  *
27  ******************************************************************************/
28 acpi_status acpi_hw_set_mode(u32 mode)
29 {
30 
31 	acpi_status status;
32 
33 	ACPI_FUNCTION_TRACE(hw_set_mode);
34 
35 	/* If the Hardware Reduced flag is set, machine is always in acpi mode */
36 
37 	if (acpi_gbl_reduced_hardware) {
38 		return_ACPI_STATUS(AE_OK);
39 	}
40 
41 	/*
42 	 * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
43 	 * system does not support mode transition.
44 	 */
45 	if (!acpi_gbl_FADT.smi_command) {
46 		ACPI_ERROR((AE_INFO,
47 			    "No SMI_CMD in FADT, mode transition failed"));
48 		return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
49 	}
50 
51 	/*
52 	 * ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE
53 	 * in FADT: If it is zero, enabling or disabling is not supported.
54 	 * As old systems may have used zero for mode transition,
55 	 * we make sure both the numbers are zero to determine these
56 	 * transitions are not supported.
57 	 */
58 	if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
59 		ACPI_ERROR((AE_INFO,
60 			    "No ACPI mode transition supported in this system "
61 			    "(enable/disable both zero)"));
62 		return_ACPI_STATUS(AE_OK);
63 	}
64 
65 	switch (mode) {
66 	case ACPI_SYS_MODE_ACPI:
67 
68 		/* BIOS should have disabled ALL fixed and GP events */
69 
70 		status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
71 					    (u32) acpi_gbl_FADT.acpi_enable, 8);
72 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
73 				  "Attempting to enable ACPI mode\n"));
74 		break;
75 
76 	case ACPI_SYS_MODE_LEGACY:
77 		/*
78 		 * BIOS should clear all fixed status bits and restore fixed event
79 		 * enable bits to default
80 		 */
81 		status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
82 					    (u32)acpi_gbl_FADT.acpi_disable, 8);
83 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
84 				  "Attempting to enable Legacy (non-ACPI) mode\n"));
85 		break;
86 
87 	default:
88 
89 		return_ACPI_STATUS(AE_BAD_PARAMETER);
90 	}
91 
92 	if (ACPI_FAILURE(status)) {
93 		ACPI_EXCEPTION((AE_INFO, status,
94 				"Could not write ACPI mode change"));
95 		return_ACPI_STATUS(status);
96 	}
97 
98 	return_ACPI_STATUS(AE_OK);
99 }
100 
101 /*******************************************************************************
102  *
103  * FUNCTION:    acpi_hw_get_mode
104  *
105  * PARAMETERS:  none
106  *
107  * RETURN:      SYS_MODE_ACPI or SYS_MODE_LEGACY
108  *
109  * DESCRIPTION: Return current operating state of system. Determined by
110  *              querying the SCI_EN bit.
111  *
112  ******************************************************************************/
113 
114 u32 acpi_hw_get_mode(void)
115 {
116 	acpi_status status;
117 	u32 value;
118 
119 	ACPI_FUNCTION_TRACE(hw_get_mode);
120 
121 	/* If the Hardware Reduced flag is set, machine is always in acpi mode */
122 
123 	if (acpi_gbl_reduced_hardware) {
124 		return_UINT32(ACPI_SYS_MODE_ACPI);
125 	}
126 
127 	/*
128 	 * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
129 	 * system does not support mode transition.
130 	 */
131 	if (!acpi_gbl_FADT.smi_command) {
132 		return_UINT32(ACPI_SYS_MODE_ACPI);
133 	}
134 
135 	status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
136 	if (ACPI_FAILURE(status)) {
137 		return_UINT32(ACPI_SYS_MODE_LEGACY);
138 	}
139 
140 	if (value) {
141 		return_UINT32(ACPI_SYS_MODE_ACPI);
142 	} else {
143 		return_UINT32(ACPI_SYS_MODE_LEGACY);
144 	}
145 }
146 
147 #endif				/* !ACPI_REDUCED_HARDWARE */
148