root/drivers/acpi/acpica/hwxface.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. ACPI_EXPORT_SYMBOL
  3. ACPI_EXPORT_SYMBOL
  4. ACPI_EXPORT_SYMBOL
  5. ACPI_EXPORT_SYMBOL
  6. ACPI_EXPORT_SYMBOL

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: hwxface - Public ACPICA hardware interfaces
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #define EXPORT_ACPI_INTERFACES
  11 
  12 #include <acpi/acpi.h>
  13 #include "accommon.h"
  14 #include "acnamesp.h"
  15 
  16 #define _COMPONENT          ACPI_HARDWARE
  17 ACPI_MODULE_NAME("hwxface")
  18 
  19 /******************************************************************************
  20  *
  21  * FUNCTION:    acpi_reset
  22  *
  23  * PARAMETERS:  None
  24  *
  25  * RETURN:      Status
  26  *
  27  * DESCRIPTION: Set reset register in memory or IO space. Note: Does not
  28  *              support reset register in PCI config space, this must be
  29  *              handled separately.
  30  *
  31  ******************************************************************************/
  32 acpi_status acpi_reset(void)
  33 {
  34         struct acpi_generic_address *reset_reg;
  35         acpi_status status;
  36 
  37         ACPI_FUNCTION_TRACE(acpi_reset);
  38 
  39         reset_reg = &acpi_gbl_FADT.reset_register;
  40 
  41         /* Check if the reset register is supported */
  42 
  43         if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
  44             !reset_reg->address) {
  45                 return_ACPI_STATUS(AE_NOT_EXIST);
  46         }
  47 
  48         if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
  49                 /*
  50                  * For I/O space, write directly to the OSL. This bypasses the port
  51                  * validation mechanism, which may block a valid write to the reset
  52                  * register.
  53                  *
  54                  * NOTE:
  55                  * The ACPI spec requires the reset register width to be 8, so we
  56                  * hardcode it here and ignore the FADT value. This maintains
  57                  * compatibility with other ACPI implementations that have allowed
  58                  * BIOS code with bad register width values to go unnoticed.
  59                  */
  60                 status = acpi_os_write_port((acpi_io_address)reset_reg->address,
  61                                             acpi_gbl_FADT.reset_value,
  62                                             ACPI_RESET_REGISTER_WIDTH);
  63         } else {
  64                 /* Write the reset value to the reset register */
  65 
  66                 status = acpi_hw_write(acpi_gbl_FADT.reset_value, reset_reg);
  67         }
  68 
  69         return_ACPI_STATUS(status);
  70 }
  71 
  72 ACPI_EXPORT_SYMBOL(acpi_reset)
  73 
  74 /******************************************************************************
  75  *
  76  * FUNCTION:    acpi_read
  77  *
  78  * PARAMETERS:  value               - Where the value is returned
  79  *              reg                 - GAS register structure
  80  *
  81  * RETURN:      Status
  82  *
  83  * DESCRIPTION: Read from either memory or IO space.
  84  *
  85  * LIMITATIONS: <These limitations also apply to acpi_write>
  86  *      bit_width must be exactly 8, 16, 32, or 64.
  87  *      space_ID must be system_memory or system_IO.
  88  *      bit_offset and access_width are currently ignored, as there has
  89  *          not been a need to implement these.
  90  *
  91  ******************************************************************************/
  92 acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
  93 {
  94         acpi_status status;
  95 
  96         ACPI_FUNCTION_NAME(acpi_read);
  97 
  98         status = acpi_hw_read(return_value, reg);
  99         return (status);
 100 }
 101 
 102 ACPI_EXPORT_SYMBOL(acpi_read)
 103 
 104 /******************************************************************************
 105  *
 106  * FUNCTION:    acpi_write
 107  *
 108  * PARAMETERS:  value               - Value to be written
 109  *              reg                 - GAS register structure
 110  *
 111  * RETURN:      Status
 112  *
 113  * DESCRIPTION: Write to either memory or IO space.
 114  *
 115  ******************************************************************************/
 116 acpi_status acpi_write(u64 value, struct acpi_generic_address *reg)
 117 {
 118         acpi_status status;
 119 
 120         ACPI_FUNCTION_NAME(acpi_write);
 121 
 122         status = acpi_hw_write(value, reg);
 123         return (status);
 124 }
 125 
 126 ACPI_EXPORT_SYMBOL(acpi_write)
 127 
 128 #if (!ACPI_REDUCED_HARDWARE)
 129 /*******************************************************************************
 130  *
 131  * FUNCTION:    acpi_read_bit_register
 132  *
 133  * PARAMETERS:  register_id     - ID of ACPI Bit Register to access
 134  *              return_value    - Value that was read from the register,
 135  *                                normalized to bit position zero.
 136  *
 137  * RETURN:      Status and the value read from the specified Register. Value
 138  *              returned is normalized to bit0 (is shifted all the way right)
 139  *
 140  * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock.
 141  *
 142  * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
 143  *              PM2 Control.
 144  *
 145  * Note: The hardware lock is not required when reading the ACPI bit registers
 146  *       since almost all of them are single bit and it does not matter that
 147  *       the parent hardware register can be split across two physical
 148  *       registers. The only multi-bit field is SLP_TYP in the PM1 control
 149  *       register, but this field does not cross an 8-bit boundary (nor does
 150  *       it make much sense to actually read this field.)
 151  *
 152  ******************************************************************************/
 153 acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value)
 154 {
 155         struct acpi_bit_register_info *bit_reg_info;
 156         u32 register_value;
 157         u32 value;
 158         acpi_status status;
 159 
 160         ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id);
 161 
 162         /* Get the info structure corresponding to the requested ACPI Register */
 163 
 164         bit_reg_info = acpi_hw_get_bit_register_info(register_id);
 165         if (!bit_reg_info) {
 166                 return_ACPI_STATUS(AE_BAD_PARAMETER);
 167         }
 168 
 169         /* Read the entire parent register */
 170 
 171         status = acpi_hw_register_read(bit_reg_info->parent_register,
 172                                        &register_value);
 173         if (ACPI_FAILURE(status)) {
 174                 return_ACPI_STATUS(status);
 175         }
 176 
 177         /* Normalize the value that was read, mask off other bits */
 178 
 179         value = ((register_value & bit_reg_info->access_bit_mask)
 180                  >> bit_reg_info->bit_position);
 181 
 182         ACPI_DEBUG_PRINT((ACPI_DB_IO,
 183                           "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
 184                           register_id, bit_reg_info->parent_register,
 185                           register_value, value));
 186 
 187         *return_value = value;
 188         return_ACPI_STATUS(AE_OK);
 189 }
 190 
 191 ACPI_EXPORT_SYMBOL(acpi_read_bit_register)
 192 
 193 /*******************************************************************************
 194  *
 195  * FUNCTION:    acpi_write_bit_register
 196  *
 197  * PARAMETERS:  register_id     - ID of ACPI Bit Register to access
 198  *              value           - Value to write to the register, in bit
 199  *                                position zero. The bit is automatically
 200  *                                shifted to the correct position.
 201  *
 202  * RETURN:      Status
 203  *
 204  * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
 205  *              since most operations require a read/modify/write sequence.
 206  *
 207  * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
 208  *              PM2 Control.
 209  *
 210  * Note that at this level, the fact that there may be actually two
 211  * hardware registers (A and B - and B may not exist) is abstracted.
 212  *
 213  ******************************************************************************/
 214 acpi_status acpi_write_bit_register(u32 register_id, u32 value)
 215 {
 216         struct acpi_bit_register_info *bit_reg_info;
 217         acpi_cpu_flags lock_flags;
 218         u32 register_value;
 219         acpi_status status = AE_OK;
 220 
 221         ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id);
 222 
 223         /* Get the info structure corresponding to the requested ACPI Register */
 224 
 225         bit_reg_info = acpi_hw_get_bit_register_info(register_id);
 226         if (!bit_reg_info) {
 227                 return_ACPI_STATUS(AE_BAD_PARAMETER);
 228         }
 229 
 230         lock_flags = acpi_os_acquire_raw_lock(acpi_gbl_hardware_lock);
 231 
 232         /*
 233          * At this point, we know that the parent register is one of the
 234          * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
 235          */
 236         if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) {
 237                 /*
 238                  * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
 239                  *
 240                  * Perform a register read to preserve the bits that we are not
 241                  * interested in
 242                  */
 243                 status = acpi_hw_register_read(bit_reg_info->parent_register,
 244                                                &register_value);
 245                 if (ACPI_FAILURE(status)) {
 246                         goto unlock_and_exit;
 247                 }
 248 
 249                 /*
 250                  * Insert the input bit into the value that was just read
 251                  * and write the register
 252                  */
 253                 ACPI_REGISTER_INSERT_VALUE(register_value,
 254                                            bit_reg_info->bit_position,
 255                                            bit_reg_info->access_bit_mask,
 256                                            value);
 257 
 258                 status = acpi_hw_register_write(bit_reg_info->parent_register,
 259                                                 register_value);
 260         } else {
 261                 /*
 262                  * 2) Case for PM1 Status
 263                  *
 264                  * The Status register is different from the rest. Clear an event
 265                  * by writing 1, writing 0 has no effect. So, the only relevant
 266                  * information is the single bit we're interested in, all others
 267                  * should be written as 0 so they will be left unchanged.
 268                  */
 269                 register_value = ACPI_REGISTER_PREPARE_BITS(value,
 270                                                             bit_reg_info->
 271                                                             bit_position,
 272                                                             bit_reg_info->
 273                                                             access_bit_mask);
 274 
 275                 /* No need to write the register if value is all zeros */
 276 
 277                 if (register_value) {
 278                         status =
 279                             acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
 280                                                    register_value);
 281                 }
 282         }
 283 
 284         ACPI_DEBUG_PRINT((ACPI_DB_IO,
 285                           "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
 286                           register_id, bit_reg_info->parent_register, value,
 287                           register_value));
 288 
 289 unlock_and_exit:
 290 
 291         acpi_os_release_raw_lock(acpi_gbl_hardware_lock, lock_flags);
 292         return_ACPI_STATUS(status);
 293 }
 294 
 295 ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
 296 #endif                          /* !ACPI_REDUCED_HARDWARE */
 297 /*******************************************************************************
 298  *
 299  * FUNCTION:    acpi_get_sleep_type_data
 300  *
 301  * PARAMETERS:  sleep_state         - Numeric sleep state
 302  *              *sleep_type_a        - Where SLP_TYPa is returned
 303  *              *sleep_type_b        - Where SLP_TYPb is returned
 304  *
 305  * RETURN:      Status
 306  *
 307  * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested
 308  *              sleep state via the appropriate \_Sx object.
 309  *
 310  *  The sleep state package returned from the corresponding \_Sx_ object
 311  *  must contain at least one integer.
 312  *
 313  *  March 2005:
 314  *  Added support for a package that contains two integers. This
 315  *  goes against the ACPI specification which defines this object as a
 316  *  package with one encoded DWORD integer. However, existing practice
 317  *  by many BIOS vendors is to return a package with 2 or more integer
 318  *  elements, at least one per sleep type (A/B).
 319  *
 320  *  January 2013:
 321  *  Therefore, we must be prepared to accept a package with either a
 322  *  single integer or multiple integers.
 323  *
 324  *  The single integer DWORD format is as follows:
 325  *      BYTE 0 - Value for the PM1A SLP_TYP register
 326  *      BYTE 1 - Value for the PM1B SLP_TYP register
 327  *      BYTE 2-3 - Reserved
 328  *
 329  *  The dual integer format is as follows:
 330  *      Integer 0 - Value for the PM1A SLP_TYP register
 331  *      Integer 1 - Value for the PM1A SLP_TYP register
 332  *
 333  ******************************************************************************/
 334 acpi_status
 335 acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
 336 {
 337         acpi_status status;
 338         struct acpi_evaluate_info *info;
 339         union acpi_operand_object **elements;
 340 
 341         ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data);
 342 
 343         /* Validate parameters */
 344 
 345         if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) {
 346                 return_ACPI_STATUS(AE_BAD_PARAMETER);
 347         }
 348 
 349         /* Allocate the evaluation information block */
 350 
 351         info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
 352         if (!info) {
 353                 return_ACPI_STATUS(AE_NO_MEMORY);
 354         }
 355 
 356         /*
 357          * Evaluate the \_Sx namespace object containing the register values
 358          * for this state
 359          */
 360         info->relative_pathname = acpi_gbl_sleep_state_names[sleep_state];
 361 
 362         status = acpi_ns_evaluate(info);
 363         if (ACPI_FAILURE(status)) {
 364                 if (status == AE_NOT_FOUND) {
 365 
 366                         /* The _Sx states are optional, ignore NOT_FOUND */
 367 
 368                         goto final_cleanup;
 369                 }
 370 
 371                 goto warning_cleanup;
 372         }
 373 
 374         /* Must have a return object */
 375 
 376         if (!info->return_object) {
 377                 ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
 378                             info->relative_pathname));
 379                 status = AE_AML_NO_RETURN_VALUE;
 380                 goto warning_cleanup;
 381         }
 382 
 383         /* Return object must be of type Package */
 384 
 385         if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
 386                 ACPI_ERROR((AE_INFO,
 387                             "Sleep State return object is not a Package"));
 388                 status = AE_AML_OPERAND_TYPE;
 389                 goto return_value_cleanup;
 390         }
 391 
 392         /*
 393          * Any warnings about the package length or the object types have
 394          * already been issued by the predefined name module -- there is no
 395          * need to repeat them here.
 396          */
 397         elements = info->return_object->package.elements;
 398         switch (info->return_object->package.count) {
 399         case 0:
 400 
 401                 status = AE_AML_PACKAGE_LIMIT;
 402                 break;
 403 
 404         case 1:
 405 
 406                 if (elements[0]->common.type != ACPI_TYPE_INTEGER) {
 407                         status = AE_AML_OPERAND_TYPE;
 408                         break;
 409                 }
 410 
 411                 /* A valid _Sx_ package with one integer */
 412 
 413                 *sleep_type_a = (u8)elements[0]->integer.value;
 414                 *sleep_type_b = (u8)(elements[0]->integer.value >> 8);
 415                 break;
 416 
 417         case 2:
 418         default:
 419 
 420                 if ((elements[0]->common.type != ACPI_TYPE_INTEGER) ||
 421                     (elements[1]->common.type != ACPI_TYPE_INTEGER)) {
 422                         status = AE_AML_OPERAND_TYPE;
 423                         break;
 424                 }
 425 
 426                 /* A valid _Sx_ package with two integers */
 427 
 428                 *sleep_type_a = (u8)elements[0]->integer.value;
 429                 *sleep_type_b = (u8)elements[1]->integer.value;
 430                 break;
 431         }
 432 
 433 return_value_cleanup:
 434         acpi_ut_remove_reference(info->return_object);
 435 
 436 warning_cleanup:
 437         if (ACPI_FAILURE(status)) {
 438                 ACPI_EXCEPTION((AE_INFO, status,
 439                                 "While evaluating Sleep State [%s]",
 440                                 info->relative_pathname));
 441         }
 442 
 443 final_cleanup:
 444         ACPI_FREE(info);
 445         return_ACPI_STATUS(status);
 446 }
 447 
 448 ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data)

/* [<][>][^][v][top][bottom][index][help] */