aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/tbfadt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/tbfadt.c')
-rw-r--r--drivers/acpi/acpica/tbfadt.c246
1 files changed, 133 insertions, 113 deletions
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 4b683ccd4a94..a8191efd9aa6 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -57,6 +57,8 @@ static void acpi_tb_convert_fadt(void);
57 57
58static void acpi_tb_validate_fadt(void); 58static void acpi_tb_validate_fadt(void);
59 59
60static void acpi_tb_setup_fadt_registers(void);
61
60/* Table for conversion of FADT to common internal format and FADT validation */ 62/* Table for conversion of FADT to common internal format and FADT validation */
61 63
62typedef struct acpi_fadt_info { 64typedef struct acpi_fadt_info {
@@ -132,6 +134,35 @@ static struct acpi_fadt_info fadt_info_table[] = {
132 134
133#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) 135#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
134 136
137/* Table used to split Event Blocks into separate status/enable registers */
138
139typedef struct acpi_fadt_pm_info {
140 struct acpi_generic_address *target;
141 u8 source;
142 u8 register_num;
143
144} acpi_fadt_pm_info;
145
146static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
147 {&acpi_gbl_xpm1a_status,
148 ACPI_FADT_OFFSET(xpm1a_event_block),
149 0},
150
151 {&acpi_gbl_xpm1a_enable,
152 ACPI_FADT_OFFSET(xpm1a_event_block),
153 1},
154
155 {&acpi_gbl_xpm1b_status,
156 ACPI_FADT_OFFSET(xpm1b_event_block),
157 0},
158
159 {&acpi_gbl_xpm1b_enable,
160 ACPI_FADT_OFFSET(xpm1b_event_block),
161 1}
162};
163
164#define ACPI_FADT_PM_INFO_ENTRIES (sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info))
165
135/******************************************************************************* 166/*******************************************************************************
136 * 167 *
137 * FUNCTION: acpi_tb_init_generic_address 168 * FUNCTION: acpi_tb_init_generic_address
@@ -207,7 +238,7 @@ void acpi_tb_parse_fadt(u32 table_index)
207 */ 238 */
208 (void)acpi_tb_verify_checksum(table, length); 239 (void)acpi_tb_verify_checksum(table, length);
209 240
210 /* Obtain a local copy of the FADT in common ACPI 2.0+ format */ 241 /* Create a local copy of the FADT in common ACPI 2.0+ format */
211 242
212 acpi_tb_create_local_fadt(table, length); 243 acpi_tb_create_local_fadt(table, length);
213 244
@@ -265,11 +296,17 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
265 ACPI_MEMCPY(&acpi_gbl_FADT, table, 296 ACPI_MEMCPY(&acpi_gbl_FADT, table,
266 ACPI_MIN(length, sizeof(struct acpi_table_fadt))); 297 ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
267 298
268 /* 299 /* Convert the local copy of the FADT to the common internal format */
269 * 1) Convert the local copy of the FADT to the common internal format 300
270 * 2) Validate some of the important values within the FADT
271 */
272 acpi_tb_convert_fadt(); 301 acpi_tb_convert_fadt();
302
303 /* Validate FADT values now, before we make any changes */
304
305 acpi_tb_validate_fadt();
306
307 /* Initialize the global ACPI register structures */
308
309 acpi_tb_setup_fadt_registers();
273} 310}
274 311
275/******************************************************************************* 312/*******************************************************************************
@@ -303,8 +340,6 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
303 340
304static void acpi_tb_convert_fadt(void) 341static void acpi_tb_convert_fadt(void)
305{ 342{
306 u8 pm1_register_bit_width;
307 u8 pm1_register_byte_width;
308 struct acpi_generic_address *target64; 343 struct acpi_generic_address *target64;
309 u32 i; 344 u32 i;
310 345
@@ -379,112 +414,6 @@ static void acpi_tb_convert_fadt(void)
379 address32)); 414 address32));
380 } 415 }
381 } 416 }
382
383 /* Validate FADT values now, before we make any changes */
384
385 acpi_tb_validate_fadt();
386
387 /*
388 * Optionally check all register lengths against the default values and
389 * update them if they are incorrect.
390 */
391 if (acpi_gbl_use_default_register_widths) {
392 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
393 target64 =
394 ACPI_ADD_PTR(struct acpi_generic_address,
395 &acpi_gbl_FADT,
396 fadt_info_table[i].address64);
397
398 /*
399 * If a valid register (Address != 0) and the (default_length > 0)
400 * (Not a GPE register), then check the width against the default.
401 */
402 if ((target64->address) &&
403 (fadt_info_table[i].default_length > 0) &&
404 (fadt_info_table[i].default_length !=
405 target64->bit_width)) {
406 ACPI_WARNING((AE_INFO,
407 "Invalid length for %s: %d, using default %d",
408 fadt_info_table[i].name,
409 target64->bit_width,
410 fadt_info_table[i].
411 default_length));
412
413 /* Incorrect size, set width to the default */
414
415 target64->bit_width =
416 fadt_info_table[i].default_length;
417 }
418 }
419 }
420
421 /*
422 * Get the length of the individual PM1 registers (enable and status).
423 * Each register is defined to be (event block length / 2).
424 */
425 pm1_register_bit_width =
426 (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width);
427 pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width);
428
429 /*
430 * Adjust the lengths of the PM1 Event Blocks so that they can be used to
431 * access the PM1 status register(s). Use (width / 2)
432 */
433 acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width;
434 acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width;
435
436 /*
437 * Calculate separate GAS structs for the PM1 Enable registers.
438 * These addresses do not appear (directly) in the FADT, so it is
439 * useful to calculate them once, here.
440 *
441 * The PM event blocks are split into two register blocks, first is the
442 * PM Status Register block, followed immediately by the PM Enable
443 * Register block. Each is of length (xpm1x_event_block.bit_width/2).
444 *
445 * On various systems the v2 fields (and particularly the bit widths)
446 * cannot be relied upon, though. Hence resort to using the v1 length
447 * here (and warn about the inconsistency).
448 */
449 if (acpi_gbl_FADT.xpm1a_event_block.bit_width
450 != acpi_gbl_FADT.pm1_event_length * 8)
451 printk(KERN_WARNING "FADT: "
452 "X_PM1a_EVT_BLK.bit_width (%u) does not match"
453 " PM1_EVT_LEN (%u)\n",
454 acpi_gbl_FADT.xpm1a_event_block.bit_width,
455 acpi_gbl_FADT.pm1_event_length);
456
457 /* The PM1A register block is required */
458
459 acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
460 acpi_gbl_FADT.xpm1a_event_block.space_id,
461 pm1_register_byte_width,
462 (acpi_gbl_FADT.xpm1a_event_block.address +
463 pm1_register_byte_width));
464 /* Don't forget to copy space_id of the GAS */
465 acpi_gbl_xpm1a_enable.space_id =
466 acpi_gbl_FADT.xpm1a_event_block.space_id;
467
468 /* The PM1B register block is optional, ignore if not present */
469
470 if (acpi_gbl_FADT.xpm1b_event_block.address) {
471 if (acpi_gbl_FADT.xpm1b_event_block.bit_width
472 != acpi_gbl_FADT.pm1_event_length * 8)
473 printk(KERN_WARNING "FADT: "
474 "X_PM1b_EVT_BLK.bit_width (%u) does not match"
475 " PM1_EVT_LEN (%u)\n",
476 acpi_gbl_FADT.xpm1b_event_block.bit_width,
477 acpi_gbl_FADT.pm1_event_length);
478 acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
479 acpi_gbl_FADT.xpm1b_event_block.space_id,
480 pm1_register_byte_width,
481 (acpi_gbl_FADT.xpm1b_event_block.
482 address + pm1_register_byte_width));
483 /* Don't forget to copy space_id of the GAS */
484 acpi_gbl_xpm1b_enable.space_id =
485 acpi_gbl_FADT.xpm1b_event_block.space_id;
486
487 }
488} 417}
489 418
490/****************************************************************************** 419/******************************************************************************
@@ -607,3 +536,94 @@ static void acpi_tb_validate_fadt(void)
607 } 536 }
608 } 537 }
609} 538}
539
540/******************************************************************************
541 *
542 * FUNCTION: acpi_tb_setup_fadt_registers
543 *
544 * PARAMETERS: None, uses acpi_gbl_FADT.
545 *
546 * RETURN: None
547 *
548 * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
549 * force FADT register definitions to their default lengths.
550 *
551 ******************************************************************************/
552
553static void acpi_tb_setup_fadt_registers(void)
554{
555 struct acpi_generic_address *target64;
556 struct acpi_generic_address *source64;
557 u8 pm1_register_byte_width;
558 u32 i;
559
560 /*
561 * Optionally check all register lengths against the default values and
562 * update them if they are incorrect.
563 */
564 if (acpi_gbl_use_default_register_widths) {
565 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
566 target64 =
567 ACPI_ADD_PTR(struct acpi_generic_address,
568 &acpi_gbl_FADT,
569 fadt_info_table[i].address64);
570
571 /*
572 * If a valid register (Address != 0) and the (default_length > 0)
573 * (Not a GPE register), then check the width against the default.
574 */
575 if ((target64->address) &&
576 (fadt_info_table[i].default_length > 0) &&
577 (fadt_info_table[i].default_length !=
578 target64->bit_width)) {
579 ACPI_WARNING((AE_INFO,
580 "Invalid length for %s: %d, using default %d",
581 fadt_info_table[i].name,
582 target64->bit_width,
583 fadt_info_table[i].
584 default_length));
585
586 /* Incorrect size, set width to the default */
587
588 target64->bit_width =
589 fadt_info_table[i].default_length;
590 }
591 }
592 }
593
594 /*
595 * Get the length of the individual PM1 registers (enable and status).
596 * Each register is defined to be (event block length / 2). Extra divide
597 * by 8 converts bits to bytes.
598 */
599 pm1_register_byte_width =
600 (u8)ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width);
601
602 /*
603 * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
604 * registers. These addresses do not appear (directly) in the FADT, so it
605 * is useful to pre-calculate them from the PM1 Event Block definitions.
606 *
607 * The PM event blocks are split into two register blocks, first is the
608 * PM Status Register block, followed immediately by the PM Enable
609 * Register block. Each is of length (pm1_event_length/2)
610 *
611 * Note: The PM1A event block is required by the ACPI specification.
612 * However, the PM1B event block is optional and is rarely, if ever,
613 * used.
614 */
615
616 for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) {
617 source64 =
618 ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
619 fadt_pm_info_table[i].source);
620
621 acpi_tb_init_generic_address(fadt_pm_info_table[i].target,
622 source64->space_id,
623 pm1_register_byte_width,
624 source64->address +
625 (fadt_pm_info_table[i].
626 register_num *
627 pm1_register_byte_width));
628 }
629}