diff options
| author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-05-31 14:07:15 +0400 |
|---|---|---|
| committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-05-31 14:07:15 +0400 |
| commit | e37c83c06c2690157a989df40dc99a6b61c9ea15 (patch) | |
| tree | 024dfb8b2c9abeec9ca7cb0c0136c276d9aacc91 /drivers/acpi/ec.c | |
| parent | ce1f7d30766f6549db6fa0b9e595e0d26a5b7d9a (diff) | |
| parent | 67a3e12b05e055c0415c556a315a3d3eb637e29e (diff) | |
| download | linux-e37c83c06c2690157a989df40dc99a6b61c9ea15.tar.xz | |
Merge commit 'v2.6.35-rc1' into for-2.6.36
Diffstat (limited to 'drivers/acpi/ec.c')
| -rw-r--r-- | drivers/acpi/ec.c | 39 |
1 files changed, 11 insertions, 28 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 1ac28c6a672e..e61d4f8e62a5 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -39,6 +39,7 @@ #include <linux/interrupt.h> #include <linux/list.h> #include <linux/spinlock.h> +#include <linux/slab.h> #include <asm/io.h> #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> @@ -628,12 +629,12 @@ static u32 acpi_ec_gpe_handler(void *data) static acpi_status acpi_ec_space_handler(u32 function, acpi_physical_address address, - u32 bits, u64 *value, + u32 bits, u64 *value64, void *handler_context, void *region_context) { struct acpi_ec *ec = handler_context; - int result = 0, i; - u8 temp = 0; + int result = 0, i, bytes = bits / 8; + u8 *value = (u8 *)value64; if ((address > 0xFF) || !value || !handler_context) return AE_BAD_PARAMETER; @@ -641,32 +642,15 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, if (function != ACPI_READ && function != ACPI_WRITE) return AE_BAD_PARAMETER; - if (bits != 8 && acpi_strict) - return AE_BAD_PARAMETER; - - if (EC_FLAGS_MSI) + if (EC_FLAGS_MSI || bits > 8) acpi_ec_burst_enable(ec); - if (function == ACPI_READ) { - result = acpi_ec_read(ec, address, &temp); - *value = temp; - } else { - temp = 0xff & (*value); - result = acpi_ec_write(ec, address, temp); - } - - for (i = 8; unlikely(bits - i > 0); i += 8) { - ++address; - if (function == ACPI_READ) { - result = acpi_ec_read(ec, address, &temp); - (*value) |= ((u64)temp) << i; - } else { - temp = 0xff & ((*value) >> i); - result = acpi_ec_write(ec, address, temp); - } - } + for (i = 0; i < bytes; ++i, ++address, ++value) + result = (function == ACPI_READ) ? + acpi_ec_read(ec, address, value) : + acpi_ec_write(ec, address, *value); - if (EC_FLAGS_MSI) + if (EC_FLAGS_MSI || bits > 8) acpi_ec_burst_disable(ec); switch (result) { @@ -1043,10 +1027,9 @@ int __init acpi_ec_ecdt_probe(void) /* Don't trust ECDT, which comes from ASUSTek */ if (!EC_FLAGS_VALIDATE_ECDT) goto install; - saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + saved_ec = kmemdup(boot_ec, sizeof(struct acpi_ec), GFP_KERNEL); if (!saved_ec) return -ENOMEM; - memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); /* fall through */ } |
