@@ -25,6 +25,7 @@
acpi_status acpi_os_initialize1(void);
int init_acpi_device_notify(void);
+int acpi_load_osdt(void);
int acpi_scan_init(void);
void acpi_pci_root_init(void);
void acpi_pci_link_init(void);
@@ -612,7 +612,7 @@ static const char * const table_sigs[] = {
ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI, ACPI_SIG_TCPA,
ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT, ACPI_SIG_WDDT,
ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT,
- ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL };
+ ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, ACPI_SIG_OSDT, NULL };
#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
@@ -770,6 +770,47 @@ acpi_os_physical_table_override(struct acpi_table_header *existing_table,
}
return AE_OK;
}
+
+int __init acpi_load_osdt(void)
+{
+ int table_offset = 0;
+ struct acpi_table_header table, *p;
+ acpi_status status;
+
+ if (!acpi_tables_addr)
+ return 0;
+
+ do {
+ if (table_offset + ACPI_HEADER_SIZE > all_tables_size)
+ return 0;
+
+ p = acpi_os_map_memory(table_offset + acpi_tables_addr,
+ ACPI_HEADER_SIZE);
+ table = *p;
+ acpi_os_unmap_memory(p, ACPI_HEADER_SIZE);
+
+ if (table_offset + table.length > all_tables_size)
+ return 0;
+
+ if (memcmp(ACPI_SIG_OSDT, table.signature, 4)) {
+ table_offset += table.length;
+ continue;
+ }
+
+ status = acpi_install_table(table_offset + acpi_tables_addr,
+ ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
+ if (ACPI_FAILURE(status))
+ pr_warn(PREFIX "Override [%4.4s-%8.8s] failed!",
+ table.signature, table.oem_table_id);
+ else
+ acpi_table_taint(&table);
+
+ table_offset += table.length;
+ } while (table_offset + ACPI_HEADER_SIZE < all_tables_size);
+
+ return 0;
+}
+
#else
acpi_status
acpi_os_physical_table_override(struct acpi_table_header *existing_table,
@@ -780,6 +821,11 @@ acpi_os_physical_table_override(struct acpi_table_header *existing_table,
*address = 0;
return AE_OK;
}
+
+int __init acpi_load_osdt(void)
+{
+ return 0;
+}
#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
acpi_status
@@ -37,6 +37,7 @@
#include <linux/acpi.h>
#include <linux/bootmem.h>
+#include "internal.h"
#define ACPI_MAX_TABLES 128
static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" };
@@ -403,6 +404,8 @@ int __init acpi_table_init(void)
if (ACPI_FAILURE(status))
return -EINVAL;
+ acpi_load_osdt();
+
check_multiple_madt();
return 0;
}
This patch uses ACPI_INITRD_TABLE_OVERRIDE feature to load the OSDT tables from initrd and install them at boot time. Signed-off-by: Zhang Rui <rui.zhang@intel.com> --- drivers/acpi/internal.h | 1 + drivers/acpi/osl.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- drivers/acpi/tables.c | 3 +++ 3 files changed, 51 insertions(+), 1 deletion(-)