aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/rsmisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/rsmisc.c')
-rw-r--r--drivers/acpi/acpica/rsmisc.c269
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 */