diff options
Diffstat (limited to 'drivers/acpi/hardware/hwregs.c')
| -rw-r--r-- | drivers/acpi/hardware/hwregs.c | 114 |
1 files changed, 68 insertions, 46 deletions
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c index 91af0c2ddcf7..6d9e4eb84836 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/hardware/hwregs.c | |||
| @@ -87,8 +87,9 @@ acpi_hw_clear_acpi_status ( | |||
| 87 | } | 87 | } |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, | 90 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, |
| 91 | ACPI_BITMASK_ALL_FIXED_STATUS); | 91 | ACPI_REGISTER_PM1_STATUS, |
| 92 | ACPI_BITMASK_ALL_FIXED_STATUS); | ||
| 92 | if (ACPI_FAILURE (status)) { | 93 | if (ACPI_FAILURE (status)) { |
| 93 | goto unlock_and_exit; | 94 | goto unlock_and_exit; |
| 94 | } | 95 | } |
| @@ -138,28 +139,30 @@ acpi_get_sleep_type_data ( | |||
| 138 | { | 139 | { |
| 139 | acpi_status status = AE_OK; | 140 | acpi_status status = AE_OK; |
| 140 | struct acpi_parameter_info info; | 141 | struct acpi_parameter_info info; |
| 142 | char *sleep_state_name; | ||
| 141 | 143 | ||
| 142 | 144 | ||
| 143 | ACPI_FUNCTION_TRACE ("acpi_get_sleep_type_data"); | 145 | ACPI_FUNCTION_TRACE ("acpi_get_sleep_type_data"); |
| 144 | 146 | ||
| 145 | 147 | ||
| 146 | /* | 148 | /* Validate parameters */ |
| 147 | * Validate parameters | 149 | |
| 148 | */ | ||
| 149 | if ((sleep_state > ACPI_S_STATES_MAX) || | 150 | if ((sleep_state > ACPI_S_STATES_MAX) || |
| 150 | !sleep_type_a || !sleep_type_b) { | 151 | !sleep_type_a || !sleep_type_b) { |
| 151 | return_ACPI_STATUS (AE_BAD_PARAMETER); | 152 | return_ACPI_STATUS (AE_BAD_PARAMETER); |
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | /* | 155 | /* Evaluate the namespace object containing the values for this state */ |
| 155 | * Evaluate the namespace object containing the values for this state | 156 | |
| 156 | */ | ||
| 157 | info.parameters = NULL; | 157 | info.parameters = NULL; |
| 158 | status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_sleep_state_names[sleep_state], | 158 | info.return_object = NULL; |
| 159 | &info); | 159 | sleep_state_name = (char *) acpi_gbl_sleep_state_names[sleep_state]; |
| 160 | |||
| 161 | status = acpi_ns_evaluate_by_name (sleep_state_name, &info); | ||
| 160 | if (ACPI_FAILURE (status)) { | 162 | if (ACPI_FAILURE (status)) { |
| 161 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n", | 163 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, |
| 162 | acpi_format_exception (status), acpi_gbl_sleep_state_names[sleep_state])); | 164 | "%s while evaluating sleep_state [%s]\n", |
| 165 | acpi_format_exception (status), sleep_state_name)); | ||
| 163 | 166 | ||
| 164 | return_ACPI_STATUS (status); | 167 | return_ACPI_STATUS (status); |
| 165 | } | 168 | } |
| @@ -167,45 +170,57 @@ acpi_get_sleep_type_data ( | |||
| 167 | /* Must have a return object */ | 170 | /* Must have a return object */ |
| 168 | 171 | ||
| 169 | if (!info.return_object) { | 172 | if (!info.return_object) { |
| 170 | ACPI_REPORT_ERROR (("Missing Sleep State object\n")); | 173 | ACPI_REPORT_ERROR (("No Sleep State object returned from [%s]\n", |
| 174 | sleep_state_name)); | ||
| 171 | status = AE_NOT_EXIST; | 175 | status = AE_NOT_EXIST; |
| 172 | } | 176 | } |
| 173 | 177 | ||
| 174 | /* It must be of type Package */ | 178 | /* It must be of type Package */ |
| 175 | 179 | ||
| 176 | else if (ACPI_GET_OBJECT_TYPE (info.return_object) != ACPI_TYPE_PACKAGE) { | 180 | else if (ACPI_GET_OBJECT_TYPE (info.return_object) != ACPI_TYPE_PACKAGE) { |
| 177 | ACPI_REPORT_ERROR (("Sleep State object not a Package\n")); | 181 | ACPI_REPORT_ERROR (("Sleep State return object is not a Package\n")); |
| 178 | status = AE_AML_OPERAND_TYPE; | 182 | status = AE_AML_OPERAND_TYPE; |
| 179 | } | 183 | } |
| 180 | 184 | ||
| 181 | /* The package must have at least two elements */ | 185 | /* |
| 182 | 186 | * The package must have at least two elements. NOTE (March 2005): This | |
| 187 | * goes against the current ACPI spec which defines this object as a | ||
| 188 | * package with one encoded DWORD element. However, existing practice | ||
| 189 | * by BIOS vendors seems to be to have 2 or more elements, at least | ||
| 190 | * one per sleep type (A/B). | ||
| 191 | */ | ||
| 183 | else if (info.return_object->package.count < 2) { | 192 | else if (info.return_object->package.count < 2) { |
| 184 | ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n")); | 193 | ACPI_REPORT_ERROR (( |
| 194 | "Sleep State return package does not have at least two elements\n")); | ||
| 185 | status = AE_AML_NO_OPERAND; | 195 | status = AE_AML_NO_OPERAND; |
| 186 | } | 196 | } |
| 187 | 197 | ||
| 188 | /* The first two elements must both be of type Integer */ | 198 | /* The first two elements must both be of type Integer */ |
| 189 | 199 | ||
| 190 | else if ((ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[0]) != ACPI_TYPE_INTEGER) || | 200 | else if ((ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[0]) |
| 191 | (ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[1]) != ACPI_TYPE_INTEGER)) { | 201 | != ACPI_TYPE_INTEGER) || |
| 192 | ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n", | 202 | (ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[1]) |
| 203 | != ACPI_TYPE_INTEGER)) { | ||
| 204 | ACPI_REPORT_ERROR (( | ||
| 205 | "Sleep State return package elements are not both Integers (%s, %s)\n", | ||
| 193 | acpi_ut_get_object_type_name (info.return_object->package.elements[0]), | 206 | acpi_ut_get_object_type_name (info.return_object->package.elements[0]), |
| 194 | acpi_ut_get_object_type_name (info.return_object->package.elements[1]))); | 207 | acpi_ut_get_object_type_name (info.return_object->package.elements[1]))); |
| 195 | status = AE_AML_OPERAND_TYPE; | 208 | status = AE_AML_OPERAND_TYPE; |
| 196 | } | 209 | } |
| 197 | else { | 210 | else { |
| 198 | /* | 211 | /* Valid _Sx_ package size, type, and value */ |
| 199 | * Valid _Sx_ package size, type, and value | 212 | |
| 200 | */ | 213 | *sleep_type_a = (u8) |
| 201 | *sleep_type_a = (u8) (info.return_object->package.elements[0])->integer.value; | 214 | (info.return_object->package.elements[0])->integer.value; |
| 202 | *sleep_type_b = (u8) (info.return_object->package.elements[1])->integer.value; | 215 | *sleep_type_b = (u8) |
| 216 | (info.return_object->package.elements[1])->integer.value; | ||
| 203 | } | 217 | } |
| 204 | 218 | ||
| 205 | if (ACPI_FAILURE (status)) { | 219 | if (ACPI_FAILURE (status)) { |
| 206 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | 220 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, |
| 207 | "While evaluating sleep_state [%s], bad Sleep object %p type %s\n", | 221 | "%s While evaluating sleep_state [%s], bad Sleep object %p type %s\n", |
| 208 | acpi_gbl_sleep_state_names[sleep_state], info.return_object, | 222 | acpi_format_exception (status), |
| 223 | sleep_state_name, info.return_object, | ||
| 209 | acpi_ut_get_object_type_name (info.return_object))); | 224 | acpi_ut_get_object_type_name (info.return_object))); |
| 210 | } | 225 | } |
| 211 | 226 | ||
| @@ -221,9 +236,9 @@ EXPORT_SYMBOL(acpi_get_sleep_type_data); | |||
| 221 | * | 236 | * |
| 222 | * PARAMETERS: register_id - Index of ACPI Register to access | 237 | * PARAMETERS: register_id - Index of ACPI Register to access |
| 223 | * | 238 | * |
| 224 | * RETURN: The bit mask to be used when accessing the register | 239 | * RETURN: The bitmask to be used when accessing the register |
| 225 | * | 240 | * |
| 226 | * DESCRIPTION: Map register_id into a register bit mask. | 241 | * DESCRIPTION: Map register_id into a register bitmask. |
| 227 | * | 242 | * |
| 228 | ******************************************************************************/ | 243 | ******************************************************************************/ |
| 229 | 244 | ||
| @@ -359,7 +374,7 @@ acpi_set_register ( | |||
| 359 | /* Always do a register read first so we can insert the new bits */ | 374 | /* Always do a register read first so we can insert the new bits */ |
| 360 | 375 | ||
| 361 | status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, | 376 | status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, |
| 362 | bit_reg_info->parent_register, ®ister_value); | 377 | bit_reg_info->parent_register, ®ister_value); |
| 363 | if (ACPI_FAILURE (status)) { | 378 | if (ACPI_FAILURE (status)) { |
| 364 | goto unlock_and_exit; | 379 | goto unlock_and_exit; |
| 365 | } | 380 | } |
| @@ -396,7 +411,7 @@ acpi_set_register ( | |||
| 396 | bit_reg_info->access_bit_mask, value); | 411 | bit_reg_info->access_bit_mask, value); |
| 397 | 412 | ||
| 398 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, | 413 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, |
| 399 | ACPI_REGISTER_PM1_ENABLE, (u16) register_value); | 414 | ACPI_REGISTER_PM1_ENABLE, (u16) register_value); |
| 400 | break; | 415 | break; |
| 401 | 416 | ||
| 402 | 417 | ||
| @@ -413,7 +428,7 @@ acpi_set_register ( | |||
| 413 | bit_reg_info->access_bit_mask, value); | 428 | bit_reg_info->access_bit_mask, value); |
| 414 | 429 | ||
| 415 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, | 430 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, |
| 416 | ACPI_REGISTER_PM1_CONTROL, (u16) register_value); | 431 | ACPI_REGISTER_PM1_CONTROL, (u16) register_value); |
| 417 | break; | 432 | break; |
| 418 | 433 | ||
| 419 | 434 | ||
| @@ -427,17 +442,19 @@ acpi_set_register ( | |||
| 427 | 442 | ||
| 428 | ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n", | 443 | ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n", |
| 429 | register_value, | 444 | register_value, |
| 430 | ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address))); | 445 | ACPI_FORMAT_UINT64 ( |
| 446 | acpi_gbl_FADT->xpm2_cnt_blk.address))); | ||
| 431 | 447 | ||
| 432 | ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position, | 448 | ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position, |
| 433 | bit_reg_info->access_bit_mask, value); | 449 | bit_reg_info->access_bit_mask, value); |
| 434 | 450 | ||
| 435 | ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n", | 451 | ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n", |
| 436 | register_value, | 452 | register_value, |
| 437 | ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address))); | 453 | ACPI_FORMAT_UINT64 ( |
| 454 | acpi_gbl_FADT->xpm2_cnt_blk.address))); | ||
| 438 | 455 | ||
| 439 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, | 456 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, |
| 440 | ACPI_REGISTER_PM2_CONTROL, (u8) (register_value)); | 457 | ACPI_REGISTER_PM2_CONTROL, (u8) (register_value)); |
| 441 | break; | 458 | break; |
| 442 | 459 | ||
| 443 | 460 | ||
| @@ -454,7 +471,9 @@ unlock_and_exit: | |||
| 454 | 471 | ||
| 455 | /* Normalize the value that was read */ | 472 | /* Normalize the value that was read */ |
| 456 | 473 | ||
| 457 | ACPI_DEBUG_EXEC (register_value = ((register_value & bit_reg_info->access_bit_mask) >> bit_reg_info->bit_position)); | 474 | ACPI_DEBUG_EXEC (register_value = |
| 475 | ((register_value & bit_reg_info->access_bit_mask) >> | ||
| 476 | bit_reg_info->bit_position)); | ||
| 458 | 477 | ||
| 459 | ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Set bits: %8.8X actual %8.8X register %X\n", | 478 | ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Set bits: %8.8X actual %8.8X register %X\n", |
| 460 | value, register_value, bit_reg_info->parent_register)); | 479 | value, register_value, bit_reg_info->parent_register)); |
| @@ -469,7 +488,7 @@ EXPORT_SYMBOL(acpi_set_register); | |||
| 469 | * | 488 | * |
| 470 | * PARAMETERS: use_lock - Mutex hw access | 489 | * PARAMETERS: use_lock - Mutex hw access |
| 471 | * register_id - register_iD + Offset | 490 | * register_id - register_iD + Offset |
| 472 | * return_value - Value that was read from the register | 491 | * return_value - Where the register value is returned |
| 473 | * | 492 | * |
| 474 | * RETURN: Status and the value read. | 493 | * RETURN: Status and the value read. |
| 475 | * | 494 | * |
| @@ -557,7 +576,8 @@ acpi_hw_register_read ( | |||
| 557 | break; | 576 | break; |
| 558 | 577 | ||
| 559 | default: | 578 | default: |
| 560 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n", register_id)); | 579 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n", |
| 580 | register_id)); | ||
| 561 | status = AE_BAD_PARAMETER; | 581 | status = AE_BAD_PARAMETER; |
| 562 | break; | 582 | break; |
| 563 | } | 583 | } |
| @@ -763,10 +783,11 @@ acpi_hw_low_level_read ( | |||
| 763 | return (AE_BAD_PARAMETER); | 783 | return (AE_BAD_PARAMETER); |
| 764 | } | 784 | } |
| 765 | 785 | ||
| 766 | ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", | 786 | ACPI_DEBUG_PRINT ((ACPI_DB_IO, |
| 767 | *value, width, | 787 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", |
| 768 | ACPI_FORMAT_UINT64 (address), | 788 | *value, width, |
| 769 | acpi_ut_get_region_name (reg->address_space_id))); | 789 | ACPI_FORMAT_UINT64 (address), |
| 790 | acpi_ut_get_region_name (reg->address_space_id))); | ||
| 770 | 791 | ||
| 771 | return (status); | 792 | return (status); |
| 772 | } | 793 | } |
| @@ -841,10 +862,11 @@ acpi_hw_low_level_write ( | |||
| 841 | return (AE_BAD_PARAMETER); | 862 | return (AE_BAD_PARAMETER); |
| 842 | } | 863 | } |
| 843 | 864 | ||
| 844 | ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", | 865 | ACPI_DEBUG_PRINT ((ACPI_DB_IO, |
| 845 | value, width, | 866 | "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", |
| 846 | ACPI_FORMAT_UINT64 (address), | 867 | value, width, |
| 847 | acpi_ut_get_region_name (reg->address_space_id))); | 868 | ACPI_FORMAT_UINT64 (address), |
| 869 | acpi_ut_get_region_name (reg->address_space_id))); | ||
| 848 | 870 | ||
| 849 | return (status); | 871 | return (status); |
| 850 | } | 872 | } |
