Linux-libre 5.3-gnu
[librecmc/linux-libre.git] / drivers / acpi / acpica / hwacpi.c
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 - 2019, 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 */