aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/hardware/hwregs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/hardware/hwregs.c')
-rw-r--r--drivers/acpi/hardware/hwregs.c77
1 files changed, 62 insertions, 15 deletions
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index ae142de19507..3143f36fcec9 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -172,9 +172,9 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b)
172 } 172 }
173 173
174 /* 174 /*
175 * The package must have at least two elements. NOTE (March 2005): This 175 * The package must have at least two elements. NOTE (March 2005): This
176 * goes against the current ACPI spec which defines this object as a 176 * goes against the current ACPI spec which defines this object as a
177 * package with one encoded DWORD element. However, existing practice 177 * package with one encoded DWORD element. However, existing practice
178 * by BIOS vendors seems to be to have 2 or more elements, at least 178 * by BIOS vendors seems to be to have 2 or more elements, at least
179 * one per sleep type (A/B). 179 * one per sleep type (A/B).
180 */ 180 */
@@ -255,7 +255,7 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
255 * return_value - Value that was read from the register 255 * return_value - Value that was read from the register
256 * Flags - Lock the hardware or not 256 * Flags - Lock the hardware or not
257 * 257 *
258 * RETURN: Status and the value read from specified Register. Value 258 * RETURN: Status and the value read from specified Register. Value
259 * returned is normalized to bit0 (is shifted all the way right) 259 * returned is normalized to bit0 (is shifted all the way right)
260 * 260 *
261 * DESCRIPTION: ACPI bit_register read function. 261 * DESCRIPTION: ACPI bit_register read function.
@@ -361,8 +361,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags)
361 case ACPI_REGISTER_PM1_STATUS: 361 case ACPI_REGISTER_PM1_STATUS:
362 362
363 /* 363 /*
364 * Status Registers are different from the rest. Clear by 364 * Status Registers are different from the rest. Clear by
365 * writing 1, and writing 0 has no effect. So, the only relevant 365 * writing 1, and writing 0 has no effect. So, the only relevant
366 * information is the single bit we're interested in, all others should 366 * information is the single bit we're interested in, all others should
367 * be written as 0 so they will be left unchanged. 367 * be written as 0 so they will be left unchanged.
368 */ 368 */
@@ -467,14 +467,13 @@ ACPI_EXPORT_SYMBOL(acpi_set_register)
467 * 467 *
468 * FUNCTION: acpi_hw_register_read 468 * FUNCTION: acpi_hw_register_read
469 * 469 *
470 * PARAMETERS: use_lock - Mutex hw access 470 * PARAMETERS: use_lock - Lock hardware? True/False
471 * register_id - register_iD + Offset 471 * register_id - ACPI Register ID
472 * return_value - Where the register value is returned 472 * return_value - Where the register value is returned
473 * 473 *
474 * RETURN: Status and the value read. 474 * RETURN: Status and the value read.
475 * 475 *
476 * DESCRIPTION: Acpi register read function. Registers are read at the 476 * DESCRIPTION: Read from the specified ACPI register
477 * given offset.
478 * 477 *
479 ******************************************************************************/ 478 ******************************************************************************/
480acpi_status 479acpi_status
@@ -580,14 +579,26 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
580 * 579 *
581 * FUNCTION: acpi_hw_register_write 580 * FUNCTION: acpi_hw_register_write
582 * 581 *
583 * PARAMETERS: use_lock - Mutex hw access 582 * PARAMETERS: use_lock - Lock hardware? True/False
584 * register_id - register_iD + Offset 583 * register_id - ACPI Register ID
585 * Value - The value to write 584 * Value - The value to write
586 * 585 *
587 * RETURN: Status 586 * RETURN: Status
588 * 587 *
589 * DESCRIPTION: Acpi register Write function. Registers are written at the 588 * DESCRIPTION: Write to the specified ACPI register
590 * given offset. 589 *
590 * NOTE: In accordance with the ACPI specification, this function automatically
591 * preserves the value of the following bits, meaning that these bits cannot be
592 * changed via this interface:
593 *
594 * PM1_CONTROL[0] = SCI_EN
595 * PM1_CONTROL[9]
596 * PM1_STATUS[11]
597 *
598 * ACPI References:
599 * 1) Hardware Ignored Bits: When software writes to a register with ignored
600 * bit fields, it preserves the ignored bit fields
601 * 2) SCI_EN: OSPM always preserves this bit position
591 * 602 *
592 ******************************************************************************/ 603 ******************************************************************************/
593 604
@@ -595,6 +606,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
595{ 606{
596 acpi_status status; 607 acpi_status status;
597 acpi_cpu_flags lock_flags = 0; 608 acpi_cpu_flags lock_flags = 0;
609 u32 read_value;
598 610
599 ACPI_FUNCTION_TRACE(hw_register_write); 611 ACPI_FUNCTION_TRACE(hw_register_write);
600 612
@@ -605,6 +617,22 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
605 switch (register_id) { 617 switch (register_id) {
606 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 618 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
607 619
620 /* Perform a read first to preserve certain bits (per ACPI spec) */
621
622 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
623 ACPI_REGISTER_PM1_STATUS,
624 &read_value);
625 if (ACPI_FAILURE(status)) {
626 goto unlock_and_exit;
627 }
628
629 /* Insert the bits to be preserved */
630
631 ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS,
632 read_value);
633
634 /* Now we can write the data */
635
608 status = 636 status =
609 acpi_hw_low_level_write(16, value, 637 acpi_hw_low_level_write(16, value,
610 &acpi_gbl_FADT->xpm1a_evt_blk); 638 &acpi_gbl_FADT->xpm1a_evt_blk);
@@ -635,6 +663,25 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
635 663
636 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ 664 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
637 665
666 /*
667 * Perform a read first to preserve certain bits (per ACPI spec)
668 *
669 * Note: This includes SCI_EN, we never want to change this bit
670 */
671 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
672 ACPI_REGISTER_PM1_CONTROL,
673 &read_value);
674 if (ACPI_FAILURE(status)) {
675 goto unlock_and_exit;
676 }
677
678 /* Insert the bits to be preserved */
679
680 ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS,
681 read_value);
682
683 /* Now we can write the data */
684
638 status = 685 status =
639 acpi_hw_low_level_write(16, value, 686 acpi_hw_low_level_write(16, value,
640 &acpi_gbl_FADT->xpm1a_cnt_blk); 687 &acpi_gbl_FADT->xpm1a_cnt_blk);
@@ -726,7 +773,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
726 return (AE_OK); 773 return (AE_OK);
727 } 774 }
728 775
729 /* Get a local copy of the address. Handles possible alignment issues */ 776 /* Get a local copy of the address. Handles possible alignment issues */
730 777
731 ACPI_MOVE_64_TO_64(&address, &reg->address); 778 ACPI_MOVE_64_TO_64(&address, &reg->address);
732 if (!address) { 779 if (!address) {
@@ -798,7 +845,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
798 return (AE_OK); 845 return (AE_OK);
799 } 846 }
800 847
801 /* Get a local copy of the address. Handles possible alignment issues */ 848 /* Get a local copy of the address. Handles possible alignment issues */
802 849
803 ACPI_MOVE_64_TO_64(&address, &reg->address); 850 ACPI_MOVE_64_TO_64(&address, &reg->address);
804 if (!address) { 851 if (!address) {