1 /****************************************************************************** 2 * 3 * Module Name: evregion - Operation Region support 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, 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 "acinterp.h" 49 50 #define _COMPONENT ACPI_EVENTS 51 ACPI_MODULE_NAME("evregion") 52 53 extern u8 acpi_gbl_default_address_spaces[]; 54 55 /* Local prototypes */ 56 57 static void 58 acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node); 59 60 static acpi_status 61 acpi_ev_reg_run(acpi_handle obj_handle, 62 u32 level, void *context, void **return_value); 63 64 /******************************************************************************* 65 * 66 * FUNCTION: acpi_ev_initialize_op_regions 67 * 68 * PARAMETERS: None 69 * 70 * RETURN: Status 71 * 72 * DESCRIPTION: Execute _REG methods for all Operation Regions that have 73 * an installed default region handler. 74 * 75 ******************************************************************************/ 76 77 acpi_status acpi_ev_initialize_op_regions(void) 78 { 79 acpi_status status; 80 u32 i; 81 82 ACPI_FUNCTION_TRACE(ev_initialize_op_regions); 83 84 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 85 if (ACPI_FAILURE(status)) { 86 return_ACPI_STATUS(status); 87 } 88 89 /* Run the _REG methods for op_regions in each default address space */ 90 91 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { 92 /* 93 * Make sure the installed handler is the DEFAULT handler. If not the 94 * default, the _REG methods will have already been run (when the 95 * handler was installed) 96 */ 97 if (acpi_ev_has_default_handler(acpi_gbl_root_node, 98 acpi_gbl_default_address_spaces 99 [i])) { 100 status = 101 acpi_ev_execute_reg_methods(acpi_gbl_root_node, 102 acpi_gbl_default_address_spaces 103 [i]); 104 } 105 } 106 107 acpi_gbl_reg_methods_executed = TRUE; 108 109 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 110 return_ACPI_STATUS(status); 111 } 112 113 /******************************************************************************* 114 * 115 * FUNCTION: acpi_ev_address_space_dispatch 116 * 117 * PARAMETERS: region_obj - Internal region object 118 * field_obj - Corresponding field. Can be NULL. 119 * function - Read or Write operation 120 * region_offset - Where in the region to read or write 121 * bit_width - Field width in bits (8, 16, 32, or 64) 122 * value - Pointer to in or out value, must be 123 * a full 64-bit integer 124 * 125 * RETURN: Status 126 * 127 * DESCRIPTION: Dispatch an address space or operation region access to 128 * a previously installed handler. 129 * 130 ******************************************************************************/ 131 132 acpi_status 133 acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, 134 union acpi_operand_object *field_obj, 135 u32 function, 136 u32 region_offset, u32 bit_width, u64 *value) 137 { 138 acpi_status status; 139 acpi_adr_space_handler handler; 140 acpi_adr_space_setup region_setup; 141 union acpi_operand_object *handler_desc; 142 union acpi_operand_object *region_obj2; 143 void *region_context = NULL; 144 struct acpi_connection_info *context; 145 146 ACPI_FUNCTION_TRACE(ev_address_space_dispatch); 147 148 region_obj2 = acpi_ns_get_secondary_object(region_obj); 149 if (!region_obj2) { 150 return_ACPI_STATUS(AE_NOT_EXIST); 151 } 152 153 /* Ensure that there is a handler associated with this region */ 154 155 handler_desc = region_obj->region.handler; 156 if (!handler_desc) { 157 ACPI_ERROR((AE_INFO, 158 "No handler for Region [%4.4s] (%p) [%s]", 159 acpi_ut_get_node_name(region_obj->region.node), 160 region_obj, 161 acpi_ut_get_region_name(region_obj->region. 162 space_id))); 163 164 return_ACPI_STATUS(AE_NOT_EXIST); 165 } 166 167 context = handler_desc->address_space.context; 168 169 /* 170 * It may be the case that the region has never been initialized. 171 * Some types of regions require special init code 172 */ 173 if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { 174 175 /* This region has not been initialized yet, do it */ 176 177 region_setup = handler_desc->address_space.setup; 178 if (!region_setup) { 179 180 /* No initialization routine, exit with error */ 181 182 ACPI_ERROR((AE_INFO, 183 "No init routine for region(%p) [%s]", 184 region_obj, 185 acpi_ut_get_region_name(region_obj->region. 186 space_id))); 187 return_ACPI_STATUS(AE_NOT_EXIST); 188 } 189 190 /* 191 * We must exit the interpreter because the region setup will 192 * potentially execute control methods (for example, the _REG method 193 * for this region) 194 */ 195 acpi_ex_exit_interpreter(); 196 197 status = region_setup(region_obj, ACPI_REGION_ACTIVATE, 198 context, ®ion_context); 199 200 /* Re-enter the interpreter */ 201 202 acpi_ex_enter_interpreter(); 203 204 /* Check for failure of the Region Setup */ 205 206 if (ACPI_FAILURE(status)) { 207 ACPI_EXCEPTION((AE_INFO, status, 208 "During region initialization: [%s]", 209 acpi_ut_get_region_name(region_obj-> 210 region. 211 space_id))); 212 return_ACPI_STATUS(status); 213 } 214 215 /* Region initialization may have been completed by region_setup */ 216 217 if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { 218 region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; 219 220 /* 221 * Save the returned context for use in all accesses to 222 * the handler for this particular region 223 */ 224 if (!(region_obj2->extra.region_context)) { 225 region_obj2->extra.region_context = 226 region_context; 227 } 228 } 229 } 230 231 /* We have everything we need, we can invoke the address space handler */ 232 233 handler = handler_desc->address_space.handler; 234 235 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 236 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", 237 ®ion_obj->region.handler->address_space, handler, 238 ACPI_FORMAT_NATIVE_UINT(region_obj->region.address + 239 region_offset), 240 acpi_ut_get_region_name(region_obj->region. 241 space_id))); 242 243 /* 244 * Special handling for generic_serial_bus and general_purpose_io: 245 * There are three extra parameters that must be passed to the 246 * handler via the context: 247 * 1) Connection buffer, a resource template from Connection() op. 248 * 2) Length of the above buffer. 249 * 3) Actual access length from the access_as() op. 250 */ 251 if (((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) || 252 (region_obj->region.space_id == ACPI_ADR_SPACE_GPIO)) && 253 context && field_obj) { 254 255 /* Get the Connection (resource_template) buffer */ 256 257 context->connection = field_obj->field.resource_buffer; 258 context->length = field_obj->field.resource_length; 259 context->access_length = field_obj->field.access_length; 260 } 261 262 if (!(handler_desc->address_space.handler_flags & 263 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { 264 /* 265 * For handlers other than the default (supplied) handlers, we must 266 * exit the interpreter because the handler *might* block -- we don't 267 * know what it will do, so we can't hold the lock on the intepreter. 268 */ 269 acpi_ex_exit_interpreter(); 270 } 271 272 /* Call the handler */ 273 274 status = handler(function, 275 (region_obj->region.address + region_offset), 276 bit_width, value, context, 277 region_obj2->extra.region_context); 278 279 if (ACPI_FAILURE(status)) { 280 ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]", 281 acpi_ut_get_region_name(region_obj->region. 282 space_id))); 283 } 284 285 if (!(handler_desc->address_space.handler_flags & 286 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { 287 /* 288 * We just returned from a non-default handler, we must re-enter the 289 * interpreter 290 */ 291 acpi_ex_enter_interpreter(); 292 } 293 294 return_ACPI_STATUS(status); 295 } 296 297 /******************************************************************************* 298 * 299 * FUNCTION: acpi_ev_detach_region 300 * 301 * PARAMETERS: region_obj - Region Object 302 * acpi_ns_is_locked - Namespace Region Already Locked? 303 * 304 * RETURN: None 305 * 306 * DESCRIPTION: Break the association between the handler and the region 307 * this is a two way association. 308 * 309 ******************************************************************************/ 310 311 void 312 acpi_ev_detach_region(union acpi_operand_object *region_obj, 313 u8 acpi_ns_is_locked) 314 { 315 union acpi_operand_object *handler_obj; 316 union acpi_operand_object *obj_desc; 317 union acpi_operand_object *start_desc; 318 union acpi_operand_object **last_obj_ptr; 319 acpi_adr_space_setup region_setup; 320 void **region_context; 321 union acpi_operand_object *region_obj2; 322 acpi_status status; 323 324 ACPI_FUNCTION_TRACE(ev_detach_region); 325 326 region_obj2 = acpi_ns_get_secondary_object(region_obj); 327 if (!region_obj2) { 328 return_VOID; 329 } 330 region_context = ®ion_obj2->extra.region_context; 331 332 /* Get the address handler from the region object */ 333 334 handler_obj = region_obj->region.handler; 335 if (!handler_obj) { 336 337 /* This region has no handler, all done */ 338 339 return_VOID; 340 } 341 342 /* Find this region in the handler's list */ 343 344 obj_desc = handler_obj->address_space.region_list; 345 start_desc = obj_desc; 346 last_obj_ptr = &handler_obj->address_space.region_list; 347 348 while (obj_desc) { 349 350 /* Is this the correct Region? */ 351 352 if (obj_desc == region_obj) { 353 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 354 "Removing Region %p from address handler %p\n", 355 region_obj, handler_obj)); 356 357 /* This is it, remove it from the handler's list */ 358 359 *last_obj_ptr = obj_desc->region.next; 360 obj_desc->region.next = NULL; /* Must clear field */ 361 362 if (acpi_ns_is_locked) { 363 status = 364 acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 365 if (ACPI_FAILURE(status)) { 366 return_VOID; 367 } 368 } 369 370 /* Now stop region accesses by executing the _REG method */ 371 372 status = 373 acpi_ev_execute_reg_method(region_obj, 374 ACPI_REG_DISCONNECT); 375 if (ACPI_FAILURE(status)) { 376 ACPI_EXCEPTION((AE_INFO, status, 377 "from region _REG, [%s]", 378 acpi_ut_get_region_name 379 (region_obj->region.space_id))); 380 } 381 382 if (acpi_ns_is_locked) { 383 status = 384 acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 385 if (ACPI_FAILURE(status)) { 386 return_VOID; 387 } 388 } 389 390 /* 391 * If the region has been activated, call the setup handler with 392 * the deactivate notification 393 */ 394 if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) { 395 region_setup = handler_obj->address_space.setup; 396 status = 397 region_setup(region_obj, 398 ACPI_REGION_DEACTIVATE, 399 handler_obj->address_space. 400 context, region_context); 401 402 /* 403 * region_context should have been released by the deactivate 404 * operation. We don't need access to it anymore here. 405 */ 406 if (region_context) { 407 *region_context = NULL; 408 } 409 410 /* Init routine may fail, Just ignore errors */ 411 412 if (ACPI_FAILURE(status)) { 413 ACPI_EXCEPTION((AE_INFO, status, 414 "from region handler - deactivate, [%s]", 415 acpi_ut_get_region_name 416 (region_obj->region. 417 space_id))); 418 } 419 420 region_obj->region.flags &= 421 ~(AOPOBJ_SETUP_COMPLETE); 422 } 423 424 /* 425 * Remove handler reference in the region 426 * 427 * NOTE: this doesn't mean that the region goes away, the region 428 * is just inaccessible as indicated to the _REG method 429 * 430 * If the region is on the handler's list, this must be the 431 * region's handler 432 */ 433 region_obj->region.handler = NULL; 434 acpi_ut_remove_reference(handler_obj); 435 436 return_VOID; 437 } 438 439 /* Walk the linked list of handlers */ 440 441 last_obj_ptr = &obj_desc->region.next; 442 obj_desc = obj_desc->region.next; 443 444 /* Prevent infinite loop if list is corrupted */ 445 446 if (obj_desc == start_desc) { 447 ACPI_ERROR((AE_INFO, 448 "Circular handler list in region object %p", 449 region_obj)); 450 return_VOID; 451 } 452 } 453 454 /* If we get here, the region was not in the handler's region list */ 455 456 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 457 "Cannot remove region %p from address handler %p\n", 458 region_obj, handler_obj)); 459 460 return_VOID; 461 } 462 463 /******************************************************************************* 464 * 465 * FUNCTION: acpi_ev_attach_region 466 * 467 * PARAMETERS: handler_obj - Handler Object 468 * region_obj - Region Object 469 * acpi_ns_is_locked - Namespace Region Already Locked? 470 * 471 * RETURN: None 472 * 473 * DESCRIPTION: Create the association between the handler and the region 474 * this is a two way association. 475 * 476 ******************************************************************************/ 477 478 acpi_status 479 acpi_ev_attach_region(union acpi_operand_object *handler_obj, 480 union acpi_operand_object *region_obj, 481 u8 acpi_ns_is_locked) 482 { 483 484 ACPI_FUNCTION_TRACE(ev_attach_region); 485 486 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 487 "Adding Region [%4.4s] %p to address handler %p [%s]\n", 488 acpi_ut_get_node_name(region_obj->region.node), 489 region_obj, handler_obj, 490 acpi_ut_get_region_name(region_obj->region. 491 space_id))); 492 493 /* Link this region to the front of the handler's list */ 494 495 region_obj->region.next = handler_obj->address_space.region_list; 496 handler_obj->address_space.region_list = region_obj; 497 498 /* Install the region's handler */ 499 500 if (region_obj->region.handler) { 501 return_ACPI_STATUS(AE_ALREADY_EXISTS); 502 } 503 504 region_obj->region.handler = handler_obj; 505 acpi_ut_add_reference(handler_obj); 506 507 return_ACPI_STATUS(AE_OK); 508 } 509 510 /******************************************************************************* 511 * 512 * FUNCTION: acpi_ev_execute_reg_method 513 * 514 * PARAMETERS: region_obj - Region object 515 * function - Passed to _REG: On (1) or Off (0) 516 * 517 * RETURN: Status 518 * 519 * DESCRIPTION: Execute _REG method for a region 520 * 521 ******************************************************************************/ 522 523 acpi_status 524 acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) 525 { 526 struct acpi_evaluate_info *info; 527 union acpi_operand_object *args[3]; 528 union acpi_operand_object *region_obj2; 529 acpi_status status; 530 531 ACPI_FUNCTION_TRACE(ev_execute_reg_method); 532 533 region_obj2 = acpi_ns_get_secondary_object(region_obj); 534 if (!region_obj2) { 535 return_ACPI_STATUS(AE_NOT_EXIST); 536 } 537 538 if (region_obj2->extra.method_REG == NULL) { 539 return_ACPI_STATUS(AE_OK); 540 } 541 542 /* Allocate and initialize the evaluation information block */ 543 544 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 545 if (!info) { 546 return_ACPI_STATUS(AE_NO_MEMORY); 547 } 548 549 info->prefix_node = region_obj2->extra.method_REG; 550 info->relative_pathname = NULL; 551 info->parameters = args; 552 info->flags = ACPI_IGNORE_RETURN_VALUE; 553 554 /* 555 * The _REG method has two arguments: 556 * 557 * arg0 - Integer: 558 * Operation region space ID Same value as region_obj->Region.space_id 559 * 560 * arg1 - Integer: 561 * connection status 1 for connecting the handler, 0 for disconnecting 562 * the handler (Passed as a parameter) 563 */ 564 args[0] = 565 acpi_ut_create_integer_object((u64)region_obj->region.space_id); 566 if (!args[0]) { 567 status = AE_NO_MEMORY; 568 goto cleanup1; 569 } 570 571 args[1] = acpi_ut_create_integer_object((u64)function); 572 if (!args[1]) { 573 status = AE_NO_MEMORY; 574 goto cleanup2; 575 } 576 577 args[2] = NULL; /* Terminate list */ 578 579 /* Execute the method, no return value */ 580 581 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname 582 (ACPI_TYPE_METHOD, info->prefix_node, NULL)); 583 584 status = acpi_ns_evaluate(info); 585 acpi_ut_remove_reference(args[1]); 586 587 cleanup2: 588 acpi_ut_remove_reference(args[0]); 589 590 cleanup1: 591 ACPI_FREE(info); 592 return_ACPI_STATUS(status); 593 } 594 595 /******************************************************************************* 596 * 597 * FUNCTION: acpi_ev_execute_reg_methods 598 * 599 * PARAMETERS: node - Namespace node for the device 600 * space_id - The address space ID 601 * 602 * RETURN: Status 603 * 604 * DESCRIPTION: Run all _REG methods for the input Space ID; 605 * Note: assumes namespace is locked, or system init time. 606 * 607 ******************************************************************************/ 608 609 acpi_status 610 acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, 611 acpi_adr_space_type space_id) 612 { 613 acpi_status status; 614 615 ACPI_FUNCTION_TRACE(ev_execute_reg_methods); 616 617 /* 618 * Run all _REG methods for all Operation Regions for this space ID. This 619 * is a separate walk in order to handle any interdependencies between 620 * regions and _REG methods. (i.e. handlers must be installed for all 621 * regions of this Space ID before we can run any _REG methods) 622 */ 623 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, 624 ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, 625 NULL, &space_id, NULL); 626 627 /* Special case for EC: handle "orphan" _REG methods with no region */ 628 629 if (space_id == ACPI_ADR_SPACE_EC) { 630 acpi_ev_orphan_ec_reg_method(node); 631 } 632 633 return_ACPI_STATUS(status); 634 } 635 636 /******************************************************************************* 637 * 638 * FUNCTION: acpi_ev_reg_run 639 * 640 * PARAMETERS: walk_namespace callback 641 * 642 * DESCRIPTION: Run _REG method for region objects of the requested spaceID 643 * 644 ******************************************************************************/ 645 646 static acpi_status 647 acpi_ev_reg_run(acpi_handle obj_handle, 648 u32 level, void *context, void **return_value) 649 { 650 union acpi_operand_object *obj_desc; 651 struct acpi_namespace_node *node; 652 acpi_adr_space_type space_id; 653 acpi_status status; 654 655 space_id = *ACPI_CAST_PTR(acpi_adr_space_type, context); 656 657 /* Convert and validate the device handle */ 658 659 node = acpi_ns_validate_handle(obj_handle); 660 if (!node) { 661 return (AE_BAD_PARAMETER); 662 } 663 664 /* 665 * We only care about regions.and objects that are allowed to have address 666 * space handlers 667 */ 668 if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) { 669 return (AE_OK); 670 } 671 672 /* Check for an existing internal object */ 673 674 obj_desc = acpi_ns_get_attached_object(node); 675 if (!obj_desc) { 676 677 /* No object, just exit */ 678 679 return (AE_OK); 680 } 681 682 /* Object is a Region */ 683 684 if (obj_desc->region.space_id != space_id) { 685 686 /* This region is for a different address space, just ignore it */ 687 688 return (AE_OK); 689 } 690 691 status = acpi_ev_execute_reg_method(obj_desc, ACPI_REG_CONNECT); 692 return (status); 693 } 694 695 /******************************************************************************* 696 * 697 * FUNCTION: acpi_ev_orphan_ec_reg_method 698 * 699 * PARAMETERS: ec_device_node - Namespace node for an EC device 700 * 701 * RETURN: None 702 * 703 * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC 704 * device. This is a _REG method that has no corresponding region 705 * within the EC device scope. The orphan _REG method appears to 706 * have been enabled by the description of the ECDT in the ACPI 707 * specification: "The availability of the region space can be 708 * detected by providing a _REG method object underneath the 709 * Embedded Controller device." 710 * 711 * To quickly access the EC device, we use the ec_device_node used 712 * during EC handler installation. Otherwise, we would need to 713 * perform a time consuming namespace walk, executing _HID 714 * methods to find the EC device. 715 * 716 * MUTEX: Assumes the namespace is locked 717 * 718 ******************************************************************************/ 719 720 static void 721 acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node) 722 { 723 acpi_handle reg_method; 724 struct acpi_namespace_node *next_node; 725 acpi_status status; 726 struct acpi_object_list args; 727 union acpi_object objects[2]; 728 729 ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method); 730 731 if (!ec_device_node) { 732 return_VOID; 733 } 734 735 /* Namespace is currently locked, must release */ 736 737 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 738 739 /* Get a handle to a _REG method immediately under the EC device */ 740 741 status = acpi_get_handle(ec_device_node, METHOD_NAME__REG, ®_method); 742 if (ACPI_FAILURE(status)) { 743 goto exit; /* There is no _REG method present */ 744 } 745 746 /* 747 * Execute the _REG method only if there is no Operation Region in 748 * this scope with the Embedded Controller space ID. Otherwise, it 749 * will already have been executed. Note, this allows for Regions 750 * with other space IDs to be present; but the code below will then 751 * execute the _REG method with the embedded_control space_ID argument. 752 */ 753 next_node = acpi_ns_get_next_node(ec_device_node, NULL); 754 while (next_node) { 755 if ((next_node->type == ACPI_TYPE_REGION) && 756 (next_node->object) && 757 (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) { 758 goto exit; /* Do not execute the _REG */ 759 } 760 761 next_node = acpi_ns_get_next_node(ec_device_node, next_node); 762 } 763 764 /* Evaluate the _REG(embedded_control,Connect) method */ 765 766 args.count = 2; 767 args.pointer = objects; 768 objects[0].type = ACPI_TYPE_INTEGER; 769 objects[0].integer.value = ACPI_ADR_SPACE_EC; 770 objects[1].type = ACPI_TYPE_INTEGER; 771 objects[1].integer.value = ACPI_REG_CONNECT; 772 773 status = acpi_evaluate_object(reg_method, NULL, &args, NULL); 774 775 exit: 776 /* We ignore all errors from above, don't care */ 777 778 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 779 return_VOID; 780 } 781