]>
Commit | Line | Data |
---|---|---|
a82817d0 GKH |
1 | From ben@decadent.org.uk Wed Apr 21 12:11:57 2010 |
2 | From: Alexey Starikovskiy <astarikovskiy@suse.de> | |
3 | Date: Sat, 10 Apr 2010 02:18:35 +0100 | |
4 | Subject: ACPI: EC: Allow multibyte access to EC | |
5 | To: stable@kernel.org | |
6 | Cc: Len Brown <len.brown@intel.com>, 563313@bugs.debian.org, Alexey Starikovskiy <astarikovskiy@suse.de> | |
7 | Message-ID: <1270862315.2176.69.camel@localhost> | |
8 | ||
9 | ||
10 | From: Alexey Starikovskiy <astarikovskiy@suse.de> | |
11 | ||
12 | commit dadf28a10c3eb29421837a2e413ab869ebd upstream | |
13 | ||
14 | http://bugzilla.kernel.org/show_bug.cgi?id=14667 | |
15 | ||
16 | [bwh: Backport to 2.6.32; same applies to 2.6.33] | |
17 | ||
18 | Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> | |
19 | Signed-off-by: Len Brown <len.brown@intel.com> | |
20 | Cc: Ben Hutchings <ben@decadent.org.uk> | |
21 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
22 | ||
23 | --- | |
24 | drivers/acpi/acpica/exprep.c | 12 ++++++++++++ | |
25 | drivers/acpi/ec.c | 35 +++++++++-------------------------- | |
26 | 2 files changed, 21 insertions(+), 26 deletions(-) | |
27 | ||
28 | --- a/drivers/acpi/acpica/exprep.c | |
29 | +++ b/drivers/acpi/acpica/exprep.c | |
30 | @@ -468,6 +468,18 @@ acpi_status acpi_ex_prep_field_value(str | |
31 | ||
32 | acpi_ut_add_reference(obj_desc->field.region_obj); | |
33 | ||
34 | + /* allow full data read from EC address space */ | |
35 | + if (obj_desc->field.region_obj->region.space_id == | |
36 | + ACPI_ADR_SPACE_EC) { | |
37 | + if (obj_desc->common_field.bit_length > 8) | |
38 | + obj_desc->common_field.access_bit_width = | |
39 | + ACPI_ROUND_UP(obj_desc->common_field. | |
40 | + bit_length, 8); | |
41 | + obj_desc->common_field.access_byte_width = | |
42 | + ACPI_DIV_8(obj_desc->common_field. | |
43 | + access_bit_width); | |
44 | + } | |
45 | + | |
46 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | |
47 | "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", | |
48 | obj_desc->field.start_field_bit_offset, | |
49 | --- a/drivers/acpi/ec.c | |
50 | +++ b/drivers/acpi/ec.c | |
51 | @@ -588,12 +588,12 @@ static u32 acpi_ec_gpe_handler(void *dat | |
52 | ||
53 | static acpi_status | |
54 | acpi_ec_space_handler(u32 function, acpi_physical_address address, | |
55 | - u32 bits, acpi_integer *value, | |
56 | + u32 bits, acpi_integer *value64, | |
57 | void *handler_context, void *region_context) | |
58 | { | |
59 | struct acpi_ec *ec = handler_context; | |
60 | - int result = 0, i; | |
61 | - u8 temp = 0; | |
62 | + int result = 0, i, bytes = bits / 8; | |
63 | + u8 *value = (u8 *)value64; | |
64 | ||
65 | if ((address > 0xFF) || !value || !handler_context) | |
66 | return AE_BAD_PARAMETER; | |
67 | @@ -601,32 +601,15 @@ acpi_ec_space_handler(u32 function, acpi | |
68 | if (function != ACPI_READ && function != ACPI_WRITE) | |
69 | return AE_BAD_PARAMETER; | |
70 | ||
71 | - if (bits != 8 && acpi_strict) | |
72 | - return AE_BAD_PARAMETER; | |
73 | - | |
74 | - if (EC_FLAGS_MSI) | |
75 | + if (EC_FLAGS_MSI || bits > 8) | |
76 | acpi_ec_burst_enable(ec); | |
77 | ||
78 | - if (function == ACPI_READ) { | |
79 | - result = acpi_ec_read(ec, address, &temp); | |
80 | - *value = temp; | |
81 | - } else { | |
82 | - temp = 0xff & (*value); | |
83 | - result = acpi_ec_write(ec, address, temp); | |
84 | - } | |
85 | - | |
86 | - for (i = 8; unlikely(bits - i > 0); i += 8) { | |
87 | - ++address; | |
88 | - if (function == ACPI_READ) { | |
89 | - result = acpi_ec_read(ec, address, &temp); | |
90 | - (*value) |= ((acpi_integer)temp) << i; | |
91 | - } else { | |
92 | - temp = 0xff & ((*value) >> i); | |
93 | - result = acpi_ec_write(ec, address, temp); | |
94 | - } | |
95 | - } | |
96 | + for (i = 0; i < bytes; ++i, ++address, ++value) | |
97 | + result = (function == ACPI_READ) ? | |
98 | + acpi_ec_read(ec, address, value) : | |
99 | + acpi_ec_write(ec, address, *value); | |
100 | ||
101 | - if (EC_FLAGS_MSI) | |
102 | + if (EC_FLAGS_MSI || bits > 8) | |
103 | acpi_ec_burst_disable(ec); | |
104 | ||
105 | switch (result) { |