Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.28-rc9 857 lines 24 kB view raw
1 2/******************************************************************************* 3 * 4 * Module Name: hwregs - Read/write access functions for the various ACPI 5 * control and status registers. 6 * 7 ******************************************************************************/ 8 9/* 10 * Copyright (C) 2000 - 2008, Intel Corp. 11 * All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions, and the following disclaimer, 18 * without modification. 19 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 20 * substantially similar to the "NO WARRANTY" disclaimer below 21 * ("Disclaimer") and any redistribution must be conditioned upon 22 * including a substantially similar Disclaimer requirement for further 23 * binary redistribution. 24 * 3. Neither the names of the above-listed copyright holders nor the names 25 * of any contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * Alternatively, this software may be distributed under the terms of the 29 * GNU General Public License ("GPL") version 2 as published by the Free 30 * Software Foundation. 31 * 32 * NO WARRANTY 33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 34 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 35 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 36 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 37 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 42 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43 * POSSIBILITY OF SUCH DAMAGES. 44 */ 45 46#include <acpi/acpi.h> 47#include <acpi/acnamesp.h> 48#include <acpi/acevents.h> 49 50#define _COMPONENT ACPI_HARDWARE 51ACPI_MODULE_NAME("hwregs") 52 53/******************************************************************************* 54 * 55 * FUNCTION: acpi_hw_clear_acpi_status 56 * 57 * PARAMETERS: None 58 * 59 * RETURN: None 60 * 61 * DESCRIPTION: Clears all fixed and general purpose status bits 62 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 63 * 64 ******************************************************************************/ 65acpi_status acpi_hw_clear_acpi_status(void) 66{ 67 acpi_status status; 68 acpi_cpu_flags lock_flags = 0; 69 70 ACPI_FUNCTION_TRACE(hw_clear_acpi_status); 71 72 ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", 73 ACPI_BITMASK_ALL_FIXED_STATUS, 74 (u16) acpi_gbl_FADT.xpm1a_event_block.address)); 75 76 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 77 78 status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, 79 ACPI_BITMASK_ALL_FIXED_STATUS); 80 if (ACPI_FAILURE(status)) { 81 goto unlock_and_exit; 82 } 83 84 /* Clear the fixed events */ 85 86 if (acpi_gbl_FADT.xpm1b_event_block.address) { 87 status = 88 acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, 89 &acpi_gbl_FADT.xpm1b_event_block); 90 if (ACPI_FAILURE(status)) { 91 goto unlock_and_exit; 92 } 93 } 94 95 /* Clear the GPE Bits in all GPE registers in all GPE blocks */ 96 97 status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); 98 99 unlock_and_exit: 100 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); 101 return_ACPI_STATUS(status); 102} 103 104/******************************************************************************* 105 * 106 * FUNCTION: acpi_get_sleep_type_data 107 * 108 * PARAMETERS: sleep_state - Numeric sleep state 109 * *sleep_type_a - Where SLP_TYPa is returned 110 * *sleep_type_b - Where SLP_TYPb is returned 111 * 112 * RETURN: Status - ACPI status 113 * 114 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep 115 * state. 116 * 117 ******************************************************************************/ 118 119acpi_status 120acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) 121{ 122 acpi_status status = AE_OK; 123 struct acpi_evaluate_info *info; 124 125 ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data); 126 127 /* Validate parameters */ 128 129 if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) { 130 return_ACPI_STATUS(AE_BAD_PARAMETER); 131 } 132 133 /* Allocate the evaluation information block */ 134 135 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 136 if (!info) { 137 return_ACPI_STATUS(AE_NO_MEMORY); 138 } 139 140 info->pathname = 141 ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); 142 143 /* Evaluate the namespace object containing the values for this state */ 144 145 status = acpi_ns_evaluate(info); 146 if (ACPI_FAILURE(status)) { 147 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 148 "%s while evaluating SleepState [%s]\n", 149 acpi_format_exception(status), 150 info->pathname)); 151 152 goto cleanup; 153 } 154 155 /* Must have a return object */ 156 157 if (!info->return_object) { 158 ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", 159 info->pathname)); 160 status = AE_NOT_EXIST; 161 } 162 163 /* It must be of type Package */ 164 165 else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) { 166 ACPI_ERROR((AE_INFO, 167 "Sleep State return object is not a Package")); 168 status = AE_AML_OPERAND_TYPE; 169 } 170 171 /* 172 * The package must have at least two elements. NOTE (March 2005): This 173 * goes against the current ACPI spec which defines this object as a 174 * package with one encoded DWORD element. However, existing practice 175 * by BIOS vendors seems to be to have 2 or more elements, at least 176 * one per sleep type (A/B). 177 */ 178 else if (info->return_object->package.count < 2) { 179 ACPI_ERROR((AE_INFO, 180 "Sleep State return package does not have at least two elements")); 181 status = AE_AML_NO_OPERAND; 182 } 183 184 /* The first two elements must both be of type Integer */ 185 186 else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0]) 187 != ACPI_TYPE_INTEGER) || 188 (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1]) 189 != ACPI_TYPE_INTEGER)) { 190 ACPI_ERROR((AE_INFO, 191 "Sleep State return package elements are not both Integers (%s, %s)", 192 acpi_ut_get_object_type_name(info->return_object-> 193 package.elements[0]), 194 acpi_ut_get_object_type_name(info->return_object-> 195 package.elements[1]))); 196 status = AE_AML_OPERAND_TYPE; 197 } else { 198 /* Valid _Sx_ package size, type, and value */ 199 200 *sleep_type_a = (u8) 201 (info->return_object->package.elements[0])->integer.value; 202 *sleep_type_b = (u8) 203 (info->return_object->package.elements[1])->integer.value; 204 } 205 206 if (ACPI_FAILURE(status)) { 207 ACPI_EXCEPTION((AE_INFO, status, 208 "While evaluating SleepState [%s], bad Sleep object %p type %s", 209 info->pathname, info->return_object, 210 acpi_ut_get_object_type_name(info-> 211 return_object))); 212 } 213 214 acpi_ut_remove_reference(info->return_object); 215 216 cleanup: 217 ACPI_FREE(info); 218 return_ACPI_STATUS(status); 219} 220 221ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data) 222 223/******************************************************************************* 224 * 225 * FUNCTION: acpi_hw_get_register_bit_mask 226 * 227 * PARAMETERS: register_id - Index of ACPI Register to access 228 * 229 * RETURN: The bitmask to be used when accessing the register 230 * 231 * DESCRIPTION: Map register_id into a register bitmask. 232 * 233 ******************************************************************************/ 234struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) 235{ 236 ACPI_FUNCTION_ENTRY(); 237 238 if (register_id > ACPI_BITREG_MAX) { 239 ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: %X", 240 register_id)); 241 return (NULL); 242 } 243 244 return (&acpi_gbl_bit_register_info[register_id]); 245} 246 247/******************************************************************************* 248 * 249 * FUNCTION: acpi_get_register 250 * 251 * PARAMETERS: register_id - ID of ACPI bit_register to access 252 * return_value - Value that was read from the register 253 * 254 * RETURN: Status and the value read from specified Register. Value 255 * returned is normalized to bit0 (is shifted all the way right) 256 * 257 * DESCRIPTION: ACPI bit_register read function. 258 * 259 ******************************************************************************/ 260 261acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value) 262{ 263 u32 register_value = 0; 264 struct acpi_bit_register_info *bit_reg_info; 265 acpi_status status; 266 267 ACPI_FUNCTION_TRACE(acpi_get_register); 268 269 /* Get the info structure corresponding to the requested ACPI Register */ 270 271 bit_reg_info = acpi_hw_get_bit_register_info(register_id); 272 if (!bit_reg_info) { 273 return_ACPI_STATUS(AE_BAD_PARAMETER); 274 } 275 276 /* Read from the register */ 277 278 status = acpi_hw_register_read(bit_reg_info->parent_register, 279 &register_value); 280 281 if (ACPI_SUCCESS(status)) { 282 283 /* Normalize the value that was read */ 284 285 register_value = 286 ((register_value & bit_reg_info->access_bit_mask) 287 >> bit_reg_info->bit_position); 288 289 *return_value = register_value; 290 291 ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n", 292 register_value, 293 bit_reg_info->parent_register)); 294 } 295 296 return_ACPI_STATUS(status); 297} 298 299acpi_status acpi_get_register(u32 register_id, u32 * return_value) 300{ 301 acpi_status status; 302 acpi_cpu_flags flags; 303 flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 304 status = acpi_get_register_unlocked(register_id, return_value); 305 acpi_os_release_lock(acpi_gbl_hardware_lock, flags); 306 return status; 307} 308 309ACPI_EXPORT_SYMBOL(acpi_get_register) 310 311/******************************************************************************* 312 * 313 * FUNCTION: acpi_set_register 314 * 315 * PARAMETERS: register_id - ID of ACPI bit_register to access 316 * Value - (only used on write) value to write to the 317 * Register, NOT pre-normalized to the bit pos 318 * 319 * RETURN: Status 320 * 321 * DESCRIPTION: ACPI Bit Register write function. 322 * 323 ******************************************************************************/ 324acpi_status acpi_set_register(u32 register_id, u32 value) 325{ 326 u32 register_value = 0; 327 struct acpi_bit_register_info *bit_reg_info; 328 acpi_status status; 329 acpi_cpu_flags lock_flags; 330 331 ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id); 332 333 /* Get the info structure corresponding to the requested ACPI Register */ 334 335 bit_reg_info = acpi_hw_get_bit_register_info(register_id); 336 if (!bit_reg_info) { 337 ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X", 338 register_id)); 339 return_ACPI_STATUS(AE_BAD_PARAMETER); 340 } 341 342 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 343 344 /* Always do a register read first so we can insert the new bits */ 345 346 status = acpi_hw_register_read(bit_reg_info->parent_register, 347 &register_value); 348 if (ACPI_FAILURE(status)) { 349 goto unlock_and_exit; 350 } 351 352 /* 353 * Decode the Register ID 354 * Register ID = [Register block ID] | [bit ID] 355 * 356 * Check bit ID to fine locate Register offset. 357 * Check Mask to determine Register offset, and then read-write. 358 */ 359 switch (bit_reg_info->parent_register) { 360 case ACPI_REGISTER_PM1_STATUS: 361 362 /* 363 * Status Registers are different from the rest. Clear by 364 * writing 1, and writing 0 has no effect. So, the only relevant 365 * information is the single bit we're interested in, all others should 366 * be written as 0 so they will be left unchanged. 367 */ 368 value = ACPI_REGISTER_PREPARE_BITS(value, 369 bit_reg_info->bit_position, 370 bit_reg_info-> 371 access_bit_mask); 372 if (value) { 373 status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, 374 (u16) value); 375 register_value = 0; 376 } 377 break; 378 379 case ACPI_REGISTER_PM1_ENABLE: 380 381 ACPI_REGISTER_INSERT_VALUE(register_value, 382 bit_reg_info->bit_position, 383 bit_reg_info->access_bit_mask, 384 value); 385 386 status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE, 387 (u16) register_value); 388 break; 389 390 case ACPI_REGISTER_PM1_CONTROL: 391 392 /* 393 * Write the PM1 Control register. 394 * Note that at this level, the fact that there are actually TWO 395 * registers (A and B - and B may not exist) is abstracted. 396 */ 397 ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n", 398 register_value)); 399 400 ACPI_REGISTER_INSERT_VALUE(register_value, 401 bit_reg_info->bit_position, 402 bit_reg_info->access_bit_mask, 403 value); 404 405 status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL, 406 (u16) register_value); 407 break; 408 409 case ACPI_REGISTER_PM2_CONTROL: 410 411 status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL, 412 &register_value); 413 if (ACPI_FAILURE(status)) { 414 goto unlock_and_exit; 415 } 416 417 ACPI_DEBUG_PRINT((ACPI_DB_IO, 418 "PM2 control: Read %X from %8.8X%8.8X\n", 419 register_value, 420 ACPI_FORMAT_UINT64(acpi_gbl_FADT. 421 xpm2_control_block. 422 address))); 423 424 ACPI_REGISTER_INSERT_VALUE(register_value, 425 bit_reg_info->bit_position, 426 bit_reg_info->access_bit_mask, 427 value); 428 429 ACPI_DEBUG_PRINT((ACPI_DB_IO, 430 "About to write %4.4X to %8.8X%8.8X\n", 431 register_value, 432 ACPI_FORMAT_UINT64(acpi_gbl_FADT. 433 xpm2_control_block. 434 address))); 435 436 status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL, 437 (u8) (register_value)); 438 break; 439 440 default: 441 break; 442 } 443 444 unlock_and_exit: 445 446 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); 447 448 /* Normalize the value that was read */ 449 450 ACPI_DEBUG_EXEC(register_value = 451 ((register_value & bit_reg_info->access_bit_mask) >> 452 bit_reg_info->bit_position)); 453 454 ACPI_DEBUG_PRINT((ACPI_DB_IO, 455 "Set bits: %8.8X actual %8.8X register %X\n", value, 456 register_value, bit_reg_info->parent_register)); 457 return_ACPI_STATUS(status); 458} 459 460ACPI_EXPORT_SYMBOL(acpi_set_register) 461 462/****************************************************************************** 463 * 464 * FUNCTION: acpi_hw_register_read 465 * 466 * PARAMETERS: register_id - ACPI Register ID 467 * return_value - Where the register value is returned 468 * 469 * RETURN: Status and the value read. 470 * 471 * DESCRIPTION: Read from the specified ACPI register 472 * 473 ******************************************************************************/ 474acpi_status 475acpi_hw_register_read(u32 register_id, u32 * return_value) 476{ 477 u32 value1 = 0; 478 u32 value2 = 0; 479 acpi_status status; 480 481 ACPI_FUNCTION_TRACE(hw_register_read); 482 483 switch (register_id) { 484 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 485 486 status = 487 acpi_hw_low_level_read(16, &value1, 488 &acpi_gbl_FADT.xpm1a_event_block); 489 if (ACPI_FAILURE(status)) { 490 goto exit; 491 } 492 493 /* PM1B is optional */ 494 495 status = 496 acpi_hw_low_level_read(16, &value2, 497 &acpi_gbl_FADT.xpm1b_event_block); 498 value1 |= value2; 499 break; 500 501 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ 502 503 status = 504 acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable); 505 if (ACPI_FAILURE(status)) { 506 goto exit; 507 } 508 509 /* PM1B is optional */ 510 511 status = 512 acpi_hw_low_level_read(16, &value2, &acpi_gbl_xpm1b_enable); 513 value1 |= value2; 514 break; 515 516 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ 517 518 status = 519 acpi_hw_low_level_read(16, &value1, 520 &acpi_gbl_FADT.xpm1a_control_block); 521 if (ACPI_FAILURE(status)) { 522 goto exit; 523 } 524 525 status = 526 acpi_hw_low_level_read(16, &value2, 527 &acpi_gbl_FADT.xpm1b_control_block); 528 value1 |= value2; 529 break; 530 531 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 532 533 status = 534 acpi_hw_low_level_read(8, &value1, 535 &acpi_gbl_FADT.xpm2_control_block); 536 break; 537 538 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 539 540 status = 541 acpi_hw_low_level_read(32, &value1, 542 &acpi_gbl_FADT.xpm_timer_block); 543 break; 544 545 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 546 547 status = 548 acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8); 549 break; 550 551 default: 552 ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id)); 553 status = AE_BAD_PARAMETER; 554 break; 555 } 556 557 exit: 558 559 if (ACPI_SUCCESS(status)) { 560 *return_value = value1; 561 } 562 563 return_ACPI_STATUS(status); 564} 565 566/****************************************************************************** 567 * 568 * FUNCTION: acpi_hw_register_write 569 * 570 * PARAMETERS: register_id - ACPI Register ID 571 * Value - The value to write 572 * 573 * RETURN: Status 574 * 575 * DESCRIPTION: Write to the specified ACPI register 576 * 577 * NOTE: In accordance with the ACPI specification, this function automatically 578 * preserves the value of the following bits, meaning that these bits cannot be 579 * changed via this interface: 580 * 581 * PM1_CONTROL[0] = SCI_EN 582 * PM1_CONTROL[9] 583 * PM1_STATUS[11] 584 * 585 * ACPI References: 586 * 1) Hardware Ignored Bits: When software writes to a register with ignored 587 * bit fields, it preserves the ignored bit fields 588 * 2) SCI_EN: OSPM always preserves this bit position 589 * 590 ******************************************************************************/ 591 592acpi_status acpi_hw_register_write(u32 register_id, u32 value) 593{ 594 acpi_status status; 595 u32 read_value; 596 597 ACPI_FUNCTION_TRACE(hw_register_write); 598 599 switch (register_id) { 600 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 601 602 /* Perform a read first to preserve certain bits (per ACPI spec) */ 603 604 status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, 605 &read_value); 606 if (ACPI_FAILURE(status)) { 607 goto exit; 608 } 609 610 /* Insert the bits to be preserved */ 611 612 ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS, 613 read_value); 614 615 /* Now we can write the data */ 616 617 status = 618 acpi_hw_low_level_write(16, value, 619 &acpi_gbl_FADT.xpm1a_event_block); 620 if (ACPI_FAILURE(status)) { 621 goto exit; 622 } 623 624 /* PM1B is optional */ 625 626 status = 627 acpi_hw_low_level_write(16, value, 628 &acpi_gbl_FADT.xpm1b_event_block); 629 break; 630 631 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ 632 633 status = 634 acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable); 635 if (ACPI_FAILURE(status)) { 636 goto exit; 637 } 638 639 /* PM1B is optional */ 640 641 status = 642 acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1b_enable); 643 break; 644 645 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ 646 647 /* 648 * Perform a read first to preserve certain bits (per ACPI spec) 649 */ 650 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, 651 &read_value); 652 if (ACPI_FAILURE(status)) { 653 goto exit; 654 } 655 656 /* Insert the bits to be preserved */ 657 658 ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS, 659 read_value); 660 661 /* Now we can write the data */ 662 663 status = 664 acpi_hw_low_level_write(16, value, 665 &acpi_gbl_FADT.xpm1a_control_block); 666 if (ACPI_FAILURE(status)) { 667 goto exit; 668 } 669 670 status = 671 acpi_hw_low_level_write(16, value, 672 &acpi_gbl_FADT.xpm1b_control_block); 673 break; 674 675 case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ 676 677 status = 678 acpi_hw_low_level_write(16, value, 679 &acpi_gbl_FADT.xpm1a_control_block); 680 break; 681 682 case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ 683 684 status = 685 acpi_hw_low_level_write(16, value, 686 &acpi_gbl_FADT.xpm1b_control_block); 687 break; 688 689 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 690 691 status = 692 acpi_hw_low_level_write(8, value, 693 &acpi_gbl_FADT.xpm2_control_block); 694 break; 695 696 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 697 698 status = 699 acpi_hw_low_level_write(32, value, 700 &acpi_gbl_FADT.xpm_timer_block); 701 break; 702 703 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 704 705 /* SMI_CMD is currently always in IO space */ 706 707 status = 708 acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8); 709 break; 710 711 default: 712 status = AE_BAD_PARAMETER; 713 break; 714 } 715 716 exit: 717 return_ACPI_STATUS(status); 718} 719 720/****************************************************************************** 721 * 722 * FUNCTION: acpi_hw_low_level_read 723 * 724 * PARAMETERS: Width - 8, 16, or 32 725 * Value - Where the value is returned 726 * Reg - GAS register structure 727 * 728 * RETURN: Status 729 * 730 * DESCRIPTION: Read from either memory or IO space. 731 * 732 ******************************************************************************/ 733 734acpi_status 735acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) 736{ 737 u64 address; 738 acpi_status status; 739 740 ACPI_FUNCTION_NAME(hw_low_level_read); 741 742 /* 743 * Must have a valid pointer to a GAS structure, and 744 * a non-zero address within. However, don't return an error 745 * because the PM1A/B code must not fail if B isn't present. 746 */ 747 if (!reg) { 748 return (AE_OK); 749 } 750 751 /* Get a local copy of the address. Handles possible alignment issues */ 752 753 ACPI_MOVE_64_TO_64(&address, &reg->address); 754 if (!address) { 755 return (AE_OK); 756 } 757 *value = 0; 758 759 /* 760 * Two address spaces supported: Memory or IO. 761 * PCI_Config is not supported here because the GAS struct is insufficient 762 */ 763 switch (reg->space_id) { 764 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 765 766 status = acpi_os_read_memory((acpi_physical_address) address, 767 value, width); 768 break; 769 770 case ACPI_ADR_SPACE_SYSTEM_IO: 771 772 status = 773 acpi_os_read_port((acpi_io_address) address, value, width); 774 break; 775 776 default: 777 ACPI_ERROR((AE_INFO, 778 "Unsupported address space: %X", reg->space_id)); 779 return (AE_BAD_PARAMETER); 780 } 781 782 ACPI_DEBUG_PRINT((ACPI_DB_IO, 783 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", 784 *value, width, ACPI_FORMAT_UINT64(address), 785 acpi_ut_get_region_name(reg->space_id))); 786 787 return (status); 788} 789 790/****************************************************************************** 791 * 792 * FUNCTION: acpi_hw_low_level_write 793 * 794 * PARAMETERS: Width - 8, 16, or 32 795 * Value - To be written 796 * Reg - GAS register structure 797 * 798 * RETURN: Status 799 * 800 * DESCRIPTION: Write to either memory or IO space. 801 * 802 ******************************************************************************/ 803 804acpi_status 805acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) 806{ 807 u64 address; 808 acpi_status status; 809 810 ACPI_FUNCTION_NAME(hw_low_level_write); 811 812 /* 813 * Must have a valid pointer to a GAS structure, and 814 * a non-zero address within. However, don't return an error 815 * because the PM1A/B code must not fail if B isn't present. 816 */ 817 if (!reg) { 818 return (AE_OK); 819 } 820 821 /* Get a local copy of the address. Handles possible alignment issues */ 822 823 ACPI_MOVE_64_TO_64(&address, &reg->address); 824 if (!address) { 825 return (AE_OK); 826 } 827 828 /* 829 * Two address spaces supported: Memory or IO. 830 * PCI_Config is not supported here because the GAS struct is insufficient 831 */ 832 switch (reg->space_id) { 833 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 834 835 status = acpi_os_write_memory((acpi_physical_address) address, 836 value, width); 837 break; 838 839 case ACPI_ADR_SPACE_SYSTEM_IO: 840 841 status = acpi_os_write_port((acpi_io_address) address, value, 842 width); 843 break; 844 845 default: 846 ACPI_ERROR((AE_INFO, 847 "Unsupported address space: %X", reg->space_id)); 848 return (AE_BAD_PARAMETER); 849 } 850 851 ACPI_DEBUG_PRINT((ACPI_DB_IO, 852 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", 853 value, width, ACPI_FORMAT_UINT64(address), 854 acpi_ut_get_region_name(reg->space_id))); 855 856 return (status); 857}