1/****************************************************************************** 2 * 3 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2010, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 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 24 * from this software without specific prior written permission. 25 * 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 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 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 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44#include <acpi/acpi.h> 45#include "accommon.h" 46#include "acevents.h" 47#include "acnamesp.h" 48#include "actables.h" 49 50#define _COMPONENT ACPI_EVENTS 51ACPI_MODULE_NAME("evxfevnt") 52 53/* Local prototypes */ 54static acpi_status 55acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 56 struct acpi_gpe_block_info *gpe_block, void *context); 57 58/******************************************************************************* 59 * 60 * FUNCTION: acpi_enable 61 * 62 * PARAMETERS: None 63 * 64 * RETURN: Status 65 * 66 * DESCRIPTION: Transfers the system into ACPI mode. 67 * 68 ******************************************************************************/ 69 70acpi_status acpi_enable(void) 71{ 72 acpi_status status; 73 int retry; 74 75 ACPI_FUNCTION_TRACE(acpi_enable); 76 77 /* ACPI tables must be present */ 78 79 if (!acpi_tb_tables_loaded()) { 80 return_ACPI_STATUS(AE_NO_ACPI_TABLES); 81 } 82 83 /* Check current mode */ 84 85 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { 86 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 87 "System is already in ACPI mode\n")); 88 return_ACPI_STATUS(AE_OK); 89 } 90 91 /* Transition to ACPI mode */ 92 93 status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); 94 if (ACPI_FAILURE(status)) { 95 ACPI_ERROR((AE_INFO, 96 "Could not transition to ACPI mode")); 97 return_ACPI_STATUS(status); 98 } 99 100 /* Sanity check that transition succeeded */ 101 102 for (retry = 0; retry < 30000; ++retry) { 103 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { 104 if (retry != 0) 105 ACPI_WARNING((AE_INFO, 106 "Platform took > %d00 usec to enter ACPI mode", retry)); 107 return_ACPI_STATUS(AE_OK); 108 } 109 acpi_os_stall(100); /* 100 usec */ 110 } 111 112 ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode")); 113 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 114} 115 116ACPI_EXPORT_SYMBOL(acpi_enable) 117 118/******************************************************************************* 119 * 120 * FUNCTION: acpi_disable 121 * 122 * PARAMETERS: None 123 * 124 * RETURN: Status 125 * 126 * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode. 127 * 128 ******************************************************************************/ 129acpi_status acpi_disable(void) 130{ 131 acpi_status status = AE_OK; 132 133 ACPI_FUNCTION_TRACE(acpi_disable); 134 135 if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { 136 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 137 "System is already in legacy (non-ACPI) mode\n")); 138 } else { 139 /* Transition to LEGACY mode */ 140 141 status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY); 142 143 if (ACPI_FAILURE(status)) { 144 ACPI_ERROR((AE_INFO, 145 "Could not exit ACPI mode to legacy mode")); 146 return_ACPI_STATUS(status); 147 } 148 149 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n")); 150 } 151 152 return_ACPI_STATUS(status); 153} 154 155ACPI_EXPORT_SYMBOL(acpi_disable) 156 157/******************************************************************************* 158 * 159 * FUNCTION: acpi_enable_event 160 * 161 * PARAMETERS: Event - The fixed eventto be enabled 162 * Flags - Reserved 163 * 164 * RETURN: Status 165 * 166 * DESCRIPTION: Enable an ACPI event (fixed) 167 * 168 ******************************************************************************/ 169acpi_status acpi_enable_event(u32 event, u32 flags) 170{ 171 acpi_status status = AE_OK; 172 u32 value; 173 174 ACPI_FUNCTION_TRACE(acpi_enable_event); 175 176 /* Decode the Fixed Event */ 177 178 if (event > ACPI_EVENT_MAX) { 179 return_ACPI_STATUS(AE_BAD_PARAMETER); 180 } 181 182 /* 183 * Enable the requested fixed event (by writing a one to the enable 184 * register bit) 185 */ 186 status = 187 acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 188 enable_register_id, ACPI_ENABLE_EVENT); 189 if (ACPI_FAILURE(status)) { 190 return_ACPI_STATUS(status); 191 } 192 193 /* Make sure that the hardware responded */ 194 195 status = 196 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 197 enable_register_id, &value); 198 if (ACPI_FAILURE(status)) { 199 return_ACPI_STATUS(status); 200 } 201 202 if (value != 1) { 203 ACPI_ERROR((AE_INFO, 204 "Could not enable %s event", 205 acpi_ut_get_event_name(event))); 206 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 207 } 208 209 return_ACPI_STATUS(status); 210} 211 212ACPI_EXPORT_SYMBOL(acpi_enable_event) 213 214/******************************************************************************* 215 * 216 * FUNCTION: acpi_gpe_wakeup 217 * 218 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 219 * gpe_number - GPE level within the GPE block 220 * Action - Enable or Disable 221 * 222 * RETURN: Status 223 * 224 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. 225 * 226 ******************************************************************************/ 227acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action) 228{ 229 acpi_status status = AE_OK; 230 struct acpi_gpe_event_info *gpe_event_info; 231 struct acpi_gpe_register_info *gpe_register_info; 232 acpi_cpu_flags flags; 233 u32 register_bit; 234 235 ACPI_FUNCTION_TRACE(acpi_gpe_wakeup); 236 237 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 238 239 /* Ensure that we have a valid GPE number */ 240 241 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 242 if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { 243 status = AE_BAD_PARAMETER; 244 goto unlock_and_exit; 245 } 246 247 gpe_register_info = gpe_event_info->register_info; 248 if (!gpe_register_info) { 249 status = AE_NOT_EXIST; 250 goto unlock_and_exit; 251 } 252 253 register_bit = 254 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); 255 256 /* Perform the action */ 257 258 switch (action) { 259 case ACPI_GPE_ENABLE: 260 ACPI_SET_BIT(gpe_register_info->enable_for_wake, 261 (u8)register_bit); 262 break; 263 264 case ACPI_GPE_DISABLE: 265 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, 266 (u8)register_bit); 267 break; 268 269 default: 270 ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); 271 status = AE_BAD_PARAMETER; 272 break; 273 } 274 275unlock_and_exit: 276 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 277 return_ACPI_STATUS(status); 278} 279 280ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup) 281 282/******************************************************************************* 283 * 284 * FUNCTION: acpi_enable_gpe 285 * 286 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 287 * gpe_number - GPE level within the GPE block 288 * 289 * RETURN: Status 290 * 291 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 292 * hardware-enabled. 293 * 294 ******************************************************************************/ 295acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) 296{ 297 acpi_status status = AE_BAD_PARAMETER; 298 struct acpi_gpe_event_info *gpe_event_info; 299 acpi_cpu_flags flags; 300 301 ACPI_FUNCTION_TRACE(acpi_enable_gpe); 302 303 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 304 305 /* Ensure that we have a valid GPE number */ 306 307 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 308 if (gpe_event_info) { 309 status = acpi_raw_enable_gpe(gpe_event_info); 310 } 311 312 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 313 return_ACPI_STATUS(status); 314} 315ACPI_EXPORT_SYMBOL(acpi_enable_gpe) 316 317/******************************************************************************* 318 * 319 * FUNCTION: acpi_disable_gpe 320 * 321 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 322 * gpe_number - GPE level within the GPE block 323 * 324 * RETURN: Status 325 * 326 * DESCRIPTION: Remove a reference to a GPE. When the last reference is 327 * removed, only then is the GPE disabled (for runtime GPEs), or 328 * the GPE mask bit disabled (for wake GPEs) 329 * 330 ******************************************************************************/ 331acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) 332{ 333 acpi_status status = AE_BAD_PARAMETER; 334 struct acpi_gpe_event_info *gpe_event_info; 335 acpi_cpu_flags flags; 336 337 ACPI_FUNCTION_TRACE(acpi_disable_gpe); 338 339 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 340 341 /* Ensure that we have a valid GPE number */ 342 343 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 344 if (gpe_event_info) { 345 status = acpi_raw_disable_gpe(gpe_event_info) ; 346 } 347 348 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 349 return_ACPI_STATUS(status); 350} 351ACPI_EXPORT_SYMBOL(acpi_disable_gpe) 352 353/******************************************************************************* 354 * 355 * FUNCTION: acpi_gpe_can_wake 356 * 357 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 358 * gpe_number - GPE level within the GPE block 359 * 360 * RETURN: Status 361 * 362 * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE 363 * has a corresponding method and is currently enabled, disable it 364 * (GPEs with corresponding methods are enabled unconditionally 365 * during initialization, but GPEs that can wake up are expected 366 * to be initially disabled). 367 * 368 ******************************************************************************/ 369acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) 370{ 371 acpi_status status = AE_OK; 372 struct acpi_gpe_event_info *gpe_event_info; 373 acpi_cpu_flags flags; 374 375 ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); 376 377 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 378 379 /* Ensure that we have a valid GPE number */ 380 381 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 382 if (!gpe_event_info) { 383 status = AE_BAD_PARAMETER; 384 goto unlock_and_exit; 385 } 386 387 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { 388 goto unlock_and_exit; 389 } 390 391 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; 392 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) { 393 (void)acpi_raw_disable_gpe(gpe_event_info); 394 } 395 396unlock_and_exit: 397 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 398 return_ACPI_STATUS(status); 399} 400ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) 401 402/******************************************************************************* 403 * 404 * FUNCTION: acpi_disable_event 405 * 406 * PARAMETERS: Event - The fixed eventto be enabled 407 * Flags - Reserved 408 * 409 * RETURN: Status 410 * 411 * DESCRIPTION: Disable an ACPI event (fixed) 412 * 413 ******************************************************************************/ 414acpi_status acpi_disable_event(u32 event, u32 flags) 415{ 416 acpi_status status = AE_OK; 417 u32 value; 418 419 ACPI_FUNCTION_TRACE(acpi_disable_event); 420 421 /* Decode the Fixed Event */ 422 423 if (event > ACPI_EVENT_MAX) { 424 return_ACPI_STATUS(AE_BAD_PARAMETER); 425 } 426 427 /* 428 * Disable the requested fixed event (by writing a zero to the enable 429 * register bit) 430 */ 431 status = 432 acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 433 enable_register_id, ACPI_DISABLE_EVENT); 434 if (ACPI_FAILURE(status)) { 435 return_ACPI_STATUS(status); 436 } 437 438 status = 439 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 440 enable_register_id, &value); 441 if (ACPI_FAILURE(status)) { 442 return_ACPI_STATUS(status); 443 } 444 445 if (value != 0) { 446 ACPI_ERROR((AE_INFO, 447 "Could not disable %s events", 448 acpi_ut_get_event_name(event))); 449 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 450 } 451 452 return_ACPI_STATUS(status); 453} 454 455ACPI_EXPORT_SYMBOL(acpi_disable_event) 456 457/******************************************************************************* 458 * 459 * FUNCTION: acpi_clear_event 460 * 461 * PARAMETERS: Event - The fixed event to be cleared 462 * 463 * RETURN: Status 464 * 465 * DESCRIPTION: Clear an ACPI event (fixed) 466 * 467 ******************************************************************************/ 468acpi_status acpi_clear_event(u32 event) 469{ 470 acpi_status status = AE_OK; 471 472 ACPI_FUNCTION_TRACE(acpi_clear_event); 473 474 /* Decode the Fixed Event */ 475 476 if (event > ACPI_EVENT_MAX) { 477 return_ACPI_STATUS(AE_BAD_PARAMETER); 478 } 479 480 /* 481 * Clear the requested fixed event (By writing a one to the status 482 * register bit) 483 */ 484 status = 485 acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 486 status_register_id, ACPI_CLEAR_STATUS); 487 488 return_ACPI_STATUS(status); 489} 490 491ACPI_EXPORT_SYMBOL(acpi_clear_event) 492 493/******************************************************************************* 494 * 495 * FUNCTION: acpi_clear_gpe 496 * 497 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 498 * gpe_number - GPE level within the GPE block 499 * 500 * RETURN: Status 501 * 502 * DESCRIPTION: Clear an ACPI event (general purpose) 503 * 504 ******************************************************************************/ 505acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number) 506{ 507 acpi_status status = AE_OK; 508 struct acpi_gpe_event_info *gpe_event_info; 509 acpi_cpu_flags flags; 510 511 ACPI_FUNCTION_TRACE(acpi_clear_gpe); 512 513 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 514 515 /* Ensure that we have a valid GPE number */ 516 517 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 518 if (!gpe_event_info) { 519 status = AE_BAD_PARAMETER; 520 goto unlock_and_exit; 521 } 522 523 status = acpi_hw_clear_gpe(gpe_event_info); 524 525 unlock_and_exit: 526 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 527 return_ACPI_STATUS(status); 528} 529 530ACPI_EXPORT_SYMBOL(acpi_clear_gpe) 531/******************************************************************************* 532 * 533 * FUNCTION: acpi_get_event_status 534 * 535 * PARAMETERS: Event - The fixed event 536 * event_status - Where the current status of the event will 537 * be returned 538 * 539 * RETURN: Status 540 * 541 * DESCRIPTION: Obtains and returns the current status of the event 542 * 543 ******************************************************************************/ 544acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) 545{ 546 acpi_status status = AE_OK; 547 u32 value; 548 549 ACPI_FUNCTION_TRACE(acpi_get_event_status); 550 551 if (!event_status) { 552 return_ACPI_STATUS(AE_BAD_PARAMETER); 553 } 554 555 /* Decode the Fixed Event */ 556 557 if (event > ACPI_EVENT_MAX) { 558 return_ACPI_STATUS(AE_BAD_PARAMETER); 559 } 560 561 /* Get the status of the requested fixed event */ 562 563 status = 564 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 565 enable_register_id, &value); 566 if (ACPI_FAILURE(status)) 567 return_ACPI_STATUS(status); 568 569 *event_status = value; 570 571 status = 572 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 573 status_register_id, &value); 574 if (ACPI_FAILURE(status)) 575 return_ACPI_STATUS(status); 576 577 if (value) 578 *event_status |= ACPI_EVENT_FLAG_SET; 579 580 if (acpi_gbl_fixed_event_handlers[event].handler) 581 *event_status |= ACPI_EVENT_FLAG_HANDLE; 582 583 return_ACPI_STATUS(status); 584} 585 586ACPI_EXPORT_SYMBOL(acpi_get_event_status) 587 588/******************************************************************************* 589 * 590 * FUNCTION: acpi_get_gpe_status 591 * 592 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 593 * gpe_number - GPE level within the GPE block 594 * event_status - Where the current status of the event will 595 * be returned 596 * 597 * RETURN: Status 598 * 599 * DESCRIPTION: Get status of an event (general purpose) 600 * 601 ******************************************************************************/ 602acpi_status 603acpi_get_gpe_status(acpi_handle gpe_device, 604 u32 gpe_number, acpi_event_status *event_status) 605{ 606 acpi_status status = AE_OK; 607 struct acpi_gpe_event_info *gpe_event_info; 608 acpi_cpu_flags flags; 609 610 ACPI_FUNCTION_TRACE(acpi_get_gpe_status); 611 612 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 613 614 /* Ensure that we have a valid GPE number */ 615 616 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 617 if (!gpe_event_info) { 618 status = AE_BAD_PARAMETER; 619 goto unlock_and_exit; 620 } 621 622 /* Obtain status on the requested GPE number */ 623 624 status = acpi_hw_get_gpe_status(gpe_event_info, event_status); 625 626 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) 627 *event_status |= ACPI_EVENT_FLAG_HANDLE; 628 629 unlock_and_exit: 630 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 631 return_ACPI_STATUS(status); 632} 633 634ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) 635/******************************************************************************* 636 * 637 * FUNCTION: acpi_install_gpe_block 638 * 639 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 640 * gpe_block_address - Address and space_iD 641 * register_count - Number of GPE register pairs in the block 642 * interrupt_number - H/W interrupt for the block 643 * 644 * RETURN: Status 645 * 646 * DESCRIPTION: Create and Install a block of GPE registers 647 * 648 ******************************************************************************/ 649acpi_status 650acpi_install_gpe_block(acpi_handle gpe_device, 651 struct acpi_generic_address *gpe_block_address, 652 u32 register_count, u32 interrupt_number) 653{ 654 acpi_status status; 655 union acpi_operand_object *obj_desc; 656 struct acpi_namespace_node *node; 657 struct acpi_gpe_block_info *gpe_block; 658 659 ACPI_FUNCTION_TRACE(acpi_install_gpe_block); 660 661 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { 662 return_ACPI_STATUS(AE_BAD_PARAMETER); 663 } 664 665 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 666 if (ACPI_FAILURE(status)) { 667 return (status); 668 } 669 670 node = acpi_ns_validate_handle(gpe_device); 671 if (!node) { 672 status = AE_BAD_PARAMETER; 673 goto unlock_and_exit; 674 } 675 676 /* 677 * For user-installed GPE Block Devices, the gpe_block_base_number 678 * is always zero 679 */ 680 status = 681 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0, 682 interrupt_number, &gpe_block); 683 if (ACPI_FAILURE(status)) { 684 goto unlock_and_exit; 685 } 686 687 /* Install block in the device_object attached to the node */ 688 689 obj_desc = acpi_ns_get_attached_object(node); 690 if (!obj_desc) { 691 692 /* 693 * No object, create a new one (Device nodes do not always have 694 * an attached object) 695 */ 696 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); 697 if (!obj_desc) { 698 status = AE_NO_MEMORY; 699 goto unlock_and_exit; 700 } 701 702 status = 703 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE); 704 705 /* Remove local reference to the object */ 706 707 acpi_ut_remove_reference(obj_desc); 708 709 if (ACPI_FAILURE(status)) { 710 goto unlock_and_exit; 711 } 712 } 713 714 /* Now install the GPE block in the device_object */ 715 716 obj_desc->device.gpe_block = gpe_block; 717 718 /* Enable the runtime GPEs in the new block */ 719 720 status = acpi_ev_initialize_gpe_block(node, gpe_block); 721 722 unlock_and_exit: 723 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 724 return_ACPI_STATUS(status); 725} 726 727ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) 728 729/******************************************************************************* 730 * 731 * FUNCTION: acpi_remove_gpe_block 732 * 733 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 734 * 735 * RETURN: Status 736 * 737 * DESCRIPTION: Remove a previously installed block of GPE registers 738 * 739 ******************************************************************************/ 740acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) 741{ 742 union acpi_operand_object *obj_desc; 743 acpi_status status; 744 struct acpi_namespace_node *node; 745 746 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); 747 748 if (!gpe_device) { 749 return_ACPI_STATUS(AE_BAD_PARAMETER); 750 } 751 752 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 753 if (ACPI_FAILURE(status)) { 754 return (status); 755 } 756 757 node = acpi_ns_validate_handle(gpe_device); 758 if (!node) { 759 status = AE_BAD_PARAMETER; 760 goto unlock_and_exit; 761 } 762 763 /* Get the device_object attached to the node */ 764 765 obj_desc = acpi_ns_get_attached_object(node); 766 if (!obj_desc || !obj_desc->device.gpe_block) { 767 return_ACPI_STATUS(AE_NULL_OBJECT); 768 } 769 770 /* Delete the GPE block (but not the device_object) */ 771 772 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block); 773 if (ACPI_SUCCESS(status)) { 774 obj_desc->device.gpe_block = NULL; 775 } 776 777 unlock_and_exit: 778 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 779 return_ACPI_STATUS(status); 780} 781 782ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) 783 784/******************************************************************************* 785 * 786 * FUNCTION: acpi_get_gpe_device 787 * 788 * PARAMETERS: Index - System GPE index (0-current_gpe_count) 789 * gpe_device - Where the parent GPE Device is returned 790 * 791 * RETURN: Status 792 * 793 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 794 * gpe device indicates that the gpe number is contained in one of 795 * the FADT-defined gpe blocks. Otherwise, the GPE block device. 796 * 797 ******************************************************************************/ 798acpi_status 799acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) 800{ 801 struct acpi_gpe_device_info info; 802 acpi_status status; 803 804 ACPI_FUNCTION_TRACE(acpi_get_gpe_device); 805 806 if (!gpe_device) { 807 return_ACPI_STATUS(AE_BAD_PARAMETER); 808 } 809 810 if (index >= acpi_current_gpe_count) { 811 return_ACPI_STATUS(AE_NOT_EXIST); 812 } 813 814 /* Setup and walk the GPE list */ 815 816 info.index = index; 817 info.status = AE_NOT_EXIST; 818 info.gpe_device = NULL; 819 info.next_block_base_index = 0; 820 821 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); 822 if (ACPI_FAILURE(status)) { 823 return_ACPI_STATUS(status); 824 } 825 826 *gpe_device = info.gpe_device; 827 return_ACPI_STATUS(info.status); 828} 829 830ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) 831 832/******************************************************************************* 833 * 834 * FUNCTION: acpi_ev_get_gpe_device 835 * 836 * PARAMETERS: GPE_WALK_CALLBACK 837 * 838 * RETURN: Status 839 * 840 * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE 841 * block device. NULL if the GPE is one of the FADT-defined GPEs. 842 * 843 ******************************************************************************/ 844static acpi_status 845acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 846 struct acpi_gpe_block_info *gpe_block, void *context) 847{ 848 struct acpi_gpe_device_info *info = context; 849 850 /* Increment Index by the number of GPEs in this block */ 851 852 info->next_block_base_index += gpe_block->gpe_count; 853 854 if (info->index < info->next_block_base_index) { 855 /* 856 * The GPE index is within this block, get the node. Leave the node 857 * NULL for the FADT-defined GPEs 858 */ 859 if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) { 860 info->gpe_device = gpe_block->node; 861 } 862 863 info->status = AE_OK; 864 return (AE_CTRL_END); 865 } 866 867 return (AE_OK); 868} 869 870/****************************************************************************** 871 * 872 * FUNCTION: acpi_disable_all_gpes 873 * 874 * PARAMETERS: None 875 * 876 * RETURN: Status 877 * 878 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 879 * 880 ******************************************************************************/ 881 882acpi_status acpi_disable_all_gpes(void) 883{ 884 acpi_status status; 885 886 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes); 887 888 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 889 if (ACPI_FAILURE(status)) { 890 return_ACPI_STATUS(status); 891 } 892 893 status = acpi_hw_disable_all_gpes(); 894 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 895 896 return_ACPI_STATUS(status); 897} 898 899/****************************************************************************** 900 * 901 * FUNCTION: acpi_enable_all_runtime_gpes 902 * 903 * PARAMETERS: None 904 * 905 * RETURN: Status 906 * 907 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 908 * 909 ******************************************************************************/ 910 911acpi_status acpi_enable_all_runtime_gpes(void) 912{ 913 acpi_status status; 914 915 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); 916 917 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 918 if (ACPI_FAILURE(status)) { 919 return_ACPI_STATUS(status); 920 } 921 922 status = acpi_hw_enable_all_runtime_gpes(); 923 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 924 925 return_ACPI_STATUS(status); 926} 927