diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpi_processor.c | 7 | ||||
-rw-r--r-- | drivers/acpi/acpica/exfield.c | 104 | ||||
-rw-r--r-- | drivers/acpi/bus.c | 5 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 21 |
4 files changed, 115 insertions, 22 deletions
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index c29c2c3ec0ad..b06f5f55ada9 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c | |||
@@ -170,6 +170,9 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) | |||
170 | acpi_status status; | 170 | acpi_status status; |
171 | int ret; | 171 | int ret; |
172 | 172 | ||
173 | if (pr->apic_id == -1) | ||
174 | return -ENODEV; | ||
175 | |||
173 | status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta); | 176 | status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta); |
174 | if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT)) | 177 | if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT)) |
175 | return -ENODEV; | 178 | return -ENODEV; |
@@ -260,10 +263,8 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
260 | } | 263 | } |
261 | 264 | ||
262 | apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id); | 265 | apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id); |
263 | if (apic_id < 0) { | 266 | if (apic_id < 0) |
264 | acpi_handle_debug(pr->handle, "failed to get CPU APIC ID.\n"); | 267 | acpi_handle_debug(pr->handle, "failed to get CPU APIC ID.\n"); |
265 | return -ENODEV; | ||
266 | } | ||
267 | pr->apic_id = apic_id; | 268 | pr->apic_id = apic_id; |
268 | 269 | ||
269 | cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); | 270 | cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); |
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 68d97441432c..12878e1982f7 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c | |||
@@ -45,10 +45,71 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acdispat.h" | 46 | #include "acdispat.h" |
47 | #include "acinterp.h" | 47 | #include "acinterp.h" |
48 | #include "amlcode.h" | ||
48 | 49 | ||
49 | #define _COMPONENT ACPI_EXECUTER | 50 | #define _COMPONENT ACPI_EXECUTER |
50 | ACPI_MODULE_NAME("exfield") | 51 | ACPI_MODULE_NAME("exfield") |
51 | 52 | ||
53 | /* Local prototypes */ | ||
54 | static u32 | ||
55 | acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length); | ||
56 | |||
57 | /******************************************************************************* | ||
58 | * | ||
59 | * FUNCTION: acpi_get_serial_access_bytes | ||
60 | * | ||
61 | * PARAMETERS: accessor_type - The type of the protocol indicated by region | ||
62 | * field access attributes | ||
63 | * access_length - The access length of the region field | ||
64 | * | ||
65 | * RETURN: Decoded access length | ||
66 | * | ||
67 | * DESCRIPTION: This routine returns the length of the generic_serial_bus | ||
68 | * protocol bytes | ||
69 | * | ||
70 | ******************************************************************************/ | ||
71 | |||
72 | static u32 | ||
73 | acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length) | ||
74 | { | ||
75 | u32 length; | ||
76 | |||
77 | switch (accessor_type) { | ||
78 | case AML_FIELD_ATTRIB_QUICK: | ||
79 | |||
80 | length = 0; | ||
81 | break; | ||
82 | |||
83 | case AML_FIELD_ATTRIB_SEND_RCV: | ||
84 | case AML_FIELD_ATTRIB_BYTE: | ||
85 | |||
86 | length = 1; | ||
87 | break; | ||
88 | |||
89 | case AML_FIELD_ATTRIB_WORD: | ||
90 | case AML_FIELD_ATTRIB_WORD_CALL: | ||
91 | |||
92 | length = 2; | ||
93 | break; | ||
94 | |||
95 | case AML_FIELD_ATTRIB_MULTIBYTE: | ||
96 | case AML_FIELD_ATTRIB_RAW_BYTES: | ||
97 | case AML_FIELD_ATTRIB_RAW_PROCESS: | ||
98 | |||
99 | length = access_length; | ||
100 | break; | ||
101 | |||
102 | case AML_FIELD_ATTRIB_BLOCK: | ||
103 | case AML_FIELD_ATTRIB_BLOCK_CALL: | ||
104 | default: | ||
105 | |||
106 | length = ACPI_GSBUS_BUFFER_SIZE; | ||
107 | break; | ||
108 | } | ||
109 | |||
110 | return (length); | ||
111 | } | ||
112 | |||
52 | /******************************************************************************* | 113 | /******************************************************************************* |
53 | * | 114 | * |
54 | * FUNCTION: acpi_ex_read_data_from_field | 115 | * FUNCTION: acpi_ex_read_data_from_field |
@@ -63,8 +124,9 @@ ACPI_MODULE_NAME("exfield") | |||
63 | * Buffer, depending on the size of the field. | 124 | * Buffer, depending on the size of the field. |
64 | * | 125 | * |
65 | ******************************************************************************/ | 126 | ******************************************************************************/ |
127 | |||
66 | acpi_status | 128 | acpi_status |
67 | acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | 129 | acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state, |
68 | union acpi_operand_object *obj_desc, | 130 | union acpi_operand_object *obj_desc, |
69 | union acpi_operand_object **ret_buffer_desc) | 131 | union acpi_operand_object **ret_buffer_desc) |
70 | { | 132 | { |
@@ -73,6 +135,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
73 | acpi_size length; | 135 | acpi_size length; |
74 | void *buffer; | 136 | void *buffer; |
75 | u32 function; | 137 | u32 function; |
138 | u16 accessor_type; | ||
76 | 139 | ||
77 | ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); | 140 | ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); |
78 | 141 | ||
@@ -116,9 +179,22 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
116 | ACPI_READ | (obj_desc->field.attribute << 16); | 179 | ACPI_READ | (obj_desc->field.attribute << 16); |
117 | } else if (obj_desc->field.region_obj->region.space_id == | 180 | } else if (obj_desc->field.region_obj->region.space_id == |
118 | ACPI_ADR_SPACE_GSBUS) { | 181 | ACPI_ADR_SPACE_GSBUS) { |
119 | length = ACPI_GSBUS_BUFFER_SIZE; | 182 | accessor_type = obj_desc->field.attribute; |
120 | function = | 183 | length = acpi_ex_get_serial_access_length(accessor_type, |
121 | ACPI_READ | (obj_desc->field.attribute << 16); | 184 | obj_desc-> |
185 | field. | ||
186 | access_length); | ||
187 | |||
188 | /* | ||
189 | * Add additional 2 bytes for modeled generic_serial_bus data buffer: | ||
190 | * typedef struct { | ||
191 | * BYTEStatus; // Byte 0 of the data buffer | ||
192 | * BYTELength; // Byte 1 of the data buffer | ||
193 | * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer, | ||
194 | * } | ||
195 | */ | ||
196 | length += 2; | ||
197 | function = ACPI_READ | (accessor_type << 16); | ||
122 | } else { /* IPMI */ | 198 | } else { /* IPMI */ |
123 | 199 | ||
124 | length = ACPI_IPMI_BUFFER_SIZE; | 200 | length = ACPI_IPMI_BUFFER_SIZE; |
@@ -231,6 +307,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
231 | void *buffer; | 307 | void *buffer; |
232 | union acpi_operand_object *buffer_desc; | 308 | union acpi_operand_object *buffer_desc; |
233 | u32 function; | 309 | u32 function; |
310 | u16 accessor_type; | ||
234 | 311 | ||
235 | ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); | 312 | ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); |
236 | 313 | ||
@@ -284,9 +361,22 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
284 | ACPI_WRITE | (obj_desc->field.attribute << 16); | 361 | ACPI_WRITE | (obj_desc->field.attribute << 16); |
285 | } else if (obj_desc->field.region_obj->region.space_id == | 362 | } else if (obj_desc->field.region_obj->region.space_id == |
286 | ACPI_ADR_SPACE_GSBUS) { | 363 | ACPI_ADR_SPACE_GSBUS) { |
287 | length = ACPI_GSBUS_BUFFER_SIZE; | 364 | accessor_type = obj_desc->field.attribute; |
288 | function = | 365 | length = acpi_ex_get_serial_access_length(accessor_type, |
289 | ACPI_WRITE | (obj_desc->field.attribute << 16); | 366 | obj_desc-> |
367 | field. | ||
368 | access_length); | ||
369 | |||
370 | /* | ||
371 | * Add additional 2 bytes for modeled generic_serial_bus data buffer: | ||
372 | * typedef struct { | ||
373 | * BYTEStatus; // Byte 0 of the data buffer | ||
374 | * BYTELength; // Byte 1 of the data buffer | ||
375 | * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer, | ||
376 | * } | ||
377 | */ | ||
378 | length += 2; | ||
379 | function = ACPI_WRITE | (accessor_type << 16); | ||
290 | } else { /* IPMI */ | 380 | } else { /* IPMI */ |
291 | 381 | ||
292 | length = ACPI_IPMI_BUFFER_SIZE; | 382 | length = ACPI_IPMI_BUFFER_SIZE; |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index e7e5844c87d0..cf925c4f36b7 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -380,9 +380,8 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
380 | break; | 380 | break; |
381 | 381 | ||
382 | default: | 382 | default: |
383 | acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type); | 383 | acpi_handle_debug(handle, "Unknown event type 0x%x\n", type); |
384 | ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY; | 384 | break; |
385 | goto err; | ||
386 | } | 385 | } |
387 | 386 | ||
388 | adev = acpi_bus_get_acpi_device(handle); | 387 | adev = acpi_bus_get_acpi_device(handle); |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d7d32c28829b..ad11ba4a412d 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -206,13 +206,13 @@ unlock: | |||
206 | spin_unlock_irqrestore(&ec->lock, flags); | 206 | spin_unlock_irqrestore(&ec->lock, flags); |
207 | } | 207 | } |
208 | 208 | ||
209 | static int acpi_ec_sync_query(struct acpi_ec *ec); | 209 | static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); |
210 | 210 | ||
211 | static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) | 211 | static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) |
212 | { | 212 | { |
213 | if (state & ACPI_EC_FLAG_SCI) { | 213 | if (state & ACPI_EC_FLAG_SCI) { |
214 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) | 214 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) |
215 | return acpi_ec_sync_query(ec); | 215 | return acpi_ec_sync_query(ec, NULL); |
216 | } | 216 | } |
217 | return 0; | 217 | return 0; |
218 | } | 218 | } |
@@ -443,10 +443,8 @@ acpi_handle ec_get_handle(void) | |||
443 | 443 | ||
444 | EXPORT_SYMBOL(ec_get_handle); | 444 | EXPORT_SYMBOL(ec_get_handle); |
445 | 445 | ||
446 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data); | ||
447 | |||
448 | /* | 446 | /* |
449 | * Clears stale _Q events that might have accumulated in the EC. | 447 | * Process _Q events that might have accumulated in the EC. |
450 | * Run with locked ec mutex. | 448 | * Run with locked ec mutex. |
451 | */ | 449 | */ |
452 | static void acpi_ec_clear(struct acpi_ec *ec) | 450 | static void acpi_ec_clear(struct acpi_ec *ec) |
@@ -455,7 +453,7 @@ static void acpi_ec_clear(struct acpi_ec *ec) | |||
455 | u8 value = 0; | 453 | u8 value = 0; |
456 | 454 | ||
457 | for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { | 455 | for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { |
458 | status = acpi_ec_query_unlocked(ec, &value); | 456 | status = acpi_ec_sync_query(ec, &value); |
459 | if (status || !value) | 457 | if (status || !value) |
460 | break; | 458 | break; |
461 | } | 459 | } |
@@ -582,13 +580,18 @@ static void acpi_ec_run(void *cxt) | |||
582 | kfree(handler); | 580 | kfree(handler); |
583 | } | 581 | } |
584 | 582 | ||
585 | static int acpi_ec_sync_query(struct acpi_ec *ec) | 583 | static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) |
586 | { | 584 | { |
587 | u8 value = 0; | 585 | u8 value = 0; |
588 | int status; | 586 | int status; |
589 | struct acpi_ec_query_handler *handler, *copy; | 587 | struct acpi_ec_query_handler *handler, *copy; |
590 | if ((status = acpi_ec_query_unlocked(ec, &value))) | 588 | |
589 | status = acpi_ec_query_unlocked(ec, &value); | ||
590 | if (data) | ||
591 | *data = value; | ||
592 | if (status) | ||
591 | return status; | 593 | return status; |
594 | |||
592 | list_for_each_entry(handler, &ec->list, node) { | 595 | list_for_each_entry(handler, &ec->list, node) { |
593 | if (value == handler->query_bit) { | 596 | if (value == handler->query_bit) { |
594 | /* have custom handler for this bit */ | 597 | /* have custom handler for this bit */ |
@@ -612,7 +615,7 @@ static void acpi_ec_gpe_query(void *ec_cxt) | |||
612 | if (!ec) | 615 | if (!ec) |
613 | return; | 616 | return; |
614 | mutex_lock(&ec->mutex); | 617 | mutex_lock(&ec->mutex); |
615 | acpi_ec_sync_query(ec); | 618 | acpi_ec_sync_query(ec, NULL); |
616 | mutex_unlock(&ec->mutex); | 619 | mutex_unlock(&ec->mutex); |
617 | } | 620 | } |
618 | 621 | ||