Merge branches 'pm-cpufreq', 'pm-cpuidle', 'pm-devfreq', 'pm-opp' and 'pm-tools'
[linux-drm-fsl-dcu.git] / drivers / acpi / acpica / tbfadt.c
index ec14588254d433e63e1b17352f16f3702b9a09f6..7d2486005e3f24fe0ca38d61d8dc36d21362066e 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -52,7 +52,8 @@ ACPI_MODULE_NAME("tbfadt")
 static void
 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
                             u8 space_id,
-                            u8 byte_width, u64 address, char *register_name);
+                            u8 byte_width,
+                            u64 address, char *register_name, u8 flags);
 
 static void acpi_tb_convert_fadt(void);
 
@@ -69,13 +70,14 @@ typedef struct acpi_fadt_info {
        u16 address32;
        u16 length;
        u8 default_length;
-       u8 type;
+       u8 flags;
 
 } acpi_fadt_info;
 
 #define ACPI_FADT_OPTIONAL          0
 #define ACPI_FADT_REQUIRED          1
 #define ACPI_FADT_SEPARATE_LENGTH   2
+#define ACPI_FADT_GPE_REGISTER      4
 
 static struct acpi_fadt_info fadt_info_table[] = {
        {"Pm1aEventBlock",
@@ -125,14 +127,14 @@ static struct acpi_fadt_info fadt_info_table[] = {
         ACPI_FADT_OFFSET(gpe0_block),
         ACPI_FADT_OFFSET(gpe0_block_length),
         0,
-        ACPI_FADT_SEPARATE_LENGTH},
+        ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER},
 
        {"Gpe1Block",
         ACPI_FADT_OFFSET(xgpe1_block),
         ACPI_FADT_OFFSET(gpe1_block),
         ACPI_FADT_OFFSET(gpe1_block_length),
         0,
-        ACPI_FADT_SEPARATE_LENGTH}
+        ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}
 };
 
 #define ACPI_FADT_INFO_ENTRIES \
@@ -189,19 +191,29 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
 static void
 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
                             u8 space_id,
-                            u8 byte_width, u64 address, char *register_name)
+                            u8 byte_width,
+                            u64 address, char *register_name, u8 flags)
 {
        u8 bit_width;
 
-       /* Bit width field in the GAS is only one byte long, 255 max */
-
+       /*
+        * Bit width field in the GAS is only one byte long, 255 max.
+        * Check for bit_width overflow in GAS.
+        */
        bit_width = (u8)(byte_width * 8);
-
-       if (byte_width > 31) {  /* (31*8)=248 */
-               ACPI_ERROR((AE_INFO,
-                           "%s - 32-bit FADT register is too long (%u bytes, %u bits) "
-                           "to convert to GAS struct - 255 bits max, truncating",
-                           register_name, byte_width, (byte_width * 8)));
+       if (byte_width > 31) {  /* (31*8)=248, (32*8)=256 */
+               /*
+                * No error for GPE blocks, because we do not use the bit_width
+                * for GPEs, the legacy length (byte_width) is used instead to
+                * allow for a large number of GPEs.
+                */
+               if (!(flags & ACPI_FADT_GPE_REGISTER)) {
+                       ACPI_ERROR((AE_INFO,
+                                   "%s - 32-bit FADT register is too long (%u bytes, %u bits) "
+                                   "to convert to GAS struct - 255 bits max, truncating",
+                                   register_name, byte_width,
+                                   (byte_width * 8)));
+               }
 
                bit_width = 255;
        }
@@ -332,15 +344,15 @@ void acpi_tb_parse_fadt(u32 table_index)
 
        /* Obtain the DSDT and FACS tables via their addresses within the FADT */
 
-       acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
-                             ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
+       acpi_tb_install_fixed_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
+                                   ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
 
        /* If Hardware Reduced flag is set, there is no FACS */
 
        if (!acpi_gbl_reduced_hardware) {
-               acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.
-                                     Xfacs, ACPI_SIG_FACS,
-                                     ACPI_TABLE_INDEX_FACS);
+               acpi_tb_install_fixed_table((acpi_physical_address)
+                                           acpi_gbl_FADT.Xfacs, ACPI_SIG_FACS,
+                                           ACPI_TABLE_INDEX_FACS);
        }
 }
 
@@ -450,6 +462,7 @@ static void acpi_tb_convert_fadt(void)
        struct acpi_generic_address *address64;
        u32 address32;
        u8 length;
+       u8 flags;
        u32 i;
 
        /*
@@ -515,6 +528,7 @@ static void acpi_tb_convert_fadt(void)
                                       fadt_info_table[i].length);
 
                name = fadt_info_table[i].name;
+               flags = fadt_info_table[i].flags;
 
                /*
                 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
@@ -554,7 +568,7 @@ static void acpi_tb_convert_fadt(void)
                                                                           [i].
                                                                           length),
                                                             (u64)address32,
-                                                            name);
+                                                            name, flags);
                        } else if (address64->address != (u64)address32) {
 
                                /* Address mismatch */
@@ -582,7 +596,8 @@ static void acpi_tb_convert_fadt(void)
                                                                      length),
                                                                     (u64)
                                                                     address32,
-                                                                    name);
+                                                                    name,
+                                                                    flags);
                                }
                        }
                }
@@ -603,7 +618,7 @@ static void acpi_tb_convert_fadt(void)
                                           address64->bit_width));
                }
 
-               if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) {
+               if (fadt_info_table[i].flags & ACPI_FADT_REQUIRED) {
                        /*
                         * Field is required (Pm1a_event, Pm1a_control).
                         * Both the address and length must be non-zero.
@@ -617,7 +632,7 @@ static void acpi_tb_convert_fadt(void)
                                                                    address),
                                                 length));
                        }
-               } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
+               } else if (fadt_info_table[i].flags & ACPI_FADT_SEPARATE_LENGTH) {
                        /*
                         * Field is optional (Pm2_control, GPE0, GPE1) AND has its own
                         * length field. If present, both the address and length must
@@ -726,7 +741,7 @@ static void acpi_tb_setup_fadt_registers(void)
                                                     (fadt_pm_info_table[i].
                                                      register_num *
                                                      pm1_register_byte_width),
-                                                    "PmRegisters");
+                                                    "PmRegisters", 0);
                }
        }
 }