diff options
author | Alexey Starikovskiy <astarikovskiy@suse.de> | 2010-03-17 13:14:13 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-03-17 13:14:13 -0400 |
commit | dadf28a10c3eb29421837a2e413ab869ebd9e168 (patch) | |
tree | f4ea66f2ceb12935e3b2c1d3889102dee0dfa778 /drivers/acpi/ec.c | |
parent | a3d3203e4bb40f253b1541e310dc0f9305be7c84 (diff) |
ACPI: EC: Allow multibyte access to EC
http://bugzilla.kernel.org/show_bug.cgi?id=14667
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 35 |
1 files changed, 9 insertions, 26 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 1ac28c6a672e..7208a692e93c 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -628,12 +628,12 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
628 | 628 | ||
629 | static acpi_status | 629 | static acpi_status |
630 | acpi_ec_space_handler(u32 function, acpi_physical_address address, | 630 | acpi_ec_space_handler(u32 function, acpi_physical_address address, |
631 | u32 bits, u64 *value, | 631 | u32 bits, u64 *value64, |
632 | void *handler_context, void *region_context) | 632 | void *handler_context, void *region_context) |
633 | { | 633 | { |
634 | struct acpi_ec *ec = handler_context; | 634 | struct acpi_ec *ec = handler_context; |
635 | int result = 0, i; | 635 | int result = 0, i, bytes = bits / 8; |
636 | u8 temp = 0; | 636 | u8 *value = (u8 *)value64; |
637 | 637 | ||
638 | if ((address > 0xFF) || !value || !handler_context) | 638 | if ((address > 0xFF) || !value || !handler_context) |
639 | return AE_BAD_PARAMETER; | 639 | return AE_BAD_PARAMETER; |
@@ -641,32 +641,15 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
641 | if (function != ACPI_READ && function != ACPI_WRITE) | 641 | if (function != ACPI_READ && function != ACPI_WRITE) |
642 | return AE_BAD_PARAMETER; | 642 | return AE_BAD_PARAMETER; |
643 | 643 | ||
644 | if (bits != 8 && acpi_strict) | 644 | if (EC_FLAGS_MSI || bits > 8) |
645 | return AE_BAD_PARAMETER; | ||
646 | |||
647 | if (EC_FLAGS_MSI) | ||
648 | acpi_ec_burst_enable(ec); | 645 | acpi_ec_burst_enable(ec); |
649 | 646 | ||
650 | if (function == ACPI_READ) { | 647 | for (i = 0; i < bytes; ++i, ++address, ++value) |
651 | result = acpi_ec_read(ec, address, &temp); | 648 | result = (function == ACPI_READ) ? |
652 | *value = temp; | 649 | acpi_ec_read(ec, address, value) : |
653 | } else { | 650 | acpi_ec_write(ec, address, *value); |
654 | temp = 0xff & (*value); | ||
655 | result = acpi_ec_write(ec, address, temp); | ||
656 | } | ||
657 | |||
658 | for (i = 8; unlikely(bits - i > 0); i += 8) { | ||
659 | ++address; | ||
660 | if (function == ACPI_READ) { | ||
661 | result = acpi_ec_read(ec, address, &temp); | ||
662 | (*value) |= ((u64)temp) << i; | ||
663 | } else { | ||
664 | temp = 0xff & ((*value) >> i); | ||
665 | result = acpi_ec_write(ec, address, temp); | ||
666 | } | ||
667 | } | ||
668 | 651 | ||
669 | if (EC_FLAGS_MSI) | 652 | if (EC_FLAGS_MSI || bits > 8) |
670 | acpi_ec_burst_disable(ec); | 653 | acpi_ec_burst_disable(ec); |
671 | 654 | ||
672 | switch (result) { | 655 | switch (result) { |