diff options
Diffstat (limited to 'drivers/acpi/ec.c')
| -rw-r--r-- | drivers/acpi/ec.c | 36 |
1 files changed, 10 insertions, 26 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 1ac28c6a672e..f2234db85da0 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
| 40 | #include <linux/list.h> | 40 | #include <linux/list.h> |
| 41 | #include <linux/spinlock.h> | 41 | #include <linux/spinlock.h> |
| 42 | #include <linux/slab.h> | ||
| 42 | #include <asm/io.h> | 43 | #include <asm/io.h> |
| 43 | #include <acpi/acpi_bus.h> | 44 | #include <acpi/acpi_bus.h> |
| 44 | #include <acpi/acpi_drivers.h> | 45 | #include <acpi/acpi_drivers.h> |
| @@ -628,12 +629,12 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
| 628 | 629 | ||
| 629 | static acpi_status | 630 | static acpi_status |
| 630 | acpi_ec_space_handler(u32 function, acpi_physical_address address, | 631 | acpi_ec_space_handler(u32 function, acpi_physical_address address, |
| 631 | u32 bits, u64 *value, | 632 | u32 bits, u64 *value64, |
| 632 | void *handler_context, void *region_context) | 633 | void *handler_context, void *region_context) |
| 633 | { | 634 | { |
| 634 | struct acpi_ec *ec = handler_context; | 635 | struct acpi_ec *ec = handler_context; |
| 635 | int result = 0, i; | 636 | int result = 0, i, bytes = bits / 8; |
| 636 | u8 temp = 0; | 637 | u8 *value = (u8 *)value64; |
| 637 | 638 | ||
| 638 | if ((address > 0xFF) || !value || !handler_context) | 639 | if ((address > 0xFF) || !value || !handler_context) |
| 639 | return AE_BAD_PARAMETER; | 640 | return AE_BAD_PARAMETER; |
| @@ -641,32 +642,15 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
| 641 | if (function != ACPI_READ && function != ACPI_WRITE) | 642 | if (function != ACPI_READ && function != ACPI_WRITE) |
| 642 | return AE_BAD_PARAMETER; | 643 | return AE_BAD_PARAMETER; |
| 643 | 644 | ||
| 644 | if (bits != 8 && acpi_strict) | 645 | if (EC_FLAGS_MSI || bits > 8) |
| 645 | return AE_BAD_PARAMETER; | ||
| 646 | |||
| 647 | if (EC_FLAGS_MSI) | ||
| 648 | acpi_ec_burst_enable(ec); | 646 | acpi_ec_burst_enable(ec); |
| 649 | 647 | ||
| 650 | if (function == ACPI_READ) { | 648 | for (i = 0; i < bytes; ++i, ++address, ++value) |
| 651 | result = acpi_ec_read(ec, address, &temp); | 649 | result = (function == ACPI_READ) ? |
| 652 | *value = temp; | 650 | acpi_ec_read(ec, address, value) : |
| 653 | } else { | 651 | 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 | 652 | ||
| 669 | if (EC_FLAGS_MSI) | 653 | if (EC_FLAGS_MSI || bits > 8) |
| 670 | acpi_ec_burst_disable(ec); | 654 | acpi_ec_burst_disable(ec); |
| 671 | 655 | ||
| 672 | switch (result) { | 656 | switch (result) { |
