diff options
Diffstat (limited to 'drivers/acpi/acpica/rsmisc.c')
-rw-r--r-- | drivers/acpi/acpica/rsmisc.c | 269 |
1 files changed, 263 insertions, 6 deletions
diff --git a/drivers/acpi/acpica/rsmisc.c b/drivers/acpi/acpica/rsmisc.c index 410264b22a29..8073b371cc7c 100644 --- a/drivers/acpi/acpica/rsmisc.c +++ b/drivers/acpi/acpica/rsmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2011, Intel Corp. | 8 | * Copyright (C) 2000 - 2012, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -83,6 +83,10 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, | |||
83 | 83 | ||
84 | ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource); | 84 | ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource); |
85 | 85 | ||
86 | if (!info) { | ||
87 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
88 | } | ||
89 | |||
86 | if (((acpi_size) resource) & 0x3) { | 90 | if (((acpi_size) resource) & 0x3) { |
87 | 91 | ||
88 | /* Each internal resource struct is expected to be 32-bit aligned */ | 92 | /* Each internal resource struct is expected to be 32-bit aligned */ |
@@ -101,7 +105,6 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, | |||
101 | * table length (# of table entries) | 105 | * table length (# of table entries) |
102 | */ | 106 | */ |
103 | count = INIT_TABLE_LENGTH(info); | 107 | count = INIT_TABLE_LENGTH(info); |
104 | |||
105 | while (count) { | 108 | while (count) { |
106 | /* | 109 | /* |
107 | * Source is the external AML byte stream buffer, | 110 | * Source is the external AML byte stream buffer, |
@@ -145,6 +148,14 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, | |||
145 | ((ACPI_GET8(source) >> info->value) & 0x03); | 148 | ((ACPI_GET8(source) >> info->value) & 0x03); |
146 | break; | 149 | break; |
147 | 150 | ||
151 | case ACPI_RSC_3BITFLAG: | ||
152 | /* | ||
153 | * Mask and shift the flag bits | ||
154 | */ | ||
155 | ACPI_SET8(destination) = (u8) | ||
156 | ((ACPI_GET8(source) >> info->value) & 0x07); | ||
157 | break; | ||
158 | |||
148 | case ACPI_RSC_COUNT: | 159 | case ACPI_RSC_COUNT: |
149 | 160 | ||
150 | item_count = ACPI_GET8(source); | 161 | item_count = ACPI_GET8(source); |
@@ -163,6 +174,69 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, | |||
163 | (info->value * (item_count - 1)); | 174 | (info->value * (item_count - 1)); |
164 | break; | 175 | break; |
165 | 176 | ||
177 | case ACPI_RSC_COUNT_GPIO_PIN: | ||
178 | |||
179 | target = ACPI_ADD_PTR(void, aml, info->value); | ||
180 | item_count = ACPI_GET16(target) - ACPI_GET16(source); | ||
181 | |||
182 | resource->length = resource->length + item_count; | ||
183 | item_count = item_count / 2; | ||
184 | ACPI_SET16(destination) = item_count; | ||
185 | break; | ||
186 | |||
187 | case ACPI_RSC_COUNT_GPIO_VEN: | ||
188 | |||
189 | item_count = ACPI_GET8(source); | ||
190 | ACPI_SET8(destination) = (u8)item_count; | ||
191 | |||
192 | resource->length = resource->length + | ||
193 | (info->value * item_count); | ||
194 | break; | ||
195 | |||
196 | case ACPI_RSC_COUNT_GPIO_RES: | ||
197 | |||
198 | /* | ||
199 | * Vendor data is optional (length/offset may both be zero) | ||
200 | * Examine vendor data length field first | ||
201 | */ | ||
202 | target = ACPI_ADD_PTR(void, aml, (info->value + 2)); | ||
203 | if (ACPI_GET16(target)) { | ||
204 | |||
205 | /* Use vendor offset to get resource source length */ | ||
206 | |||
207 | target = ACPI_ADD_PTR(void, aml, info->value); | ||
208 | item_count = | ||
209 | ACPI_GET16(target) - ACPI_GET16(source); | ||
210 | } else { | ||
211 | /* No vendor data to worry about */ | ||
212 | |||
213 | item_count = aml->large_header.resource_length + | ||
214 | sizeof(struct aml_resource_large_header) - | ||
215 | ACPI_GET16(source); | ||
216 | } | ||
217 | |||
218 | resource->length = resource->length + item_count; | ||
219 | ACPI_SET16(destination) = item_count; | ||
220 | break; | ||
221 | |||
222 | case ACPI_RSC_COUNT_SERIAL_VEN: | ||
223 | |||
224 | item_count = ACPI_GET16(source) - info->value; | ||
225 | |||
226 | resource->length = resource->length + item_count; | ||
227 | ACPI_SET16(destination) = item_count; | ||
228 | break; | ||
229 | |||
230 | case ACPI_RSC_COUNT_SERIAL_RES: | ||
231 | |||
232 | item_count = (aml_resource_length + | ||
233 | sizeof(struct aml_resource_large_header)) | ||
234 | - ACPI_GET16(source) - info->value; | ||
235 | |||
236 | resource->length = resource->length + item_count; | ||
237 | ACPI_SET16(destination) = item_count; | ||
238 | break; | ||
239 | |||
166 | case ACPI_RSC_LENGTH: | 240 | case ACPI_RSC_LENGTH: |
167 | 241 | ||
168 | resource->length = resource->length + info->value; | 242 | resource->length = resource->length + info->value; |
@@ -183,6 +257,72 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, | |||
183 | info->opcode); | 257 | info->opcode); |
184 | break; | 258 | break; |
185 | 259 | ||
260 | case ACPI_RSC_MOVE_GPIO_PIN: | ||
261 | |||
262 | /* Generate and set the PIN data pointer */ | ||
263 | |||
264 | target = (char *)ACPI_ADD_PTR(void, resource, | ||
265 | (resource->length - | ||
266 | item_count * 2)); | ||
267 | *(u16 **)destination = ACPI_CAST_PTR(u16, target); | ||
268 | |||
269 | /* Copy the PIN data */ | ||
270 | |||
271 | source = ACPI_ADD_PTR(void, aml, ACPI_GET16(source)); | ||
272 | acpi_rs_move_data(target, source, item_count, | ||
273 | info->opcode); | ||
274 | break; | ||
275 | |||
276 | case ACPI_RSC_MOVE_GPIO_RES: | ||
277 | |||
278 | /* Generate and set the resource_source string pointer */ | ||
279 | |||
280 | target = (char *)ACPI_ADD_PTR(void, resource, | ||
281 | (resource->length - | ||
282 | item_count)); | ||
283 | *(u8 **)destination = ACPI_CAST_PTR(u8, target); | ||
284 | |||
285 | /* Copy the resource_source string */ | ||
286 | |||
287 | source = ACPI_ADD_PTR(void, aml, ACPI_GET16(source)); | ||
288 | acpi_rs_move_data(target, source, item_count, | ||
289 | info->opcode); | ||
290 | break; | ||
291 | |||
292 | case ACPI_RSC_MOVE_SERIAL_VEN: | ||
293 | |||
294 | /* Generate and set the Vendor Data pointer */ | ||
295 | |||
296 | target = (char *)ACPI_ADD_PTR(void, resource, | ||
297 | (resource->length - | ||
298 | item_count)); | ||
299 | *(u8 **)destination = ACPI_CAST_PTR(u8, target); | ||
300 | |||
301 | /* Copy the Vendor Data */ | ||
302 | |||
303 | source = ACPI_ADD_PTR(void, aml, info->value); | ||
304 | acpi_rs_move_data(target, source, item_count, | ||
305 | info->opcode); | ||
306 | break; | ||
307 | |||
308 | case ACPI_RSC_MOVE_SERIAL_RES: | ||
309 | |||
310 | /* Generate and set the resource_source string pointer */ | ||
311 | |||
312 | target = (char *)ACPI_ADD_PTR(void, resource, | ||
313 | (resource->length - | ||
314 | item_count)); | ||
315 | *(u8 **)destination = ACPI_CAST_PTR(u8, target); | ||
316 | |||
317 | /* Copy the resource_source string */ | ||
318 | |||
319 | source = | ||
320 | ACPI_ADD_PTR(void, aml, | ||
321 | (ACPI_GET16(source) + info->value)); | ||
322 | acpi_rs_move_data(target, source, item_count, | ||
323 | info->opcode); | ||
324 | break; | ||
325 | |||
186 | case ACPI_RSC_SET8: | 326 | case ACPI_RSC_SET8: |
187 | 327 | ||
188 | ACPI_MEMSET(destination, info->aml_offset, info->value); | 328 | ACPI_MEMSET(destination, info->aml_offset, info->value); |
@@ -219,13 +359,18 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, | |||
219 | * Optional resource_source (Index and String). This is the more | 359 | * Optional resource_source (Index and String). This is the more |
220 | * complicated case used by the Interrupt() macro | 360 | * complicated case used by the Interrupt() macro |
221 | */ | 361 | */ |
222 | target = | 362 | target = ACPI_ADD_PTR(char, resource, |
223 | ACPI_ADD_PTR(char, resource, | 363 | info->aml_offset + |
224 | info->aml_offset + (item_count * 4)); | 364 | (item_count * 4)); |
225 | 365 | ||
226 | resource->length += | 366 | resource->length += |
227 | acpi_rs_get_resource_source(aml_resource_length, | 367 | acpi_rs_get_resource_source(aml_resource_length, |
228 | (acpi_rs_length) (((item_count - 1) * sizeof(u32)) + info->value), destination, aml, target); | 368 | (acpi_rs_length) |
369 | (((item_count - | ||
370 | 1) * sizeof(u32)) + | ||
371 | info->value), | ||
372 | destination, aml, | ||
373 | target); | ||
229 | break; | 374 | break; |
230 | 375 | ||
231 | case ACPI_RSC_BITMASK: | 376 | case ACPI_RSC_BITMASK: |
@@ -327,6 +472,7 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, | |||
327 | { | 472 | { |
328 | void *source = NULL; | 473 | void *source = NULL; |
329 | void *destination; | 474 | void *destination; |
475 | char *target; | ||
330 | acpi_rsdesc_size aml_length = 0; | 476 | acpi_rsdesc_size aml_length = 0; |
331 | u8 count; | 477 | u8 count; |
332 | u16 temp16 = 0; | 478 | u16 temp16 = 0; |
@@ -334,6 +480,10 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, | |||
334 | 480 | ||
335 | ACPI_FUNCTION_TRACE(rs_convert_resource_to_aml); | 481 | ACPI_FUNCTION_TRACE(rs_convert_resource_to_aml); |
336 | 482 | ||
483 | if (!info) { | ||
484 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
485 | } | ||
486 | |||
337 | /* | 487 | /* |
338 | * First table entry must be ACPI_RSC_INITxxx and must contain the | 488 | * First table entry must be ACPI_RSC_INITxxx and must contain the |
339 | * table length (# of table entries) | 489 | * table length (# of table entries) |
@@ -383,6 +533,14 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, | |||
383 | ((ACPI_GET8(source) & 0x03) << info->value); | 533 | ((ACPI_GET8(source) & 0x03) << info->value); |
384 | break; | 534 | break; |
385 | 535 | ||
536 | case ACPI_RSC_3BITFLAG: | ||
537 | /* | ||
538 | * Mask and shift the flag bits | ||
539 | */ | ||
540 | ACPI_SET8(destination) |= (u8) | ||
541 | ((ACPI_GET8(source) & 0x07) << info->value); | ||
542 | break; | ||
543 | |||
386 | case ACPI_RSC_COUNT: | 544 | case ACPI_RSC_COUNT: |
387 | 545 | ||
388 | item_count = ACPI_GET8(source); | 546 | item_count = ACPI_GET8(source); |
@@ -400,6 +558,63 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, | |||
400 | acpi_rs_set_resource_length(aml_length, aml); | 558 | acpi_rs_set_resource_length(aml_length, aml); |
401 | break; | 559 | break; |
402 | 560 | ||
561 | case ACPI_RSC_COUNT_GPIO_PIN: | ||
562 | |||
563 | item_count = ACPI_GET16(source); | ||
564 | ACPI_SET16(destination) = (u16)aml_length; | ||
565 | |||
566 | aml_length = (u16)(aml_length + item_count * 2); | ||
567 | target = ACPI_ADD_PTR(void, aml, info->value); | ||
568 | ACPI_SET16(target) = (u16)aml_length; | ||
569 | acpi_rs_set_resource_length(aml_length, aml); | ||
570 | break; | ||
571 | |||
572 | case ACPI_RSC_COUNT_GPIO_VEN: | ||
573 | |||
574 | item_count = ACPI_GET16(source); | ||
575 | ACPI_SET16(destination) = (u16)item_count; | ||
576 | |||
577 | aml_length = | ||
578 | (u16)(aml_length + (info->value * item_count)); | ||
579 | acpi_rs_set_resource_length(aml_length, aml); | ||
580 | break; | ||
581 | |||
582 | case ACPI_RSC_COUNT_GPIO_RES: | ||
583 | |||
584 | /* Set resource source string length */ | ||
585 | |||
586 | item_count = ACPI_GET16(source); | ||
587 | ACPI_SET16(destination) = (u16)aml_length; | ||
588 | |||
589 | /* Compute offset for the Vendor Data */ | ||
590 | |||
591 | aml_length = (u16)(aml_length + item_count); | ||
592 | target = ACPI_ADD_PTR(void, aml, info->value); | ||
593 | |||
594 | /* Set vendor offset only if there is vendor data */ | ||
595 | |||
596 | if (resource->data.gpio.vendor_length) { | ||
597 | ACPI_SET16(target) = (u16)aml_length; | ||
598 | } | ||
599 | |||
600 | acpi_rs_set_resource_length(aml_length, aml); | ||
601 | break; | ||
602 | |||
603 | case ACPI_RSC_COUNT_SERIAL_VEN: | ||
604 | |||
605 | item_count = ACPI_GET16(source); | ||
606 | ACPI_SET16(destination) = item_count + info->value; | ||
607 | aml_length = (u16)(aml_length + item_count); | ||
608 | acpi_rs_set_resource_length(aml_length, aml); | ||
609 | break; | ||
610 | |||
611 | case ACPI_RSC_COUNT_SERIAL_RES: | ||
612 | |||
613 | item_count = ACPI_GET16(source); | ||
614 | aml_length = (u16)(aml_length + item_count); | ||
615 | acpi_rs_set_resource_length(aml_length, aml); | ||
616 | break; | ||
617 | |||
403 | case ACPI_RSC_LENGTH: | 618 | case ACPI_RSC_LENGTH: |
404 | 619 | ||
405 | acpi_rs_set_resource_length(info->value, aml); | 620 | acpi_rs_set_resource_length(info->value, aml); |
@@ -417,6 +632,48 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, | |||
417 | info->opcode); | 632 | info->opcode); |
418 | break; | 633 | break; |
419 | 634 | ||
635 | case ACPI_RSC_MOVE_GPIO_PIN: | ||
636 | |||
637 | destination = (char *)ACPI_ADD_PTR(void, aml, | ||
638 | ACPI_GET16 | ||
639 | (destination)); | ||
640 | source = *(u16 **)source; | ||
641 | acpi_rs_move_data(destination, source, item_count, | ||
642 | info->opcode); | ||
643 | break; | ||
644 | |||
645 | case ACPI_RSC_MOVE_GPIO_RES: | ||
646 | |||
647 | /* Used for both resource_source string and vendor_data */ | ||
648 | |||
649 | destination = (char *)ACPI_ADD_PTR(void, aml, | ||
650 | ACPI_GET16 | ||
651 | (destination)); | ||
652 | source = *(u8 **)source; | ||
653 | acpi_rs_move_data(destination, source, item_count, | ||
654 | info->opcode); | ||
655 | break; | ||
656 | |||
657 | case ACPI_RSC_MOVE_SERIAL_VEN: | ||
658 | |||
659 | destination = (char *)ACPI_ADD_PTR(void, aml, | ||
660 | (aml_length - | ||
661 | item_count)); | ||
662 | source = *(u8 **)source; | ||
663 | acpi_rs_move_data(destination, source, item_count, | ||
664 | info->opcode); | ||
665 | break; | ||
666 | |||
667 | case ACPI_RSC_MOVE_SERIAL_RES: | ||
668 | |||
669 | destination = (char *)ACPI_ADD_PTR(void, aml, | ||
670 | (aml_length - | ||
671 | item_count)); | ||
672 | source = *(u8 **)source; | ||
673 | acpi_rs_move_data(destination, source, item_count, | ||
674 | info->opcode); | ||
675 | break; | ||
676 | |||
420 | case ACPI_RSC_ADDRESS: | 677 | case ACPI_RSC_ADDRESS: |
421 | 678 | ||
422 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ | 679 | /* Set the Resource Type, General Flags, and Type-Specific Flags */ |