1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /******************************************************************************* 3 * 4 * Module Name: hwregs - Read/write access functions for the various ACPI 5 * control and status registers. 6 * 7 ******************************************************************************/ 8 9 #include <acpi/acpi.h> 10 #include "accommon.h" 11 #include "acevents.h" 12 13 #define _COMPONENT ACPI_HARDWARE 14 ACPI_MODULE_NAME("hwregs") 15 16 #if (!ACPI_REDUCED_HARDWARE) 17 /* Local Prototypes */ 18 static u8 19 acpi_hw_get_access_bit_width(u64 address, 20 struct acpi_generic_address *reg, 21 u8 max_bit_width); 22 23 static acpi_status 24 acpi_hw_read_multiple(u32 *value, 25 struct acpi_generic_address *register_a, 26 struct acpi_generic_address *register_b); 27 28 static acpi_status 29 acpi_hw_write_multiple(u32 value, 30 struct acpi_generic_address *register_a, 31 struct acpi_generic_address *register_b); 32 33 #endif /* !ACPI_REDUCED_HARDWARE */ 34 35 /****************************************************************************** 36 * 37 * FUNCTION: acpi_hw_get_access_bit_width 38 * 39 * PARAMETERS: address - GAS register address 40 * reg - GAS register structure 41 * max_bit_width - Max bit_width supported (32 or 64) 42 * 43 * RETURN: Status 44 * 45 * DESCRIPTION: Obtain optimal access bit width 46 * 47 ******************************************************************************/ 48 49 static u8 50 acpi_hw_get_access_bit_width(u64 address, 51 struct acpi_generic_address *reg, u8 max_bit_width) 52 { 53 u8 access_bit_width; 54 55 /* 56 * GAS format "register", used by FADT: 57 * 1. Detected if bit_offset is 0 and bit_width is 8/16/32/64; 58 * 2. access_size field is ignored and bit_width field is used for 59 * determining the boundary of the IO accesses. 60 * GAS format "region", used by APEI registers: 61 * 1. Detected if bit_offset is not 0 or bit_width is not 8/16/32/64; 62 * 2. access_size field is used for determining the boundary of the 63 * IO accesses; 64 * 3. bit_offset/bit_width fields are used to describe the "region". 65 * 66 * Note: This algorithm assumes that the "Address" fields should always 67 * contain aligned values. 68 */ 69 if (!reg->bit_offset && reg->bit_width && 70 ACPI_IS_POWER_OF_TWO(reg->bit_width) && 71 ACPI_IS_ALIGNED(reg->bit_width, 8)) { 72 access_bit_width = reg->bit_width; 73 } else if (reg->access_width) { 74 access_bit_width = ACPI_ACCESS_BIT_WIDTH(reg->access_width); 75 } else { 76 access_bit_width = 77 ACPI_ROUND_UP_POWER_OF_TWO_8(reg->bit_offset + 78 reg->bit_width); 79 if (access_bit_width <= 8) { 80 access_bit_width = 8; 81 } else { 82 while (!ACPI_IS_ALIGNED(address, access_bit_width >> 3)) { 83 access_bit_width >>= 1; 84 } 85 } 86 } 87 88 /* Maximum IO port access bit width is 32 */ 89 90 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { 91 max_bit_width = 32; 92 } 93 94 /* 95 * Return access width according to the requested maximum access bit width, 96 * as the caller should know the format of the register and may enforce 97 * a 32-bit accesses. 98 */ 99 if (access_bit_width < max_bit_width) { 100 return (access_bit_width); 101 } 102 return (max_bit_width); 103 } 104 105 /****************************************************************************** 106 * 107 * FUNCTION: acpi_hw_validate_register 108 * 109 * PARAMETERS: reg - GAS register structure 110 * max_bit_width - Max bit_width supported (32 or 64) 111 * address - Pointer to where the gas->address 112 * is returned 113 * 114 * RETURN: Status 115 * 116 * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS 117 * pointer, Address, space_id, bit_width, and bit_offset. 118 * 119 ******************************************************************************/ 120 121 acpi_status 122 acpi_hw_validate_register(struct acpi_generic_address *reg, 123 u8 max_bit_width, u64 *address) 124 { 125 u8 bit_width; 126 u8 access_width; 127 128 /* Must have a valid pointer to a GAS structure */ 129 130 if (!reg) { 131 return (AE_BAD_PARAMETER); 132 } 133 134 /* 135 * Copy the target address. This handles possible alignment issues. 136 * Address must not be null. A null address also indicates an optional 137 * ACPI register that is not supported, so no error message. 138 */ 139 ACPI_MOVE_64_TO_64(address, ®->address); 140 if (!(*address)) { 141 return (AE_BAD_ADDRESS); 142 } 143 144 /* Validate the space_ID */ 145 146 if ((reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 147 (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { 148 ACPI_ERROR((AE_INFO, 149 "Unsupported address space: 0x%X", reg->space_id)); 150 return (AE_SUPPORT); 151 } 152 153 /* Validate the access_width */ 154 155 if (reg->access_width > 4) { 156 ACPI_ERROR((AE_INFO, 157 "Unsupported register access width: 0x%X", 158 reg->access_width)); 159 return (AE_SUPPORT); 160 } 161 162 /* Validate the bit_width, convert access_width into number of bits */ 163 164 access_width = 165 acpi_hw_get_access_bit_width(*address, reg, max_bit_width); 166 bit_width = 167 ACPI_ROUND_UP(reg->bit_offset + reg->bit_width, access_width); 168 if (max_bit_width < bit_width) { 169 ACPI_WARNING((AE_INFO, 170 "Requested bit width 0x%X is smaller than register bit width 0x%X", 171 max_bit_width, bit_width)); 172 return (AE_SUPPORT); 173 } 174 175 return (AE_OK); 176 } 177 178 /****************************************************************************** 179 * 180 * FUNCTION: acpi_hw_read 181 * 182 * PARAMETERS: value - Where the value is returned 183 * reg - GAS register structure 184 * 185 * RETURN: Status 186 * 187 * DESCRIPTION: Read from either memory or IO space. This is a 64-bit max 188 * version of acpi_read. 189 * 190 * LIMITATIONS: <These limitations also apply to acpi_hw_write> 191 * space_ID must be system_memory or system_IO. 192 * 193 ******************************************************************************/ 194 195 acpi_status acpi_hw_read(u64 *value, struct acpi_generic_address *reg) 196 { 197 u64 address; 198 u8 access_width; 199 u32 bit_width; 200 u8 bit_offset; 201 u64 value64; 202 u32 value32; 203 u8 index; 204 acpi_status status; 205 206 ACPI_FUNCTION_NAME(hw_read); 207 208 /* Validate contents of the GAS register */ 209 210 status = acpi_hw_validate_register(reg, 64, &address); 211 if (ACPI_FAILURE(status)) { 212 return (status); 213 } 214 215 /* 216 * Initialize entire 64-bit return value to zero, convert access_width 217 * into number of bits based 218 */ 219 *value = 0; 220 access_width = acpi_hw_get_access_bit_width(address, reg, 64); 221 bit_width = reg->bit_offset + reg->bit_width; 222 bit_offset = reg->bit_offset; 223 224 /* 225 * Two address spaces supported: Memory or IO. PCI_Config is 226 * not supported here because the GAS structure is insufficient 227 */ 228 index = 0; 229 while (bit_width) { 230 if (bit_offset >= access_width) { 231 value64 = 0; 232 bit_offset -= access_width; 233 } else { 234 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { 235 status = 236 acpi_os_read_memory((acpi_physical_address) 237 address + 238 index * 239 ACPI_DIV_8 240 (access_width), 241 &value64, access_width); 242 } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 243 244 status = acpi_hw_read_port((acpi_io_address) 245 address + 246 index * 247 ACPI_DIV_8 248 (access_width), 249 &value32, 250 access_width); 251 value64 = (u64)value32; 252 } 253 } 254 255 /* 256 * Use offset style bit writes because "Index * AccessWidth" is 257 * ensured to be less than 64-bits by acpi_hw_validate_register(). 258 */ 259 ACPI_SET_BITS(value, index * access_width, 260 ACPI_MASK_BITS_ABOVE_64(access_width), value64); 261 262 bit_width -= 263 bit_width > access_width ? access_width : bit_width; 264 index++; 265 } 266 267 ACPI_DEBUG_PRINT((ACPI_DB_IO, 268 "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", 269 ACPI_FORMAT_UINT64(*value), access_width, 270 ACPI_FORMAT_UINT64(address), 271 acpi_ut_get_region_name(reg->space_id))); 272 273 return (status); 274 } 275 276 /****************************************************************************** 277 * 278 * FUNCTION: acpi_hw_write 279 * 280 * PARAMETERS: value - Value to be written 281 * reg - GAS register structure 282 * 283 * RETURN: Status 284 * 285 * DESCRIPTION: Write to either memory or IO space. This is a 64-bit max 286 * version of acpi_write. 287 * 288 ******************************************************************************/ 289 290 acpi_status acpi_hw_write(u64 value, struct acpi_generic_address *reg) 291 { 292 u64 address; 293 u8 access_width; 294 u32 bit_width; 295 u8 bit_offset; 296 u64 value64; 297 u8 index; 298 acpi_status status; 299 300 ACPI_FUNCTION_NAME(hw_write); 301 302 /* Validate contents of the GAS register */ 303 304 status = acpi_hw_validate_register(reg, 64, &address); 305 if (ACPI_FAILURE(status)) { 306 return (status); 307 } 308 309 /* Convert access_width into number of bits based */ 310 311 access_width = acpi_hw_get_access_bit_width(address, reg, 64); 312 bit_width = reg->bit_offset + reg->bit_width; 313 bit_offset = reg->bit_offset; 314 315 /* 316 * Two address spaces supported: Memory or IO. PCI_Config is 317 * not supported here because the GAS structure is insufficient 318 */ 319 index = 0; 320 while (bit_width) { 321 /* 322 * Use offset style bit reads because "Index * AccessWidth" is 323 * ensured to be less than 64-bits by acpi_hw_validate_register(). 324 */ 325 value64 = ACPI_GET_BITS(&value, index * access_width, 326 ACPI_MASK_BITS_ABOVE_64(access_width)); 327 328 if (bit_offset >= access_width) { 329 bit_offset -= access_width; 330 } else { 331 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { 332 status = 333 acpi_os_write_memory((acpi_physical_address) 334 address + 335 index * 336 ACPI_DIV_8 337 (access_width), 338 value64, access_width); 339 } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 340 341 status = acpi_hw_write_port((acpi_io_address) 342 address + 343 index * 344 ACPI_DIV_8 345 (access_width), 346 (u32)value64, 347 access_width); 348 } 349 } 350 351 /* 352 * Index * access_width is ensured to be less than 32-bits by 353 * acpi_hw_validate_register(). 354 */ 355 bit_width -= 356 bit_width > access_width ? access_width : bit_width; 357 index++; 358 } 359 360 ACPI_DEBUG_PRINT((ACPI_DB_IO, 361 "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", 362 ACPI_FORMAT_UINT64(value), access_width, 363 ACPI_FORMAT_UINT64(address), 364 acpi_ut_get_region_name(reg->space_id))); 365 366 return (status); 367 } 368 369 #if (!ACPI_REDUCED_HARDWARE) 370 /******************************************************************************* 371 * 372 * FUNCTION: acpi_hw_clear_acpi_status 373 * 374 * PARAMETERS: None 375 * 376 * RETURN: Status 377 * 378 * DESCRIPTION: Clears all fixed and general purpose status bits 379 * 380 ******************************************************************************/ 381 382 acpi_status acpi_hw_clear_acpi_status(void) 383 { 384 acpi_status status; 385 acpi_cpu_flags lock_flags = 0; 386 387 ACPI_FUNCTION_TRACE(hw_clear_acpi_status); 388 389 ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", 390 ACPI_BITMASK_ALL_FIXED_STATUS, 391 ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); 392 393 lock_flags = acpi_os_acquire_raw_lock(acpi_gbl_hardware_lock); 394 395 /* Clear the fixed events in PM1 A/B */ 396 397 status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, 398 ACPI_BITMASK_ALL_FIXED_STATUS); 399 400 acpi_os_release_raw_lock(acpi_gbl_hardware_lock, lock_flags); 401 402 if (ACPI_FAILURE(status)) { 403 goto exit; 404 } 405 406 /* Clear the GPE Bits in all GPE registers in all GPE blocks */ 407 408 status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL); 409 410 exit: 411 return_ACPI_STATUS(status); 412 } 413 414 /******************************************************************************* 415 * 416 * FUNCTION: acpi_hw_get_bit_register_info 417 * 418 * PARAMETERS: register_id - Index of ACPI Register to access 419 * 420 * RETURN: The bitmask to be used when accessing the register 421 * 422 * DESCRIPTION: Map register_id into a register bitmask. 423 * 424 ******************************************************************************/ 425 426 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) 427 { 428 ACPI_FUNCTION_ENTRY(); 429 430 if (register_id > ACPI_BITREG_MAX) { 431 ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: 0x%X", 432 register_id)); 433 return (NULL); 434 } 435 436 return (&acpi_gbl_bit_register_info[register_id]); 437 } 438 439 /****************************************************************************** 440 * 441 * FUNCTION: acpi_hw_write_pm1_control 442 * 443 * PARAMETERS: pm1a_control - Value to be written to PM1A control 444 * pm1b_control - Value to be written to PM1B control 445 * 446 * RETURN: Status 447 * 448 * DESCRIPTION: Write the PM1 A/B control registers. These registers are 449 * different than than the PM1 A/B status and enable registers 450 * in that different values can be written to the A/B registers. 451 * Most notably, the SLP_TYP bits can be different, as per the 452 * values returned from the _Sx predefined methods. 453 * 454 ******************************************************************************/ 455 456 acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control) 457 { 458 acpi_status status; 459 460 ACPI_FUNCTION_TRACE(hw_write_pm1_control); 461 462 status = 463 acpi_hw_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block); 464 if (ACPI_FAILURE(status)) { 465 return_ACPI_STATUS(status); 466 } 467 468 if (acpi_gbl_FADT.xpm1b_control_block.address) { 469 status = 470 acpi_hw_write(pm1b_control, 471 &acpi_gbl_FADT.xpm1b_control_block); 472 } 473 return_ACPI_STATUS(status); 474 } 475 476 /****************************************************************************** 477 * 478 * FUNCTION: acpi_hw_register_read 479 * 480 * PARAMETERS: register_id - ACPI Register ID 481 * return_value - Where the register value is returned 482 * 483 * RETURN: Status and the value read. 484 * 485 * DESCRIPTION: Read from the specified ACPI register 486 * 487 ******************************************************************************/ 488 acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) 489 { 490 u32 value = 0; 491 u64 value64; 492 acpi_status status; 493 494 ACPI_FUNCTION_TRACE(hw_register_read); 495 496 switch (register_id) { 497 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 498 499 status = acpi_hw_read_multiple(&value, 500 &acpi_gbl_xpm1a_status, 501 &acpi_gbl_xpm1b_status); 502 break; 503 504 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ 505 506 status = acpi_hw_read_multiple(&value, 507 &acpi_gbl_xpm1a_enable, 508 &acpi_gbl_xpm1b_enable); 509 break; 510 511 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 512 513 status = acpi_hw_read_multiple(&value, 514 &acpi_gbl_FADT. 515 xpm1a_control_block, 516 &acpi_gbl_FADT. 517 xpm1b_control_block); 518 519 /* 520 * Zero the write-only bits. From the ACPI specification, "Hardware 521 * Write-Only Bits": "Upon reads to registers with write-only bits, 522 * software masks out all write-only bits." 523 */ 524 value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS; 525 break; 526 527 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 528 529 status = 530 acpi_hw_read(&value64, &acpi_gbl_FADT.xpm2_control_block); 531 if (ACPI_SUCCESS(status)) { 532 value = (u32)value64; 533 } 534 break; 535 536 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 537 538 status = acpi_hw_read(&value64, &acpi_gbl_FADT.xpm_timer_block); 539 if (ACPI_SUCCESS(status)) { 540 value = (u32)value64; 541 } 542 543 break; 544 545 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 546 547 status = 548 acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8); 549 break; 550 551 default: 552 553 ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id)); 554 status = AE_BAD_PARAMETER; 555 break; 556 } 557 558 if (ACPI_SUCCESS(status)) { 559 *return_value = (u32)value; 560 } 561 562 return_ACPI_STATUS(status); 563 } 564 565 /****************************************************************************** 566 * 567 * FUNCTION: acpi_hw_register_write 568 * 569 * PARAMETERS: register_id - ACPI Register ID 570 * value - The value to write 571 * 572 * RETURN: Status 573 * 574 * DESCRIPTION: Write to the specified ACPI register 575 * 576 * NOTE: In accordance with the ACPI specification, this function automatically 577 * preserves the value of the following bits, meaning that these bits cannot be 578 * changed via this interface: 579 * 580 * PM1_CONTROL[0] = SCI_EN 581 * PM1_CONTROL[9] 582 * PM1_STATUS[11] 583 * 584 * ACPI References: 585 * 1) Hardware Ignored Bits: When software writes to a register with ignored 586 * bit fields, it preserves the ignored bit fields 587 * 2) SCI_EN: OSPM always preserves this bit position 588 * 589 ******************************************************************************/ 590 591 acpi_status acpi_hw_register_write(u32 register_id, u32 value) 592 { 593 acpi_status status; 594 u32 read_value; 595 u64 read_value64; 596 597 ACPI_FUNCTION_TRACE(hw_register_write); 598 599 switch (register_id) { 600 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 601 /* 602 * Handle the "ignored" bit in PM1 Status. According to the ACPI 603 * specification, ignored bits are to be preserved when writing. 604 * Normally, this would mean a read/modify/write sequence. However, 605 * preserving a bit in the status register is different. Writing a 606 * one clears the status, and writing a zero preserves the status. 607 * Therefore, we must always write zero to the ignored bit. 608 * 609 * This behavior is clarified in the ACPI 4.0 specification. 610 */ 611 value &= ~ACPI_PM1_STATUS_PRESERVED_BITS; 612 613 status = acpi_hw_write_multiple(value, 614 &acpi_gbl_xpm1a_status, 615 &acpi_gbl_xpm1b_status); 616 break; 617 618 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ 619 620 status = acpi_hw_write_multiple(value, 621 &acpi_gbl_xpm1a_enable, 622 &acpi_gbl_xpm1b_enable); 623 break; 624 625 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 626 /* 627 * Perform a read first to preserve certain bits (per ACPI spec) 628 * Note: This includes SCI_EN, we never want to change this bit 629 */ 630 status = acpi_hw_read_multiple(&read_value, 631 &acpi_gbl_FADT. 632 xpm1a_control_block, 633 &acpi_gbl_FADT. 634 xpm1b_control_block); 635 if (ACPI_FAILURE(status)) { 636 goto exit; 637 } 638 639 /* Insert the bits to be preserved */ 640 641 ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS, 642 read_value); 643 644 /* Now we can write the data */ 645 646 status = acpi_hw_write_multiple(value, 647 &acpi_gbl_FADT. 648 xpm1a_control_block, 649 &acpi_gbl_FADT. 650 xpm1b_control_block); 651 break; 652 653 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 654 /* 655 * For control registers, all reserved bits must be preserved, 656 * as per the ACPI spec. 657 */ 658 status = 659 acpi_hw_read(&read_value64, 660 &acpi_gbl_FADT.xpm2_control_block); 661 if (ACPI_FAILURE(status)) { 662 goto exit; 663 } 664 read_value = (u32)read_value64; 665 666 /* Insert the bits to be preserved */ 667 668 ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS, 669 read_value); 670 671 status = 672 acpi_hw_write(value, &acpi_gbl_FADT.xpm2_control_block); 673 break; 674 675 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 676 677 status = acpi_hw_write(value, &acpi_gbl_FADT.xpm_timer_block); 678 break; 679 680 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 681 682 /* SMI_CMD is currently always in IO space */ 683 684 status = 685 acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8); 686 break; 687 688 default: 689 690 ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id)); 691 status = AE_BAD_PARAMETER; 692 break; 693 } 694 695 exit: 696 return_ACPI_STATUS(status); 697 } 698 699 /****************************************************************************** 700 * 701 * FUNCTION: acpi_hw_read_multiple 702 * 703 * PARAMETERS: value - Where the register value is returned 704 * register_a - First ACPI register (required) 705 * register_b - Second ACPI register (optional) 706 * 707 * RETURN: Status 708 * 709 * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B) 710 * 711 ******************************************************************************/ 712 713 static acpi_status 714 acpi_hw_read_multiple(u32 *value, 715 struct acpi_generic_address *register_a, 716 struct acpi_generic_address *register_b) 717 { 718 u32 value_a = 0; 719 u32 value_b = 0; 720 u64 value64; 721 acpi_status status; 722 723 /* The first register is always required */ 724 725 status = acpi_hw_read(&value64, register_a); 726 if (ACPI_FAILURE(status)) { 727 return (status); 728 } 729 value_a = (u32)value64; 730 731 /* Second register is optional */ 732 733 if (register_b->address) { 734 status = acpi_hw_read(&value64, register_b); 735 if (ACPI_FAILURE(status)) { 736 return (status); 737 } 738 value_b = (u32)value64; 739 } 740 741 /* 742 * OR the two return values together. No shifting or masking is necessary, 743 * because of how the PM1 registers are defined in the ACPI specification: 744 * 745 * "Although the bits can be split between the two register blocks (each 746 * register block has a unique pointer within the FADT), the bit positions 747 * are maintained. The register block with unimplemented bits (that is, 748 * those implemented in the other register block) always returns zeros, 749 * and writes have no side effects" 750 */ 751 *value = (value_a | value_b); 752 return (AE_OK); 753 } 754 755 /****************************************************************************** 756 * 757 * FUNCTION: acpi_hw_write_multiple 758 * 759 * PARAMETERS: value - The value to write 760 * register_a - First ACPI register (required) 761 * register_b - Second ACPI register (optional) 762 * 763 * RETURN: Status 764 * 765 * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B) 766 * 767 ******************************************************************************/ 768 769 static acpi_status 770 acpi_hw_write_multiple(u32 value, 771 struct acpi_generic_address *register_a, 772 struct acpi_generic_address *register_b) 773 { 774 acpi_status status; 775 776 /* The first register is always required */ 777 778 status = acpi_hw_write(value, register_a); 779 if (ACPI_FAILURE(status)) { 780 return (status); 781 } 782 783 /* 784 * Second register is optional 785 * 786 * No bit shifting or clearing is necessary, because of how the PM1 787 * registers are defined in the ACPI specification: 788 * 789 * "Although the bits can be split between the two register blocks (each 790 * register block has a unique pointer within the FADT), the bit positions 791 * are maintained. The register block with unimplemented bits (that is, 792 * those implemented in the other register block) always returns zeros, 793 * and writes have no side effects" 794 */ 795 if (register_b->address) { 796 status = acpi_hw_write(value, register_b); 797 } 798 799 return (status); 800 } 801 802 #endif /* !ACPI_REDUCED_HARDWARE */ 803