linux/drivers/acpi/acpica/hwregs.c
<<
>>
Prefs
   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 - 2011, 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 "accommon.h"
  48#include "acnamesp.h"
  49#include "acevents.h"
  50
  51#define _COMPONENT          ACPI_HARDWARE
  52ACPI_MODULE_NAME("hwregs")
  53
  54/* Local Prototypes */
  55static acpi_status
  56acpi_hw_read_multiple(u32 *value,
  57                      struct acpi_generic_address *register_a,
  58                      struct acpi_generic_address *register_b);
  59
  60static acpi_status
  61acpi_hw_write_multiple(u32 value,
  62                       struct acpi_generic_address *register_a,
  63                       struct acpi_generic_address *register_b);
  64
  65/******************************************************************************
  66 *
  67 * FUNCTION:    acpi_hw_validate_register
  68 *
  69 * PARAMETERS:  Reg                 - GAS register structure
  70 *              max_bit_width       - Max bit_width supported (32 or 64)
  71 *              Address             - Pointer to where the gas->address
  72 *                                    is returned
  73 *
  74 * RETURN:      Status
  75 *
  76 * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS
  77 *              pointer, Address, space_id, bit_width, and bit_offset.
  78 *
  79 ******************************************************************************/
  80
  81acpi_status
  82acpi_hw_validate_register(struct acpi_generic_address *reg,
  83                          u8 max_bit_width, u64 *address)
  84{
  85
  86        /* Must have a valid pointer to a GAS structure */
  87
  88        if (!reg) {
  89                return (AE_BAD_PARAMETER);
  90        }
  91
  92        /*
  93         * Copy the target address. This handles possible alignment issues.
  94         * Address must not be null. A null address also indicates an optional
  95         * ACPI register that is not supported, so no error message.
  96         */
  97        ACPI_MOVE_64_TO_64(address, &reg->address);
  98        if (!(*address)) {
  99                return (AE_BAD_ADDRESS);
 100        }
 101
 102        /* Validate the space_iD */
 103
 104        if ((reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
 105            (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
 106                ACPI_ERROR((AE_INFO,
 107                            "Unsupported address space: 0x%X", reg->space_id));
 108                return (AE_SUPPORT);
 109        }
 110
 111        /* Validate the bit_width */
 112
 113        if ((reg->bit_width != 8) &&
 114            (reg->bit_width != 16) &&
 115            (reg->bit_width != 32) && (reg->bit_width != max_bit_width)) {
 116                ACPI_ERROR((AE_INFO,
 117                            "Unsupported register bit width: 0x%X",
 118                            reg->bit_width));
 119                return (AE_SUPPORT);
 120        }
 121
 122        /* Validate the bit_offset. Just a warning for now. */
 123
 124        if (reg->bit_offset != 0) {
 125                ACPI_WARNING((AE_INFO,
 126                              "Unsupported register bit offset: 0x%X",
 127                              reg->bit_offset));
 128        }
 129
 130        return (AE_OK);
 131}
 132
 133/******************************************************************************
 134 *
 135 * FUNCTION:    acpi_hw_read
 136 *
 137 * PARAMETERS:  Value               - Where the value is returned
 138 *              Reg                 - GAS register structure
 139 *
 140 * RETURN:      Status
 141 *
 142 * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max
 143 *              version of acpi_read, used internally since the overhead of
 144 *              64-bit values is not needed.
 145 *
 146 * LIMITATIONS: <These limitations also apply to acpi_hw_write>
 147 *      bit_width must be exactly 8, 16, or 32.
 148 *      space_iD must be system_memory or system_iO.
 149 *      bit_offset and access_width are currently ignored, as there has
 150 *          not been a need to implement these.
 151 *
 152 ******************************************************************************/
 153
 154acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
 155{
 156        u64 address;
 157        acpi_status status;
 158
 159        ACPI_FUNCTION_NAME(hw_read);
 160
 161        /* Validate contents of the GAS register */
 162
 163        status = acpi_hw_validate_register(reg, 32, &address);
 164        if (ACPI_FAILURE(status)) {
 165                return (status);
 166        }
 167
 168        /* Initialize entire 32-bit return value to zero */
 169
 170        *value = 0;
 171
 172        /*
 173         * Two address spaces supported: Memory or IO. PCI_Config is
 174         * not supported here because the GAS structure is insufficient
 175         */
 176        if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
 177                status = acpi_os_read_memory((acpi_physical_address)
 178                                             address, value, reg->bit_width);
 179        } else {                /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
 180
 181                status = acpi_hw_read_port((acpi_io_address)
 182                                           address, value, reg->bit_width);
 183        }
 184
 185        ACPI_DEBUG_PRINT((ACPI_DB_IO,
 186                          "Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
 187                          *value, reg->bit_width, ACPI_FORMAT_UINT64(address),
 188                          acpi_ut_get_region_name(reg->space_id)));
 189
 190        return (status);
 191}
 192
 193/******************************************************************************
 194 *
 195 * FUNCTION:    acpi_hw_write
 196 *
 197 * PARAMETERS:  Value               - Value to be written
 198 *              Reg                 - GAS register structure
 199 *
 200 * RETURN:      Status
 201 *
 202 * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max
 203 *              version of acpi_write, used internally since the overhead of
 204 *              64-bit values is not needed.
 205 *
 206 ******************************************************************************/
 207
 208acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
 209{
 210        u64 address;
 211        acpi_status status;
 212
 213        ACPI_FUNCTION_NAME(hw_write);
 214
 215        /* Validate contents of the GAS register */
 216
 217        status = acpi_hw_validate_register(reg, 32, &address);
 218        if (ACPI_FAILURE(status)) {
 219                return (status);
 220        }
 221
 222        /*
 223         * Two address spaces supported: Memory or IO. PCI_Config is
 224         * not supported here because the GAS structure is insufficient
 225         */
 226        if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
 227                status = acpi_os_write_memory((acpi_physical_address)
 228                                              address, value, reg->bit_width);
 229        } else {                /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
 230
 231                status = acpi_hw_write_port((acpi_io_address)
 232                                            address, value, reg->bit_width);
 233        }
 234
 235        ACPI_DEBUG_PRINT((ACPI_DB_IO,
 236                          "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
 237                          value, reg->bit_width, ACPI_FORMAT_UINT64(address),
 238                          acpi_ut_get_region_name(reg->space_id)));
 239
 240        return (status);
 241}
 242
 243/*******************************************************************************
 244 *
 245 * FUNCTION:    acpi_hw_clear_acpi_status
 246 *
 247 * PARAMETERS:  None
 248 *
 249 * RETURN:      Status
 250 *
 251 * DESCRIPTION: Clears all fixed and general purpose status bits
 252 *
 253 ******************************************************************************/
 254
 255acpi_status acpi_hw_clear_acpi_status(void)
 256{
 257        acpi_status status;
 258        acpi_cpu_flags lock_flags = 0;
 259
 260        ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
 261
 262        ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
 263                          ACPI_BITMASK_ALL_FIXED_STATUS,
 264                          ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address)));
 265
 266        lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
 267
 268        /* Clear the fixed events in PM1 A/B */
 269
 270        status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
 271                                        ACPI_BITMASK_ALL_FIXED_STATUS);
 272        if (ACPI_FAILURE(status)) {
 273                goto unlock_and_exit;
 274        }
 275
 276        /* Clear the GPE Bits in all GPE registers in all GPE blocks */
 277
 278        status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
 279
 280      unlock_and_exit:
 281        acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
 282        return_ACPI_STATUS(status);
 283}
 284
 285/*******************************************************************************
 286 *
 287 * FUNCTION:    acpi_hw_get_register_bit_mask
 288 *
 289 * PARAMETERS:  register_id         - Index of ACPI Register to access
 290 *
 291 * RETURN:      The bitmask to be used when accessing the register
 292 *
 293 * DESCRIPTION: Map register_id into a register bitmask.
 294 *
 295 ******************************************************************************/
 296
 297struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
 298{
 299        ACPI_FUNCTION_ENTRY();
 300
 301        if (register_id > ACPI_BITREG_MAX) {
 302                ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: 0x%X",
 303                            register_id));
 304                return (NULL);
 305        }
 306
 307        return (&acpi_gbl_bit_register_info[register_id]);
 308}
 309
 310/******************************************************************************
 311 *
 312 * FUNCTION:    acpi_hw_write_pm1_control
 313 *
 314 * PARAMETERS:  pm1a_control        - Value to be written to PM1A control
 315 *              pm1b_control        - Value to be written to PM1B control
 316 *
 317 * RETURN:      Status
 318 *
 319 * DESCRIPTION: Write the PM1 A/B control registers. These registers are
 320 *              different than than the PM1 A/B status and enable registers
 321 *              in that different values can be written to the A/B registers.
 322 *              Most notably, the SLP_TYP bits can be different, as per the
 323 *              values returned from the _Sx predefined methods.
 324 *
 325 ******************************************************************************/
 326
 327acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control)
 328{
 329        acpi_status status;
 330
 331        ACPI_FUNCTION_TRACE(hw_write_pm1_control);
 332
 333        status =
 334            acpi_hw_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block);
 335        if (ACPI_FAILURE(status)) {
 336                return_ACPI_STATUS(status);
 337        }
 338
 339        if (acpi_gbl_FADT.xpm1b_control_block.address) {
 340                status =
 341                    acpi_hw_write(pm1b_control,
 342                                  &acpi_gbl_FADT.xpm1b_control_block);
 343        }
 344        return_ACPI_STATUS(status);
 345}
 346
 347/******************************************************************************
 348 *
 349 * FUNCTION:    acpi_hw_register_read
 350 *
 351 * PARAMETERS:  register_id         - ACPI Register ID
 352 *              return_value        - Where the register value is returned
 353 *
 354 * RETURN:      Status and the value read.
 355 *
 356 * DESCRIPTION: Read from the specified ACPI register
 357 *
 358 ******************************************************************************/
 359acpi_status
 360acpi_hw_register_read(u32 register_id, u32 * return_value)
 361{
 362        u32 value = 0;
 363        acpi_status status;
 364
 365        ACPI_FUNCTION_TRACE(hw_register_read);
 366
 367        switch (register_id) {
 368        case ACPI_REGISTER_PM1_STATUS:  /* PM1 A/B: 16-bit access each */
 369
 370                status = acpi_hw_read_multiple(&value,
 371                                               &acpi_gbl_xpm1a_status,
 372                                               &acpi_gbl_xpm1b_status);
 373                break;
 374
 375        case ACPI_REGISTER_PM1_ENABLE:  /* PM1 A/B: 16-bit access each */
 376
 377                status = acpi_hw_read_multiple(&value,
 378                                               &acpi_gbl_xpm1a_enable,
 379                                               &acpi_gbl_xpm1b_enable);
 380                break;
 381
 382        case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
 383
 384                status = acpi_hw_read_multiple(&value,
 385                                               &acpi_gbl_FADT.
 386                                               xpm1a_control_block,
 387                                               &acpi_gbl_FADT.
 388                                               xpm1b_control_block);
 389
 390                /*
 391                 * Zero the write-only bits. From the ACPI specification, "Hardware
 392                 * Write-Only Bits": "Upon reads to registers with write-only bits,
 393                 * software masks out all write-only bits."
 394                 */
 395                value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
 396                break;
 397
 398        case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
 399
 400                status =
 401                    acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block);
 402                break;
 403
 404        case ACPI_REGISTER_PM_TIMER:    /* 32-bit access */
 405
 406                status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block);
 407                break;
 408
 409        case ACPI_REGISTER_SMI_COMMAND_BLOCK:   /* 8-bit access */
 410
 411                status =
 412                    acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8);
 413                break;
 414
 415        default:
 416                ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id));
 417                status = AE_BAD_PARAMETER;
 418                break;
 419        }
 420
 421        if (ACPI_SUCCESS(status)) {
 422                *return_value = value;
 423        }
 424
 425        return_ACPI_STATUS(status);
 426}
 427
 428/******************************************************************************
 429 *
 430 * FUNCTION:    acpi_hw_register_write
 431 *
 432 * PARAMETERS:  register_id         - ACPI Register ID
 433 *              Value               - The value to write
 434 *
 435 * RETURN:      Status
 436 *
 437 * DESCRIPTION: Write to the specified ACPI register
 438 *
 439 * NOTE: In accordance with the ACPI specification, this function automatically
 440 * preserves the value of the following bits, meaning that these bits cannot be
 441 * changed via this interface:
 442 *
 443 * PM1_CONTROL[0] = SCI_EN
 444 * PM1_CONTROL[9]
 445 * PM1_STATUS[11]
 446 *
 447 * ACPI References:
 448 * 1) Hardware Ignored Bits: When software writes to a register with ignored
 449 *      bit fields, it preserves the ignored bit fields
 450 * 2) SCI_EN: OSPM always preserves this bit position
 451 *
 452 ******************************************************************************/
 453
 454acpi_status acpi_hw_register_write(u32 register_id, u32 value)
 455{
 456        acpi_status status;
 457        u32 read_value;
 458
 459        ACPI_FUNCTION_TRACE(hw_register_write);
 460
 461        switch (register_id) {
 462        case ACPI_REGISTER_PM1_STATUS:  /* PM1 A/B: 16-bit access each */
 463                /*
 464                 * Handle the "ignored" bit in PM1 Status. According to the ACPI
 465                 * specification, ignored bits are to be preserved when writing.
 466                 * Normally, this would mean a read/modify/write sequence. However,
 467                 * preserving a bit in the status register is different. Writing a
 468                 * one clears the status, and writing a zero preserves the status.
 469                 * Therefore, we must always write zero to the ignored bit.
 470                 *
 471                 * This behavior is clarified in the ACPI 4.0 specification.
 472                 */
 473                value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
 474
 475                status = acpi_hw_write_multiple(value,
 476                                                &acpi_gbl_xpm1a_status,
 477                                                &acpi_gbl_xpm1b_status);
 478                break;
 479
 480        case ACPI_REGISTER_PM1_ENABLE:  /* PM1 A/B: 16-bit access */
 481
 482                status = acpi_hw_write_multiple(value,
 483                                                &acpi_gbl_xpm1a_enable,
 484                                                &acpi_gbl_xpm1b_enable);
 485                break;
 486
 487        case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
 488
 489                /*
 490                 * Perform a read first to preserve certain bits (per ACPI spec)
 491                 * Note: This includes SCI_EN, we never want to change this bit
 492                 */
 493                status = acpi_hw_read_multiple(&read_value,
 494                                               &acpi_gbl_FADT.
 495                                               xpm1a_control_block,
 496                                               &acpi_gbl_FADT.
 497                                               xpm1b_control_block);
 498                if (ACPI_FAILURE(status)) {
 499                        goto exit;
 500                }
 501
 502                /* Insert the bits to be preserved */
 503
 504                ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS,
 505                                 read_value);
 506
 507                /* Now we can write the data */
 508
 509                status = acpi_hw_write_multiple(value,
 510                                                &acpi_gbl_FADT.
 511                                                xpm1a_control_block,
 512                                                &acpi_gbl_FADT.
 513                                                xpm1b_control_block);
 514                break;
 515
 516        case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
 517
 518                /*
 519                 * For control registers, all reserved bits must be preserved,
 520                 * as per the ACPI spec.
 521                 */
 522                status =
 523                    acpi_hw_read(&read_value,
 524                                 &acpi_gbl_FADT.xpm2_control_block);
 525                if (ACPI_FAILURE(status)) {
 526                        goto exit;
 527                }
 528
 529                /* Insert the bits to be preserved */
 530
 531                ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS,
 532                                 read_value);
 533
 534                status =
 535                    acpi_hw_write(value, &acpi_gbl_FADT.xpm2_control_block);
 536                break;
 537
 538        case ACPI_REGISTER_PM_TIMER:    /* 32-bit access */
 539
 540                status = acpi_hw_write(value, &acpi_gbl_FADT.xpm_timer_block);
 541                break;
 542
 543        case ACPI_REGISTER_SMI_COMMAND_BLOCK:   /* 8-bit access */
 544
 545                /* SMI_CMD is currently always in IO space */
 546
 547                status =
 548                    acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8);
 549                break;
 550
 551        default:
 552                ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id));
 553                status = AE_BAD_PARAMETER;
 554                break;
 555        }
 556
 557      exit:
 558        return_ACPI_STATUS(status);
 559}
 560
 561/******************************************************************************
 562 *
 563 * FUNCTION:    acpi_hw_read_multiple
 564 *
 565 * PARAMETERS:  Value               - Where the register value is returned
 566 *              register_a           - First ACPI register (required)
 567 *              register_b           - Second ACPI register (optional)
 568 *
 569 * RETURN:      Status
 570 *
 571 * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
 572 *
 573 ******************************************************************************/
 574
 575static acpi_status
 576acpi_hw_read_multiple(u32 *value,
 577                      struct acpi_generic_address *register_a,
 578                      struct acpi_generic_address *register_b)
 579{
 580        u32 value_a = 0;
 581        u32 value_b = 0;
 582        acpi_status status;
 583
 584        /* The first register is always required */
 585
 586        status = acpi_hw_read(&value_a, register_a);
 587        if (ACPI_FAILURE(status)) {
 588                return (status);
 589        }
 590
 591        /* Second register is optional */
 592
 593        if (register_b->address) {
 594                status = acpi_hw_read(&value_b, register_b);
 595                if (ACPI_FAILURE(status)) {
 596                        return (status);
 597                }
 598        }
 599
 600        /*
 601         * OR the two return values together. No shifting or masking is necessary,
 602         * because of how the PM1 registers are defined in the ACPI specification:
 603         *
 604         * "Although the bits can be split between the two register blocks (each
 605         * register block has a unique pointer within the FADT), the bit positions
 606         * are maintained. The register block with unimplemented bits (that is,
 607         * those implemented in the other register block) always returns zeros,
 608         * and writes have no side effects"
 609         */
 610        *value = (value_a | value_b);
 611        return (AE_OK);
 612}
 613
 614/******************************************************************************
 615 *
 616 * FUNCTION:    acpi_hw_write_multiple
 617 *
 618 * PARAMETERS:  Value               - The value to write
 619 *              register_a           - First ACPI register (required)
 620 *              register_b           - Second ACPI register (optional)
 621 *
 622 * RETURN:      Status
 623 *
 624 * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
 625 *
 626 ******************************************************************************/
 627
 628static acpi_status
 629acpi_hw_write_multiple(u32 value,
 630                       struct acpi_generic_address *register_a,
 631                       struct acpi_generic_address *register_b)
 632{
 633        acpi_status status;
 634
 635        /* The first register is always required */
 636
 637        status = acpi_hw_write(value, register_a);
 638        if (ACPI_FAILURE(status)) {
 639                return (status);
 640        }
 641
 642        /*
 643         * Second register is optional
 644         *
 645         * No bit shifting or clearing is necessary, because of how the PM1
 646         * registers are defined in the ACPI specification:
 647         *
 648         * "Although the bits can be split between the two register blocks (each
 649         * register block has a unique pointer within the FADT), the bit positions
 650         * are maintained. The register block with unimplemented bits (that is,
 651         * those implemented in the other register block) always returns zeros,
 652         * and writes have no side effects"
 653         */
 654        if (register_b->address) {
 655                status = acpi_hw_write(value, register_b);
 656        }
 657
 658        return (status);
 659}
 660