1 | // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 |
2 | /****************************************************************************** |
3 | * |
4 | * Module Name: hwgpe - Low level GPE enable/disable/clear functions |
5 | * |
6 | * Copyright (C) 2000 - 2023, Intel Corp. |
7 | * |
8 | *****************************************************************************/ |
9 | |
10 | #include <acpi/acpi.h> |
11 | #include "accommon.h" |
12 | #include "acevents.h" |
13 | |
14 | #define _COMPONENT ACPI_HARDWARE |
15 | ACPI_MODULE_NAME("hwgpe" ) |
16 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ |
17 | /* Local prototypes */ |
18 | static acpi_status |
19 | acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
20 | struct acpi_gpe_block_info *gpe_block, |
21 | void *context); |
22 | |
23 | static acpi_status |
24 | acpi_hw_gpe_enable_write(u8 enable_mask, |
25 | struct acpi_gpe_register_info *gpe_register_info); |
26 | |
27 | /****************************************************************************** |
28 | * |
29 | * FUNCTION: acpi_hw_gpe_read |
30 | * |
31 | * PARAMETERS: value - Where the value is returned |
32 | * reg - GPE register structure |
33 | * |
34 | * RETURN: Status |
35 | * |
36 | * DESCRIPTION: Read from a GPE register in either memory or IO space. |
37 | * |
38 | * LIMITATIONS: <These limitations also apply to acpi_hw_gpe_write> |
39 | * space_ID must be system_memory or system_IO. |
40 | * |
41 | ******************************************************************************/ |
42 | |
43 | acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg) |
44 | { |
45 | acpi_status status; |
46 | u32 value32; |
47 | |
48 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
49 | #ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES |
50 | *value = (u64)ACPI_GET8((unsigned long)reg->address); |
51 | return_ACPI_STATUS(AE_OK); |
52 | #else |
53 | return acpi_os_read_memory((acpi_physical_address)reg->address, |
54 | value, ACPI_GPE_REGISTER_WIDTH); |
55 | #endif |
56 | } |
57 | |
58 | status = acpi_os_read_port((acpi_io_address)reg->address, |
59 | &value32, ACPI_GPE_REGISTER_WIDTH); |
60 | if (ACPI_FAILURE(status)) |
61 | return_ACPI_STATUS(status); |
62 | |
63 | *value = (u64)value32; |
64 | |
65 | return_ACPI_STATUS(AE_OK); |
66 | } |
67 | |
68 | /****************************************************************************** |
69 | * |
70 | * FUNCTION: acpi_hw_gpe_write |
71 | * |
72 | * PARAMETERS: value - Value to be written |
73 | * reg - GPE register structure |
74 | * |
75 | * RETURN: Status |
76 | * |
77 | * DESCRIPTION: Write to a GPE register in either memory or IO space. |
78 | * |
79 | ******************************************************************************/ |
80 | |
81 | acpi_status acpi_hw_gpe_write(u64 value, struct acpi_gpe_address *reg) |
82 | { |
83 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
84 | #ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES |
85 | ACPI_SET8((unsigned long)reg->address, value); |
86 | return_ACPI_STATUS(AE_OK); |
87 | #else |
88 | return acpi_os_write_memory((acpi_physical_address)reg->address, |
89 | value, ACPI_GPE_REGISTER_WIDTH); |
90 | #endif |
91 | } |
92 | |
93 | return acpi_os_write_port((acpi_io_address)reg->address, (u32)value, |
94 | ACPI_GPE_REGISTER_WIDTH); |
95 | } |
96 | |
97 | /****************************************************************************** |
98 | * |
99 | * FUNCTION: acpi_hw_get_gpe_register_bit |
100 | * |
101 | * PARAMETERS: gpe_event_info - Info block for the GPE |
102 | * |
103 | * RETURN: Register mask with a one in the GPE bit position |
104 | * |
105 | * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the |
106 | * correct position for the input GPE. |
107 | * |
108 | ******************************************************************************/ |
109 | |
110 | u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info) |
111 | { |
112 | |
113 | return ((u32)1 << |
114 | (gpe_event_info->gpe_number - |
115 | gpe_event_info->register_info->base_gpe_number)); |
116 | } |
117 | |
118 | /****************************************************************************** |
119 | * |
120 | * FUNCTION: acpi_hw_low_set_gpe |
121 | * |
122 | * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled |
123 | * action - Enable or disable |
124 | * |
125 | * RETURN: Status |
126 | * |
127 | * DESCRIPTION: Enable or disable a single GPE in the parent enable register. |
128 | * The enable_mask field of the involved GPE register must be |
129 | * updated by the caller if necessary. |
130 | * |
131 | ******************************************************************************/ |
132 | |
133 | acpi_status |
134 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) |
135 | { |
136 | struct acpi_gpe_register_info *gpe_register_info; |
137 | acpi_status status = AE_OK; |
138 | u64 enable_mask; |
139 | u32 register_bit; |
140 | |
141 | ACPI_FUNCTION_ENTRY(); |
142 | |
143 | /* Get the info block for the entire GPE register */ |
144 | |
145 | gpe_register_info = gpe_event_info->register_info; |
146 | if (!gpe_register_info) { |
147 | return (AE_NOT_EXIST); |
148 | } |
149 | |
150 | /* Get current value of the enable register that contains this GPE */ |
151 | |
152 | status = acpi_hw_gpe_read(&enable_mask, |
153 | &gpe_register_info->enable_address); |
154 | if (ACPI_FAILURE(status)) { |
155 | return (status); |
156 | } |
157 | |
158 | /* Set or clear just the bit that corresponds to this GPE */ |
159 | |
160 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); |
161 | switch (action) { |
162 | case ACPI_GPE_CONDITIONAL_ENABLE: |
163 | |
164 | /* Only enable if the corresponding enable_mask bit is set */ |
165 | |
166 | if (!(register_bit & gpe_register_info->enable_mask)) { |
167 | return (AE_BAD_PARAMETER); |
168 | } |
169 | |
170 | ACPI_FALLTHROUGH; |
171 | |
172 | case ACPI_GPE_ENABLE: |
173 | |
174 | ACPI_SET_BIT(enable_mask, register_bit); |
175 | break; |
176 | |
177 | case ACPI_GPE_DISABLE: |
178 | |
179 | ACPI_CLEAR_BIT(enable_mask, register_bit); |
180 | break; |
181 | |
182 | default: |
183 | |
184 | ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u" , action)); |
185 | return (AE_BAD_PARAMETER); |
186 | } |
187 | |
188 | if (!(register_bit & gpe_register_info->mask_for_run)) { |
189 | |
190 | /* Write the updated enable mask */ |
191 | |
192 | status = acpi_hw_gpe_write(enable_mask, |
193 | &gpe_register_info->enable_address); |
194 | } |
195 | return (status); |
196 | } |
197 | |
198 | /****************************************************************************** |
199 | * |
200 | * FUNCTION: acpi_hw_clear_gpe |
201 | * |
202 | * PARAMETERS: gpe_event_info - Info block for the GPE to be cleared |
203 | * |
204 | * RETURN: Status |
205 | * |
206 | * DESCRIPTION: Clear the status bit for a single GPE. |
207 | * |
208 | ******************************************************************************/ |
209 | |
210 | acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info *gpe_event_info) |
211 | { |
212 | struct acpi_gpe_register_info *gpe_register_info; |
213 | acpi_status status; |
214 | u32 register_bit; |
215 | |
216 | ACPI_FUNCTION_ENTRY(); |
217 | |
218 | /* Get the info block for the entire GPE register */ |
219 | |
220 | gpe_register_info = gpe_event_info->register_info; |
221 | if (!gpe_register_info) { |
222 | return (AE_NOT_EXIST); |
223 | } |
224 | |
225 | /* |
226 | * Write a one to the appropriate bit in the status register to |
227 | * clear this GPE. |
228 | */ |
229 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); |
230 | |
231 | status = acpi_hw_gpe_write(register_bit, |
232 | &gpe_register_info->status_address); |
233 | return (status); |
234 | } |
235 | |
236 | /****************************************************************************** |
237 | * |
238 | * FUNCTION: acpi_hw_get_gpe_status |
239 | * |
240 | * PARAMETERS: gpe_event_info - Info block for the GPE to queried |
241 | * event_status - Where the GPE status is returned |
242 | * |
243 | * RETURN: Status |
244 | * |
245 | * DESCRIPTION: Return the status of a single GPE. |
246 | * |
247 | ******************************************************************************/ |
248 | |
249 | acpi_status |
250 | acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, |
251 | acpi_event_status *event_status) |
252 | { |
253 | u64 in_byte; |
254 | u32 register_bit; |
255 | struct acpi_gpe_register_info *gpe_register_info; |
256 | acpi_event_status local_event_status = 0; |
257 | acpi_status status; |
258 | |
259 | ACPI_FUNCTION_ENTRY(); |
260 | |
261 | if (!event_status) { |
262 | return (AE_BAD_PARAMETER); |
263 | } |
264 | |
265 | /* GPE currently handled? */ |
266 | |
267 | if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != |
268 | ACPI_GPE_DISPATCH_NONE) { |
269 | local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER; |
270 | } |
271 | |
272 | /* Get the info block for the entire GPE register */ |
273 | |
274 | gpe_register_info = gpe_event_info->register_info; |
275 | |
276 | /* Get the register bitmask for this GPE */ |
277 | |
278 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); |
279 | |
280 | /* GPE currently enabled? (enabled for runtime?) */ |
281 | |
282 | if (register_bit & gpe_register_info->enable_for_run) { |
283 | local_event_status |= ACPI_EVENT_FLAG_ENABLED; |
284 | } |
285 | |
286 | /* GPE currently masked? (masked for runtime?) */ |
287 | |
288 | if (register_bit & gpe_register_info->mask_for_run) { |
289 | local_event_status |= ACPI_EVENT_FLAG_MASKED; |
290 | } |
291 | |
292 | /* GPE enabled for wake? */ |
293 | |
294 | if (register_bit & gpe_register_info->enable_for_wake) { |
295 | local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED; |
296 | } |
297 | |
298 | /* GPE currently enabled (enable bit == 1)? */ |
299 | |
300 | status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->enable_address); |
301 | if (ACPI_FAILURE(status)) { |
302 | return (status); |
303 | } |
304 | |
305 | if (register_bit & in_byte) { |
306 | local_event_status |= ACPI_EVENT_FLAG_ENABLE_SET; |
307 | } |
308 | |
309 | /* GPE currently active (status bit == 1)? */ |
310 | |
311 | status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->status_address); |
312 | if (ACPI_FAILURE(status)) { |
313 | return (status); |
314 | } |
315 | |
316 | if (register_bit & in_byte) { |
317 | local_event_status |= ACPI_EVENT_FLAG_STATUS_SET; |
318 | } |
319 | |
320 | /* Set return value */ |
321 | |
322 | (*event_status) = local_event_status; |
323 | return (AE_OK); |
324 | } |
325 | |
326 | /****************************************************************************** |
327 | * |
328 | * FUNCTION: acpi_hw_gpe_enable_write |
329 | * |
330 | * PARAMETERS: enable_mask - Bit mask to write to the GPE register |
331 | * gpe_register_info - Gpe Register info |
332 | * |
333 | * RETURN: Status |
334 | * |
335 | * DESCRIPTION: Write the enable mask byte to the given GPE register. |
336 | * |
337 | ******************************************************************************/ |
338 | |
339 | static acpi_status |
340 | acpi_hw_gpe_enable_write(u8 enable_mask, |
341 | struct acpi_gpe_register_info *gpe_register_info) |
342 | { |
343 | acpi_status status; |
344 | |
345 | gpe_register_info->enable_mask = enable_mask; |
346 | |
347 | status = acpi_hw_gpe_write(enable_mask, |
348 | &gpe_register_info->enable_address); |
349 | return (status); |
350 | } |
351 | |
352 | /****************************************************************************** |
353 | * |
354 | * FUNCTION: acpi_hw_disable_gpe_block |
355 | * |
356 | * PARAMETERS: gpe_xrupt_info - GPE Interrupt info |
357 | * gpe_block - Gpe Block info |
358 | * |
359 | * RETURN: Status |
360 | * |
361 | * DESCRIPTION: Disable all GPEs within a single GPE block |
362 | * |
363 | ******************************************************************************/ |
364 | |
365 | acpi_status |
366 | acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
367 | struct acpi_gpe_block_info *gpe_block, void *context) |
368 | { |
369 | u32 i; |
370 | acpi_status status; |
371 | |
372 | /* Examine each GPE Register within the block */ |
373 | |
374 | for (i = 0; i < gpe_block->register_count; i++) { |
375 | |
376 | /* Disable all GPEs in this register */ |
377 | |
378 | status = |
379 | acpi_hw_gpe_enable_write(0x00, |
380 | &gpe_block->register_info[i]); |
381 | if (ACPI_FAILURE(status)) { |
382 | return (status); |
383 | } |
384 | } |
385 | |
386 | return (AE_OK); |
387 | } |
388 | |
389 | /****************************************************************************** |
390 | * |
391 | * FUNCTION: acpi_hw_clear_gpe_block |
392 | * |
393 | * PARAMETERS: gpe_xrupt_info - GPE Interrupt info |
394 | * gpe_block - Gpe Block info |
395 | * |
396 | * RETURN: Status |
397 | * |
398 | * DESCRIPTION: Clear status bits for all GPEs within a single GPE block |
399 | * |
400 | ******************************************************************************/ |
401 | |
402 | acpi_status |
403 | acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
404 | struct acpi_gpe_block_info *gpe_block, void *context) |
405 | { |
406 | u32 i; |
407 | acpi_status status; |
408 | |
409 | /* Examine each GPE Register within the block */ |
410 | |
411 | for (i = 0; i < gpe_block->register_count; i++) { |
412 | |
413 | /* Clear status on all GPEs in this register */ |
414 | |
415 | status = acpi_hw_gpe_write(0xFF, |
416 | &gpe_block->register_info[i].status_address); |
417 | if (ACPI_FAILURE(status)) { |
418 | return (status); |
419 | } |
420 | } |
421 | |
422 | return (AE_OK); |
423 | } |
424 | |
425 | /****************************************************************************** |
426 | * |
427 | * FUNCTION: acpi_hw_enable_runtime_gpe_block |
428 | * |
429 | * PARAMETERS: gpe_xrupt_info - GPE Interrupt info |
430 | * gpe_block - Gpe Block info |
431 | * |
432 | * RETURN: Status |
433 | * |
434 | * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes |
435 | * combination wake/run GPEs. |
436 | * |
437 | ******************************************************************************/ |
438 | |
439 | acpi_status |
440 | acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
441 | struct acpi_gpe_block_info *gpe_block, |
442 | void *context) |
443 | { |
444 | u32 i; |
445 | acpi_status status; |
446 | struct acpi_gpe_register_info *gpe_register_info; |
447 | u8 enable_mask; |
448 | |
449 | /* NOTE: assumes that all GPEs are currently disabled */ |
450 | |
451 | /* Examine each GPE Register within the block */ |
452 | |
453 | for (i = 0; i < gpe_block->register_count; i++) { |
454 | gpe_register_info = &gpe_block->register_info[i]; |
455 | if (!gpe_register_info->enable_for_run) { |
456 | continue; |
457 | } |
458 | |
459 | /* Enable all "runtime" GPEs in this register */ |
460 | |
461 | enable_mask = gpe_register_info->enable_for_run & |
462 | ~gpe_register_info->mask_for_run; |
463 | status = |
464 | acpi_hw_gpe_enable_write(enable_mask, gpe_register_info); |
465 | if (ACPI_FAILURE(status)) { |
466 | return (status); |
467 | } |
468 | } |
469 | |
470 | return (AE_OK); |
471 | } |
472 | |
473 | /****************************************************************************** |
474 | * |
475 | * FUNCTION: acpi_hw_enable_wakeup_gpe_block |
476 | * |
477 | * PARAMETERS: gpe_xrupt_info - GPE Interrupt info |
478 | * gpe_block - Gpe Block info |
479 | * |
480 | * RETURN: Status |
481 | * |
482 | * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes |
483 | * combination wake/run GPEs. |
484 | * |
485 | ******************************************************************************/ |
486 | |
487 | static acpi_status |
488 | acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
489 | struct acpi_gpe_block_info *gpe_block, |
490 | void *context) |
491 | { |
492 | u32 i; |
493 | acpi_status status; |
494 | struct acpi_gpe_register_info *gpe_register_info; |
495 | |
496 | /* Examine each GPE Register within the block */ |
497 | |
498 | for (i = 0; i < gpe_block->register_count; i++) { |
499 | gpe_register_info = &gpe_block->register_info[i]; |
500 | |
501 | /* |
502 | * Enable all "wake" GPEs in this register and disable the |
503 | * remaining ones. |
504 | */ |
505 | |
506 | status = |
507 | acpi_hw_gpe_enable_write(gpe_register_info->enable_for_wake, |
508 | gpe_register_info); |
509 | if (ACPI_FAILURE(status)) { |
510 | return (status); |
511 | } |
512 | } |
513 | |
514 | return (AE_OK); |
515 | } |
516 | |
517 | struct acpi_gpe_block_status_context { |
518 | struct acpi_gpe_register_info *gpe_skip_register_info; |
519 | u8 gpe_skip_mask; |
520 | u8 retval; |
521 | }; |
522 | |
523 | /****************************************************************************** |
524 | * |
525 | * FUNCTION: acpi_hw_get_gpe_block_status |
526 | * |
527 | * PARAMETERS: gpe_xrupt_info - GPE Interrupt info |
528 | * gpe_block - Gpe Block info |
529 | * context - GPE list walk context data |
530 | * |
531 | * RETURN: Success |
532 | * |
533 | * DESCRIPTION: Produce a combined GPE status bits mask for the given block. |
534 | * |
535 | ******************************************************************************/ |
536 | |
537 | static acpi_status |
538 | acpi_hw_get_gpe_block_status(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
539 | struct acpi_gpe_block_info *gpe_block, |
540 | void *context) |
541 | { |
542 | struct acpi_gpe_block_status_context *c = context; |
543 | struct acpi_gpe_register_info *gpe_register_info; |
544 | u64 in_enable, in_status; |
545 | acpi_status status; |
546 | u8 ret_mask; |
547 | u32 i; |
548 | |
549 | /* Examine each GPE Register within the block */ |
550 | |
551 | for (i = 0; i < gpe_block->register_count; i++) { |
552 | gpe_register_info = &gpe_block->register_info[i]; |
553 | |
554 | status = acpi_hw_gpe_read(&in_enable, |
555 | &gpe_register_info->enable_address); |
556 | if (ACPI_FAILURE(status)) { |
557 | continue; |
558 | } |
559 | |
560 | status = acpi_hw_gpe_read(&in_status, |
561 | &gpe_register_info->status_address); |
562 | if (ACPI_FAILURE(status)) { |
563 | continue; |
564 | } |
565 | |
566 | ret_mask = in_enable & in_status; |
567 | if (ret_mask && c->gpe_skip_register_info == gpe_register_info) { |
568 | ret_mask &= ~c->gpe_skip_mask; |
569 | } |
570 | c->retval |= ret_mask; |
571 | } |
572 | |
573 | return (AE_OK); |
574 | } |
575 | |
576 | /****************************************************************************** |
577 | * |
578 | * FUNCTION: acpi_hw_disable_all_gpes |
579 | * |
580 | * PARAMETERS: None |
581 | * |
582 | * RETURN: Status |
583 | * |
584 | * DESCRIPTION: Disable and clear all GPEs in all GPE blocks |
585 | * |
586 | ******************************************************************************/ |
587 | |
588 | acpi_status acpi_hw_disable_all_gpes(void) |
589 | { |
590 | acpi_status status; |
591 | |
592 | ACPI_FUNCTION_TRACE(hw_disable_all_gpes); |
593 | |
594 | status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL); |
595 | return_ACPI_STATUS(status); |
596 | } |
597 | |
598 | /****************************************************************************** |
599 | * |
600 | * FUNCTION: acpi_hw_enable_all_runtime_gpes |
601 | * |
602 | * PARAMETERS: None |
603 | * |
604 | * RETURN: Status |
605 | * |
606 | * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks |
607 | * |
608 | ******************************************************************************/ |
609 | |
610 | acpi_status acpi_hw_enable_all_runtime_gpes(void) |
611 | { |
612 | acpi_status status; |
613 | |
614 | ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes); |
615 | |
616 | status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block, NULL); |
617 | return_ACPI_STATUS(status); |
618 | } |
619 | |
620 | /****************************************************************************** |
621 | * |
622 | * FUNCTION: acpi_hw_enable_all_wakeup_gpes |
623 | * |
624 | * PARAMETERS: None |
625 | * |
626 | * RETURN: Status |
627 | * |
628 | * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks |
629 | * |
630 | ******************************************************************************/ |
631 | |
632 | acpi_status acpi_hw_enable_all_wakeup_gpes(void) |
633 | { |
634 | acpi_status status; |
635 | |
636 | ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes); |
637 | |
638 | status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL); |
639 | return_ACPI_STATUS(status); |
640 | } |
641 | |
642 | /****************************************************************************** |
643 | * |
644 | * FUNCTION: acpi_hw_check_all_gpes |
645 | * |
646 | * PARAMETERS: gpe_skip_device - GPE devoce of the GPE to skip |
647 | * gpe_skip_number - Number of the GPE to skip |
648 | * |
649 | * RETURN: Combined status of all GPEs |
650 | * |
651 | * DESCRIPTION: Check all enabled GPEs in all GPE blocks, except for the one |
652 | * represented by the "skip" arguments, and return TRUE if the |
653 | * status bit is set for at least one of them of FALSE otherwise. |
654 | * |
655 | ******************************************************************************/ |
656 | |
657 | u8 acpi_hw_check_all_gpes(acpi_handle gpe_skip_device, u32 gpe_skip_number) |
658 | { |
659 | struct acpi_gpe_block_status_context context = { |
660 | .gpe_skip_register_info = NULL, |
661 | .retval = 0, |
662 | }; |
663 | struct acpi_gpe_event_info *gpe_event_info; |
664 | acpi_cpu_flags flags; |
665 | |
666 | ACPI_FUNCTION_TRACE(acpi_hw_check_all_gpes); |
667 | |
668 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
669 | |
670 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_skip_device, |
671 | gpe_skip_number); |
672 | if (gpe_event_info) { |
673 | context.gpe_skip_register_info = gpe_event_info->register_info; |
674 | context.gpe_skip_mask = acpi_hw_get_gpe_register_bit(gpe_event_info); |
675 | } |
676 | |
677 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
678 | |
679 | (void)acpi_ev_walk_gpe_list(acpi_hw_get_gpe_block_status, &context); |
680 | return (context.retval != 0); |
681 | } |
682 | |
683 | #endif /* !ACPI_REDUCED_HARDWARE */ |
684 | |