Commit d30dc9abb4aacfd4df3f486f22bcbc0531b73283
Committed by
Len Brown
1 parent
bbf25010f1
Exists in
master
and in
7 other branches
ACPICA: hw: remove use_lock flag from acpi_hw_register_{read, write}
use_lock flag is used once for acpi_hw_register_read, and never for acpi_hw_register_write. It will greatly simplify understanding of locking if we just drop this use_lock altogether, and wrap the only call to ..._read in lock/unlock. Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> Signed-off-by: Len Brown <len.brown@intel.com>
Showing 4 changed files with 48 additions and 78 deletions Inline Diff
drivers/acpi/events/evevent.c
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Module Name: evevent - Fixed Event handling and dispatch | 3 | * Module Name: evevent - Fixed Event handling and dispatch |
4 | * | 4 | * |
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions, and the following disclaimer, | 15 | * notice, this list of conditions, and the following disclaimer, |
16 | * without modification. | 16 | * without modification. |
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | 17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
18 | * substantially similar to the "NO WARRANTY" disclaimer below | 18 | * substantially similar to the "NO WARRANTY" disclaimer below |
19 | * ("Disclaimer") and any redistribution must be conditioned upon | 19 | * ("Disclaimer") and any redistribution must be conditioned upon |
20 | * including a substantially similar Disclaimer requirement for further | 20 | * including a substantially similar Disclaimer requirement for further |
21 | * binary redistribution. | 21 | * binary redistribution. |
22 | * 3. Neither the names of the above-listed copyright holders nor the names | 22 | * 3. Neither the names of the above-listed copyright holders nor the names |
23 | * of any contributors may be used to endorse or promote products derived | 23 | * of any contributors may be used to endorse or promote products derived |
24 | * from this software without specific prior written permission. | 24 | * from this software without specific prior written permission. |
25 | * | 25 | * |
26 | * Alternatively, this software may be distributed under the terms of the | 26 | * Alternatively, this software may be distributed under the terms of the |
27 | * GNU General Public License ("GPL") version 2 as published by the Free | 27 | * GNU General Public License ("GPL") version 2 as published by the Free |
28 | * Software Foundation. | 28 | * Software Foundation. |
29 | * | 29 | * |
30 | * NO WARRANTY | 30 | * NO WARRANTY |
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | 33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | 39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acevents.h> | 45 | #include <acpi/acevents.h> |
46 | 46 | ||
47 | #define _COMPONENT ACPI_EVENTS | 47 | #define _COMPONENT ACPI_EVENTS |
48 | ACPI_MODULE_NAME("evevent") | 48 | ACPI_MODULE_NAME("evevent") |
49 | 49 | ||
50 | /* Local prototypes */ | 50 | /* Local prototypes */ |
51 | static acpi_status acpi_ev_fixed_event_initialize(void); | 51 | static acpi_status acpi_ev_fixed_event_initialize(void); |
52 | 52 | ||
53 | static u32 acpi_ev_fixed_event_dispatch(u32 event); | 53 | static u32 acpi_ev_fixed_event_dispatch(u32 event); |
54 | 54 | ||
55 | /******************************************************************************* | 55 | /******************************************************************************* |
56 | * | 56 | * |
57 | * FUNCTION: acpi_ev_initialize_events | 57 | * FUNCTION: acpi_ev_initialize_events |
58 | * | 58 | * |
59 | * PARAMETERS: None | 59 | * PARAMETERS: None |
60 | * | 60 | * |
61 | * RETURN: Status | 61 | * RETURN: Status |
62 | * | 62 | * |
63 | * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE) | 63 | * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE) |
64 | * | 64 | * |
65 | ******************************************************************************/ | 65 | ******************************************************************************/ |
66 | 66 | ||
67 | acpi_status acpi_ev_initialize_events(void) | 67 | acpi_status acpi_ev_initialize_events(void) |
68 | { | 68 | { |
69 | acpi_status status; | 69 | acpi_status status; |
70 | 70 | ||
71 | ACPI_FUNCTION_TRACE(ev_initialize_events); | 71 | ACPI_FUNCTION_TRACE(ev_initialize_events); |
72 | 72 | ||
73 | /* | 73 | /* |
74 | * Initialize the Fixed and General Purpose Events. This is done prior to | 74 | * Initialize the Fixed and General Purpose Events. This is done prior to |
75 | * enabling SCIs to prevent interrupts from occurring before the handlers are | 75 | * enabling SCIs to prevent interrupts from occurring before the handlers are |
76 | * installed. | 76 | * installed. |
77 | */ | 77 | */ |
78 | status = acpi_ev_fixed_event_initialize(); | 78 | status = acpi_ev_fixed_event_initialize(); |
79 | if (ACPI_FAILURE(status)) { | 79 | if (ACPI_FAILURE(status)) { |
80 | ACPI_EXCEPTION((AE_INFO, status, | 80 | ACPI_EXCEPTION((AE_INFO, status, |
81 | "Unable to initialize fixed events")); | 81 | "Unable to initialize fixed events")); |
82 | return_ACPI_STATUS(status); | 82 | return_ACPI_STATUS(status); |
83 | } | 83 | } |
84 | 84 | ||
85 | status = acpi_ev_gpe_initialize(); | 85 | status = acpi_ev_gpe_initialize(); |
86 | if (ACPI_FAILURE(status)) { | 86 | if (ACPI_FAILURE(status)) { |
87 | ACPI_EXCEPTION((AE_INFO, status, | 87 | ACPI_EXCEPTION((AE_INFO, status, |
88 | "Unable to initialize general purpose events")); | 88 | "Unable to initialize general purpose events")); |
89 | return_ACPI_STATUS(status); | 89 | return_ACPI_STATUS(status); |
90 | } | 90 | } |
91 | 91 | ||
92 | return_ACPI_STATUS(status); | 92 | return_ACPI_STATUS(status); |
93 | } | 93 | } |
94 | 94 | ||
95 | /******************************************************************************* | 95 | /******************************************************************************* |
96 | * | 96 | * |
97 | * FUNCTION: acpi_ev_install_fadt_gpes | 97 | * FUNCTION: acpi_ev_install_fadt_gpes |
98 | * | 98 | * |
99 | * PARAMETERS: None | 99 | * PARAMETERS: None |
100 | * | 100 | * |
101 | * RETURN: Status | 101 | * RETURN: Status |
102 | * | 102 | * |
103 | * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks | 103 | * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks |
104 | * (0 and 1). This causes the _PRW methods to be run, so the HW | 104 | * (0 and 1). This causes the _PRW methods to be run, so the HW |
105 | * must be fully initialized at this point, including global lock | 105 | * must be fully initialized at this point, including global lock |
106 | * support. | 106 | * support. |
107 | * | 107 | * |
108 | ******************************************************************************/ | 108 | ******************************************************************************/ |
109 | 109 | ||
110 | acpi_status acpi_ev_install_fadt_gpes(void) | 110 | acpi_status acpi_ev_install_fadt_gpes(void) |
111 | { | 111 | { |
112 | acpi_status status; | 112 | acpi_status status; |
113 | 113 | ||
114 | ACPI_FUNCTION_TRACE(ev_install_fadt_gpes); | 114 | ACPI_FUNCTION_TRACE(ev_install_fadt_gpes); |
115 | 115 | ||
116 | /* Namespace must be locked */ | 116 | /* Namespace must be locked */ |
117 | 117 | ||
118 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 118 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
119 | if (ACPI_FAILURE(status)) { | 119 | if (ACPI_FAILURE(status)) { |
120 | return (status); | 120 | return (status); |
121 | } | 121 | } |
122 | 122 | ||
123 | /* FADT GPE Block 0 */ | 123 | /* FADT GPE Block 0 */ |
124 | 124 | ||
125 | (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, | 125 | (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, |
126 | acpi_gbl_gpe_fadt_blocks[0]); | 126 | acpi_gbl_gpe_fadt_blocks[0]); |
127 | 127 | ||
128 | /* FADT GPE Block 1 */ | 128 | /* FADT GPE Block 1 */ |
129 | 129 | ||
130 | (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, | 130 | (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, |
131 | acpi_gbl_gpe_fadt_blocks[1]); | 131 | acpi_gbl_gpe_fadt_blocks[1]); |
132 | 132 | ||
133 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 133 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
134 | return_ACPI_STATUS(AE_OK); | 134 | return_ACPI_STATUS(AE_OK); |
135 | } | 135 | } |
136 | 136 | ||
137 | /******************************************************************************* | 137 | /******************************************************************************* |
138 | * | 138 | * |
139 | * FUNCTION: acpi_ev_install_xrupt_handlers | 139 | * FUNCTION: acpi_ev_install_xrupt_handlers |
140 | * | 140 | * |
141 | * PARAMETERS: None | 141 | * PARAMETERS: None |
142 | * | 142 | * |
143 | * RETURN: Status | 143 | * RETURN: Status |
144 | * | 144 | * |
145 | * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock | 145 | * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock |
146 | * | 146 | * |
147 | ******************************************************************************/ | 147 | ******************************************************************************/ |
148 | 148 | ||
149 | acpi_status acpi_ev_install_xrupt_handlers(void) | 149 | acpi_status acpi_ev_install_xrupt_handlers(void) |
150 | { | 150 | { |
151 | acpi_status status; | 151 | acpi_status status; |
152 | 152 | ||
153 | ACPI_FUNCTION_TRACE(ev_install_xrupt_handlers); | 153 | ACPI_FUNCTION_TRACE(ev_install_xrupt_handlers); |
154 | 154 | ||
155 | /* Install the SCI handler */ | 155 | /* Install the SCI handler */ |
156 | 156 | ||
157 | status = acpi_ev_install_sci_handler(); | 157 | status = acpi_ev_install_sci_handler(); |
158 | if (ACPI_FAILURE(status)) { | 158 | if (ACPI_FAILURE(status)) { |
159 | ACPI_EXCEPTION((AE_INFO, status, | 159 | ACPI_EXCEPTION((AE_INFO, status, |
160 | "Unable to install System Control Interrupt handler")); | 160 | "Unable to install System Control Interrupt handler")); |
161 | return_ACPI_STATUS(status); | 161 | return_ACPI_STATUS(status); |
162 | } | 162 | } |
163 | 163 | ||
164 | /* Install the handler for the Global Lock */ | 164 | /* Install the handler for the Global Lock */ |
165 | 165 | ||
166 | status = acpi_ev_init_global_lock_handler(); | 166 | status = acpi_ev_init_global_lock_handler(); |
167 | if (ACPI_FAILURE(status)) { | 167 | if (ACPI_FAILURE(status)) { |
168 | ACPI_EXCEPTION((AE_INFO, status, | 168 | ACPI_EXCEPTION((AE_INFO, status, |
169 | "Unable to initialize Global Lock handler")); | 169 | "Unable to initialize Global Lock handler")); |
170 | return_ACPI_STATUS(status); | 170 | return_ACPI_STATUS(status); |
171 | } | 171 | } |
172 | 172 | ||
173 | acpi_gbl_events_initialized = TRUE; | 173 | acpi_gbl_events_initialized = TRUE; |
174 | return_ACPI_STATUS(status); | 174 | return_ACPI_STATUS(status); |
175 | } | 175 | } |
176 | 176 | ||
177 | /******************************************************************************* | 177 | /******************************************************************************* |
178 | * | 178 | * |
179 | * FUNCTION: acpi_ev_fixed_event_initialize | 179 | * FUNCTION: acpi_ev_fixed_event_initialize |
180 | * | 180 | * |
181 | * PARAMETERS: None | 181 | * PARAMETERS: None |
182 | * | 182 | * |
183 | * RETURN: Status | 183 | * RETURN: Status |
184 | * | 184 | * |
185 | * DESCRIPTION: Install the fixed event handlers and enable the fixed events. | 185 | * DESCRIPTION: Install the fixed event handlers and enable the fixed events. |
186 | * | 186 | * |
187 | ******************************************************************************/ | 187 | ******************************************************************************/ |
188 | 188 | ||
189 | static acpi_status acpi_ev_fixed_event_initialize(void) | 189 | static acpi_status acpi_ev_fixed_event_initialize(void) |
190 | { | 190 | { |
191 | acpi_native_uint i; | 191 | acpi_native_uint i; |
192 | acpi_status status; | 192 | acpi_status status; |
193 | 193 | ||
194 | /* | 194 | /* |
195 | * Initialize the structure that keeps track of fixed event handlers | 195 | * Initialize the structure that keeps track of fixed event handlers |
196 | * and enable the fixed events. | 196 | * and enable the fixed events. |
197 | */ | 197 | */ |
198 | for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { | 198 | for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { |
199 | acpi_gbl_fixed_event_handlers[i].handler = NULL; | 199 | acpi_gbl_fixed_event_handlers[i].handler = NULL; |
200 | acpi_gbl_fixed_event_handlers[i].context = NULL; | 200 | acpi_gbl_fixed_event_handlers[i].context = NULL; |
201 | 201 | ||
202 | /* Enable the fixed event */ | 202 | /* Enable the fixed event */ |
203 | 203 | ||
204 | if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) { | 204 | if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) { |
205 | status = | 205 | status = |
206 | acpi_set_register(acpi_gbl_fixed_event_info[i]. | 206 | acpi_set_register(acpi_gbl_fixed_event_info[i]. |
207 | enable_register_id, 0); | 207 | enable_register_id, 0); |
208 | if (ACPI_FAILURE(status)) { | 208 | if (ACPI_FAILURE(status)) { |
209 | return (status); | 209 | return (status); |
210 | } | 210 | } |
211 | } | 211 | } |
212 | } | 212 | } |
213 | 213 | ||
214 | return (AE_OK); | 214 | return (AE_OK); |
215 | } | 215 | } |
216 | 216 | ||
217 | /******************************************************************************* | 217 | /******************************************************************************* |
218 | * | 218 | * |
219 | * FUNCTION: acpi_ev_fixed_event_detect | 219 | * FUNCTION: acpi_ev_fixed_event_detect |
220 | * | 220 | * |
221 | * PARAMETERS: None | 221 | * PARAMETERS: None |
222 | * | 222 | * |
223 | * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED | 223 | * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED |
224 | * | 224 | * |
225 | * DESCRIPTION: Checks the PM status register for active fixed events | 225 | * DESCRIPTION: Checks the PM status register for active fixed events |
226 | * | 226 | * |
227 | ******************************************************************************/ | 227 | ******************************************************************************/ |
228 | 228 | ||
229 | u32 acpi_ev_fixed_event_detect(void) | 229 | u32 acpi_ev_fixed_event_detect(void) |
230 | { | 230 | { |
231 | u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; | 231 | u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; |
232 | u32 fixed_status; | 232 | u32 fixed_status; |
233 | u32 fixed_enable; | 233 | u32 fixed_enable; |
234 | acpi_native_uint i; | 234 | acpi_native_uint i; |
235 | 235 | ||
236 | ACPI_FUNCTION_NAME(ev_fixed_event_detect); | 236 | ACPI_FUNCTION_NAME(ev_fixed_event_detect); |
237 | 237 | ||
238 | /* | 238 | /* |
239 | * Read the fixed feature status and enable registers, as all the cases | 239 | * Read the fixed feature status and enable registers, as all the cases |
240 | * depend on their values. Ignore errors here. | 240 | * depend on their values. Ignore errors here. |
241 | */ | 241 | */ |
242 | (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, | 242 | (void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status); |
243 | ACPI_REGISTER_PM1_STATUS, &fixed_status); | 243 | (void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable); |
244 | (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, | ||
245 | ACPI_REGISTER_PM1_ENABLE, &fixed_enable); | ||
246 | 244 | ||
247 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, | 245 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, |
248 | "Fixed Event Block: Enable %08X Status %08X\n", | 246 | "Fixed Event Block: Enable %08X Status %08X\n", |
249 | fixed_enable, fixed_status)); | 247 | fixed_enable, fixed_status)); |
250 | 248 | ||
251 | /* | 249 | /* |
252 | * Check for all possible Fixed Events and dispatch those that are active | 250 | * Check for all possible Fixed Events and dispatch those that are active |
253 | */ | 251 | */ |
254 | for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { | 252 | for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { |
255 | 253 | ||
256 | /* Both the status and enable bits must be on for this event */ | 254 | /* Both the status and enable bits must be on for this event */ |
257 | 255 | ||
258 | if ((fixed_status & acpi_gbl_fixed_event_info[i]. | 256 | if ((fixed_status & acpi_gbl_fixed_event_info[i]. |
259 | status_bit_mask) | 257 | status_bit_mask) |
260 | && (fixed_enable & acpi_gbl_fixed_event_info[i]. | 258 | && (fixed_enable & acpi_gbl_fixed_event_info[i]. |
261 | enable_bit_mask)) { | 259 | enable_bit_mask)) { |
262 | 260 | ||
263 | /* Found an active (signalled) event */ | 261 | /* Found an active (signalled) event */ |
264 | 262 | ||
265 | int_status |= acpi_ev_fixed_event_dispatch((u32) i); | 263 | int_status |= acpi_ev_fixed_event_dispatch((u32) i); |
266 | } | 264 | } |
267 | } | 265 | } |
268 | 266 | ||
269 | return (int_status); | 267 | return (int_status); |
270 | } | 268 | } |
271 | 269 | ||
272 | /******************************************************************************* | 270 | /******************************************************************************* |
273 | * | 271 | * |
274 | * FUNCTION: acpi_ev_fixed_event_dispatch | 272 | * FUNCTION: acpi_ev_fixed_event_dispatch |
275 | * | 273 | * |
276 | * PARAMETERS: Event - Event type | 274 | * PARAMETERS: Event - Event type |
277 | * | 275 | * |
278 | * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED | 276 | * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED |
279 | * | 277 | * |
280 | * DESCRIPTION: Clears the status bit for the requested event, calls the | 278 | * DESCRIPTION: Clears the status bit for the requested event, calls the |
281 | * handler that previously registered for the event. | 279 | * handler that previously registered for the event. |
282 | * | 280 | * |
283 | ******************************************************************************/ | 281 | ******************************************************************************/ |
284 | 282 | ||
285 | static u32 acpi_ev_fixed_event_dispatch(u32 event) | 283 | static u32 acpi_ev_fixed_event_dispatch(u32 event) |
286 | { | 284 | { |
287 | 285 | ||
288 | ACPI_FUNCTION_ENTRY(); | 286 | ACPI_FUNCTION_ENTRY(); |
289 | 287 | ||
290 | /* Clear the status bit */ | 288 | /* Clear the status bit */ |
291 | 289 | ||
292 | (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. | 290 | (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. |
293 | status_register_id, 1); | 291 | status_register_id, 1); |
294 | 292 | ||
295 | /* | 293 | /* |
296 | * Make sure we've got a handler. If not, report an error. | 294 | * Make sure we've got a handler. If not, report an error. |
297 | * The event is disabled to prevent further interrupts. | 295 | * The event is disabled to prevent further interrupts. |
298 | */ | 296 | */ |
299 | if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { | 297 | if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { |
300 | (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. | 298 | (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. |
301 | enable_register_id, 0); | 299 | enable_register_id, 0); |
302 | 300 | ||
303 | ACPI_ERROR((AE_INFO, | 301 | ACPI_ERROR((AE_INFO, |
304 | "No installed handler for fixed event [%08X]", | 302 | "No installed handler for fixed event [%08X]", |
305 | event)); | 303 | event)); |
306 | 304 | ||
307 | return (ACPI_INTERRUPT_NOT_HANDLED); | 305 | return (ACPI_INTERRUPT_NOT_HANDLED); |
308 | } | 306 | } |
309 | 307 | ||
310 | /* Invoke the Fixed Event handler */ | 308 | /* Invoke the Fixed Event handler */ |
311 | 309 | ||
312 | return ((acpi_gbl_fixed_event_handlers[event]. | 310 | return ((acpi_gbl_fixed_event_handlers[event]. |
313 | handler) (acpi_gbl_fixed_event_handlers[event].context)); | 311 | handler) (acpi_gbl_fixed_event_handlers[event].context)); |
314 | } | 312 | } |
315 | 313 |
drivers/acpi/hardware/hwregs.c
1 | 1 | ||
2 | /******************************************************************************* | 2 | /******************************************************************************* |
3 | * | 3 | * |
4 | * Module Name: hwregs - Read/write access functions for the various ACPI | 4 | * Module Name: hwregs - Read/write access functions for the various ACPI |
5 | * control and status registers. | 5 | * control and status registers. |
6 | * | 6 | * |
7 | ******************************************************************************/ | 7 | ******************************************************************************/ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Copyright (C) 2000 - 2007, R. Byron Moore | 10 | * Copyright (C) 2000 - 2007, R. Byron Moore |
11 | * All rights reserved. | 11 | * All rights reserved. |
12 | * | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without |
14 | * modification, are permitted provided that the following conditions | 14 | * modification, are permitted provided that the following conditions |
15 | * are met: | 15 | * are met: |
16 | * 1. Redistributions of source code must retain the above copyright | 16 | * 1. Redistributions of source code must retain the above copyright |
17 | * notice, this list of conditions, and the following disclaimer, | 17 | * notice, this list of conditions, and the following disclaimer, |
18 | * without modification. | 18 | * without modification. |
19 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | 19 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
20 | * substantially similar to the "NO WARRANTY" disclaimer below | 20 | * substantially similar to the "NO WARRANTY" disclaimer below |
21 | * ("Disclaimer") and any redistribution must be conditioned upon | 21 | * ("Disclaimer") and any redistribution must be conditioned upon |
22 | * including a substantially similar Disclaimer requirement for further | 22 | * including a substantially similar Disclaimer requirement for further |
23 | * binary redistribution. | 23 | * binary redistribution. |
24 | * 3. Neither the names of the above-listed copyright holders nor the names | 24 | * 3. Neither the names of the above-listed copyright holders nor the names |
25 | * of any contributors may be used to endorse or promote products derived | 25 | * of any contributors may be used to endorse or promote products derived |
26 | * from this software without specific prior written permission. | 26 | * from this software without specific prior written permission. |
27 | * | 27 | * |
28 | * Alternatively, this software may be distributed under the terms of the | 28 | * Alternatively, this software may be distributed under the terms of the |
29 | * GNU General Public License ("GPL") version 2 as published by the Free | 29 | * GNU General Public License ("GPL") version 2 as published by the Free |
30 | * Software Foundation. | 30 | * Software Foundation. |
31 | * | 31 | * |
32 | * NO WARRANTY | 32 | * NO WARRANTY |
33 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 33 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
34 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 34 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
35 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | 35 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
36 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 36 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
37 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 37 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
38 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 38 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
39 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 39 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
40 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 40 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
41 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | 41 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
42 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 42 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
43 | * POSSIBILITY OF SUCH DAMAGES. | 43 | * POSSIBILITY OF SUCH DAMAGES. |
44 | */ | 44 | */ |
45 | 45 | ||
46 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
47 | #include <acpi/acnamesp.h> | 47 | #include <acpi/acnamesp.h> |
48 | #include <acpi/acevents.h> | 48 | #include <acpi/acevents.h> |
49 | 49 | ||
50 | #define _COMPONENT ACPI_HARDWARE | 50 | #define _COMPONENT ACPI_HARDWARE |
51 | ACPI_MODULE_NAME("hwregs") | 51 | ACPI_MODULE_NAME("hwregs") |
52 | 52 | ||
53 | /******************************************************************************* | 53 | /******************************************************************************* |
54 | * | 54 | * |
55 | * FUNCTION: acpi_hw_clear_acpi_status | 55 | * FUNCTION: acpi_hw_clear_acpi_status |
56 | * | 56 | * |
57 | * PARAMETERS: None | 57 | * PARAMETERS: None |
58 | * | 58 | * |
59 | * RETURN: None | 59 | * RETURN: None |
60 | * | 60 | * |
61 | * DESCRIPTION: Clears all fixed and general purpose status bits | 61 | * DESCRIPTION: Clears all fixed and general purpose status bits |
62 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | 62 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED |
63 | * | 63 | * |
64 | ******************************************************************************/ | 64 | ******************************************************************************/ |
65 | acpi_status acpi_hw_clear_acpi_status(void) | 65 | acpi_status acpi_hw_clear_acpi_status(void) |
66 | { | 66 | { |
67 | acpi_status status; | 67 | acpi_status status; |
68 | acpi_cpu_flags lock_flags = 0; | 68 | acpi_cpu_flags lock_flags = 0; |
69 | 69 | ||
70 | ACPI_FUNCTION_TRACE(hw_clear_acpi_status); | 70 | ACPI_FUNCTION_TRACE(hw_clear_acpi_status); |
71 | 71 | ||
72 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", | 72 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", |
73 | ACPI_BITMASK_ALL_FIXED_STATUS, | 73 | ACPI_BITMASK_ALL_FIXED_STATUS, |
74 | (u16) acpi_gbl_FADT.xpm1a_event_block.address)); | 74 | (u16) acpi_gbl_FADT.xpm1a_event_block.address)); |
75 | 75 | ||
76 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 76 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); |
77 | 77 | ||
78 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 78 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, |
79 | ACPI_REGISTER_PM1_STATUS, | ||
80 | ACPI_BITMASK_ALL_FIXED_STATUS); | 79 | ACPI_BITMASK_ALL_FIXED_STATUS); |
81 | if (ACPI_FAILURE(status)) { | 80 | if (ACPI_FAILURE(status)) { |
82 | goto unlock_and_exit; | 81 | goto unlock_and_exit; |
83 | } | 82 | } |
84 | 83 | ||
85 | /* Clear the fixed events */ | 84 | /* Clear the fixed events */ |
86 | 85 | ||
87 | if (acpi_gbl_FADT.xpm1b_event_block.address) { | 86 | if (acpi_gbl_FADT.xpm1b_event_block.address) { |
88 | status = | 87 | status = |
89 | acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, | 88 | acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, |
90 | &acpi_gbl_FADT.xpm1b_event_block); | 89 | &acpi_gbl_FADT.xpm1b_event_block); |
91 | if (ACPI_FAILURE(status)) { | 90 | if (ACPI_FAILURE(status)) { |
92 | goto unlock_and_exit; | 91 | goto unlock_and_exit; |
93 | } | 92 | } |
94 | } | 93 | } |
95 | 94 | ||
96 | /* Clear the GPE Bits in all GPE registers in all GPE blocks */ | 95 | /* Clear the GPE Bits in all GPE registers in all GPE blocks */ |
97 | 96 | ||
98 | status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); | 97 | status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); |
99 | 98 | ||
100 | unlock_and_exit: | 99 | unlock_and_exit: |
101 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); | 100 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); |
102 | return_ACPI_STATUS(status); | 101 | return_ACPI_STATUS(status); |
103 | } | 102 | } |
104 | 103 | ||
105 | /******************************************************************************* | 104 | /******************************************************************************* |
106 | * | 105 | * |
107 | * FUNCTION: acpi_get_sleep_type_data | 106 | * FUNCTION: acpi_get_sleep_type_data |
108 | * | 107 | * |
109 | * PARAMETERS: sleep_state - Numeric sleep state | 108 | * PARAMETERS: sleep_state - Numeric sleep state |
110 | * *sleep_type_a - Where SLP_TYPa is returned | 109 | * *sleep_type_a - Where SLP_TYPa is returned |
111 | * *sleep_type_b - Where SLP_TYPb is returned | 110 | * *sleep_type_b - Where SLP_TYPb is returned |
112 | * | 111 | * |
113 | * RETURN: Status - ACPI status | 112 | * RETURN: Status - ACPI status |
114 | * | 113 | * |
115 | * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep | 114 | * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep |
116 | * state. | 115 | * state. |
117 | * | 116 | * |
118 | ******************************************************************************/ | 117 | ******************************************************************************/ |
119 | 118 | ||
120 | acpi_status | 119 | acpi_status |
121 | acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) | 120 | acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) |
122 | { | 121 | { |
123 | acpi_status status = AE_OK; | 122 | acpi_status status = AE_OK; |
124 | struct acpi_evaluate_info *info; | 123 | struct acpi_evaluate_info *info; |
125 | 124 | ||
126 | ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data); | 125 | ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data); |
127 | 126 | ||
128 | /* Validate parameters */ | 127 | /* Validate parameters */ |
129 | 128 | ||
130 | if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) { | 129 | if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) { |
131 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 130 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
132 | } | 131 | } |
133 | 132 | ||
134 | /* Allocate the evaluation information block */ | 133 | /* Allocate the evaluation information block */ |
135 | 134 | ||
136 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); | 135 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); |
137 | if (!info) { | 136 | if (!info) { |
138 | return_ACPI_STATUS(AE_NO_MEMORY); | 137 | return_ACPI_STATUS(AE_NO_MEMORY); |
139 | } | 138 | } |
140 | 139 | ||
141 | info->pathname = | 140 | info->pathname = |
142 | ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); | 141 | ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); |
143 | 142 | ||
144 | /* Evaluate the namespace object containing the values for this state */ | 143 | /* Evaluate the namespace object containing the values for this state */ |
145 | 144 | ||
146 | status = acpi_ns_evaluate(info); | 145 | status = acpi_ns_evaluate(info); |
147 | if (ACPI_FAILURE(status)) { | 146 | if (ACPI_FAILURE(status)) { |
148 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 147 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
149 | "%s while evaluating SleepState [%s]\n", | 148 | "%s while evaluating SleepState [%s]\n", |
150 | acpi_format_exception(status), | 149 | acpi_format_exception(status), |
151 | info->pathname)); | 150 | info->pathname)); |
152 | 151 | ||
153 | goto cleanup; | 152 | goto cleanup; |
154 | } | 153 | } |
155 | 154 | ||
156 | /* Must have a return object */ | 155 | /* Must have a return object */ |
157 | 156 | ||
158 | if (!info->return_object) { | 157 | if (!info->return_object) { |
159 | ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", | 158 | ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", |
160 | info->pathname)); | 159 | info->pathname)); |
161 | status = AE_NOT_EXIST; | 160 | status = AE_NOT_EXIST; |
162 | } | 161 | } |
163 | 162 | ||
164 | /* It must be of type Package */ | 163 | /* It must be of type Package */ |
165 | 164 | ||
166 | else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) { | 165 | else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) { |
167 | ACPI_ERROR((AE_INFO, | 166 | ACPI_ERROR((AE_INFO, |
168 | "Sleep State return object is not a Package")); | 167 | "Sleep State return object is not a Package")); |
169 | status = AE_AML_OPERAND_TYPE; | 168 | status = AE_AML_OPERAND_TYPE; |
170 | } | 169 | } |
171 | 170 | ||
172 | /* | 171 | /* |
173 | * The package must have at least two elements. NOTE (March 2005): This | 172 | * The package must have at least two elements. NOTE (March 2005): This |
174 | * goes against the current ACPI spec which defines this object as a | 173 | * goes against the current ACPI spec which defines this object as a |
175 | * package with one encoded DWORD element. However, existing practice | 174 | * package with one encoded DWORD element. However, existing practice |
176 | * by BIOS vendors seems to be to have 2 or more elements, at least | 175 | * by BIOS vendors seems to be to have 2 or more elements, at least |
177 | * one per sleep type (A/B). | 176 | * one per sleep type (A/B). |
178 | */ | 177 | */ |
179 | else if (info->return_object->package.count < 2) { | 178 | else if (info->return_object->package.count < 2) { |
180 | ACPI_ERROR((AE_INFO, | 179 | ACPI_ERROR((AE_INFO, |
181 | "Sleep State return package does not have at least two elements")); | 180 | "Sleep State return package does not have at least two elements")); |
182 | status = AE_AML_NO_OPERAND; | 181 | status = AE_AML_NO_OPERAND; |
183 | } | 182 | } |
184 | 183 | ||
185 | /* The first two elements must both be of type Integer */ | 184 | /* The first two elements must both be of type Integer */ |
186 | 185 | ||
187 | else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0]) | 186 | else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0]) |
188 | != ACPI_TYPE_INTEGER) || | 187 | != ACPI_TYPE_INTEGER) || |
189 | (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1]) | 188 | (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1]) |
190 | != ACPI_TYPE_INTEGER)) { | 189 | != ACPI_TYPE_INTEGER)) { |
191 | ACPI_ERROR((AE_INFO, | 190 | ACPI_ERROR((AE_INFO, |
192 | "Sleep State return package elements are not both Integers (%s, %s)", | 191 | "Sleep State return package elements are not both Integers (%s, %s)", |
193 | acpi_ut_get_object_type_name(info->return_object-> | 192 | acpi_ut_get_object_type_name(info->return_object-> |
194 | package.elements[0]), | 193 | package.elements[0]), |
195 | acpi_ut_get_object_type_name(info->return_object-> | 194 | acpi_ut_get_object_type_name(info->return_object-> |
196 | package.elements[1]))); | 195 | package.elements[1]))); |
197 | status = AE_AML_OPERAND_TYPE; | 196 | status = AE_AML_OPERAND_TYPE; |
198 | } else { | 197 | } else { |
199 | /* Valid _Sx_ package size, type, and value */ | 198 | /* Valid _Sx_ package size, type, and value */ |
200 | 199 | ||
201 | *sleep_type_a = (u8) | 200 | *sleep_type_a = (u8) |
202 | (info->return_object->package.elements[0])->integer.value; | 201 | (info->return_object->package.elements[0])->integer.value; |
203 | *sleep_type_b = (u8) | 202 | *sleep_type_b = (u8) |
204 | (info->return_object->package.elements[1])->integer.value; | 203 | (info->return_object->package.elements[1])->integer.value; |
205 | } | 204 | } |
206 | 205 | ||
207 | if (ACPI_FAILURE(status)) { | 206 | if (ACPI_FAILURE(status)) { |
208 | ACPI_EXCEPTION((AE_INFO, status, | 207 | ACPI_EXCEPTION((AE_INFO, status, |
209 | "While evaluating SleepState [%s], bad Sleep object %p type %s", | 208 | "While evaluating SleepState [%s], bad Sleep object %p type %s", |
210 | info->pathname, info->return_object, | 209 | info->pathname, info->return_object, |
211 | acpi_ut_get_object_type_name(info-> | 210 | acpi_ut_get_object_type_name(info-> |
212 | return_object))); | 211 | return_object))); |
213 | } | 212 | } |
214 | 213 | ||
215 | acpi_ut_remove_reference(info->return_object); | 214 | acpi_ut_remove_reference(info->return_object); |
216 | 215 | ||
217 | cleanup: | 216 | cleanup: |
218 | ACPI_FREE(info); | 217 | ACPI_FREE(info); |
219 | return_ACPI_STATUS(status); | 218 | return_ACPI_STATUS(status); |
220 | } | 219 | } |
221 | 220 | ||
222 | ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data) | 221 | ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data) |
223 | 222 | ||
224 | /******************************************************************************* | 223 | /******************************************************************************* |
225 | * | 224 | * |
226 | * FUNCTION: acpi_hw_get_register_bit_mask | 225 | * FUNCTION: acpi_hw_get_register_bit_mask |
227 | * | 226 | * |
228 | * PARAMETERS: register_id - Index of ACPI Register to access | 227 | * PARAMETERS: register_id - Index of ACPI Register to access |
229 | * | 228 | * |
230 | * RETURN: The bitmask to be used when accessing the register | 229 | * RETURN: The bitmask to be used when accessing the register |
231 | * | 230 | * |
232 | * DESCRIPTION: Map register_id into a register bitmask. | 231 | * DESCRIPTION: Map register_id into a register bitmask. |
233 | * | 232 | * |
234 | ******************************************************************************/ | 233 | ******************************************************************************/ |
235 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) | 234 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) |
236 | { | 235 | { |
237 | ACPI_FUNCTION_ENTRY(); | 236 | ACPI_FUNCTION_ENTRY(); |
238 | 237 | ||
239 | if (register_id > ACPI_BITREG_MAX) { | 238 | if (register_id > ACPI_BITREG_MAX) { |
240 | ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: %X", | 239 | ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: %X", |
241 | register_id)); | 240 | register_id)); |
242 | return (NULL); | 241 | return (NULL); |
243 | } | 242 | } |
244 | 243 | ||
245 | return (&acpi_gbl_bit_register_info[register_id]); | 244 | return (&acpi_gbl_bit_register_info[register_id]); |
246 | } | 245 | } |
247 | 246 | ||
248 | /******************************************************************************* | 247 | /******************************************************************************* |
249 | * | 248 | * |
250 | * FUNCTION: acpi_get_register | 249 | * FUNCTION: acpi_get_register |
251 | * | 250 | * |
252 | * PARAMETERS: register_id - ID of ACPI bit_register to access | 251 | * PARAMETERS: register_id - ID of ACPI bit_register to access |
253 | * return_value - Value that was read from the register | 252 | * return_value - Value that was read from the register |
254 | * | 253 | * |
255 | * RETURN: Status and the value read from specified Register. Value | 254 | * RETURN: Status and the value read from specified Register. Value |
256 | * returned is normalized to bit0 (is shifted all the way right) | 255 | * returned is normalized to bit0 (is shifted all the way right) |
257 | * | 256 | * |
258 | * DESCRIPTION: ACPI bit_register read function. | 257 | * DESCRIPTION: ACPI bit_register read function. |
259 | * | 258 | * |
260 | ******************************************************************************/ | 259 | ******************************************************************************/ |
261 | 260 | ||
262 | acpi_status acpi_get_register(u32 register_id, u32 * return_value) | 261 | acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value) |
263 | { | 262 | { |
264 | u32 register_value = 0; | 263 | u32 register_value = 0; |
265 | struct acpi_bit_register_info *bit_reg_info; | 264 | struct acpi_bit_register_info *bit_reg_info; |
266 | acpi_status status; | 265 | acpi_status status; |
267 | 266 | ||
268 | ACPI_FUNCTION_TRACE(acpi_get_register); | 267 | ACPI_FUNCTION_TRACE(acpi_get_register); |
269 | 268 | ||
270 | /* Get the info structure corresponding to the requested ACPI Register */ | 269 | /* Get the info structure corresponding to the requested ACPI Register */ |
271 | 270 | ||
272 | bit_reg_info = acpi_hw_get_bit_register_info(register_id); | 271 | bit_reg_info = acpi_hw_get_bit_register_info(register_id); |
273 | if (!bit_reg_info) { | 272 | if (!bit_reg_info) { |
274 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 273 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
275 | } | 274 | } |
276 | 275 | ||
277 | /* Read from the register */ | 276 | /* Read from the register */ |
278 | 277 | ||
279 | status = acpi_hw_register_read(ACPI_MTX_LOCK, | 278 | status = acpi_hw_register_read(bit_reg_info->parent_register, |
280 | bit_reg_info->parent_register, | ||
281 | ®ister_value); | 279 | ®ister_value); |
282 | 280 | ||
283 | if (ACPI_SUCCESS(status)) { | 281 | if (ACPI_SUCCESS(status)) { |
284 | 282 | ||
285 | /* Normalize the value that was read */ | 283 | /* Normalize the value that was read */ |
286 | 284 | ||
287 | register_value = | 285 | register_value = |
288 | ((register_value & bit_reg_info->access_bit_mask) | 286 | ((register_value & bit_reg_info->access_bit_mask) |
289 | >> bit_reg_info->bit_position); | 287 | >> bit_reg_info->bit_position); |
290 | 288 | ||
291 | *return_value = register_value; | 289 | *return_value = register_value; |
292 | 290 | ||
293 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n", | 291 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n", |
294 | register_value, | 292 | register_value, |
295 | bit_reg_info->parent_register)); | 293 | bit_reg_info->parent_register)); |
296 | } | 294 | } |
297 | 295 | ||
298 | return_ACPI_STATUS(status); | 296 | return_ACPI_STATUS(status); |
299 | } | 297 | } |
300 | 298 | ||
299 | acpi_status acpi_get_register(u32 register_id, u32 * return_value) | ||
300 | { | ||
301 | acpi_status status; | ||
302 | acpi_cpu_flags flags; | ||
303 | flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | ||
304 | status = acpi_get_register_unlocked(register_id, return_value); | ||
305 | acpi_os_release_lock(acpi_gbl_hardware_lock, flags); | ||
306 | return status; | ||
307 | } | ||
308 | |||
301 | ACPI_EXPORT_SYMBOL(acpi_get_register) | 309 | ACPI_EXPORT_SYMBOL(acpi_get_register) |
302 | 310 | ||
303 | /******************************************************************************* | 311 | /******************************************************************************* |
304 | * | 312 | * |
305 | * FUNCTION: acpi_set_register | 313 | * FUNCTION: acpi_set_register |
306 | * | 314 | * |
307 | * PARAMETERS: register_id - ID of ACPI bit_register to access | 315 | * PARAMETERS: register_id - ID of ACPI bit_register to access |
308 | * Value - (only used on write) value to write to the | 316 | * Value - (only used on write) value to write to the |
309 | * Register, NOT pre-normalized to the bit pos | 317 | * Register, NOT pre-normalized to the bit pos |
310 | * | 318 | * |
311 | * RETURN: Status | 319 | * RETURN: Status |
312 | * | 320 | * |
313 | * DESCRIPTION: ACPI Bit Register write function. | 321 | * DESCRIPTION: ACPI Bit Register write function. |
314 | * | 322 | * |
315 | ******************************************************************************/ | 323 | ******************************************************************************/ |
316 | acpi_status acpi_set_register(u32 register_id, u32 value) | 324 | acpi_status acpi_set_register(u32 register_id, u32 value) |
317 | { | 325 | { |
318 | u32 register_value = 0; | 326 | u32 register_value = 0; |
319 | struct acpi_bit_register_info *bit_reg_info; | 327 | struct acpi_bit_register_info *bit_reg_info; |
320 | acpi_status status; | 328 | acpi_status status; |
321 | acpi_cpu_flags lock_flags; | 329 | acpi_cpu_flags lock_flags; |
322 | 330 | ||
323 | ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id); | 331 | ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id); |
324 | 332 | ||
325 | /* Get the info structure corresponding to the requested ACPI Register */ | 333 | /* Get the info structure corresponding to the requested ACPI Register */ |
326 | 334 | ||
327 | bit_reg_info = acpi_hw_get_bit_register_info(register_id); | 335 | bit_reg_info = acpi_hw_get_bit_register_info(register_id); |
328 | if (!bit_reg_info) { | 336 | if (!bit_reg_info) { |
329 | ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X", | 337 | ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X", |
330 | register_id)); | 338 | register_id)); |
331 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 339 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
332 | } | 340 | } |
333 | 341 | ||
334 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 342 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); |
335 | 343 | ||
336 | /* Always do a register read first so we can insert the new bits */ | 344 | /* Always do a register read first so we can insert the new bits */ |
337 | 345 | ||
338 | status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, | 346 | status = acpi_hw_register_read(bit_reg_info->parent_register, |
339 | bit_reg_info->parent_register, | ||
340 | ®ister_value); | 347 | ®ister_value); |
341 | if (ACPI_FAILURE(status)) { | 348 | if (ACPI_FAILURE(status)) { |
342 | goto unlock_and_exit; | 349 | goto unlock_and_exit; |
343 | } | 350 | } |
344 | 351 | ||
345 | /* | 352 | /* |
346 | * Decode the Register ID | 353 | * Decode the Register ID |
347 | * Register ID = [Register block ID] | [bit ID] | 354 | * Register ID = [Register block ID] | [bit ID] |
348 | * | 355 | * |
349 | * Check bit ID to fine locate Register offset. | 356 | * Check bit ID to fine locate Register offset. |
350 | * Check Mask to determine Register offset, and then read-write. | 357 | * Check Mask to determine Register offset, and then read-write. |
351 | */ | 358 | */ |
352 | switch (bit_reg_info->parent_register) { | 359 | switch (bit_reg_info->parent_register) { |
353 | case ACPI_REGISTER_PM1_STATUS: | 360 | case ACPI_REGISTER_PM1_STATUS: |
354 | 361 | ||
355 | /* | 362 | /* |
356 | * Status Registers are different from the rest. Clear by | 363 | * Status Registers are different from the rest. Clear by |
357 | * writing 1, and writing 0 has no effect. So, the only relevant | 364 | * writing 1, and writing 0 has no effect. So, the only relevant |
358 | * information is the single bit we're interested in, all others should | 365 | * information is the single bit we're interested in, all others should |
359 | * be written as 0 so they will be left unchanged. | 366 | * be written as 0 so they will be left unchanged. |
360 | */ | 367 | */ |
361 | value = ACPI_REGISTER_PREPARE_BITS(value, | 368 | value = ACPI_REGISTER_PREPARE_BITS(value, |
362 | bit_reg_info->bit_position, | 369 | bit_reg_info->bit_position, |
363 | bit_reg_info-> | 370 | bit_reg_info-> |
364 | access_bit_mask); | 371 | access_bit_mask); |
365 | if (value) { | 372 | if (value) { |
366 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 373 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, |
367 | ACPI_REGISTER_PM1_STATUS, | ||
368 | (u16) value); | 374 | (u16) value); |
369 | register_value = 0; | 375 | register_value = 0; |
370 | } | 376 | } |
371 | break; | 377 | break; |
372 | 378 | ||
373 | case ACPI_REGISTER_PM1_ENABLE: | 379 | case ACPI_REGISTER_PM1_ENABLE: |
374 | 380 | ||
375 | ACPI_REGISTER_INSERT_VALUE(register_value, | 381 | ACPI_REGISTER_INSERT_VALUE(register_value, |
376 | bit_reg_info->bit_position, | 382 | bit_reg_info->bit_position, |
377 | bit_reg_info->access_bit_mask, | 383 | bit_reg_info->access_bit_mask, |
378 | value); | 384 | value); |
379 | 385 | ||
380 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 386 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE, |
381 | ACPI_REGISTER_PM1_ENABLE, | ||
382 | (u16) register_value); | 387 | (u16) register_value); |
383 | break; | 388 | break; |
384 | 389 | ||
385 | case ACPI_REGISTER_PM1_CONTROL: | 390 | case ACPI_REGISTER_PM1_CONTROL: |
386 | 391 | ||
387 | /* | 392 | /* |
388 | * Write the PM1 Control register. | 393 | * Write the PM1 Control register. |
389 | * Note that at this level, the fact that there are actually TWO | 394 | * Note that at this level, the fact that there are actually TWO |
390 | * registers (A and B - and B may not exist) is abstracted. | 395 | * registers (A and B - and B may not exist) is abstracted. |
391 | */ | 396 | */ |
392 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n", | 397 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n", |
393 | register_value)); | 398 | register_value)); |
394 | 399 | ||
395 | ACPI_REGISTER_INSERT_VALUE(register_value, | 400 | ACPI_REGISTER_INSERT_VALUE(register_value, |
396 | bit_reg_info->bit_position, | 401 | bit_reg_info->bit_position, |
397 | bit_reg_info->access_bit_mask, | 402 | bit_reg_info->access_bit_mask, |
398 | value); | 403 | value); |
399 | 404 | ||
400 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 405 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL, |
401 | ACPI_REGISTER_PM1_CONTROL, | ||
402 | (u16) register_value); | 406 | (u16) register_value); |
403 | break; | 407 | break; |
404 | 408 | ||
405 | case ACPI_REGISTER_PM2_CONTROL: | 409 | case ACPI_REGISTER_PM2_CONTROL: |
406 | 410 | ||
407 | status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, | 411 | status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL, |
408 | ACPI_REGISTER_PM2_CONTROL, | ||
409 | ®ister_value); | 412 | ®ister_value); |
410 | if (ACPI_FAILURE(status)) { | 413 | if (ACPI_FAILURE(status)) { |
411 | goto unlock_and_exit; | 414 | goto unlock_and_exit; |
412 | } | 415 | } |
413 | 416 | ||
414 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 417 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
415 | "PM2 control: Read %X from %8.8X%8.8X\n", | 418 | "PM2 control: Read %X from %8.8X%8.8X\n", |
416 | register_value, | 419 | register_value, |
417 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. | 420 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. |
418 | xpm2_control_block. | 421 | xpm2_control_block. |
419 | address))); | 422 | address))); |
420 | 423 | ||
421 | ACPI_REGISTER_INSERT_VALUE(register_value, | 424 | ACPI_REGISTER_INSERT_VALUE(register_value, |
422 | bit_reg_info->bit_position, | 425 | bit_reg_info->bit_position, |
423 | bit_reg_info->access_bit_mask, | 426 | bit_reg_info->access_bit_mask, |
424 | value); | 427 | value); |
425 | 428 | ||
426 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 429 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
427 | "About to write %4.4X to %8.8X%8.8X\n", | 430 | "About to write %4.4X to %8.8X%8.8X\n", |
428 | register_value, | 431 | register_value, |
429 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. | 432 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. |
430 | xpm2_control_block. | 433 | xpm2_control_block. |
431 | address))); | 434 | address))); |
432 | 435 | ||
433 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 436 | status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL, |
434 | ACPI_REGISTER_PM2_CONTROL, | ||
435 | (u8) (register_value)); | 437 | (u8) (register_value)); |
436 | break; | 438 | break; |
437 | 439 | ||
438 | default: | 440 | default: |
439 | break; | 441 | break; |
440 | } | 442 | } |
441 | 443 | ||
442 | unlock_and_exit: | 444 | unlock_and_exit: |
443 | 445 | ||
444 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); | 446 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); |
445 | 447 | ||
446 | /* Normalize the value that was read */ | 448 | /* Normalize the value that was read */ |
447 | 449 | ||
448 | ACPI_DEBUG_EXEC(register_value = | 450 | ACPI_DEBUG_EXEC(register_value = |
449 | ((register_value & bit_reg_info->access_bit_mask) >> | 451 | ((register_value & bit_reg_info->access_bit_mask) >> |
450 | bit_reg_info->bit_position)); | 452 | bit_reg_info->bit_position)); |
451 | 453 | ||
452 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 454 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
453 | "Set bits: %8.8X actual %8.8X register %X\n", value, | 455 | "Set bits: %8.8X actual %8.8X register %X\n", value, |
454 | register_value, bit_reg_info->parent_register)); | 456 | register_value, bit_reg_info->parent_register)); |
455 | return_ACPI_STATUS(status); | 457 | return_ACPI_STATUS(status); |
456 | } | 458 | } |
457 | 459 | ||
458 | ACPI_EXPORT_SYMBOL(acpi_set_register) | 460 | ACPI_EXPORT_SYMBOL(acpi_set_register) |
459 | 461 | ||
460 | /****************************************************************************** | 462 | /****************************************************************************** |
461 | * | 463 | * |
462 | * FUNCTION: acpi_hw_register_read | 464 | * FUNCTION: acpi_hw_register_read |
463 | * | 465 | * |
464 | * PARAMETERS: use_lock - Lock hardware? True/False | 466 | * PARAMETERS: register_id - ACPI Register ID |
465 | * register_id - ACPI Register ID | ||
466 | * return_value - Where the register value is returned | 467 | * return_value - Where the register value is returned |
467 | * | 468 | * |
468 | * RETURN: Status and the value read. | 469 | * RETURN: Status and the value read. |
469 | * | 470 | * |
470 | * DESCRIPTION: Read from the specified ACPI register | 471 | * DESCRIPTION: Read from the specified ACPI register |
471 | * | 472 | * |
472 | ******************************************************************************/ | 473 | ******************************************************************************/ |
473 | acpi_status | 474 | acpi_status |
474 | acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) | 475 | acpi_hw_register_read(u32 register_id, u32 * return_value) |
475 | { | 476 | { |
476 | u32 value1 = 0; | 477 | u32 value1 = 0; |
477 | u32 value2 = 0; | 478 | u32 value2 = 0; |
478 | acpi_status status; | 479 | acpi_status status; |
479 | acpi_cpu_flags lock_flags = 0; | ||
480 | 480 | ||
481 | ACPI_FUNCTION_TRACE(hw_register_read); | 481 | ACPI_FUNCTION_TRACE(hw_register_read); |
482 | 482 | ||
483 | if (ACPI_MTX_LOCK == use_lock) { | ||
484 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | ||
485 | } | ||
486 | |||
487 | switch (register_id) { | 483 | switch (register_id) { |
488 | case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ | 484 | case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ |
489 | 485 | ||
490 | status = | 486 | status = |
491 | acpi_hw_low_level_read(16, &value1, | 487 | acpi_hw_low_level_read(16, &value1, |
492 | &acpi_gbl_FADT.xpm1a_event_block); | 488 | &acpi_gbl_FADT.xpm1a_event_block); |
493 | if (ACPI_FAILURE(status)) { | 489 | if (ACPI_FAILURE(status)) { |
494 | goto unlock_and_exit; | 490 | goto exit; |
495 | } | 491 | } |
496 | 492 | ||
497 | /* PM1B is optional */ | 493 | /* PM1B is optional */ |
498 | 494 | ||
499 | status = | 495 | status = |
500 | acpi_hw_low_level_read(16, &value2, | 496 | acpi_hw_low_level_read(16, &value2, |
501 | &acpi_gbl_FADT.xpm1b_event_block); | 497 | &acpi_gbl_FADT.xpm1b_event_block); |
502 | value1 |= value2; | 498 | value1 |= value2; |
503 | break; | 499 | break; |
504 | 500 | ||
505 | case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ | 501 | case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ |
506 | 502 | ||
507 | status = | 503 | status = |
508 | acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable); | 504 | acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable); |
509 | if (ACPI_FAILURE(status)) { | 505 | if (ACPI_FAILURE(status)) { |
510 | goto unlock_and_exit; | 506 | goto exit; |
511 | } | 507 | } |
512 | 508 | ||
513 | /* PM1B is optional */ | 509 | /* PM1B is optional */ |
514 | 510 | ||
515 | status = | 511 | status = |
516 | acpi_hw_low_level_read(16, &value2, &acpi_gbl_xpm1b_enable); | 512 | acpi_hw_low_level_read(16, &value2, &acpi_gbl_xpm1b_enable); |
517 | value1 |= value2; | 513 | value1 |= value2; |
518 | break; | 514 | break; |
519 | 515 | ||
520 | case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ | 516 | case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ |
521 | 517 | ||
522 | status = | 518 | status = |
523 | acpi_hw_low_level_read(16, &value1, | 519 | acpi_hw_low_level_read(16, &value1, |
524 | &acpi_gbl_FADT.xpm1a_control_block); | 520 | &acpi_gbl_FADT.xpm1a_control_block); |
525 | if (ACPI_FAILURE(status)) { | 521 | if (ACPI_FAILURE(status)) { |
526 | goto unlock_and_exit; | 522 | goto exit; |
527 | } | 523 | } |
528 | 524 | ||
529 | status = | 525 | status = |
530 | acpi_hw_low_level_read(16, &value2, | 526 | acpi_hw_low_level_read(16, &value2, |
531 | &acpi_gbl_FADT.xpm1b_control_block); | 527 | &acpi_gbl_FADT.xpm1b_control_block); |
532 | value1 |= value2; | 528 | value1 |= value2; |
533 | break; | 529 | break; |
534 | 530 | ||
535 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ | 531 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ |
536 | 532 | ||
537 | status = | 533 | status = |
538 | acpi_hw_low_level_read(8, &value1, | 534 | acpi_hw_low_level_read(8, &value1, |
539 | &acpi_gbl_FADT.xpm2_control_block); | 535 | &acpi_gbl_FADT.xpm2_control_block); |
540 | break; | 536 | break; |
541 | 537 | ||
542 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 538 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
543 | 539 | ||
544 | status = | 540 | status = |
545 | acpi_hw_low_level_read(32, &value1, | 541 | acpi_hw_low_level_read(32, &value1, |
546 | &acpi_gbl_FADT.xpm_timer_block); | 542 | &acpi_gbl_FADT.xpm_timer_block); |
547 | break; | 543 | break; |
548 | 544 | ||
549 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 545 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
550 | 546 | ||
551 | status = | 547 | status = |
552 | acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8); | 548 | acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8); |
553 | break; | 549 | break; |
554 | 550 | ||
555 | default: | 551 | default: |
556 | ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id)); | 552 | ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id)); |
557 | status = AE_BAD_PARAMETER; | 553 | status = AE_BAD_PARAMETER; |
558 | break; | 554 | break; |
559 | } | 555 | } |
560 | 556 | ||
561 | unlock_and_exit: | 557 | exit: |
562 | if (ACPI_MTX_LOCK == use_lock) { | ||
563 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); | ||
564 | } | ||
565 | 558 | ||
566 | if (ACPI_SUCCESS(status)) { | 559 | if (ACPI_SUCCESS(status)) { |
567 | *return_value = value1; | 560 | *return_value = value1; |
568 | } | 561 | } |
569 | 562 | ||
570 | return_ACPI_STATUS(status); | 563 | return_ACPI_STATUS(status); |
571 | } | 564 | } |
572 | 565 | ||
573 | /****************************************************************************** | 566 | /****************************************************************************** |
574 | * | 567 | * |
575 | * FUNCTION: acpi_hw_register_write | 568 | * FUNCTION: acpi_hw_register_write |
576 | * | 569 | * |
577 | * PARAMETERS: use_lock - Lock hardware? True/False | 570 | * PARAMETERS: register_id - ACPI Register ID |
578 | * register_id - ACPI Register ID | ||
579 | * Value - The value to write | 571 | * Value - The value to write |
580 | * | 572 | * |
581 | * RETURN: Status | 573 | * RETURN: Status |
582 | * | 574 | * |
583 | * DESCRIPTION: Write to the specified ACPI register | 575 | * DESCRIPTION: Write to the specified ACPI register |
584 | * | 576 | * |
585 | * NOTE: In accordance with the ACPI specification, this function automatically | 577 | * NOTE: In accordance with the ACPI specification, this function automatically |
586 | * preserves the value of the following bits, meaning that these bits cannot be | 578 | * preserves the value of the following bits, meaning that these bits cannot be |
587 | * changed via this interface: | 579 | * changed via this interface: |
588 | * | 580 | * |
589 | * PM1_CONTROL[0] = SCI_EN | 581 | * PM1_CONTROL[0] = SCI_EN |
590 | * PM1_CONTROL[9] | 582 | * PM1_CONTROL[9] |
591 | * PM1_STATUS[11] | 583 | * PM1_STATUS[11] |
592 | * | 584 | * |
593 | * ACPI References: | 585 | * ACPI References: |
594 | * 1) Hardware Ignored Bits: When software writes to a register with ignored | 586 | * 1) Hardware Ignored Bits: When software writes to a register with ignored |
595 | * bit fields, it preserves the ignored bit fields | 587 | * bit fields, it preserves the ignored bit fields |
596 | * 2) SCI_EN: OSPM always preserves this bit position | 588 | * 2) SCI_EN: OSPM always preserves this bit position |
597 | * | 589 | * |
598 | ******************************************************************************/ | 590 | ******************************************************************************/ |
599 | 591 | ||
600 | acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) | 592 | acpi_status acpi_hw_register_write(u32 register_id, u32 value) |
601 | { | 593 | { |
602 | acpi_status status; | 594 | acpi_status status; |
603 | acpi_cpu_flags lock_flags = 0; | ||
604 | u32 read_value; | 595 | u32 read_value; |
605 | 596 | ||
606 | ACPI_FUNCTION_TRACE(hw_register_write); | 597 | ACPI_FUNCTION_TRACE(hw_register_write); |
607 | 598 | ||
608 | if (ACPI_MTX_LOCK == use_lock) { | ||
609 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | ||
610 | } | ||
611 | |||
612 | switch (register_id) { | 599 | switch (register_id) { |
613 | case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ | 600 | case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ |
614 | 601 | ||
615 | /* Perform a read first to preserve certain bits (per ACPI spec) */ | 602 | /* Perform a read first to preserve certain bits (per ACPI spec) */ |
616 | 603 | ||
617 | status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, | 604 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, |
618 | ACPI_REGISTER_PM1_STATUS, | ||
619 | &read_value); | 605 | &read_value); |
620 | if (ACPI_FAILURE(status)) { | 606 | if (ACPI_FAILURE(status)) { |
621 | goto unlock_and_exit; | 607 | goto exit; |
622 | } | 608 | } |
623 | 609 | ||
624 | /* Insert the bits to be preserved */ | 610 | /* Insert the bits to be preserved */ |
625 | 611 | ||
626 | ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS, | 612 | ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS, |
627 | read_value); | 613 | read_value); |
628 | 614 | ||
629 | /* Now we can write the data */ | 615 | /* Now we can write the data */ |
630 | 616 | ||
631 | status = | 617 | status = |
632 | acpi_hw_low_level_write(16, value, | 618 | acpi_hw_low_level_write(16, value, |
633 | &acpi_gbl_FADT.xpm1a_event_block); | 619 | &acpi_gbl_FADT.xpm1a_event_block); |
634 | if (ACPI_FAILURE(status)) { | 620 | if (ACPI_FAILURE(status)) { |
635 | goto unlock_and_exit; | 621 | goto exit; |
636 | } | 622 | } |
637 | 623 | ||
638 | /* PM1B is optional */ | 624 | /* PM1B is optional */ |
639 | 625 | ||
640 | status = | 626 | status = |
641 | acpi_hw_low_level_write(16, value, | 627 | acpi_hw_low_level_write(16, value, |
642 | &acpi_gbl_FADT.xpm1b_event_block); | 628 | &acpi_gbl_FADT.xpm1b_event_block); |
643 | break; | 629 | break; |
644 | 630 | ||
645 | case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ | 631 | case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ |
646 | 632 | ||
647 | status = | 633 | status = |
648 | acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable); | 634 | acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable); |
649 | if (ACPI_FAILURE(status)) { | 635 | if (ACPI_FAILURE(status)) { |
650 | goto unlock_and_exit; | 636 | goto exit; |
651 | } | 637 | } |
652 | 638 | ||
653 | /* PM1B is optional */ | 639 | /* PM1B is optional */ |
654 | 640 | ||
655 | status = | 641 | status = |
656 | acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1b_enable); | 642 | acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1b_enable); |
657 | break; | 643 | break; |
658 | 644 | ||
659 | case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ | 645 | case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ |
660 | 646 | ||
661 | /* | 647 | /* |
662 | * Perform a read first to preserve certain bits (per ACPI spec) | 648 | * Perform a read first to preserve certain bits (per ACPI spec) |
663 | */ | 649 | */ |
664 | status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, | 650 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, |
665 | ACPI_REGISTER_PM1_CONTROL, | ||
666 | &read_value); | 651 | &read_value); |
667 | if (ACPI_FAILURE(status)) { | 652 | if (ACPI_FAILURE(status)) { |
668 | goto unlock_and_exit; | 653 | goto exit; |
669 | } | 654 | } |
670 | 655 | ||
671 | /* Insert the bits to be preserved */ | 656 | /* Insert the bits to be preserved */ |
672 | 657 | ||
673 | ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS, | 658 | ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS, |
674 | read_value); | 659 | read_value); |
675 | 660 | ||
676 | /* Now we can write the data */ | 661 | /* Now we can write the data */ |
677 | 662 | ||
678 | status = | 663 | status = |
679 | acpi_hw_low_level_write(16, value, | 664 | acpi_hw_low_level_write(16, value, |
680 | &acpi_gbl_FADT.xpm1a_control_block); | 665 | &acpi_gbl_FADT.xpm1a_control_block); |
681 | if (ACPI_FAILURE(status)) { | 666 | if (ACPI_FAILURE(status)) { |
682 | goto unlock_and_exit; | 667 | goto exit; |
683 | } | 668 | } |
684 | 669 | ||
685 | status = | 670 | status = |
686 | acpi_hw_low_level_write(16, value, | 671 | acpi_hw_low_level_write(16, value, |
687 | &acpi_gbl_FADT.xpm1b_control_block); | 672 | &acpi_gbl_FADT.xpm1b_control_block); |
688 | break; | 673 | break; |
689 | 674 | ||
690 | case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ | 675 | case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ |
691 | 676 | ||
692 | status = | 677 | status = |
693 | acpi_hw_low_level_write(16, value, | 678 | acpi_hw_low_level_write(16, value, |
694 | &acpi_gbl_FADT.xpm1a_control_block); | 679 | &acpi_gbl_FADT.xpm1a_control_block); |
695 | break; | 680 | break; |
696 | 681 | ||
697 | case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ | 682 | case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ |
698 | 683 | ||
699 | status = | 684 | status = |
700 | acpi_hw_low_level_write(16, value, | 685 | acpi_hw_low_level_write(16, value, |
701 | &acpi_gbl_FADT.xpm1b_control_block); | 686 | &acpi_gbl_FADT.xpm1b_control_block); |
702 | break; | 687 | break; |
703 | 688 | ||
704 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ | 689 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ |
705 | 690 | ||
706 | status = | 691 | status = |
707 | acpi_hw_low_level_write(8, value, | 692 | acpi_hw_low_level_write(8, value, |
708 | &acpi_gbl_FADT.xpm2_control_block); | 693 | &acpi_gbl_FADT.xpm2_control_block); |
709 | break; | 694 | break; |
710 | 695 | ||
711 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 696 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
712 | 697 | ||
713 | status = | 698 | status = |
714 | acpi_hw_low_level_write(32, value, | 699 | acpi_hw_low_level_write(32, value, |
715 | &acpi_gbl_FADT.xpm_timer_block); | 700 | &acpi_gbl_FADT.xpm_timer_block); |
716 | break; | 701 | break; |
717 | 702 | ||
718 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 703 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
719 | 704 | ||
720 | /* SMI_CMD is currently always in IO space */ | 705 | /* SMI_CMD is currently always in IO space */ |
721 | 706 | ||
722 | status = | 707 | status = |
723 | acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8); | 708 | acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8); |
724 | break; | 709 | break; |
725 | 710 | ||
726 | default: | 711 | default: |
727 | status = AE_BAD_PARAMETER; | 712 | status = AE_BAD_PARAMETER; |
728 | break; | 713 | break; |
729 | } | 714 | } |
730 | 715 | ||
731 | unlock_and_exit: | 716 | exit: |
732 | if (ACPI_MTX_LOCK == use_lock) { | ||
733 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); | ||
734 | } | ||
735 | |||
736 | return_ACPI_STATUS(status); | 717 | return_ACPI_STATUS(status); |
737 | } | 718 | } |
738 | 719 | ||
739 | /****************************************************************************** | 720 | /****************************************************************************** |
740 | * | 721 | * |
741 | * FUNCTION: acpi_hw_low_level_read | 722 | * FUNCTION: acpi_hw_low_level_read |
742 | * | 723 | * |
743 | * PARAMETERS: Width - 8, 16, or 32 | 724 | * PARAMETERS: Width - 8, 16, or 32 |
744 | * Value - Where the value is returned | 725 | * Value - Where the value is returned |
745 | * Reg - GAS register structure | 726 | * Reg - GAS register structure |
746 | * | 727 | * |
747 | * RETURN: Status | 728 | * RETURN: Status |
748 | * | 729 | * |
749 | * DESCRIPTION: Read from either memory or IO space. | 730 | * DESCRIPTION: Read from either memory or IO space. |
750 | * | 731 | * |
751 | ******************************************************************************/ | 732 | ******************************************************************************/ |
752 | 733 | ||
753 | acpi_status | 734 | acpi_status |
754 | acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) | 735 | acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) |
755 | { | 736 | { |
756 | u64 address; | 737 | u64 address; |
757 | acpi_status status; | 738 | acpi_status status; |
758 | 739 | ||
759 | ACPI_FUNCTION_NAME(hw_low_level_read); | 740 | ACPI_FUNCTION_NAME(hw_low_level_read); |
760 | 741 | ||
761 | /* | 742 | /* |
762 | * Must have a valid pointer to a GAS structure, and | 743 | * Must have a valid pointer to a GAS structure, and |
763 | * a non-zero address within. However, don't return an error | 744 | * a non-zero address within. However, don't return an error |
764 | * because the PM1A/B code must not fail if B isn't present. | 745 | * because the PM1A/B code must not fail if B isn't present. |
765 | */ | 746 | */ |
766 | if (!reg) { | 747 | if (!reg) { |
767 | return (AE_OK); | 748 | return (AE_OK); |
768 | } | 749 | } |
769 | 750 | ||
770 | /* Get a local copy of the address. Handles possible alignment issues */ | 751 | /* Get a local copy of the address. Handles possible alignment issues */ |
771 | 752 | ||
772 | ACPI_MOVE_64_TO_64(&address, ®->address); | 753 | ACPI_MOVE_64_TO_64(&address, ®->address); |
773 | if (!address) { | 754 | if (!address) { |
774 | return (AE_OK); | 755 | return (AE_OK); |
775 | } | 756 | } |
776 | *value = 0; | 757 | *value = 0; |
777 | 758 | ||
778 | /* | 759 | /* |
779 | * Two address spaces supported: Memory or IO. | 760 | * Two address spaces supported: Memory or IO. |
780 | * PCI_Config is not supported here because the GAS struct is insufficient | 761 | * PCI_Config is not supported here because the GAS struct is insufficient |
781 | */ | 762 | */ |
782 | switch (reg->space_id) { | 763 | switch (reg->space_id) { |
783 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 764 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
784 | 765 | ||
785 | status = acpi_os_read_memory((acpi_physical_address) address, | 766 | status = acpi_os_read_memory((acpi_physical_address) address, |
786 | value, width); | 767 | value, width); |
787 | break; | 768 | break; |
788 | 769 | ||
789 | case ACPI_ADR_SPACE_SYSTEM_IO: | 770 | case ACPI_ADR_SPACE_SYSTEM_IO: |
790 | 771 | ||
791 | status = | 772 | status = |
792 | acpi_os_read_port((acpi_io_address) address, value, width); | 773 | acpi_os_read_port((acpi_io_address) address, value, width); |
793 | break; | 774 | break; |
794 | 775 | ||
795 | default: | 776 | default: |
796 | ACPI_ERROR((AE_INFO, | 777 | ACPI_ERROR((AE_INFO, |
797 | "Unsupported address space: %X", reg->space_id)); | 778 | "Unsupported address space: %X", reg->space_id)); |
798 | return (AE_BAD_PARAMETER); | 779 | return (AE_BAD_PARAMETER); |
799 | } | 780 | } |
800 | 781 | ||
801 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 782 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
802 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", | 783 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", |
803 | *value, width, ACPI_FORMAT_UINT64(address), | 784 | *value, width, ACPI_FORMAT_UINT64(address), |
804 | acpi_ut_get_region_name(reg->space_id))); | 785 | acpi_ut_get_region_name(reg->space_id))); |
805 | 786 | ||
806 | return (status); | 787 | return (status); |
807 | } | 788 | } |
808 | 789 | ||
809 | /****************************************************************************** | 790 | /****************************************************************************** |
810 | * | 791 | * |
811 | * FUNCTION: acpi_hw_low_level_write | 792 | * FUNCTION: acpi_hw_low_level_write |
812 | * | 793 | * |
813 | * PARAMETERS: Width - 8, 16, or 32 | 794 | * PARAMETERS: Width - 8, 16, or 32 |
814 | * Value - To be written | 795 | * Value - To be written |
815 | * Reg - GAS register structure | 796 | * Reg - GAS register structure |
816 | * | 797 | * |
817 | * RETURN: Status | 798 | * RETURN: Status |
818 | * | 799 | * |
819 | * DESCRIPTION: Write to either memory or IO space. | 800 | * DESCRIPTION: Write to either memory or IO space. |
820 | * | 801 | * |
821 | ******************************************************************************/ | 802 | ******************************************************************************/ |
822 | 803 | ||
823 | acpi_status | 804 | acpi_status |
824 | acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) | 805 | acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) |
825 | { | 806 | { |
826 | u64 address; | 807 | u64 address; |
827 | acpi_status status; | 808 | acpi_status status; |
828 | 809 | ||
829 | ACPI_FUNCTION_NAME(hw_low_level_write); | 810 | ACPI_FUNCTION_NAME(hw_low_level_write); |
830 | 811 | ||
831 | /* | 812 | /* |
832 | * Must have a valid pointer to a GAS structure, and | 813 | * Must have a valid pointer to a GAS structure, and |
833 | * a non-zero address within. However, don't return an error | 814 | * a non-zero address within. However, don't return an error |
834 | * because the PM1A/B code must not fail if B isn't present. | 815 | * because the PM1A/B code must not fail if B isn't present. |
835 | */ | 816 | */ |
836 | if (!reg) { | 817 | if (!reg) { |
837 | return (AE_OK); | 818 | return (AE_OK); |
838 | } | 819 | } |
839 | 820 | ||
840 | /* Get a local copy of the address. Handles possible alignment issues */ | 821 | /* Get a local copy of the address. Handles possible alignment issues */ |
841 | 822 | ||
842 | ACPI_MOVE_64_TO_64(&address, ®->address); | 823 | ACPI_MOVE_64_TO_64(&address, ®->address); |
843 | if (!address) { | 824 | if (!address) { |
844 | return (AE_OK); | 825 | return (AE_OK); |
845 | } | 826 | } |
846 | 827 | ||
847 | /* | 828 | /* |
848 | * Two address spaces supported: Memory or IO. | 829 | * Two address spaces supported: Memory or IO. |
849 | * PCI_Config is not supported here because the GAS struct is insufficient | 830 | * PCI_Config is not supported here because the GAS struct is insufficient |
850 | */ | 831 | */ |
851 | switch (reg->space_id) { | 832 | switch (reg->space_id) { |
852 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 833 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
853 | 834 | ||
854 | status = acpi_os_write_memory((acpi_physical_address) address, | 835 | status = acpi_os_write_memory((acpi_physical_address) address, |
855 | value, width); | 836 | value, width); |
856 | break; | 837 | break; |
857 | 838 | ||
858 | case ACPI_ADR_SPACE_SYSTEM_IO: | 839 | case ACPI_ADR_SPACE_SYSTEM_IO: |
859 | 840 | ||
860 | status = acpi_os_write_port((acpi_io_address) address, value, | 841 | status = acpi_os_write_port((acpi_io_address) address, value, |
861 | width); | 842 | width); |
862 | break; | 843 | break; |
863 | 844 | ||
864 | default: | 845 | default: |
865 | ACPI_ERROR((AE_INFO, | 846 | ACPI_ERROR((AE_INFO, |
866 | "Unsupported address space: %X", reg->space_id)); | 847 | "Unsupported address space: %X", reg->space_id)); |
867 | return (AE_BAD_PARAMETER); | 848 | return (AE_BAD_PARAMETER); |
drivers/acpi/hardware/hwsleep.c
1 | 1 | ||
2 | /****************************************************************************** | 2 | /****************************************************************************** |
3 | * | 3 | * |
4 | * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface | 4 | * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface |
5 | * | 5 | * |
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2007, R. Byron Moore |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions | 13 | * modification, are permitted provided that the following conditions |
14 | * are met: | 14 | * are met: |
15 | * 1. Redistributions of source code must retain the above copyright | 15 | * 1. Redistributions of source code must retain the above copyright |
16 | * notice, this list of conditions, and the following disclaimer, | 16 | * notice, this list of conditions, and the following disclaimer, |
17 | * without modification. | 17 | * without modification. |
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | 18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
19 | * substantially similar to the "NO WARRANTY" disclaimer below | 19 | * substantially similar to the "NO WARRANTY" disclaimer below |
20 | * ("Disclaimer") and any redistribution must be conditioned upon | 20 | * ("Disclaimer") and any redistribution must be conditioned upon |
21 | * including a substantially similar Disclaimer requirement for further | 21 | * including a substantially similar Disclaimer requirement for further |
22 | * binary redistribution. | 22 | * binary redistribution. |
23 | * 3. Neither the names of the above-listed copyright holders nor the names | 23 | * 3. Neither the names of the above-listed copyright holders nor the names |
24 | * of any contributors may be used to endorse or promote products derived | 24 | * of any contributors may be used to endorse or promote products derived |
25 | * from this software without specific prior written permission. | 25 | * from this software without specific prior written permission. |
26 | * | 26 | * |
27 | * Alternatively, this software may be distributed under the terms of the | 27 | * Alternatively, this software may be distributed under the terms of the |
28 | * GNU General Public License ("GPL") version 2 as published by the Free | 28 | * GNU General Public License ("GPL") version 2 as published by the Free |
29 | * Software Foundation. | 29 | * Software Foundation. |
30 | * | 30 | * |
31 | * NO WARRANTY | 31 | * NO WARRANTY |
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | 34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | 40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
42 | * POSSIBILITY OF SUCH DAMAGES. | 42 | * POSSIBILITY OF SUCH DAMAGES. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
46 | #include <acpi/actables.h> | 46 | #include <acpi/actables.h> |
47 | 47 | ||
48 | #define _COMPONENT ACPI_HARDWARE | 48 | #define _COMPONENT ACPI_HARDWARE |
49 | ACPI_MODULE_NAME("hwsleep") | 49 | ACPI_MODULE_NAME("hwsleep") |
50 | 50 | ||
51 | /******************************************************************************* | 51 | /******************************************************************************* |
52 | * | 52 | * |
53 | * FUNCTION: acpi_set_firmware_waking_vector | 53 | * FUNCTION: acpi_set_firmware_waking_vector |
54 | * | 54 | * |
55 | * PARAMETERS: physical_address - Physical address of ACPI real mode | 55 | * PARAMETERS: physical_address - Physical address of ACPI real mode |
56 | * entry point. | 56 | * entry point. |
57 | * | 57 | * |
58 | * RETURN: Status | 58 | * RETURN: Status |
59 | * | 59 | * |
60 | * DESCRIPTION: Access function for the firmware_waking_vector field in FACS | 60 | * DESCRIPTION: Access function for the firmware_waking_vector field in FACS |
61 | * | 61 | * |
62 | ******************************************************************************/ | 62 | ******************************************************************************/ |
63 | acpi_status | 63 | acpi_status |
64 | acpi_set_firmware_waking_vector(acpi_physical_address physical_address) | 64 | acpi_set_firmware_waking_vector(acpi_physical_address physical_address) |
65 | { | 65 | { |
66 | struct acpi_table_facs *facs; | 66 | struct acpi_table_facs *facs; |
67 | acpi_status status; | 67 | acpi_status status; |
68 | 68 | ||
69 | ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); | 69 | ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); |
70 | 70 | ||
71 | /* Get the FACS */ | 71 | /* Get the FACS */ |
72 | 72 | ||
73 | status = | 73 | status = |
74 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, | 74 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, |
75 | (struct acpi_table_header **)&facs); | 75 | (struct acpi_table_header **)&facs); |
76 | if (ACPI_FAILURE(status)) { | 76 | if (ACPI_FAILURE(status)) { |
77 | return_ACPI_STATUS(status); | 77 | return_ACPI_STATUS(status); |
78 | } | 78 | } |
79 | 79 | ||
80 | /* Set the vector */ | 80 | /* Set the vector */ |
81 | 81 | ||
82 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { | 82 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { |
83 | /* | 83 | /* |
84 | * ACPI 1.0 FACS or short table or optional X_ field is zero | 84 | * ACPI 1.0 FACS or short table or optional X_ field is zero |
85 | */ | 85 | */ |
86 | facs->firmware_waking_vector = (u32) physical_address; | 86 | facs->firmware_waking_vector = (u32) physical_address; |
87 | } else { | 87 | } else { |
88 | /* | 88 | /* |
89 | * ACPI 2.0 FACS with valid X_ field | 89 | * ACPI 2.0 FACS with valid X_ field |
90 | */ | 90 | */ |
91 | facs->xfirmware_waking_vector = physical_address; | 91 | facs->xfirmware_waking_vector = physical_address; |
92 | } | 92 | } |
93 | 93 | ||
94 | return_ACPI_STATUS(AE_OK); | 94 | return_ACPI_STATUS(AE_OK); |
95 | } | 95 | } |
96 | 96 | ||
97 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) | 97 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) |
98 | 98 | ||
99 | /******************************************************************************* | 99 | /******************************************************************************* |
100 | * | 100 | * |
101 | * FUNCTION: acpi_get_firmware_waking_vector | 101 | * FUNCTION: acpi_get_firmware_waking_vector |
102 | * | 102 | * |
103 | * PARAMETERS: *physical_address - Where the contents of | 103 | * PARAMETERS: *physical_address - Where the contents of |
104 | * the firmware_waking_vector field of | 104 | * the firmware_waking_vector field of |
105 | * the FACS will be returned. | 105 | * the FACS will be returned. |
106 | * | 106 | * |
107 | * RETURN: Status, vector | 107 | * RETURN: Status, vector |
108 | * | 108 | * |
109 | * DESCRIPTION: Access function for the firmware_waking_vector field in FACS | 109 | * DESCRIPTION: Access function for the firmware_waking_vector field in FACS |
110 | * | 110 | * |
111 | ******************************************************************************/ | 111 | ******************************************************************************/ |
112 | #ifdef ACPI_FUTURE_USAGE | 112 | #ifdef ACPI_FUTURE_USAGE |
113 | acpi_status | 113 | acpi_status |
114 | acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) | 114 | acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) |
115 | { | 115 | { |
116 | struct acpi_table_facs *facs; | 116 | struct acpi_table_facs *facs; |
117 | acpi_status status; | 117 | acpi_status status; |
118 | 118 | ||
119 | ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector); | 119 | ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector); |
120 | 120 | ||
121 | if (!physical_address) { | 121 | if (!physical_address) { |
122 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 122 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
123 | } | 123 | } |
124 | 124 | ||
125 | /* Get the FACS */ | 125 | /* Get the FACS */ |
126 | 126 | ||
127 | status = | 127 | status = |
128 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, | 128 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, |
129 | (struct acpi_table_header **)&facs); | 129 | (struct acpi_table_header **)&facs); |
130 | if (ACPI_FAILURE(status)) { | 130 | if (ACPI_FAILURE(status)) { |
131 | return_ACPI_STATUS(status); | 131 | return_ACPI_STATUS(status); |
132 | } | 132 | } |
133 | 133 | ||
134 | /* Get the vector */ | 134 | /* Get the vector */ |
135 | 135 | ||
136 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { | 136 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { |
137 | /* | 137 | /* |
138 | * ACPI 1.0 FACS or short table or optional X_ field is zero | 138 | * ACPI 1.0 FACS or short table or optional X_ field is zero |
139 | */ | 139 | */ |
140 | *physical_address = | 140 | *physical_address = |
141 | (acpi_physical_address) facs->firmware_waking_vector; | 141 | (acpi_physical_address) facs->firmware_waking_vector; |
142 | } else { | 142 | } else { |
143 | /* | 143 | /* |
144 | * ACPI 2.0 FACS with valid X_ field | 144 | * ACPI 2.0 FACS with valid X_ field |
145 | */ | 145 | */ |
146 | *physical_address = | 146 | *physical_address = |
147 | (acpi_physical_address) facs->xfirmware_waking_vector; | 147 | (acpi_physical_address) facs->xfirmware_waking_vector; |
148 | } | 148 | } |
149 | 149 | ||
150 | return_ACPI_STATUS(AE_OK); | 150 | return_ACPI_STATUS(AE_OK); |
151 | } | 151 | } |
152 | 152 | ||
153 | ACPI_EXPORT_SYMBOL(acpi_get_firmware_waking_vector) | 153 | ACPI_EXPORT_SYMBOL(acpi_get_firmware_waking_vector) |
154 | #endif | 154 | #endif |
155 | /******************************************************************************* | 155 | /******************************************************************************* |
156 | * | 156 | * |
157 | * FUNCTION: acpi_enter_sleep_state_prep | 157 | * FUNCTION: acpi_enter_sleep_state_prep |
158 | * | 158 | * |
159 | * PARAMETERS: sleep_state - Which sleep state to enter | 159 | * PARAMETERS: sleep_state - Which sleep state to enter |
160 | * | 160 | * |
161 | * RETURN: Status | 161 | * RETURN: Status |
162 | * | 162 | * |
163 | * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231) | 163 | * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231) |
164 | * This function must execute with interrupts enabled. | 164 | * This function must execute with interrupts enabled. |
165 | * We break sleeping into 2 stages so that OSPM can handle | 165 | * We break sleeping into 2 stages so that OSPM can handle |
166 | * various OS-specific tasks between the two steps. | 166 | * various OS-specific tasks between the two steps. |
167 | * | 167 | * |
168 | ******************************************************************************/ | 168 | ******************************************************************************/ |
169 | acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) | 169 | acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) |
170 | { | 170 | { |
171 | acpi_status status; | 171 | acpi_status status; |
172 | struct acpi_object_list arg_list; | 172 | struct acpi_object_list arg_list; |
173 | union acpi_object arg; | 173 | union acpi_object arg; |
174 | 174 | ||
175 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep); | 175 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep); |
176 | 176 | ||
177 | /* | 177 | /* |
178 | * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. | 178 | * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. |
179 | */ | 179 | */ |
180 | status = acpi_get_sleep_type_data(sleep_state, | 180 | status = acpi_get_sleep_type_data(sleep_state, |
181 | &acpi_gbl_sleep_type_a, | 181 | &acpi_gbl_sleep_type_a, |
182 | &acpi_gbl_sleep_type_b); | 182 | &acpi_gbl_sleep_type_b); |
183 | if (ACPI_FAILURE(status)) { | 183 | if (ACPI_FAILURE(status)) { |
184 | return_ACPI_STATUS(status); | 184 | return_ACPI_STATUS(status); |
185 | } | 185 | } |
186 | 186 | ||
187 | /* Setup parameter object */ | 187 | /* Setup parameter object */ |
188 | 188 | ||
189 | arg_list.count = 1; | 189 | arg_list.count = 1; |
190 | arg_list.pointer = &arg; | 190 | arg_list.pointer = &arg; |
191 | 191 | ||
192 | arg.type = ACPI_TYPE_INTEGER; | 192 | arg.type = ACPI_TYPE_INTEGER; |
193 | arg.integer.value = sleep_state; | 193 | arg.integer.value = sleep_state; |
194 | 194 | ||
195 | /* Run the _PTS and _GTS methods */ | 195 | /* Run the _PTS and _GTS methods */ |
196 | 196 | ||
197 | status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL); | 197 | status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL); |
198 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 198 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
199 | return_ACPI_STATUS(status); | 199 | return_ACPI_STATUS(status); |
200 | } | 200 | } |
201 | 201 | ||
202 | status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); | 202 | status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); |
203 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 203 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
204 | return_ACPI_STATUS(status); | 204 | return_ACPI_STATUS(status); |
205 | } | 205 | } |
206 | 206 | ||
207 | /* Setup the argument to _SST */ | 207 | /* Setup the argument to _SST */ |
208 | 208 | ||
209 | switch (sleep_state) { | 209 | switch (sleep_state) { |
210 | case ACPI_STATE_S0: | 210 | case ACPI_STATE_S0: |
211 | arg.integer.value = ACPI_SST_WORKING; | 211 | arg.integer.value = ACPI_SST_WORKING; |
212 | break; | 212 | break; |
213 | 213 | ||
214 | case ACPI_STATE_S1: | 214 | case ACPI_STATE_S1: |
215 | case ACPI_STATE_S2: | 215 | case ACPI_STATE_S2: |
216 | case ACPI_STATE_S3: | 216 | case ACPI_STATE_S3: |
217 | arg.integer.value = ACPI_SST_SLEEPING; | 217 | arg.integer.value = ACPI_SST_SLEEPING; |
218 | break; | 218 | break; |
219 | 219 | ||
220 | case ACPI_STATE_S4: | 220 | case ACPI_STATE_S4: |
221 | arg.integer.value = ACPI_SST_SLEEP_CONTEXT; | 221 | arg.integer.value = ACPI_SST_SLEEP_CONTEXT; |
222 | break; | 222 | break; |
223 | 223 | ||
224 | default: | 224 | default: |
225 | arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is off */ | 225 | arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is off */ |
226 | break; | 226 | break; |
227 | } | 227 | } |
228 | 228 | ||
229 | /* Set the system indicators to show the desired sleep state. */ | 229 | /* Set the system indicators to show the desired sleep state. */ |
230 | 230 | ||
231 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); | 231 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); |
232 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 232 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
233 | ACPI_EXCEPTION((AE_INFO, status, | 233 | ACPI_EXCEPTION((AE_INFO, status, |
234 | "While executing method _SST")); | 234 | "While executing method _SST")); |
235 | } | 235 | } |
236 | 236 | ||
237 | /* | 237 | /* |
238 | * 1) Disable/Clear all GPEs | 238 | * 1) Disable/Clear all GPEs |
239 | */ | 239 | */ |
240 | status = acpi_hw_disable_all_gpes(); | 240 | status = acpi_hw_disable_all_gpes(); |
241 | if (ACPI_FAILURE(status)) { | 241 | if (ACPI_FAILURE(status)) { |
242 | return_ACPI_STATUS(status); | 242 | return_ACPI_STATUS(status); |
243 | } | 243 | } |
244 | 244 | ||
245 | return_ACPI_STATUS(AE_OK); | 245 | return_ACPI_STATUS(AE_OK); |
246 | } | 246 | } |
247 | 247 | ||
248 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | 248 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) |
249 | 249 | ||
250 | /******************************************************************************* | 250 | /******************************************************************************* |
251 | * | 251 | * |
252 | * FUNCTION: acpi_enter_sleep_state | 252 | * FUNCTION: acpi_enter_sleep_state |
253 | * | 253 | * |
254 | * PARAMETERS: sleep_state - Which sleep state to enter | 254 | * PARAMETERS: sleep_state - Which sleep state to enter |
255 | * | 255 | * |
256 | * RETURN: Status | 256 | * RETURN: Status |
257 | * | 257 | * |
258 | * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) | 258 | * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) |
259 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | 259 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED |
260 | * | 260 | * |
261 | ******************************************************************************/ | 261 | ******************************************************************************/ |
262 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | 262 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) |
263 | { | 263 | { |
264 | u32 PM1Acontrol; | 264 | u32 PM1Acontrol; |
265 | u32 PM1Bcontrol; | 265 | u32 PM1Bcontrol; |
266 | struct acpi_bit_register_info *sleep_type_reg_info; | 266 | struct acpi_bit_register_info *sleep_type_reg_info; |
267 | struct acpi_bit_register_info *sleep_enable_reg_info; | 267 | struct acpi_bit_register_info *sleep_enable_reg_info; |
268 | u32 in_value; | 268 | u32 in_value; |
269 | acpi_status status; | 269 | acpi_status status; |
270 | 270 | ||
271 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); | 271 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); |
272 | 272 | ||
273 | if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) || | 273 | if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) || |
274 | (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) { | 274 | (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) { |
275 | ACPI_ERROR((AE_INFO, "Sleep values out of range: A=%X B=%X", | 275 | ACPI_ERROR((AE_INFO, "Sleep values out of range: A=%X B=%X", |
276 | acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b)); | 276 | acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b)); |
277 | return_ACPI_STATUS(AE_AML_OPERAND_VALUE); | 277 | return_ACPI_STATUS(AE_AML_OPERAND_VALUE); |
278 | } | 278 | } |
279 | 279 | ||
280 | sleep_type_reg_info = | 280 | sleep_type_reg_info = |
281 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A); | 281 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A); |
282 | sleep_enable_reg_info = | 282 | sleep_enable_reg_info = |
283 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE); | 283 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE); |
284 | 284 | ||
285 | /* Clear wake status */ | 285 | /* Clear wake status */ |
286 | 286 | ||
287 | status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); | 287 | status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); |
288 | if (ACPI_FAILURE(status)) { | 288 | if (ACPI_FAILURE(status)) { |
289 | return_ACPI_STATUS(status); | 289 | return_ACPI_STATUS(status); |
290 | } | 290 | } |
291 | 291 | ||
292 | /* Clear all fixed and general purpose status bits */ | 292 | /* Clear all fixed and general purpose status bits */ |
293 | 293 | ||
294 | status = acpi_hw_clear_acpi_status(); | 294 | status = acpi_hw_clear_acpi_status(); |
295 | if (ACPI_FAILURE(status)) { | 295 | if (ACPI_FAILURE(status)) { |
296 | return_ACPI_STATUS(status); | 296 | return_ACPI_STATUS(status); |
297 | } | 297 | } |
298 | 298 | ||
299 | /* | 299 | /* |
300 | * 2) Enable all wakeup GPEs | 300 | * 2) Enable all wakeup GPEs |
301 | */ | 301 | */ |
302 | status = acpi_hw_disable_all_gpes(); | 302 | status = acpi_hw_disable_all_gpes(); |
303 | if (ACPI_FAILURE(status)) { | 303 | if (ACPI_FAILURE(status)) { |
304 | return_ACPI_STATUS(status); | 304 | return_ACPI_STATUS(status); |
305 | } | 305 | } |
306 | 306 | ||
307 | acpi_gbl_system_awake_and_running = FALSE; | 307 | acpi_gbl_system_awake_and_running = FALSE; |
308 | 308 | ||
309 | status = acpi_hw_enable_all_wakeup_gpes(); | 309 | status = acpi_hw_enable_all_wakeup_gpes(); |
310 | if (ACPI_FAILURE(status)) { | 310 | if (ACPI_FAILURE(status)) { |
311 | return_ACPI_STATUS(status); | 311 | return_ACPI_STATUS(status); |
312 | } | 312 | } |
313 | 313 | ||
314 | /* Get current value of PM1A control */ | 314 | /* Get current value of PM1A control */ |
315 | 315 | ||
316 | status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, | 316 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); |
317 | ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); | ||
318 | if (ACPI_FAILURE(status)) { | 317 | if (ACPI_FAILURE(status)) { |
319 | return_ACPI_STATUS(status); | 318 | return_ACPI_STATUS(status); |
320 | } | 319 | } |
321 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 320 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
322 | "Entering sleep state [S%d]\n", sleep_state)); | 321 | "Entering sleep state [S%d]\n", sleep_state)); |
323 | 322 | ||
324 | /* Clear SLP_EN and SLP_TYP fields */ | 323 | /* Clear SLP_EN and SLP_TYP fields */ |
325 | 324 | ||
326 | PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | | 325 | PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | |
327 | sleep_enable_reg_info->access_bit_mask); | 326 | sleep_enable_reg_info->access_bit_mask); |
328 | PM1Bcontrol = PM1Acontrol; | 327 | PM1Bcontrol = PM1Acontrol; |
329 | 328 | ||
330 | /* Insert SLP_TYP bits */ | 329 | /* Insert SLP_TYP bits */ |
331 | 330 | ||
332 | PM1Acontrol |= | 331 | PM1Acontrol |= |
333 | (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position); | 332 | (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position); |
334 | PM1Bcontrol |= | 333 | PM1Bcontrol |= |
335 | (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position); | 334 | (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position); |
336 | 335 | ||
337 | /* | 336 | /* |
338 | * We split the writes of SLP_TYP and SLP_EN to workaround | 337 | * We split the writes of SLP_TYP and SLP_EN to workaround |
339 | * poorly implemented hardware. | 338 | * poorly implemented hardware. |
340 | */ | 339 | */ |
341 | 340 | ||
342 | /* Write #1: fill in SLP_TYP data */ | 341 | /* Write #1: fill in SLP_TYP data */ |
343 | 342 | ||
344 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 343 | status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, |
345 | ACPI_REGISTER_PM1A_CONTROL, | ||
346 | PM1Acontrol); | 344 | PM1Acontrol); |
347 | if (ACPI_FAILURE(status)) { | 345 | if (ACPI_FAILURE(status)) { |
348 | return_ACPI_STATUS(status); | 346 | return_ACPI_STATUS(status); |
349 | } | 347 | } |
350 | 348 | ||
351 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 349 | status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, |
352 | ACPI_REGISTER_PM1B_CONTROL, | ||
353 | PM1Bcontrol); | 350 | PM1Bcontrol); |
354 | if (ACPI_FAILURE(status)) { | 351 | if (ACPI_FAILURE(status)) { |
355 | return_ACPI_STATUS(status); | 352 | return_ACPI_STATUS(status); |
356 | } | 353 | } |
357 | 354 | ||
358 | /* Insert SLP_ENABLE bit */ | 355 | /* Insert SLP_ENABLE bit */ |
359 | 356 | ||
360 | PM1Acontrol |= sleep_enable_reg_info->access_bit_mask; | 357 | PM1Acontrol |= sleep_enable_reg_info->access_bit_mask; |
361 | PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask; | 358 | PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask; |
362 | 359 | ||
363 | /* Write #2: SLP_TYP + SLP_EN */ | 360 | /* Write #2: SLP_TYP + SLP_EN */ |
364 | 361 | ||
365 | ACPI_FLUSH_CPU_CACHE(); | 362 | ACPI_FLUSH_CPU_CACHE(); |
366 | 363 | ||
367 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 364 | status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, |
368 | ACPI_REGISTER_PM1A_CONTROL, | ||
369 | PM1Acontrol); | 365 | PM1Acontrol); |
370 | if (ACPI_FAILURE(status)) { | 366 | if (ACPI_FAILURE(status)) { |
371 | return_ACPI_STATUS(status); | 367 | return_ACPI_STATUS(status); |
372 | } | 368 | } |
373 | 369 | ||
374 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 370 | status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, |
375 | ACPI_REGISTER_PM1B_CONTROL, | ||
376 | PM1Bcontrol); | 371 | PM1Bcontrol); |
377 | if (ACPI_FAILURE(status)) { | 372 | if (ACPI_FAILURE(status)) { |
378 | return_ACPI_STATUS(status); | 373 | return_ACPI_STATUS(status); |
379 | } | 374 | } |
380 | 375 | ||
381 | if (sleep_state > ACPI_STATE_S3) { | 376 | if (sleep_state > ACPI_STATE_S3) { |
382 | /* | 377 | /* |
383 | * We wanted to sleep > S3, but it didn't happen (by virtue of the | 378 | * We wanted to sleep > S3, but it didn't happen (by virtue of the |
384 | * fact that we are still executing!) | 379 | * fact that we are still executing!) |
385 | * | 380 | * |
386 | * Wait ten seconds, then try again. This is to get S4/S5 to work on | 381 | * Wait ten seconds, then try again. This is to get S4/S5 to work on |
387 | * all machines. | 382 | * all machines. |
388 | * | 383 | * |
389 | * We wait so long to allow chipsets that poll this reg very slowly to | 384 | * We wait so long to allow chipsets that poll this reg very slowly to |
390 | * still read the right value. Ideally, this block would go | 385 | * still read the right value. Ideally, this block would go |
391 | * away entirely. | 386 | * away entirely. |
392 | */ | 387 | */ |
393 | acpi_os_stall(10000000); | 388 | acpi_os_stall(10000000); |
394 | 389 | ||
395 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 390 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL, |
396 | ACPI_REGISTER_PM1_CONTROL, | ||
397 | sleep_enable_reg_info-> | 391 | sleep_enable_reg_info-> |
398 | access_bit_mask); | 392 | access_bit_mask); |
399 | if (ACPI_FAILURE(status)) { | 393 | if (ACPI_FAILURE(status)) { |
400 | return_ACPI_STATUS(status); | 394 | return_ACPI_STATUS(status); |
401 | } | 395 | } |
402 | } | 396 | } |
403 | 397 | ||
404 | /* Wait until we enter sleep state */ | 398 | /* Wait until we enter sleep state */ |
405 | 399 | ||
406 | do { | 400 | do { |
407 | status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); | 401 | status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); |
408 | if (ACPI_FAILURE(status)) { | 402 | if (ACPI_FAILURE(status)) { |
409 | return_ACPI_STATUS(status); | 403 | return_ACPI_STATUS(status); |
410 | } | 404 | } |
411 | 405 | ||
412 | /* Spin until we wake */ | 406 | /* Spin until we wake */ |
413 | 407 | ||
414 | } while (!in_value); | 408 | } while (!in_value); |
415 | 409 | ||
416 | return_ACPI_STATUS(AE_OK); | 410 | return_ACPI_STATUS(AE_OK); |
417 | } | 411 | } |
418 | 412 | ||
419 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) | 413 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) |
420 | 414 | ||
421 | /******************************************************************************* | 415 | /******************************************************************************* |
422 | * | 416 | * |
423 | * FUNCTION: acpi_enter_sleep_state_s4bios | 417 | * FUNCTION: acpi_enter_sleep_state_s4bios |
424 | * | 418 | * |
425 | * PARAMETERS: None | 419 | * PARAMETERS: None |
426 | * | 420 | * |
427 | * RETURN: Status | 421 | * RETURN: Status |
428 | * | 422 | * |
429 | * DESCRIPTION: Perform a S4 bios request. | 423 | * DESCRIPTION: Perform a S4 bios request. |
430 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | 424 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED |
431 | * | 425 | * |
432 | ******************************************************************************/ | 426 | ******************************************************************************/ |
433 | acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) | 427 | acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) |
434 | { | 428 | { |
435 | u32 in_value; | 429 | u32 in_value; |
436 | acpi_status status; | 430 | acpi_status status; |
437 | 431 | ||
438 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); | 432 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); |
439 | 433 | ||
440 | status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); | 434 | status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); |
441 | if (ACPI_FAILURE(status)) { | 435 | if (ACPI_FAILURE(status)) { |
442 | return_ACPI_STATUS(status); | 436 | return_ACPI_STATUS(status); |
443 | } | 437 | } |
444 | 438 | ||
445 | status = acpi_hw_clear_acpi_status(); | 439 | status = acpi_hw_clear_acpi_status(); |
446 | if (ACPI_FAILURE(status)) { | 440 | if (ACPI_FAILURE(status)) { |
447 | return_ACPI_STATUS(status); | 441 | return_ACPI_STATUS(status); |
448 | } | 442 | } |
449 | 443 | ||
450 | /* | 444 | /* |
451 | * 1) Disable/Clear all GPEs | 445 | * 1) Disable/Clear all GPEs |
452 | * 2) Enable all wakeup GPEs | 446 | * 2) Enable all wakeup GPEs |
453 | */ | 447 | */ |
454 | status = acpi_hw_disable_all_gpes(); | 448 | status = acpi_hw_disable_all_gpes(); |
455 | if (ACPI_FAILURE(status)) { | 449 | if (ACPI_FAILURE(status)) { |
456 | return_ACPI_STATUS(status); | 450 | return_ACPI_STATUS(status); |
457 | } | 451 | } |
458 | acpi_gbl_system_awake_and_running = FALSE; | 452 | acpi_gbl_system_awake_and_running = FALSE; |
459 | 453 | ||
460 | status = acpi_hw_enable_all_wakeup_gpes(); | 454 | status = acpi_hw_enable_all_wakeup_gpes(); |
461 | if (ACPI_FAILURE(status)) { | 455 | if (ACPI_FAILURE(status)) { |
462 | return_ACPI_STATUS(status); | 456 | return_ACPI_STATUS(status); |
463 | } | 457 | } |
464 | 458 | ||
465 | ACPI_FLUSH_CPU_CACHE(); | 459 | ACPI_FLUSH_CPU_CACHE(); |
466 | 460 | ||
467 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, | 461 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, |
468 | (u32) acpi_gbl_FADT.S4bios_request, 8); | 462 | (u32) acpi_gbl_FADT.S4bios_request, 8); |
469 | 463 | ||
470 | do { | 464 | do { |
471 | acpi_os_stall(1000); | 465 | acpi_os_stall(1000); |
472 | status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); | 466 | status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); |
473 | if (ACPI_FAILURE(status)) { | 467 | if (ACPI_FAILURE(status)) { |
474 | return_ACPI_STATUS(status); | 468 | return_ACPI_STATUS(status); |
475 | } | 469 | } |
476 | } while (!in_value); | 470 | } while (!in_value); |
477 | 471 | ||
478 | return_ACPI_STATUS(AE_OK); | 472 | return_ACPI_STATUS(AE_OK); |
479 | } | 473 | } |
480 | 474 | ||
481 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) | 475 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) |
482 | 476 | ||
483 | /******************************************************************************* | 477 | /******************************************************************************* |
484 | * | 478 | * |
485 | * FUNCTION: acpi_leave_sleep_state | 479 | * FUNCTION: acpi_leave_sleep_state |
486 | * | 480 | * |
487 | * PARAMETERS: sleep_state - Which sleep state we just exited | 481 | * PARAMETERS: sleep_state - Which sleep state we just exited |
488 | * | 482 | * |
489 | * RETURN: Status | 483 | * RETURN: Status |
490 | * | 484 | * |
491 | * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep | 485 | * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep |
492 | * Called with interrupts ENABLED. | 486 | * Called with interrupts ENABLED. |
493 | * | 487 | * |
494 | ******************************************************************************/ | 488 | ******************************************************************************/ |
495 | acpi_status acpi_leave_sleep_state(u8 sleep_state) | 489 | acpi_status acpi_leave_sleep_state(u8 sleep_state) |
496 | { | 490 | { |
497 | struct acpi_object_list arg_list; | 491 | struct acpi_object_list arg_list; |
498 | union acpi_object arg; | 492 | union acpi_object arg; |
499 | acpi_status status; | 493 | acpi_status status; |
500 | struct acpi_bit_register_info *sleep_type_reg_info; | 494 | struct acpi_bit_register_info *sleep_type_reg_info; |
501 | struct acpi_bit_register_info *sleep_enable_reg_info; | 495 | struct acpi_bit_register_info *sleep_enable_reg_info; |
502 | u32 PM1Acontrol; | 496 | u32 PM1Acontrol; |
503 | u32 PM1Bcontrol; | 497 | u32 PM1Bcontrol; |
504 | 498 | ||
505 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); | 499 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); |
506 | 500 | ||
507 | /* | 501 | /* |
508 | * Set SLP_TYPE and SLP_EN to state S0. | 502 | * Set SLP_TYPE and SLP_EN to state S0. |
509 | * This is unclear from the ACPI Spec, but it is required | 503 | * This is unclear from the ACPI Spec, but it is required |
510 | * by some machines. | 504 | * by some machines. |
511 | */ | 505 | */ |
512 | status = acpi_get_sleep_type_data(ACPI_STATE_S0, | 506 | status = acpi_get_sleep_type_data(ACPI_STATE_S0, |
513 | &acpi_gbl_sleep_type_a, | 507 | &acpi_gbl_sleep_type_a, |
514 | &acpi_gbl_sleep_type_b); | 508 | &acpi_gbl_sleep_type_b); |
515 | if (ACPI_SUCCESS(status)) { | 509 | if (ACPI_SUCCESS(status)) { |
516 | sleep_type_reg_info = | 510 | sleep_type_reg_info = |
517 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A); | 511 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A); |
518 | sleep_enable_reg_info = | 512 | sleep_enable_reg_info = |
519 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE); | 513 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE); |
520 | 514 | ||
521 | /* Get current value of PM1A control */ | 515 | /* Get current value of PM1A control */ |
522 | 516 | ||
523 | status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, | 517 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, |
524 | ACPI_REGISTER_PM1_CONTROL, | ||
525 | &PM1Acontrol); | 518 | &PM1Acontrol); |
526 | if (ACPI_SUCCESS(status)) { | 519 | if (ACPI_SUCCESS(status)) { |
527 | 520 | ||
528 | /* Clear SLP_EN and SLP_TYP fields */ | 521 | /* Clear SLP_EN and SLP_TYP fields */ |
529 | 522 | ||
530 | PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | | 523 | PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | |
531 | sleep_enable_reg_info-> | 524 | sleep_enable_reg_info-> |
532 | access_bit_mask); | 525 | access_bit_mask); |
533 | PM1Bcontrol = PM1Acontrol; | 526 | PM1Bcontrol = PM1Acontrol; |
534 | 527 | ||
535 | /* Insert SLP_TYP bits */ | 528 | /* Insert SLP_TYP bits */ |
536 | 529 | ||
537 | PM1Acontrol |= | 530 | PM1Acontrol |= |
538 | (acpi_gbl_sleep_type_a << sleep_type_reg_info-> | 531 | (acpi_gbl_sleep_type_a << sleep_type_reg_info-> |
539 | bit_position); | 532 | bit_position); |
540 | PM1Bcontrol |= | 533 | PM1Bcontrol |= |
541 | (acpi_gbl_sleep_type_b << sleep_type_reg_info-> | 534 | (acpi_gbl_sleep_type_b << sleep_type_reg_info-> |
542 | bit_position); | 535 | bit_position); |
543 | 536 | ||
544 | /* Just ignore any errors */ | 537 | /* Just ignore any errors */ |
545 | 538 | ||
546 | (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 539 | (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, |
547 | ACPI_REGISTER_PM1A_CONTROL, | ||
548 | PM1Acontrol); | 540 | PM1Acontrol); |
549 | (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 541 | (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, |
550 | ACPI_REGISTER_PM1B_CONTROL, | ||
551 | PM1Bcontrol); | 542 | PM1Bcontrol); |
552 | } | 543 | } |
553 | } | 544 | } |
554 | 545 | ||
555 | /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ | 546 | /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ |
556 | 547 | ||
557 | acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; | 548 | acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; |
558 | 549 | ||
559 | /* Setup parameter object */ | 550 | /* Setup parameter object */ |
560 | 551 | ||
561 | arg_list.count = 1; | 552 | arg_list.count = 1; |
562 | arg_list.pointer = &arg; | 553 | arg_list.pointer = &arg; |
563 | arg.type = ACPI_TYPE_INTEGER; | 554 | arg.type = ACPI_TYPE_INTEGER; |
564 | 555 | ||
565 | /* Ignore any errors from these methods */ | 556 | /* Ignore any errors from these methods */ |
566 | 557 | ||
567 | arg.integer.value = ACPI_SST_WAKING; | 558 | arg.integer.value = ACPI_SST_WAKING; |
568 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); | 559 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); |
569 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 560 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
570 | ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); | 561 | ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); |
571 | } | 562 | } |
572 | 563 | ||
573 | arg.integer.value = sleep_state; | 564 | arg.integer.value = sleep_state; |
574 | status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); | 565 | status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); |
575 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 566 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
576 | ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); | 567 | ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); |
577 | } | 568 | } |
578 | 569 | ||
579 | /* | 570 | /* |
580 | * GPEs must be enabled before _WAK is called as GPEs | 571 | * GPEs must be enabled before _WAK is called as GPEs |
581 | * might get fired there | 572 | * might get fired there |
582 | * | 573 | * |
583 | * Restore the GPEs: | 574 | * Restore the GPEs: |
584 | * 1) Disable/Clear all GPEs | 575 | * 1) Disable/Clear all GPEs |
585 | * 2) Enable all runtime GPEs | 576 | * 2) Enable all runtime GPEs |
586 | */ | 577 | */ |
587 | status = acpi_hw_disable_all_gpes(); | 578 | status = acpi_hw_disable_all_gpes(); |
588 | if (ACPI_FAILURE(status)) { | 579 | if (ACPI_FAILURE(status)) { |
589 | return_ACPI_STATUS(status); | 580 | return_ACPI_STATUS(status); |
590 | } | 581 | } |
591 | status = acpi_hw_enable_all_runtime_gpes(); | 582 | status = acpi_hw_enable_all_runtime_gpes(); |
592 | if (ACPI_FAILURE(status)) { | 583 | if (ACPI_FAILURE(status)) { |
593 | return_ACPI_STATUS(status); | 584 | return_ACPI_STATUS(status); |
594 | } | 585 | } |
595 | 586 | ||
596 | status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL); | 587 | status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL); |
597 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 588 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
598 | ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK")); | 589 | ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK")); |
599 | } | 590 | } |
600 | /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ | 591 | /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ |
601 | 592 | ||
602 | acpi_gbl_system_awake_and_running = TRUE; | 593 | acpi_gbl_system_awake_and_running = TRUE; |
603 | 594 | ||
604 | /* Enable power button */ | 595 | /* Enable power button */ |
605 | 596 | ||
606 | (void) | 597 | (void) |
607 | acpi_set_register(acpi_gbl_fixed_event_info | 598 | acpi_set_register(acpi_gbl_fixed_event_info |
608 | [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1); | 599 | [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1); |
609 | 600 | ||
610 | (void) | 601 | (void) |
611 | acpi_set_register(acpi_gbl_fixed_event_info | 602 | acpi_set_register(acpi_gbl_fixed_event_info |
612 | [ACPI_EVENT_POWER_BUTTON].status_register_id, 1); | 603 | [ACPI_EVENT_POWER_BUTTON].status_register_id, 1); |
613 | 604 | ||
614 | arg.integer.value = ACPI_SST_WORKING; | 605 | arg.integer.value = ACPI_SST_WORKING; |
615 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); | 606 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); |
616 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 607 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
617 | ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); | 608 | ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); |
618 | } | 609 | } |
619 | 610 | ||
620 | return_ACPI_STATUS(status); | 611 | return_ACPI_STATUS(status); |
621 | } | 612 | } |
622 | 613 | ||
623 | ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state) | 614 | ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state) |
624 | 615 |
include/acpi/achware.h
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Name: achware.h -- hardware specific interfaces | 3 | * Name: achware.h -- hardware specific interfaces |
4 | * | 4 | * |
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2007, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions, and the following disclaimer, | 15 | * notice, this list of conditions, and the following disclaimer, |
16 | * without modification. | 16 | * without modification. |
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | 17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
18 | * substantially similar to the "NO WARRANTY" disclaimer below | 18 | * substantially similar to the "NO WARRANTY" disclaimer below |
19 | * ("Disclaimer") and any redistribution must be conditioned upon | 19 | * ("Disclaimer") and any redistribution must be conditioned upon |
20 | * including a substantially similar Disclaimer requirement for further | 20 | * including a substantially similar Disclaimer requirement for further |
21 | * binary redistribution. | 21 | * binary redistribution. |
22 | * 3. Neither the names of the above-listed copyright holders nor the names | 22 | * 3. Neither the names of the above-listed copyright holders nor the names |
23 | * of any contributors may be used to endorse or promote products derived | 23 | * of any contributors may be used to endorse or promote products derived |
24 | * from this software without specific prior written permission. | 24 | * from this software without specific prior written permission. |
25 | * | 25 | * |
26 | * Alternatively, this software may be distributed under the terms of the | 26 | * Alternatively, this software may be distributed under the terms of the |
27 | * GNU General Public License ("GPL") version 2 as published by the Free | 27 | * GNU General Public License ("GPL") version 2 as published by the Free |
28 | * Software Foundation. | 28 | * Software Foundation. |
29 | * | 29 | * |
30 | * NO WARRANTY | 30 | * NO WARRANTY |
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | 33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | 39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #ifndef __ACHWARE_H__ | 44 | #ifndef __ACHWARE_H__ |
45 | #define __ACHWARE_H__ | 45 | #define __ACHWARE_H__ |
46 | 46 | ||
47 | /* PM Timer ticks per second (HZ) */ | 47 | /* PM Timer ticks per second (HZ) */ |
48 | 48 | ||
49 | #define PM_TIMER_FREQUENCY 3579545 | 49 | #define PM_TIMER_FREQUENCY 3579545 |
50 | 50 | ||
51 | /* Values for the _SST reserved method */ | 51 | /* Values for the _SST reserved method */ |
52 | 52 | ||
53 | #define ACPI_SST_INDICATOR_OFF 0 | 53 | #define ACPI_SST_INDICATOR_OFF 0 |
54 | #define ACPI_SST_WORKING 1 | 54 | #define ACPI_SST_WORKING 1 |
55 | #define ACPI_SST_WAKING 2 | 55 | #define ACPI_SST_WAKING 2 |
56 | #define ACPI_SST_SLEEPING 3 | 56 | #define ACPI_SST_SLEEPING 3 |
57 | #define ACPI_SST_SLEEP_CONTEXT 4 | 57 | #define ACPI_SST_SLEEP_CONTEXT 4 |
58 | 58 | ||
59 | /* Prototypes */ | 59 | /* Prototypes */ |
60 | 60 | ||
61 | /* | 61 | /* |
62 | * hwacpi - high level functions | 62 | * hwacpi - high level functions |
63 | */ | 63 | */ |
64 | acpi_status acpi_hw_set_mode(u32 mode); | 64 | acpi_status acpi_hw_set_mode(u32 mode); |
65 | 65 | ||
66 | u32 acpi_hw_get_mode(void); | 66 | u32 acpi_hw_get_mode(void); |
67 | 67 | ||
68 | /* | 68 | /* |
69 | * hwregs - ACPI Register I/O | 69 | * hwregs - ACPI Register I/O |
70 | */ | 70 | */ |
71 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); | 71 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); |
72 | 72 | ||
73 | acpi_status | 73 | acpi_status |
74 | acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value); | 74 | acpi_hw_register_read(u32 register_id, u32 * return_value); |
75 | 75 | ||
76 | acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value); | 76 | acpi_status acpi_hw_register_write(u32 register_id, u32 value); |
77 | 77 | ||
78 | acpi_status | 78 | acpi_status |
79 | acpi_hw_low_level_read(u32 width, | 79 | acpi_hw_low_level_read(u32 width, |
80 | u32 * value, struct acpi_generic_address *reg); | 80 | u32 * value, struct acpi_generic_address *reg); |
81 | 81 | ||
82 | acpi_status | 82 | acpi_status |
83 | acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address *reg); | 83 | acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address *reg); |
84 | 84 | ||
85 | acpi_status acpi_hw_clear_acpi_status(void); | 85 | acpi_status acpi_hw_clear_acpi_status(void); |
86 | 86 | ||
87 | /* | 87 | /* |
88 | * hwgpe - GPE support | 88 | * hwgpe - GPE support |
89 | */ | 89 | */ |
90 | acpi_status | 90 | acpi_status |
91 | acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info); | 91 | acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info); |
92 | 92 | ||
93 | acpi_status | 93 | acpi_status |
94 | acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 94 | acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
95 | struct acpi_gpe_block_info *gpe_block); | 95 | struct acpi_gpe_block_info *gpe_block); |
96 | 96 | ||
97 | acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info *gpe_event_info); | 97 | acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info *gpe_event_info); |
98 | 98 | ||
99 | acpi_status | 99 | acpi_status |
100 | acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 100 | acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
101 | struct acpi_gpe_block_info *gpe_block); | 101 | struct acpi_gpe_block_info *gpe_block); |
102 | 102 | ||
103 | #ifdef ACPI_FUTURE_USAGE | 103 | #ifdef ACPI_FUTURE_USAGE |
104 | acpi_status | 104 | acpi_status |
105 | acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, | 105 | acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, |
106 | acpi_event_status * event_status); | 106 | acpi_event_status * event_status); |
107 | #endif /* ACPI_FUTURE_USAGE */ | 107 | #endif /* ACPI_FUTURE_USAGE */ |
108 | 108 | ||
109 | acpi_status acpi_hw_disable_all_gpes(void); | 109 | acpi_status acpi_hw_disable_all_gpes(void); |
110 | 110 | ||
111 | acpi_status acpi_hw_enable_all_runtime_gpes(void); | 111 | acpi_status acpi_hw_enable_all_runtime_gpes(void); |
112 | 112 | ||
113 | acpi_status acpi_hw_enable_all_wakeup_gpes(void); | 113 | acpi_status acpi_hw_enable_all_wakeup_gpes(void); |
114 | 114 | ||
115 | acpi_status | 115 | acpi_status |
116 | acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 116 | acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
117 | struct acpi_gpe_block_info *gpe_block); | 117 | struct acpi_gpe_block_info *gpe_block); |
118 | 118 | ||
119 | #ifdef ACPI_FUTURE_USAGE | 119 | #ifdef ACPI_FUTURE_USAGE |
120 | /* | 120 | /* |
121 | * hwtimer - ACPI Timer prototypes | 121 | * hwtimer - ACPI Timer prototypes |
122 | */ | 122 | */ |
123 | acpi_status acpi_get_timer_resolution(u32 * resolution); | 123 | acpi_status acpi_get_timer_resolution(u32 * resolution); |
124 | 124 | ||
125 | acpi_status acpi_get_timer(u32 * ticks); | 125 | acpi_status acpi_get_timer(u32 * ticks); |
126 | 126 | ||
127 | acpi_status | 127 | acpi_status |
128 | acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed); | 128 | acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed); |
129 | #endif /* ACPI_FUTURE_USAGE */ | 129 | #endif /* ACPI_FUTURE_USAGE */ |
130 | 130 | ||
131 | #endif /* __ACHWARE_H__ */ | 131 | #endif /* __ACHWARE_H__ */ |
132 | 132 |