.. | .. |
---|
3 | 3 | * |
---|
4 | 4 | * Module Name: hwgpe - Low level GPE enable/disable/clear functions |
---|
5 | 5 | * |
---|
6 | | - * Copyright (C) 2000 - 2018, Intel Corp. |
---|
| 6 | + * Copyright (C) 2000 - 2020, Intel Corp. |
---|
7 | 7 | * |
---|
8 | 8 | *****************************************************************************/ |
---|
9 | 9 | |
---|
.. | .. |
---|
23 | 23 | static acpi_status |
---|
24 | 24 | acpi_hw_gpe_enable_write(u8 enable_mask, |
---|
25 | 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 | +} |
---|
26 | 96 | |
---|
27 | 97 | /****************************************************************************** |
---|
28 | 98 | * |
---|
.. | .. |
---|
79 | 149 | |
---|
80 | 150 | /* Get current value of the enable register that contains this GPE */ |
---|
81 | 151 | |
---|
82 | | - status = acpi_hw_read(&enable_mask, &gpe_register_info->enable_address); |
---|
| 152 | + status = acpi_hw_gpe_read(&enable_mask, |
---|
| 153 | + &gpe_register_info->enable_address); |
---|
83 | 154 | if (ACPI_FAILURE(status)) { |
---|
84 | 155 | return (status); |
---|
85 | 156 | } |
---|
.. | .. |
---|
118 | 189 | |
---|
119 | 190 | /* Write the updated enable mask */ |
---|
120 | 191 | |
---|
121 | | - status = |
---|
122 | | - acpi_hw_write(enable_mask, |
---|
123 | | - &gpe_register_info->enable_address); |
---|
| 192 | + status = acpi_hw_gpe_write(enable_mask, |
---|
| 193 | + &gpe_register_info->enable_address); |
---|
124 | 194 | } |
---|
125 | 195 | return (status); |
---|
126 | 196 | } |
---|
.. | .. |
---|
158 | 228 | */ |
---|
159 | 229 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); |
---|
160 | 230 | |
---|
161 | | - status = |
---|
162 | | - acpi_hw_write(register_bit, &gpe_register_info->status_address); |
---|
| 231 | + status = acpi_hw_gpe_write(register_bit, |
---|
| 232 | + &gpe_register_info->status_address); |
---|
163 | 233 | return (status); |
---|
164 | 234 | } |
---|
165 | 235 | |
---|
.. | .. |
---|
227 | 297 | |
---|
228 | 298 | /* GPE currently enabled (enable bit == 1)? */ |
---|
229 | 299 | |
---|
230 | | - status = acpi_hw_read(&in_byte, &gpe_register_info->enable_address); |
---|
| 300 | + status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->enable_address); |
---|
231 | 301 | if (ACPI_FAILURE(status)) { |
---|
232 | 302 | return (status); |
---|
233 | 303 | } |
---|
.. | .. |
---|
238 | 308 | |
---|
239 | 309 | /* GPE currently active (status bit == 1)? */ |
---|
240 | 310 | |
---|
241 | | - status = acpi_hw_read(&in_byte, &gpe_register_info->status_address); |
---|
| 311 | + status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->status_address); |
---|
242 | 312 | if (ACPI_FAILURE(status)) { |
---|
243 | 313 | return (status); |
---|
244 | 314 | } |
---|
.. | .. |
---|
274 | 344 | |
---|
275 | 345 | gpe_register_info->enable_mask = enable_mask; |
---|
276 | 346 | |
---|
277 | | - status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); |
---|
| 347 | + status = acpi_hw_gpe_write(enable_mask, |
---|
| 348 | + &gpe_register_info->enable_address); |
---|
278 | 349 | return (status); |
---|
279 | 350 | } |
---|
280 | 351 | |
---|
.. | .. |
---|
341 | 412 | |
---|
342 | 413 | /* Clear status on all GPEs in this register */ |
---|
343 | 414 | |
---|
344 | | - status = |
---|
345 | | - acpi_hw_write(0xFF, |
---|
346 | | - &gpe_block->register_info[i].status_address); |
---|
| 415 | + status = acpi_hw_gpe_write(0xFF, |
---|
| 416 | + &gpe_block->register_info[i].status_address); |
---|
347 | 417 | if (ACPI_FAILURE(status)) { |
---|
348 | 418 | return (status); |
---|
349 | 419 | } |
---|
.. | .. |
---|
444 | 514 | return (AE_OK); |
---|
445 | 515 | } |
---|
446 | 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 | + |
---|
447 | 576 | /****************************************************************************** |
---|
448 | 577 | * |
---|
449 | 578 | * FUNCTION: acpi_hw_disable_all_gpes |
---|
.. | .. |
---|
510 | 639 | return_ACPI_STATUS(status); |
---|
511 | 640 | } |
---|
512 | 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 | + |
---|
513 | 683 | #endif /* !ACPI_REDUCED_HARDWARE */ |
---|