static void acpi_tb_convert_fadt(void);
 
-static void acpi_tb_validate_fadt(void);
-
 static void acpi_tb_setup_fadt_registers(void);
 
+static u64
+acpi_tb_select_address(char *register_name, u32 address32, u64 address64);
+
 /* Table for conversion of FADT to common internal format and FADT validation */
 
 typedef struct acpi_fadt_info {
  *              space_id            - ACPI Space ID for this register
  *              byte_width          - Width of this register
  *              address             - Address of the register
+ *              register_name       - ASCII name of the ACPI register
  *
  * RETURN:      None
  *
        generic_address->access_width = 0;      /* Access width ANY */
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_select_address
+ *
+ * PARAMETERS:  register_name       - ASCII name of the ACPI register
+ *              address32           - 32-bit address of the register
+ *              address64           - 64-bit address of the register
+ *
+ * RETURN:      The resolved 64-bit address
+ *
+ * DESCRIPTION: Select between 32-bit and 64-bit versions of addresses within
+ *              the FADT. Used for the FACS and DSDT addresses.
+ *
+ * NOTES:
+ *
+ * Check for FACS and DSDT address mismatches. An address mismatch between
+ * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
+ * DSDT/X_DSDT) could be a corrupted address field or it might indicate
+ * the presence of two FACS or two DSDT tables.
+ *
+ * November 2013:
+ * By default, as per the ACPICA specification, a valid 64-bit address is
+ * used regardless of the value of the 32-bit address. However, this
+ * behavior can be overridden via the acpi_gbl_use32_bit_fadt_addresses flag.
+ *
+ ******************************************************************************/
+
+static u64
+acpi_tb_select_address(char *register_name, u32 address32, u64 address64)
+{
+
+       if (!address64) {
+
+               /* 64-bit address is zero, use 32-bit address */
+
+               return ((u64)address32);
+       }
+
+       if (address32 && (address64 != (u64)address32)) {
+
+               /* Address mismatch between 32-bit and 64-bit versions */
+
+               ACPI_BIOS_WARNING((AE_INFO,
+                                  "32/64X %s address mismatch in FADT: "
+                                  "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
+                                  register_name, address32,
+                                  ACPI_FORMAT_UINT64(address64),
+                                  acpi_gbl_use32_bit_fadt_addresses ? 32 :
+                                  64));
+
+               /* 32-bit address override */
+
+               if (acpi_gbl_use32_bit_fadt_addresses) {
+                       return ((u64)address32);
+               }
+       }
+
+       /* Default is to use the 64-bit address */
+
+       return (address64);
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_parse_fadt
 
        acpi_tb_convert_fadt();
 
-       /* Validate FADT values now, before we make any changes */
-
-       acpi_tb_validate_fadt();
-
        /* Initialize the global ACPI register structures */
 
        acpi_tb_setup_fadt_registers();
  *
  * FUNCTION:    acpi_tb_convert_fadt
  *
- * PARAMETERS:  None, uses acpi_gbl_FADT
+ * PARAMETERS:  none - acpi_gbl_FADT is used.
  *
  * RETURN:      None
  *
  * DESCRIPTION: Converts all versions of the FADT to a common internal format.
- *              Expand 32-bit addresses to 64-bit as necessary.
+ *              Expand 32-bit addresses to 64-bit as necessary. Also validate
+ *              important fields within the FADT.
  *
- * NOTE:        acpi_gbl_FADT must be of size (struct acpi_table_fadt),
- *              and must contain a copy of the actual FADT.
+ * NOTE:        acpi_gbl_FADT must be of size (struct acpi_table_fadt), and must
+ *              contain a copy of the actual BIOS-provided FADT.
  *
  * Notes on 64-bit register addresses:
  *
  * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
  * fields of the FADT for all ACPI register addresses.
  *
- * The 64-bit "X" fields are optional extensions to the original 32-bit FADT
+ * The 64-bit X fields are optional extensions to the original 32-bit FADT
  * V1.0 fields. Even if they are present in the FADT, they are optional and
  * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
- * 32-bit V1.0 fields if the corresponding X field is zero.
+ * 32-bit V1.0 fields to the 64-bit X fields if the the 64-bit X field is
+ * originally zero.
  *
- * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the
- * corresponding "X" fields in the internal FADT.
+ * For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address
+ * fields are expanded to the corresponding 64-bit X fields in the internal
+ * common FADT.
  *
  * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
- * to the corresponding 64-bit X fields. For compatibility with other ACPI
- * implementations, we ignore the 64-bit field if the 32-bit field is valid,
- * regardless of whether the host OS is 32-bit or 64-bit.
+ * to the corresponding 64-bit X fields, if the 64-bit field is originally
+ * zero. Adhering to the ACPI specification, we completely ignore the 32-bit
+ * field if the 64-bit field is valid, regardless of whether the host OS is
+ * 32-bit or 64-bit.
+ *
+ * Possible additional checks:
+ *  (acpi_gbl_FADT.pm1_event_length >= 4)
+ *  (acpi_gbl_FADT.pm1_control_length >= 2)
+ *  (acpi_gbl_FADT.pm_timer_length >= 4)
+ *  Gpe block lengths must be multiple of 2
  *
  ******************************************************************************/
 
 static void acpi_tb_convert_fadt(void)
 {
+       char *name;
        struct acpi_generic_address *address64;
        u32 address32;
+       u8 length;
        u32 i;
 
-       /*
-        * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
-        * Later code will always use the X 64-bit field. Also, check for an
-        * address mismatch between the 32-bit and 64-bit address fields
-        * (FIRMWARE_CTRL/X_FIRMWARE_CTRL, DSDT/X_DSDT) which would indicate
-        * the presence of two FACS or two DSDT tables.
-        */
-       if (!acpi_gbl_FADT.Xfacs) {
-               acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
-       } else if (acpi_gbl_FADT.facs &&
-                  (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
-               ACPI_WARNING((AE_INFO,
-                   "32/64 FACS address mismatch in FADT - two FACS tables!"));
-       }
-
-       if (!acpi_gbl_FADT.Xdsdt) {
-               acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
-       } else if (acpi_gbl_FADT.dsdt &&
-                  (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
-               ACPI_WARNING((AE_INFO,
-                   "32/64 DSDT address mismatch in FADT - two DSDT tables!"));
-       }
-
        /*
         * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
         * should be zero are indeed zero. This will workaround BIOSs that
                acpi_gbl_FADT.boot_flags = 0;
        }
 
-       /* Update the local FADT table header length */
-
-       acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
-
        /*
-        * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
-        * generic address structures as necessary. Later code will always use
-        * the 64-bit address structures.
-        *
-        * March 2009:
-        * We now always use the 32-bit address if it is valid (non-null). This
-        * is not in accordance with the ACPI specification which states that
-        * the 64-bit address supersedes the 32-bit version, but we do this for
-        * compatibility with other ACPI implementations. Most notably, in the
-        * case where both the 32 and 64 versions are non-null, we use the 32-bit
-        * version. This is the only address that is guaranteed to have been
-        * tested by the BIOS manufacturer.
+        * Now we can update the local FADT length to the length of the
+        * current FADT version as defined by the ACPI specification.
+        * Thus, we will have a common FADT internally.
         */
-       for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
-               address32 = *ACPI_ADD_PTR(u32,
-                                         &acpi_gbl_FADT,
-                                         fadt_info_table[i].address32);
-
-               address64 = ACPI_ADD_PTR(struct acpi_generic_address,
-                                        &acpi_gbl_FADT,
-                                        fadt_info_table[i].address64);
-
-               /*
-                * If both 32- and 64-bit addresses are valid (non-zero),
-                * they must match.
-                */
-               if (address64->address && address32 &&
-                   (address64->address != (u64)address32)) {
-                       ACPI_BIOS_ERROR((AE_INFO,
-                                        "32/64X address mismatch in FADT/%s: "
-                                        "0x%8.8X/0x%8.8X%8.8X, using 32",
-                                        fadt_info_table[i].name, address32,
-                                        ACPI_FORMAT_UINT64(address64->
-                                                           address)));
-               }
-
-               /* Always use 32-bit address if it is valid (non-null) */
-
-               if (address32) {
-                       /*
-                        * Copy the 32-bit address to the 64-bit GAS structure. The
-                        * Space ID is always I/O for 32-bit legacy address fields
-                       */
-                       acpi_tb_init_generic_address(address64,
-                                                    ACPI_ADR_SPACE_SYSTEM_IO,
-                                                    *ACPI_ADD_PTR(u8,
-                                                                  &acpi_gbl_FADT,
-                                                                  fadt_info_table
-                                                                  [i].length),
-                                                    (u64) address32,
-                                                    fadt_info_table[i].name);
-               }
-       }
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_validate_fadt
- *
- * PARAMETERS:  table           - Pointer to the FADT to be validated
- *
- * RETURN:      None
- *
- * DESCRIPTION: Validate various important fields within the FADT. If a problem
- *              is found, issue a message, but no status is returned.
- *              Used by both the table manager and the disassembler.
- *
- * Possible additional checks:
- * (acpi_gbl_FADT.pm1_event_length >= 4)
- * (acpi_gbl_FADT.pm1_control_length >= 2)
- * (acpi_gbl_FADT.pm_timer_length >= 4)
- * Gpe block lengths must be multiple of 2
- *
- ******************************************************************************/
-
-static void acpi_tb_validate_fadt(void)
-{
-       char *name;
-       struct acpi_generic_address *address64;
-       u8 length;
-       u32 i;
+       acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
 
        /*
-        * Check for FACS and DSDT address mismatches. An address mismatch between
-        * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
-        * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables.
+        * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
+        * Later ACPICA code will always use the X 64-bit field.
         */
-       if (acpi_gbl_FADT.facs &&
-           (acpi_gbl_FADT.Xfacs != (u64)acpi_gbl_FADT.facs)) {
-               ACPI_BIOS_WARNING((AE_INFO,
-                                  "32/64X FACS address mismatch in FADT - "
-                                  "0x%8.8X/0x%8.8X%8.8X, using 32",
-                                  acpi_gbl_FADT.facs,
-                                  ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
-
-               acpi_gbl_FADT.Xfacs = (u64)acpi_gbl_FADT.facs;
-       }
-
-       if (acpi_gbl_FADT.dsdt &&
-           (acpi_gbl_FADT.Xdsdt != (u64)acpi_gbl_FADT.dsdt)) {
-               ACPI_BIOS_WARNING((AE_INFO,
-                                  "32/64X DSDT address mismatch in FADT - "
-                                  "0x%8.8X/0x%8.8X%8.8X, using 32",
-                                  acpi_gbl_FADT.dsdt,
-                                  ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
+       acpi_gbl_FADT.Xfacs = acpi_tb_select_address("FACS",
+                                                    acpi_gbl_FADT.facs,
+                                                    acpi_gbl_FADT.Xfacs);
 
-               acpi_gbl_FADT.Xdsdt = (u64)acpi_gbl_FADT.dsdt;
-       }
+       acpi_gbl_FADT.Xdsdt = acpi_tb_select_address("DSDT",
+                                                    acpi_gbl_FADT.dsdt,
+                                                    acpi_gbl_FADT.Xdsdt);
 
        /* If Hardware Reduced flag is set, we are all done */
 
 
        for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
                /*
-                * Generate pointer to the 64-bit address, get the register
-                * length (width) and the register name
+                * Get the 32-bit and 64-bit addresses, as well as the register
+                * length and register name.
                 */
+               address32 = *ACPI_ADD_PTR(u32,
+                                         &acpi_gbl_FADT,
+                                         fadt_info_table[i].address32);
+
                address64 = ACPI_ADD_PTR(struct acpi_generic_address,
                                         &acpi_gbl_FADT,
                                         fadt_info_table[i].address64);
-               length =
-                   *ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
-                                 fadt_info_table[i].length);
+
+               length = *ACPI_ADD_PTR(u8,
+                                      &acpi_gbl_FADT,
+                                      fadt_info_table[i].length);
+
                name = fadt_info_table[i].name;
 
+               /*
+                * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
+                * generic address structures as necessary. Later code will always use
+                * the 64-bit address structures.
+                *
+                * November 2013:
+                * Now always use the 64-bit address if it is valid (non-zero), in
+                * accordance with the ACPI specification which states that a 64-bit
+                * address supersedes the 32-bit version. This behavior can be
+                * overridden by the acpi_gbl_use32_bit_fadt_addresses flag.
+                *
+                * During 64-bit address construction and verification,
+                * these cases are handled:
+                *
+                * Address32 zero, Address64 [don't care]   - Use Address64
+                *
+                * Address32 non-zero, Address64 zero       - Copy/use Address32
+                * Address32 non-zero == Address64 non-zero - Use Address64
+                * Address32 non-zero != Address64 non-zero - Warning, use Address64
+                *
+                * Override: if acpi_gbl_use32_bit_fadt_addresses is TRUE, and:
+                * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32
+                *
+                * Note: space_id is always I/O for 32-bit legacy address fields
+                */
+               if (address32) {
+                       if (!address64->address) {
+
+                               /* 64-bit address is zero, use 32-bit address */
+
+                               acpi_tb_init_generic_address(address64,
+                                                            ACPI_ADR_SPACE_SYSTEM_IO,
+                                                            *ACPI_ADD_PTR(u8,
+                                                                          &acpi_gbl_FADT,
+                                                                          fadt_info_table
+                                                                          [i].
+                                                                          length),
+                                                            (u64)address32,
+                                                            name);
+                       } else if (address64->address != (u64)address32) {
+
+                               /* Address mismatch */
+
+                               ACPI_BIOS_WARNING((AE_INFO,
+                                                  "32/64X address mismatch in FADT/%s: "
+                                                  "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
+                                                  name, address32,
+                                                  ACPI_FORMAT_UINT64
+                                                  (address64->address),
+                                                  acpi_gbl_use32_bit_fadt_addresses
+                                                  ? 32 : 64));
+
+                               if (acpi_gbl_use32_bit_fadt_addresses) {
+
+                                       /* 32-bit address override */
+
+                                       acpi_tb_init_generic_address(address64,
+                                                                    ACPI_ADR_SPACE_SYSTEM_IO,
+                                                                    *ACPI_ADD_PTR
+                                                                    (u8,
+                                                                     &acpi_gbl_FADT,
+                                                                     fadt_info_table
+                                                                     [i].
+                                                                     length),
+                                                                    (u64)
+                                                                    address32,
+                                                                    name);
+                               }
+                       }
+               }
+
                /*
                 * For each extended field, check for length mismatch between the
                 * legacy length field and the corresponding 64-bit X length field.