From 5ae74f2cc2f150c1a5cee54cabbd71dd0661285a Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Mon, 11 Apr 2016 10:13:18 +0800 Subject: ACPI / tables: Move table override mechanisms to tables.c This patch moves acpi_os_table_override() and acpi_os_physical_table_override() to tables.c. Along with the mechanisms, acpi_initrd_initialize_tables() is also moved to tables.c to form a static function. The following functions are renamed according to this change: 1. acpi_initrd_override() -> renamed to early_acpi_table_init(), which invokes acpi_table_initrd_init() 2. acpi_os_physical_table_override() -> which invokes acpi_table_initrd_override() 3. acpi_initialize_initrd_tables() -> renamed to acpi_table_initrd_scan() Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/internal.h | 1 - drivers/acpi/osl.c | 274 --------------------------------------------- drivers/acpi/tables.c | 292 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 291 insertions(+), 276 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 7c188472d9c2..1b0e6fd6b280 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -20,7 +20,6 @@ #define PREFIX "ACPI: " -void acpi_initrd_initialize_tables(void); acpi_status acpi_os_initialize1(void); void init_acpi_device_notify(void); int acpi_scan_init(void); diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 814d5f83b75e..0796ad96dc32 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -602,280 +602,6 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val, return AE_OK; } -static void acpi_table_taint(struct acpi_table_header *table) -{ - pr_warn(PREFIX - "Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n", - table->signature, table->oem_table_id); - add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE); -} - -#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE -#include -#include - -static u64 acpi_tables_addr; -static int all_tables_size; - -/* Copied from acpica/tbutils.c:acpi_tb_checksum() */ -static u8 __init acpi_table_checksum(u8 *buffer, u32 length) -{ - u8 sum = 0; - u8 *end = buffer + length; - - while (buffer < end) - sum = (u8) (sum + *(buffer++)); - return sum; -} - -/* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */ -static const char * const table_sigs[] = { - ACPI_SIG_BERT, ACPI_SIG_CPEP, ACPI_SIG_ECDT, ACPI_SIG_EINJ, - ACPI_SIG_ERST, ACPI_SIG_HEST, ACPI_SIG_MADT, ACPI_SIG_MSCT, - ACPI_SIG_SBST, ACPI_SIG_SLIT, ACPI_SIG_SRAT, ACPI_SIG_ASF, - ACPI_SIG_BOOT, ACPI_SIG_DBGP, ACPI_SIG_DMAR, ACPI_SIG_HPET, - ACPI_SIG_IBFT, ACPI_SIG_IVRS, ACPI_SIG_MCFG, ACPI_SIG_MCHI, - 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 }; - -#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) - -#define ACPI_OVERRIDE_TABLES 64 -static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES]; -static DECLARE_BITMAP(acpi_initrd_installed, ACPI_OVERRIDE_TABLES); - -#define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT) - -void __init acpi_initrd_override(void *data, size_t size) -{ - int sig, no, table_nr = 0, total_offset = 0; - long offset = 0; - struct acpi_table_header *table; - char cpio_path[32] = "kernel/firmware/acpi/"; - struct cpio_data file; - - if (data == NULL || size == 0) - return; - - for (no = 0; no < ACPI_OVERRIDE_TABLES; no++) { - file = find_cpio_data(cpio_path, data, size, &offset); - if (!file.data) - break; - - data += offset; - size -= offset; - - if (file.size < sizeof(struct acpi_table_header)) { - pr_err("ACPI OVERRIDE: Table smaller than ACPI header [%s%s]\n", - cpio_path, file.name); - continue; - } - - table = file.data; - - for (sig = 0; table_sigs[sig]; sig++) - if (!memcmp(table->signature, table_sigs[sig], 4)) - break; - - if (!table_sigs[sig]) { - pr_err("ACPI OVERRIDE: Unknown signature [%s%s]\n", - cpio_path, file.name); - continue; - } - if (file.size != table->length) { - pr_err("ACPI OVERRIDE: File length does not match table length [%s%s]\n", - cpio_path, file.name); - continue; - } - if (acpi_table_checksum(file.data, table->length)) { - pr_err("ACPI OVERRIDE: Bad table checksum [%s%s]\n", - cpio_path, file.name); - continue; - } - - pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n", - table->signature, cpio_path, file.name, table->length); - - all_tables_size += table->length; - acpi_initrd_files[table_nr].data = file.data; - acpi_initrd_files[table_nr].size = file.size; - table_nr++; - } - if (table_nr == 0) - return; - - acpi_tables_addr = - memblock_find_in_range(0, max_low_pfn_mapped << PAGE_SHIFT, - all_tables_size, PAGE_SIZE); - if (!acpi_tables_addr) { - WARN_ON(1); - return; - } - /* - * Only calling e820_add_reserve does not work and the - * tables are invalid (memory got used) later. - * memblock_reserve works as expected and the tables won't get modified. - * But it's not enough on X86 because ioremap will - * complain later (used by acpi_os_map_memory) that the pages - * that should get mapped are not marked "reserved". - * Both memblock_reserve and e820_add_region (via arch_reserve_mem_area) - * works fine. - */ - memblock_reserve(acpi_tables_addr, all_tables_size); - arch_reserve_mem_area(acpi_tables_addr, all_tables_size); - - /* - * early_ioremap only can remap 256k one time. If we map all - * tables one time, we will hit the limit. Need to map chunks - * one by one during copying the same as that in relocate_initrd(). - */ - for (no = 0; no < table_nr; no++) { - unsigned char *src_p = acpi_initrd_files[no].data; - phys_addr_t size = acpi_initrd_files[no].size; - phys_addr_t dest_addr = acpi_tables_addr + total_offset; - phys_addr_t slop, clen; - char *dest_p; - - total_offset += size; - - while (size) { - slop = dest_addr & ~PAGE_MASK; - clen = size; - if (clen > MAP_CHUNK_SIZE - slop) - clen = MAP_CHUNK_SIZE - slop; - dest_p = early_ioremap(dest_addr & PAGE_MASK, - clen + slop); - memcpy(dest_p + slop, src_p, clen); - early_iounmap(dest_p, clen + slop); - src_p += clen; - dest_addr += clen; - size -= clen; - } - } -} - -acpi_status -acpi_os_physical_table_override(struct acpi_table_header *existing_table, - acpi_physical_address *address, u32 *length) -{ - int table_offset = 0; - int table_index = 0; - struct acpi_table_header *table; - u32 table_length; - - *length = 0; - *address = 0; - if (!acpi_tables_addr) - return AE_OK; - - while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) { - table = acpi_os_map_memory(acpi_tables_addr + table_offset, - ACPI_HEADER_SIZE); - if (table_offset + table->length > all_tables_size) { - acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); - WARN_ON(1); - return AE_OK; - } - - table_length = table->length; - - /* Only override tables matched */ - if (test_bit(table_index, acpi_initrd_installed) || - memcmp(existing_table->signature, table->signature, 4) || - memcmp(table->oem_table_id, existing_table->oem_table_id, - ACPI_OEM_TABLE_ID_SIZE)) { - acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); - goto next_table; - } - - *length = table_length; - *address = acpi_tables_addr + table_offset; - acpi_table_taint(existing_table); - acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); - set_bit(table_index, acpi_initrd_installed); - break; - -next_table: - table_offset += table_length; - table_index++; - } - return AE_OK; -} - -void __init acpi_initrd_initialize_tables(void) -{ - int table_offset = 0; - int table_index = 0; - u32 table_length; - struct acpi_table_header *table; - - if (!acpi_tables_addr) - return; - - while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) { - table = acpi_os_map_memory(acpi_tables_addr + table_offset, - ACPI_HEADER_SIZE); - if (table_offset + table->length > all_tables_size) { - acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); - WARN_ON(1); - return; - } - - table_length = table->length; - - /* Skip RSDT/XSDT which should only be used for override */ - if (test_bit(table_index, acpi_initrd_installed) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_RSDT) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_XSDT)) { - acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); - goto next_table; - } - - acpi_table_taint(table); - acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); - acpi_install_table(acpi_tables_addr + table_offset, TRUE); - set_bit(table_index, acpi_initrd_installed); -next_table: - table_offset += table_length; - table_index++; - } -} -#else -acpi_status -acpi_os_physical_table_override(struct acpi_table_header *existing_table, - acpi_physical_address *address, - u32 *table_length) -{ - *table_length = 0; - *address = 0; - return AE_OK; -} - -void __init acpi_initrd_initialize_tables(void) -{ -} -#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */ - -acpi_status -acpi_os_table_override(struct acpi_table_header *existing_table, - struct acpi_table_header **new_table) -{ - if (!existing_table || !new_table) - return AE_BAD_PARAMETER; - - *new_table = NULL; - -#ifdef CONFIG_ACPI_CUSTOM_DSDT - if (strncmp(existing_table->signature, "DSDT", 4) == 0) - *new_table = (struct acpi_table_header *)AmlCode; -#endif - if (*new_table != NULL) - acpi_table_taint(existing_table); - return AE_OK; -} - static irqreturn_t acpi_irq(int irq, void *dev_id) { u32 handled; diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index f49c02442d65..2e74dbf45dd4 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include "internal.h" #define ACPI_MAX_TABLES 128 @@ -433,6 +435,294 @@ static void __init check_multiple_madt(void) return; } +static void acpi_table_taint(struct acpi_table_header *table) +{ + pr_warn("Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n", + table->signature, table->oem_table_id); + add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE); +} + +#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE +static u64 acpi_tables_addr; +static int all_tables_size; + +/* Copied from acpica/tbutils.c:acpi_tb_checksum() */ +static u8 __init acpi_table_checksum(u8 *buffer, u32 length) +{ + u8 sum = 0; + u8 *end = buffer + length; + + while (buffer < end) + sum = (u8) (sum + *(buffer++)); + return sum; +} + +/* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */ +static const char * const table_sigs[] = { + ACPI_SIG_BERT, ACPI_SIG_CPEP, ACPI_SIG_ECDT, ACPI_SIG_EINJ, + ACPI_SIG_ERST, ACPI_SIG_HEST, ACPI_SIG_MADT, ACPI_SIG_MSCT, + ACPI_SIG_SBST, ACPI_SIG_SLIT, ACPI_SIG_SRAT, ACPI_SIG_ASF, + ACPI_SIG_BOOT, ACPI_SIG_DBGP, ACPI_SIG_DMAR, ACPI_SIG_HPET, + ACPI_SIG_IBFT, ACPI_SIG_IVRS, ACPI_SIG_MCFG, ACPI_SIG_MCHI, + 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 }; + +#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) + +#define ACPI_OVERRIDE_TABLES 64 +static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES]; +static DECLARE_BITMAP(acpi_initrd_installed, ACPI_OVERRIDE_TABLES); + +#define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT) + +static void __init acpi_table_initrd_init(void *data, size_t size) +{ + int sig, no, table_nr = 0, total_offset = 0; + long offset = 0; + struct acpi_table_header *table; + char cpio_path[32] = "kernel/firmware/acpi/"; + struct cpio_data file; + + if (data == NULL || size == 0) + return; + + for (no = 0; no < ACPI_OVERRIDE_TABLES; no++) { + file = find_cpio_data(cpio_path, data, size, &offset); + if (!file.data) + break; + + data += offset; + size -= offset; + + if (file.size < sizeof(struct acpi_table_header)) { + pr_err("ACPI OVERRIDE: Table smaller than ACPI header [%s%s]\n", + cpio_path, file.name); + continue; + } + + table = file.data; + + for (sig = 0; table_sigs[sig]; sig++) + if (!memcmp(table->signature, table_sigs[sig], 4)) + break; + + if (!table_sigs[sig]) { + pr_err("ACPI OVERRIDE: Unknown signature [%s%s]\n", + cpio_path, file.name); + continue; + } + if (file.size != table->length) { + pr_err("ACPI OVERRIDE: File length does not match table length [%s%s]\n", + cpio_path, file.name); + continue; + } + if (acpi_table_checksum(file.data, table->length)) { + pr_err("ACPI OVERRIDE: Bad table checksum [%s%s]\n", + cpio_path, file.name); + continue; + } + + pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n", + table->signature, cpio_path, file.name, table->length); + + all_tables_size += table->length; + acpi_initrd_files[table_nr].data = file.data; + acpi_initrd_files[table_nr].size = file.size; + table_nr++; + } + if (table_nr == 0) + return; + + acpi_tables_addr = + memblock_find_in_range(0, max_low_pfn_mapped << PAGE_SHIFT, + all_tables_size, PAGE_SIZE); + if (!acpi_tables_addr) { + WARN_ON(1); + return; + } + /* + * Only calling e820_add_reserve does not work and the + * tables are invalid (memory got used) later. + * memblock_reserve works as expected and the tables won't get modified. + * But it's not enough on X86 because ioremap will + * complain later (used by acpi_os_map_memory) that the pages + * that should get mapped are not marked "reserved". + * Both memblock_reserve and e820_add_region (via arch_reserve_mem_area) + * works fine. + */ + memblock_reserve(acpi_tables_addr, all_tables_size); + arch_reserve_mem_area(acpi_tables_addr, all_tables_size); + + /* + * early_ioremap only can remap 256k one time. If we map all + * tables one time, we will hit the limit. Need to map chunks + * one by one during copying the same as that in relocate_initrd(). + */ + for (no = 0; no < table_nr; no++) { + unsigned char *src_p = acpi_initrd_files[no].data; + phys_addr_t size = acpi_initrd_files[no].size; + phys_addr_t dest_addr = acpi_tables_addr + total_offset; + phys_addr_t slop, clen; + char *dest_p; + + total_offset += size; + + while (size) { + slop = dest_addr & ~PAGE_MASK; + clen = size; + if (clen > MAP_CHUNK_SIZE - slop) + clen = MAP_CHUNK_SIZE - slop; + dest_p = early_ioremap(dest_addr & PAGE_MASK, + clen + slop); + memcpy(dest_p + slop, src_p, clen); + early_iounmap(dest_p, clen + slop); + src_p += clen; + dest_addr += clen; + size -= clen; + } + } +} + +static acpi_status +acpi_table_initrd_override(struct acpi_table_header *existing_table, + acpi_physical_address *address, u32 *length) +{ + int table_offset = 0; + int table_index = 0; + struct acpi_table_header *table; + u32 table_length; + + *length = 0; + *address = 0; + if (!acpi_tables_addr) + return AE_OK; + + while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) { + table = acpi_os_map_memory(acpi_tables_addr + table_offset, + ACPI_HEADER_SIZE); + if (table_offset + table->length > all_tables_size) { + acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); + WARN_ON(1); + return AE_OK; + } + + table_length = table->length; + + /* Only override tables matched */ + if (test_bit(table_index, acpi_initrd_installed) || + memcmp(existing_table->signature, table->signature, 4) || + memcmp(table->oem_table_id, existing_table->oem_table_id, + ACPI_OEM_TABLE_ID_SIZE)) { + acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); + goto next_table; + } + + *length = table_length; + *address = acpi_tables_addr + table_offset; + acpi_table_taint(existing_table); + acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); + set_bit(table_index, acpi_initrd_installed); + break; + +next_table: + table_offset += table_length; + table_index++; + } + return AE_OK; +} + +static void __init acpi_table_initrd_scan(void) +{ + int table_offset = 0; + int table_index = 0; + u32 table_length; + struct acpi_table_header *table; + + if (!acpi_tables_addr) + return; + + while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) { + table = acpi_os_map_memory(acpi_tables_addr + table_offset, + ACPI_HEADER_SIZE); + if (table_offset + table->length > all_tables_size) { + acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); + WARN_ON(1); + return; + } + + table_length = table->length; + + /* Skip RSDT/XSDT which should only be used for override */ + if (test_bit(table_index, acpi_initrd_installed) || + ACPI_COMPARE_NAME(table->signature, ACPI_SIG_RSDT) || + ACPI_COMPARE_NAME(table->signature, ACPI_SIG_XSDT)) { + acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); + goto next_table; + } + + acpi_table_taint(table); + acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); + acpi_install_table(acpi_tables_addr + table_offset, TRUE); + set_bit(table_index, acpi_initrd_installed); +next_table: + table_offset += table_length; + table_index++; + } +} +#else +static void __init acpi_table_initrd_init(void *data, size_t size) +{ +} + +static acpi_status +acpi_table_initrd_override(struct acpi_table_header *existing_table, + acpi_physical_address *address, + u32 *table_length) +{ + *table_length = 0; + *address = 0; + return AE_OK; +} + +static void __init acpi_table_initrd_scan(void) +{ +} +#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */ + +acpi_status +acpi_os_physical_table_override(struct acpi_table_header *existing_table, + acpi_physical_address *address, + u32 *table_length) +{ + return acpi_table_initrd_override(existing_table, address, + table_length); +} + +acpi_status +acpi_os_table_override(struct acpi_table_header *existing_table, + struct acpi_table_header **new_table) +{ + if (!existing_table || !new_table) + return AE_BAD_PARAMETER; + + *new_table = NULL; + +#ifdef CONFIG_ACPI_CUSTOM_DSDT + if (strncmp(existing_table->signature, "DSDT", 4) == 0) + *new_table = (struct acpi_table_header *)AmlCode; +#endif + if (*new_table != NULL) + acpi_table_taint(existing_table); + return AE_OK; +} + +void __init early_acpi_table_init(void *data, size_t size) +{ + acpi_table_initrd_init(data, size); +} + /* * acpi_table_init() * @@ -457,7 +747,7 @@ int __init acpi_table_init(void) status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); if (ACPI_FAILURE(status)) return -EINVAL; - acpi_initrd_initialize_tables(); + acpi_table_initrd_scan(); check_multiple_madt(); return 0; -- cgit v1.2.3 From 5d8813271f8a7c86027afb2ef554f2a5a9ba7c15 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Mon, 11 Apr 2016 10:13:33 +0800 Subject: ACPI / tables: Convert initrd table override to table upgrade mechanism This patch converts the initrd table override mechanism to the table upgrade mechanism by restricting its usage to the tables released with compatibility and more recent revision. This use case has been encouraged by the ACPI specification: 1. OEMID: An OEM-supplied string that identifies the OEM. 2. OEM Table ID: An OEM-supplied string that the OEM uses to identify the particular data table. This field is particularly useful when defining a definition block to distinguish definition block functions. OEM assigns each dissimilar table a new OEM Table Id. 3. OEM Revision: An OEM-supplied revision number. Larger numbers are assumed to be newer revisions. For OEMs, good practices will ensure consistency when assigning OEMID and OEM Table ID fields in any table. The intent of these fields is to allow for a binary control system that support services can use. Because many support function can be automated, it is useful when a tool can programatically determine which table release is a compatible and more recent revision of a prior table on the same OEMID and OEM Table ID. The facility can now be used by the vendors to upgrade wrong tables for bug fixing purpose, thus lockdep disabling taint is not suitable for it and it should be a default 'y' option to implement the spec encouraged use case. Note that, by implementing table upgrade inside of ACPICA itself, it is possible to remove acpi_table_initrd_override() and tables can be upgraded by acpi_install_table() automatically. Though current ACPICA impelentation hasn't implemented this, this patched changes the table flag setting timing to allow this to be implemented in ACPICA without changing the code here. Documentation of initrd override mechanism is upgraded accordingly. Original-by: Octavian Purdila Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Kconfig | 8 ++++---- drivers/acpi/tables.c | 48 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 38 insertions(+), 18 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 82b96ee8624c..b225c4b9ba14 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -311,12 +311,12 @@ config ACPI_CUSTOM_DSDT bool default ACPI_CUSTOM_DSDT_FILE != "" -config ACPI_INITRD_TABLE_OVERRIDE - bool "ACPI tables override via initrd" +config ACPI_TABLE_UPGRADE + bool "Allow upgrading ACPI tables via initrd" depends on BLK_DEV_INITRD && X86 - default n + default y help - This option provides functionality to override arbitrary ACPI tables + This option provides functionality to upgrade arbitrary ACPI tables via initrd. No functional change if no ACPI tables are passed via initrd, therefore it's safe to say Y. See Documentation/acpi/initrd_table_override.txt for details diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 2e74dbf45dd4..08795fbde3fa 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -442,7 +442,7 @@ static void acpi_table_taint(struct acpi_table_header *table) add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE); } -#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE +#ifdef CONFIG_ACPI_TABLE_UPGRADE static u64 acpi_tables_addr; static int all_tables_size; @@ -471,9 +471,9 @@ static const char * const table_sigs[] = { #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) -#define ACPI_OVERRIDE_TABLES 64 -static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES]; -static DECLARE_BITMAP(acpi_initrd_installed, ACPI_OVERRIDE_TABLES); +#define NR_ACPI_INITRD_TABLES 64 +static struct cpio_data __initdata acpi_initrd_files[NR_ACPI_INITRD_TABLES]; +static DECLARE_BITMAP(acpi_initrd_installed, NR_ACPI_INITRD_TABLES); #define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT) @@ -488,7 +488,7 @@ static void __init acpi_table_initrd_init(void *data, size_t size) if (data == NULL || size == 0) return; - for (no = 0; no < ACPI_OVERRIDE_TABLES; no++) { + for (no = 0; no < NR_ACPI_INITRD_TABLES; no++) { file = find_cpio_data(cpio_path, data, size, &offset); if (!file.data) break; @@ -611,19 +611,30 @@ acpi_table_initrd_override(struct acpi_table_header *existing_table, table_length = table->length; /* Only override tables matched */ - if (test_bit(table_index, acpi_initrd_installed) || - memcmp(existing_table->signature, table->signature, 4) || + if (memcmp(existing_table->signature, table->signature, 4) || + memcmp(table->oem_id, existing_table->oem_id, + ACPI_OEM_ID_SIZE) || memcmp(table->oem_table_id, existing_table->oem_table_id, ACPI_OEM_TABLE_ID_SIZE)) { acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); goto next_table; } + /* + * Mark the table to avoid being used in + * acpi_table_initrd_scan() and check the revision. + */ + if (test_and_set_bit(table_index, acpi_initrd_installed) || + existing_table->oem_revision >= table->oem_revision) { + acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); + goto next_table; + } *length = table_length; *address = acpi_tables_addr + table_offset; - acpi_table_taint(existing_table); + pr_info("Table Upgrade: override [%4.4s-%6.6s-%8.8s]\n", + table->signature, table->oem_id, + table->oem_table_id); acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); - set_bit(table_index, acpi_initrd_installed); break; next_table: @@ -655,17 +666,26 @@ static void __init acpi_table_initrd_scan(void) table_length = table->length; /* Skip RSDT/XSDT which should only be used for override */ - if (test_bit(table_index, acpi_initrd_installed) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_RSDT) || + if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_RSDT) || ACPI_COMPARE_NAME(table->signature, ACPI_SIG_XSDT)) { acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); goto next_table; } + /* + * Mark the table to avoid being used in + * acpi_table_initrd_override(). Though this is not possible + * because override is disabled in acpi_install_table(). + */ + if (test_and_set_bit(table_index, acpi_initrd_installed)) { + acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); + goto next_table; + } - acpi_table_taint(table); + pr_info("Table Upgrade: install [%4.4s-%6.6s-%8.8s]\n", + table->signature, table->oem_id, + table->oem_table_id); acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); acpi_install_table(acpi_tables_addr + table_offset, TRUE); - set_bit(table_index, acpi_initrd_installed); next_table: table_offset += table_length; table_index++; @@ -689,7 +709,7 @@ acpi_table_initrd_override(struct acpi_table_header *existing_table, static void __init acpi_table_initrd_scan(void) { } -#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */ +#endif /* CONFIG_ACPI_TABLE_UPGRADE */ acpi_status acpi_os_physical_table_override(struct acpi_table_header *existing_table, -- cgit v1.2.3 From 702b07fcc9b264c9afd372676bbdd50a762dcde0 Mon Sep 17 00:00:00 2001 From: Lukasz Anaczkowski Date: Thu, 21 Apr 2016 11:29:00 +0200 Subject: ACPI / SRAT: fix SRAT parsing order with both LAPIC and X2APIC present SRAT maps APIC ID to proximity domains ids (PXM). Mapping from PXM to NUMA node ids is based on order of entries in SRAT table. SRAT table has just LAPIC entires or mix of LAPIC and X2APIC entries. As long as there are only LAPIC entires, mapping from proximity domain id to NUMA node id is as assumed by BIOS. However, once APIC entries are mixed, X2APIC entries would be first mapped which causes unexpected NUMA node mapping. To fix that, change parsing to check each entry against both LAPIC and X2APIC so mapping is in the SRAT/PXM order. This is supplemental change to the fix made by commit d81056b5278 (Handle apic/x2apic entries in MADT in correct order) and using the mechanism introduced by 9b3fedd (ACPI / tables: Add acpi_subtable_proc to ACPI table parsers). Fixes: d81056b5278 (Handle apic/x2apic entries in MADT in correct order) Signed-off-by: Lukasz Anaczkowski [ rjw : Subject & changelog ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/numa.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 72b6e9ef0ae9..d176e0ece470 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -327,10 +327,18 @@ int __init acpi_numa_init(void) /* SRAT: Static Resource Affinity Table */ if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { - acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY, - acpi_parse_x2apic_affinity, 0); - acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, - acpi_parse_processor_affinity, 0); + struct acpi_subtable_proc srat_proc[2]; + + memset(srat_proc, 0, sizeof(srat_proc)); + srat_proc[0].id = ACPI_SRAT_TYPE_CPU_AFFINITY; + srat_proc[0].handler = acpi_parse_processor_affinity; + srat_proc[1].id = ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY; + srat_proc[1].handler = acpi_parse_x2apic_affinity; + + acpi_table_parse_entries_array(ACPI_SIG_SRAT, + sizeof(struct acpi_table_srat), + srat_proc, ARRAY_SIZE(srat_proc), 0); + cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); -- cgit v1.2.3 From 30c9bb0d7603e7b3f4d6a0ea231e1cddae020c32 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 3 May 2016 16:48:20 +0800 Subject: ACPI / osi: Fix an issue that acpi_osi=!* cannot disable ACPICA internal strings The order of the _OSI related functionalities is as follows: acpi_blacklisted() acpi_dmi_osi_linux() acpi_osi_setup() acpi_osi_setup() acpi_update_interfaces() if "!*" <<<<<<<<<<<<<<<<<<<<<<<< parse_args() __setup("acpi_osi=") acpi_osi_setup_linux() acpi_update_interfaces() if "!*" <<<<<<<<<<<<<<<<<<<<<<<< acpi_early_init() acpi_initialize_subsystem() acpi_ut_initialize_interfaces() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ acpi_bus_init() acpi_os_initialize1() acpi_install_interface_handler(acpi_osi_handler) acpi_osi_setup_late() acpi_update_interfaces() for "!" >>>>>>>>>>>>>>>>>>>>>>>> acpi_osi_handler() Since acpi_osi_setup_linux() can override acpi_dmi_osi_linux(), the command line setting can override the DMI detection. That's why acpi_blacklisted() is put before __setup("acpi_osi="). Then we can notice the following wrong invocation order. There are acpi_update_interfaces() (marked by <<<<) calls invoked before acpi_ut_initialize_interfaces() (marked by ^^^^). This makes it impossible to use acpi_osi=!* correctly from OSI DMI table or from the command line. The use of acpi_osi=!* is meant to disable both ACPICA (acpi_gbl_supported_interfaces) and Linux specific strings (osi_setup_entries) while the ACPICA part should have stopped working because of the order issue. This patch fixes this issue by moving acpi_update_interfaces() to where it is invoked for acpi_osi=! (marked by >>>>) as this is ensured to be invoked after acpi_ut_initialize_interfaces() (marked by ^^^^). Linux specific strings are still handled in the original place in order to make the following command line working: acpi_osi=!* acpi_osi="Module Device". Note that since acpi_osi=!* is meant to further disable linux specific string comparing to the acpi_osi=!, there is no such use case in our bug fixing work and hence there is no one using acpi_osi=!* either from the command line or from the DMI quirks, this issue is just a theoretical issue. Fixes: 741d81280ad2 (ACPI: Add facility to remove all _OSI strings) Cc: 3.12+ # 3.12+ Tested-by: Lukas Wunner Tested-by: Chen Yu Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 814d5f83b75e..f03677588b9d 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -135,7 +135,7 @@ static struct osi_linux { unsigned int enable:1; unsigned int dmi:1; unsigned int cmdline:1; - unsigned int default_disabling:1; + u8 default_disabling; } osi_linux = {0, 0, 0, 0}; static u32 acpi_osi_handler(acpi_string interface, u32 supported) @@ -1751,10 +1751,13 @@ void __init acpi_osi_setup(char *str) if (*str == '!') { str++; if (*str == '\0') { - osi_linux.default_disabling = 1; + /* Do not override acpi_osi=!* */ + if (!osi_linux.default_disabling) + osi_linux.default_disabling = + ACPI_DISABLE_ALL_VENDOR_STRINGS; return; } else if (*str == '*') { - acpi_update_interfaces(ACPI_DISABLE_ALL_STRINGS); + osi_linux.default_disabling = ACPI_DISABLE_ALL_STRINGS; for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { osi = &osi_setup_entries[i]; osi->enable = false; @@ -1827,10 +1830,13 @@ static void __init acpi_osi_setup_late(void) acpi_status status; if (osi_linux.default_disabling) { - status = acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS); + status = acpi_update_interfaces(osi_linux.default_disabling); if (ACPI_SUCCESS(status)) - printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors\n"); + printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors%s\n", + osi_linux.default_disabling == + ACPI_DISABLE_ALL_STRINGS ? + " and feature groups" : ""); } for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { -- cgit v1.2.3 From dbee890bf69ad62c021e299e24881fdcd1f2c481 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 3 May 2016 16:48:27 +0800 Subject: ACPI / osi: Cleanup _OSI("Linux") related code before introducing new support This patch cleans up OSI code in osl.c to make osi_linux work for OSI strings other than "Linux", so it can be re-used for other purposes. Tested-by: Lukas Wunner Tested-by: Chen Yu Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index f03677588b9d..9f59dd1a0af7 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -131,12 +131,12 @@ static void __init acpi_osi_setup_late(void); * or boot with "acpi_osi=Linux" */ -static struct osi_linux { - unsigned int enable:1; - unsigned int dmi:1; - unsigned int cmdline:1; +static struct acpi_osi_config { + unsigned int linux_enable:1; + unsigned int linux_dmi:1; + unsigned int linux_cmdline:1; u8 default_disabling; -} osi_linux = {0, 0, 0, 0}; +} osi_config = {0, 0, 0, 0}; static u32 acpi_osi_handler(acpi_string interface, u32 supported) { @@ -144,9 +144,9 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported) printk_once(KERN_NOTICE FW_BUG PREFIX "BIOS _OSI(Linux) query %s%s\n", - osi_linux.enable ? "honored" : "ignored", - osi_linux.cmdline ? " via cmdline" : - osi_linux.dmi ? " via DMI" : ""); + osi_config.linux_enable ? "honored" : "ignored", + osi_config.linux_cmdline ? " via cmdline" : + osi_config.linux_dmi ? " via DMI" : ""); } if (!strcmp("Darwin", interface)) { @@ -1752,12 +1752,12 @@ void __init acpi_osi_setup(char *str) str++; if (*str == '\0') { /* Do not override acpi_osi=!* */ - if (!osi_linux.default_disabling) - osi_linux.default_disabling = + if (!osi_config.default_disabling) + osi_config.default_disabling = ACPI_DISABLE_ALL_VENDOR_STRINGS; return; } else if (*str == '*') { - osi_linux.default_disabling = ACPI_DISABLE_ALL_STRINGS; + osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS; for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { osi = &osi_setup_entries[i]; osi->enable = false; @@ -1782,10 +1782,10 @@ void __init acpi_osi_setup(char *str) static void __init set_osi_linux(unsigned int enable) { - if (osi_linux.enable != enable) - osi_linux.enable = enable; + if (osi_config.linux_enable != enable) + osi_config.linux_enable = enable; - if (osi_linux.enable) + if (osi_config.linux_enable) acpi_osi_setup("Linux"); else acpi_osi_setup("!Linux"); @@ -1795,8 +1795,9 @@ static void __init set_osi_linux(unsigned int enable) static void __init acpi_cmdline_osi_linux(unsigned int enable) { - osi_linux.cmdline = 1; /* cmdline set the default and override DMI */ - osi_linux.dmi = 0; + /* cmdline set the default and override DMI */ + osi_config.linux_cmdline = 1; + osi_config.linux_dmi = 0; set_osi_linux(enable); return; @@ -1809,7 +1810,8 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) if (enable == -1) return; - osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ + /* DMI knows that this box asks OSI(Linux) */ + osi_config.linux_dmi = 1; set_osi_linux(enable); return; @@ -1829,12 +1831,12 @@ static void __init acpi_osi_setup_late(void) int i; acpi_status status; - if (osi_linux.default_disabling) { - status = acpi_update_interfaces(osi_linux.default_disabling); + if (osi_config.default_disabling) { + status = acpi_update_interfaces(osi_config.default_disabling); if (ACPI_SUCCESS(status)) printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors%s\n", - osi_linux.default_disabling == + osi_config.default_disabling == ACPI_DISABLE_ALL_STRINGS ? " and feature groups" : ""); } -- cgit v1.2.3 From a707edebadf1230f202000f29b28b7586ada4aa3 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 3 May 2016 16:48:32 +0800 Subject: ACPI / osi: Add acpi_osi=!! to allow reverting acpi_osi=! This patch introduces acpi_osi=!! so that quirks may use it to revert acpi_osi=!. Tested-by: Lukas Wunner Tested-by: Chen Yu Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 9f59dd1a0af7..f801b59f2a94 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1763,6 +1763,9 @@ void __init acpi_osi_setup(char *str) osi->enable = false; } return; + } else if (*str == '!') { + osi_config.default_disabling = 0; + return; } enable = false; } -- cgit v1.2.3 From e10cfdc33a0f23dc8449be7267f0a642e96a2a24 Mon Sep 17 00:00:00 2001 From: Chen Yu Date: Tue, 3 May 2016 16:48:39 +0800 Subject: ACPI / osi: Fix default _OSI(Darwin) support The following commit always reports positive value when Apple hardware queries _OSI("Darwin"): Commit: 7bc5a2bad0b8d9d1ac9f7b8b33150e4ddf197334 Subject: ACPI: Support _OSI("Darwin") correctly However since this implementation places the judgement in runtime, it breaks acpi_osi=!Darwin and cannot return unsupported for _OSI("WinXXX") invoked before invoking _OSI("Darwin"). This patch fixes the issues by reverting the wrong support and implementing the default behavior of _OSI("Darwin")/_OSI("WinXXX") on Apple hardware via DMI matching. Fixes: 7bc5a2bad0b8 (ACPI: Support _OSI("Darwin") correctly) Link: https://bugzilla.kernel.org/show_bug.cgi?id=92111 Reported-and-tested-by: Lukas Wunner Signed-off-by: Chen Yu Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/blacklist.c | 23 +++++++++++++++++++ drivers/acpi/osl.c | 58 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 74 insertions(+), 7 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 96809cd99ace..45390a953fb2 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -133,6 +133,11 @@ int __init acpi_blacklisted(void) return blacklisted; } #ifdef CONFIG_DMI +static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d) +{ + acpi_dmi_osi_darwin(1, d); /* enable */ + return 0; +} static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) { acpi_dmi_osi_linux(1, d); /* enable */ @@ -331,6 +336,24 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { }, }, + /* + * Enable _OSI("Darwin") for all apple platforms. + */ + { + .callback = dmi_enable_osi_darwin, + .ident = "Apple hardware", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + }, + }, + { + .callback = dmi_enable_osi_darwin, + .ident = "Apple hardware", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), + }, + }, + #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE /* * DELL XPS 13 (2015) switches sound between HDA and I2S diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index f801b59f2a94..1b84e4635ae0 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -135,6 +135,9 @@ static struct acpi_osi_config { unsigned int linux_enable:1; unsigned int linux_dmi:1; unsigned int linux_cmdline:1; + unsigned int darwin_enable:1; + unsigned int darwin_dmi:1; + unsigned int darwin_cmdline:1; u8 default_disabling; } osi_config = {0, 0, 0, 0}; @@ -150,13 +153,12 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported) } if (!strcmp("Darwin", interface)) { - /* - * Apple firmware will behave poorly if it receives positive - * answers to "Darwin" and any other OS. Respond positively - * to Darwin and then disable all other vendor strings. - */ - acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS); - supported = ACPI_UINT32_MAX; + + printk_once(KERN_NOTICE PREFIX + "BIOS _OSI(Darwin) query %s%s\n", + osi_config.darwin_enable ? "honored" : "ignored", + osi_config.darwin_cmdline ? " via cmdline" : + osi_config.darwin_dmi ? " via DMI" : ""); } return supported; @@ -1783,6 +1785,44 @@ void __init acpi_osi_setup(char *str) } } +static void __init set_osi_darwin(unsigned int enable) +{ + if (osi_config.darwin_enable != enable) + osi_config.darwin_enable = enable; + + if (enable) { + acpi_osi_setup("!"); + acpi_osi_setup("Darwin"); + } else { + acpi_osi_setup("!!"); + acpi_osi_setup("!Darwin"); + } +} + +static void __init acpi_cmdline_osi_darwin(unsigned int enable) +{ + /* cmdline set the default and override DMI */ + osi_config.darwin_cmdline = 1; + osi_config.darwin_dmi = 0; + set_osi_darwin(enable); + + return; +} + +void __init acpi_dmi_osi_darwin(int enable, const struct dmi_system_id *d) +{ + printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); + + if (enable == -1) + return; + + /* DMI knows that this box asks OSI(Darwin) */ + osi_config.darwin_dmi = 1; + set_osi_darwin(enable); + + return; +} + static void __init set_osi_linux(unsigned int enable) { if (osi_config.linux_enable != enable) @@ -1870,6 +1910,10 @@ static int __init osi_setup(char *str) acpi_cmdline_osi_linux(1); else if (str && !strcmp("!Linux", str)) acpi_cmdline_osi_linux(0); + else if (str && !strcmp("Darwin", str)) + acpi_cmdline_osi_darwin(1); + else if (str && !strcmp("!Darwin", str)) + acpi_cmdline_osi_darwin(0); else acpi_osi_setup(str); -- cgit v1.2.3 From dc45eb20a83d11ed649169fbe9159ed6bf586c88 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 3 May 2016 16:48:46 +0800 Subject: ACPI / osi: Cleanup OSI handling code to use bool This patch changes "int/unsigned int" to "bool" to simplify the code. Tested-by: Lukas Wunner Tested-by: Chen Yu Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/blacklist.c | 4 ++-- drivers/acpi/osl.c | 36 +++++++++++++----------------------- 2 files changed, 15 insertions(+), 25 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 45390a953fb2..d7d498abc5d3 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -135,12 +135,12 @@ int __init acpi_blacklisted(void) #ifdef CONFIG_DMI static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d) { - acpi_dmi_osi_darwin(1, d); /* enable */ + acpi_dmi_osi_darwin(true, d); /* enable */ return 0; } static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) { - acpi_dmi_osi_linux(1, d); /* enable */ + acpi_dmi_osi_linux(true, d); /* enable */ return 0; } static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 1b84e4635ae0..e30f3251fd14 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1785,11 +1785,9 @@ void __init acpi_osi_setup(char *str) } } -static void __init set_osi_darwin(unsigned int enable) +static void __init set_osi_darwin(bool enable) { - if (osi_config.darwin_enable != enable) - osi_config.darwin_enable = enable; - + osi_config.darwin_enable = !!enable; if (enable) { acpi_osi_setup("!"); acpi_osi_setup("Darwin"); @@ -1799,7 +1797,7 @@ static void __init set_osi_darwin(unsigned int enable) } } -static void __init acpi_cmdline_osi_darwin(unsigned int enable) +static void __init acpi_cmdline_osi_darwin(bool enable) { /* cmdline set the default and override DMI */ osi_config.darwin_cmdline = 1; @@ -1809,13 +1807,10 @@ static void __init acpi_cmdline_osi_darwin(unsigned int enable) return; } -void __init acpi_dmi_osi_darwin(int enable, const struct dmi_system_id *d) +void __init acpi_dmi_osi_darwin(bool enable, const struct dmi_system_id *d) { printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); - if (enable == -1) - return; - /* DMI knows that this box asks OSI(Darwin) */ osi_config.darwin_dmi = 1; set_osi_darwin(enable); @@ -1823,12 +1818,10 @@ void __init acpi_dmi_osi_darwin(int enable, const struct dmi_system_id *d) return; } -static void __init set_osi_linux(unsigned int enable) +static void __init set_osi_linux(bool enable) { - if (osi_config.linux_enable != enable) - osi_config.linux_enable = enable; - - if (osi_config.linux_enable) + osi_config.linux_enable = !!enable; + if (enable) acpi_osi_setup("Linux"); else acpi_osi_setup("!Linux"); @@ -1836,7 +1829,7 @@ static void __init set_osi_linux(unsigned int enable) return; } -static void __init acpi_cmdline_osi_linux(unsigned int enable) +static void __init acpi_cmdline_osi_linux(bool enable) { /* cmdline set the default and override DMI */ osi_config.linux_cmdline = 1; @@ -1846,13 +1839,10 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable) return; } -void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) +void __init acpi_dmi_osi_linux(bool enable, const struct dmi_system_id *d) { printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); - if (enable == -1) - return; - /* DMI knows that this box asks OSI(Linux) */ osi_config.linux_dmi = 1; set_osi_linux(enable); @@ -1907,13 +1897,13 @@ static void __init acpi_osi_setup_late(void) static int __init osi_setup(char *str) { if (str && !strcmp("Linux", str)) - acpi_cmdline_osi_linux(1); + acpi_cmdline_osi_linux(true); else if (str && !strcmp("!Linux", str)) - acpi_cmdline_osi_linux(0); + acpi_cmdline_osi_linux(false); else if (str && !strcmp("Darwin", str)) - acpi_cmdline_osi_darwin(1); + acpi_cmdline_osi_darwin(true); else if (str && !strcmp("!Darwin", str)) - acpi_cmdline_osi_darwin(0); + acpi_cmdline_osi_darwin(false); else acpi_osi_setup(str); -- cgit v1.2.3 From d5a91d74c6d7da2cebadbb9f2d03e56f84d7be62 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 3 May 2016 16:48:53 +0800 Subject: ACPI / osi: Cleanup coding style issues before creating a separate OSI source file This patch performs necessary cleanups before moving OSI support to another file. 1. Change printk into pr_xxx 2. Do not initialize values to 0 3. Do not append additional "return" at the end of the function 4. Remove useless comments which may easily break line breaking rule After fixing the coding style issues, rename functions to make them looking like acpi_osi_xxx. No functional changes. Tested-by: Lukas Wunner Tested-by: Chen Yu Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/blacklist.c | 10 +++---- drivers/acpi/osl.c | 76 ++++++++++++++++++++---------------------------- 2 files changed, 36 insertions(+), 50 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index d7d498abc5d3..ba1601d26c48 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -135,17 +135,17 @@ int __init acpi_blacklisted(void) #ifdef CONFIG_DMI static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d) { - acpi_dmi_osi_darwin(true, d); /* enable */ + acpi_osi_dmi_darwin(true, d); return 0; } static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) { - acpi_dmi_osi_linux(true, d); /* enable */ + acpi_osi_dmi_linux(true, d); return 0; } static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) { - printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); + pr_notice(PREFIX "DMI detected: %s\n", d->ident); acpi_osi_setup("!Windows 2006"); acpi_osi_setup("!Windows 2006 SP1"); acpi_osi_setup("!Windows 2006 SP2"); @@ -153,13 +153,13 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) } static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) { - printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); + pr_notice(PREFIX "DMI detected: %s\n", d->ident); acpi_osi_setup("!Windows 2009"); return 0; } static int __init dmi_disable_osi_win8(const struct dmi_system_id *d) { - printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); + pr_notice(PREFIX "DMI detected: %s\n", d->ident); acpi_osi_setup("!Windows 2012"); return 0; } diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e30f3251fd14..134051689d72 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -139,13 +139,13 @@ static struct acpi_osi_config { unsigned int darwin_dmi:1; unsigned int darwin_cmdline:1; u8 default_disabling; -} osi_config = {0, 0, 0, 0}; +} osi_config; static u32 acpi_osi_handler(acpi_string interface, u32 supported) { if (!strcmp("Linux", interface)) { - printk_once(KERN_NOTICE FW_BUG PREFIX + pr_notice_once(FW_BUG PREFIX "BIOS _OSI(Linux) query %s%s\n", osi_config.linux_enable ? "honored" : "ignored", osi_config.linux_cmdline ? " via cmdline" : @@ -154,7 +154,7 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported) if (!strcmp("Darwin", interface)) { - printk_once(KERN_NOTICE PREFIX + pr_notice_once(PREFIX "BIOS _OSI(Darwin) query %s%s\n", osi_config.darwin_enable ? "honored" : "ignored", osi_config.darwin_cmdline ? " via cmdline" : @@ -1719,15 +1719,15 @@ static int __init acpi_os_name_setup(char *str) __setup("acpi_os_name=", acpi_os_name_setup); -#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ -#define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */ +#define OSI_STRING_LENGTH_MAX 64 +#define OSI_STRING_ENTRIES_MAX 16 -struct osi_setup_entry { +struct acpi_osi_entry { char string[OSI_STRING_LENGTH_MAX]; bool enable; }; -static struct osi_setup_entry +static struct acpi_osi_entry osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { {"Module Device", true}, {"Processor Device", true}, @@ -1737,7 +1737,7 @@ static struct osi_setup_entry void __init acpi_osi_setup(char *str) { - struct osi_setup_entry *osi; + struct acpi_osi_entry *osi; bool enable = true; int i; @@ -1745,7 +1745,7 @@ void __init acpi_osi_setup(char *str) return; if (str == NULL || *str == '\0') { - printk(KERN_INFO PREFIX "_OSI method disabled\n"); + pr_info(PREFIX "_OSI method disabled\n"); acpi_gbl_create_osi_method = FALSE; return; } @@ -1785,7 +1785,7 @@ void __init acpi_osi_setup(char *str) } } -static void __init set_osi_darwin(bool enable) +static void __init __acpi_osi_setup_darwin(bool enable) { osi_config.darwin_enable = !!enable; if (enable) { @@ -1797,57 +1797,43 @@ static void __init set_osi_darwin(bool enable) } } -static void __init acpi_cmdline_osi_darwin(bool enable) +static void __init acpi_osi_setup_darwin(bool enable) { - /* cmdline set the default and override DMI */ osi_config.darwin_cmdline = 1; osi_config.darwin_dmi = 0; - set_osi_darwin(enable); - - return; + __acpi_osi_setup_darwin(enable); } -void __init acpi_dmi_osi_darwin(bool enable, const struct dmi_system_id *d) +void __init acpi_osi_dmi_darwin(bool enable, const struct dmi_system_id *d) { - printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); - - /* DMI knows that this box asks OSI(Darwin) */ + pr_notice(PREFIX "DMI detected to setup _OSI(\"Darwin\"): %s\n", + d->ident); osi_config.darwin_dmi = 1; - set_osi_darwin(enable); - - return; + __acpi_osi_setup_darwin(enable); } -static void __init set_osi_linux(bool enable) +static void __init __acpi_osi_setup_linux(bool enable) { osi_config.linux_enable = !!enable; if (enable) acpi_osi_setup("Linux"); else acpi_osi_setup("!Linux"); - - return; } -static void __init acpi_cmdline_osi_linux(bool enable) +static void __init acpi_osi_setup_linux(bool enable) { - /* cmdline set the default and override DMI */ osi_config.linux_cmdline = 1; osi_config.linux_dmi = 0; - set_osi_linux(enable); - - return; + __acpi_osi_setup_linux(enable); } -void __init acpi_dmi_osi_linux(bool enable, const struct dmi_system_id *d) +void __init acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d) { - printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); - - /* DMI knows that this box asks OSI(Linux) */ + pr_notice(PREFIX "DMI detected to setup _OSI(\"Linux\"): %s\n", + d->ident); osi_config.linux_dmi = 1; - set_osi_linux(enable); - - return; + __acpi_osi_setup_linux(enable); } /* @@ -1859,7 +1845,7 @@ void __init acpi_dmi_osi_linux(bool enable, const struct dmi_system_id *d) */ static void __init acpi_osi_setup_late(void) { - struct osi_setup_entry *osi; + struct acpi_osi_entry *osi; char *str; int i; acpi_status status; @@ -1868,7 +1854,7 @@ static void __init acpi_osi_setup_late(void) status = acpi_update_interfaces(osi_config.default_disabling); if (ACPI_SUCCESS(status)) - printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors%s\n", + pr_info(PREFIX "Disabled all _OSI OS vendors%s\n", osi_config.default_disabling == ACPI_DISABLE_ALL_STRINGS ? " and feature groups" : ""); @@ -1884,12 +1870,12 @@ static void __init acpi_osi_setup_late(void) status = acpi_install_interface(str); if (ACPI_SUCCESS(status)) - printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); + pr_info(PREFIX "Added _OSI(%s)\n", str); } else { status = acpi_remove_interface(str); if (ACPI_SUCCESS(status)) - printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); + pr_info(PREFIX "Deleted _OSI(%s)\n", str); } } } @@ -1897,13 +1883,13 @@ static void __init acpi_osi_setup_late(void) static int __init osi_setup(char *str) { if (str && !strcmp("Linux", str)) - acpi_cmdline_osi_linux(true); + acpi_osi_setup_linux(true); else if (str && !strcmp("!Linux", str)) - acpi_cmdline_osi_linux(false); + acpi_osi_setup_linux(false); else if (str && !strcmp("Darwin", str)) - acpi_cmdline_osi_darwin(true); + acpi_osi_setup_darwin(true); else if (str && !strcmp("!Darwin", str)) - acpi_cmdline_osi_darwin(false); + acpi_osi_setup_darwin(false); else acpi_osi_setup(str); -- cgit v1.2.3 From e5f660ebef68e3ed1a988ad06ba23562153cee5c Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 3 May 2016 16:49:01 +0800 Subject: ACPI / osi: Collect _OSI handling into one single file _OSI handling code grows giant and it's time to move them into one file. This patch collects all _OSI handling code into one single file. So that we only have the following functions to be used externally: early_acpi_osi_init(): Used by DMI detections; acpi_osi_init(): Used to initialize OSI command line settings and install Linux specific _OSI handler; acpi_osi_setup(): The API that should be used by the external quirks. acpi_osi_is_win8(): The API is used by the external drivers to determine if BIOS supports Win8. CONFIG_DMI is not useful as stub dmi_check_system() can make everything stub because of strip. No functional changes. Tested-by: Lukas Wunner Tested-by: Chen Yu Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Makefile | 2 +- drivers/acpi/blacklist.c | 219 +------------------- drivers/acpi/internal.h | 2 + drivers/acpi/osi.c | 522 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/osl.c | 256 +---------------------- 5 files changed, 531 insertions(+), 470 deletions(-) create mode 100644 drivers/acpi/osi.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index edeb2d1d99be..345df7f960b6 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_ACPI) += acpi.o \ acpica/ # All the builtin files are in the "acpi." module_param namespace. -acpi-y += osl.o utils.o reboot.o +acpi-y += osi.o osl.o utils.o reboot.o acpi-y += nvs.o # Power management related files diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index ba1601d26c48..bdc67bad61a7 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -3,7 +3,7 @@ * * Check to see if the given machine has a known bad ACPI BIOS * or if the BIOS is too old. - * Check given machine against acpi_osi_dmi_table[]. + * Check given machine against acpi_rev_dmi_table[]. * * Copyright (C) 2004 Len Brown * Copyright (C) 2002 Andy Grover @@ -47,7 +47,7 @@ struct acpi_blacklist_item { u32 is_critical_error; }; -static struct dmi_system_id acpi_osi_dmi_table[] __initdata; +static struct dmi_system_id acpi_rev_dmi_table[] __initdata; /* * POLICY: If *anything* doesn't work, put it on the blacklist. @@ -128,41 +128,12 @@ int __init acpi_blacklisted(void) } } - dmi_check_system(acpi_osi_dmi_table); + (void)early_acpi_osi_init(); + dmi_check_system(acpi_rev_dmi_table); return blacklisted; } #ifdef CONFIG_DMI -static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d) -{ - acpi_osi_dmi_darwin(true, d); - return 0; -} -static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) -{ - acpi_osi_dmi_linux(true, d); - return 0; -} -static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) -{ - pr_notice(PREFIX "DMI detected: %s\n", d->ident); - acpi_osi_setup("!Windows 2006"); - acpi_osi_setup("!Windows 2006 SP1"); - acpi_osi_setup("!Windows 2006 SP2"); - return 0; -} -static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) -{ - pr_notice(PREFIX "DMI detected: %s\n", d->ident); - acpi_osi_setup("!Windows 2009"); - return 0; -} -static int __init dmi_disable_osi_win8(const struct dmi_system_id *d) -{ - pr_notice(PREFIX "DMI detected: %s\n", d->ident); - acpi_osi_setup("!Windows 2012"); - return 0; -} #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE static int __init dmi_enable_rev_override(const struct dmi_system_id *d) { @@ -173,187 +144,7 @@ static int __init dmi_enable_rev_override(const struct dmi_system_id *d) } #endif -static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { - { - .callback = dmi_disable_osi_vista, - .ident = "Fujitsu Siemens", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), - }, - }, - { - /* - * There have a NVIF method in MSI GX723 DSDT need call by Nvidia - * driver (e.g. nouveau) when user press brightness hotkey. - * Currently, nouveau driver didn't do the job and it causes there - * have a infinite while loop in DSDT when user press hotkey. - * We add MSI GX723's dmi information to this table for workaround - * this issue. - * Will remove MSI GX723 from the table after nouveau grows support. - */ - .callback = dmi_disable_osi_vista, - .ident = "MSI GX723", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), - DMI_MATCH(DMI_PRODUCT_NAME, "GX723"), - }, - }, - { - .callback = dmi_disable_osi_vista, - .ident = "Sony VGN-NS10J_S", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"), - }, - }, - { - .callback = dmi_disable_osi_vista, - .ident = "Sony VGN-SR290J", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"), - }, - }, - { - .callback = dmi_disable_osi_vista, - .ident = "VGN-NS50B_L", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"), - }, - }, - { - .callback = dmi_disable_osi_vista, - .ident = "VGN-SR19XN", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"), - }, - }, - { - .callback = dmi_disable_osi_vista, - .ident = "Toshiba Satellite L355", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), - }, - }, - { - .callback = dmi_disable_osi_win7, - .ident = "ASUS K50IJ", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), - }, - }, - { - .callback = dmi_disable_osi_vista, - .ident = "Toshiba P305D", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), - }, - }, - { - .callback = dmi_disable_osi_vista, - .ident = "Toshiba NB100", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "NB100"), - }, - }, - - /* - * The wireless hotkey does not work on those machines when - * returning true for _OSI("Windows 2012") - */ - { - .callback = dmi_disable_osi_win8, - .ident = "Dell Inspiron 7737", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "Dell Inspiron 7537", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "Dell Inspiron 5437", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5437"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "Dell Inspiron 3437", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3437"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "Dell Vostro 3446", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "Dell Vostro 3546", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"), - }, - }, - - /* - * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. - * Linux ignores it, except for the machines enumerated below. - */ - - /* - * Without this this EEEpc exports a non working WMI interface, with - * this it exports a working "good old" eeepc_laptop interface, fixing - * both brightness control, and rfkill not working. - */ - { - .callback = dmi_enable_osi_linux, - .ident = "Asus EEE PC 1015PX", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"), - }, - }, - - /* - * Enable _OSI("Darwin") for all apple platforms. - */ - { - .callback = dmi_enable_osi_darwin, - .ident = "Apple hardware", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - }, - }, - { - .callback = dmi_enable_osi_darwin, - .ident = "Apple hardware", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), - }, - }, - +static struct dmi_system_id acpi_rev_dmi_table[] __initdata = { #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE /* * DELL XPS 13 (2015) switches sound between HDA and I2S diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 7c188472d9c2..a8780a2e1975 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -20,6 +20,8 @@ #define PREFIX "ACPI: " +int early_acpi_osi_init(void); +int acpi_osi_init(void); void acpi_initrd_initialize_tables(void); acpi_status acpi_os_initialize1(void); void init_acpi_device_notify(void); diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c new file mode 100644 index 000000000000..849f9d2245ca --- /dev/null +++ b/drivers/acpi/osi.c @@ -0,0 +1,522 @@ +/* + * osi.c - _OSI implementation + * + * Copyright (C) 2016 Intel Corporation + * Author: Lv Zheng + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +/* Uncomment next line to get verbose printout */ +/* #define DEBUG */ +#define pr_fmt(fmt) "ACPI: " fmt + +#include +#include +#include +#include + +#include "internal.h" + + +#define OSI_STRING_LENGTH_MAX 64 +#define OSI_STRING_ENTRIES_MAX 16 + +struct acpi_osi_entry { + char string[OSI_STRING_LENGTH_MAX]; + bool enable; +}; + +static struct acpi_osi_config { + u8 default_disabling; + unsigned int linux_enable:1; + unsigned int linux_dmi:1; + unsigned int linux_cmdline:1; + unsigned int darwin_enable:1; + unsigned int darwin_dmi:1; + unsigned int darwin_cmdline:1; +} osi_config; + +static struct acpi_osi_config osi_config; +static struct acpi_osi_entry +osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { + {"Module Device", true}, + {"Processor Device", true}, + {"3.0 _SCP Extensions", true}, + {"Processor Aggregator Device", true}, +}; + +static u32 acpi_osi_handler(acpi_string interface, u32 supported) +{ + if (!strcmp("Linux", interface)) { + pr_notice_once(FW_BUG + "BIOS _OSI(Linux) query %s%s\n", + osi_config.linux_enable ? "honored" : "ignored", + osi_config.linux_cmdline ? " via cmdline" : + osi_config.linux_dmi ? " via DMI" : ""); + } + if (!strcmp("Darwin", interface)) { + pr_notice_once( + "BIOS _OSI(Darwin) query %s%s\n", + osi_config.darwin_enable ? "honored" : "ignored", + osi_config.darwin_cmdline ? " via cmdline" : + osi_config.darwin_dmi ? " via DMI" : ""); + } + + return supported; +} + +void __init acpi_osi_setup(char *str) +{ + struct acpi_osi_entry *osi; + bool enable = true; + int i; + + if (!acpi_gbl_create_osi_method) + return; + + if (str == NULL || *str == '\0') { + pr_info("_OSI method disabled\n"); + acpi_gbl_create_osi_method = FALSE; + return; + } + + if (*str == '!') { + str++; + if (*str == '\0') { + /* Do not override acpi_osi=!* */ + if (!osi_config.default_disabling) + osi_config.default_disabling = + ACPI_DISABLE_ALL_VENDOR_STRINGS; + return; + } else if (*str == '*') { + osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS; + for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { + osi = &osi_setup_entries[i]; + osi->enable = false; + } + return; + } else if (*str == '!') { + osi_config.default_disabling = 0; + return; + } + enable = false; + } + + for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { + osi = &osi_setup_entries[i]; + if (!strcmp(osi->string, str)) { + osi->enable = enable; + break; + } else if (osi->string[0] == '\0') { + osi->enable = enable; + strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); + break; + } + } +} + +static void __init __acpi_osi_setup_darwin(bool enable) +{ + osi_config.darwin_enable = !!enable; + if (enable) { + acpi_osi_setup("!"); + acpi_osi_setup("Darwin"); + } else { + acpi_osi_setup("!!"); + acpi_osi_setup("!Darwin"); + } +} + +static void __init acpi_osi_setup_darwin(bool enable) +{ + /* Override acpi_osi_dmi_blacklisted() */ + osi_config.darwin_dmi = 0; + osi_config.darwin_cmdline = 1; + __acpi_osi_setup_darwin(enable); +} + +/* + * The story of _OSI(Linux) + * + * From pre-history through Linux-2.6.22, Linux responded TRUE upon a BIOS + * OSI(Linux) query. + * + * Unfortunately, reference BIOS writers got wind of this and put + * OSI(Linux) in their example code, quickly exposing this string as + * ill-conceived and opening the door to an un-bounded number of BIOS + * incompatibilities. + * + * For example, OSI(Linux) was used on resume to re-POST a video card on + * one system, because Linux at that time could not do a speedy restore in + * its native driver. But then upon gaining quick native restore + * capability, Linux has no way to tell the BIOS to skip the time-consuming + * POST -- putting Linux at a permanent performance disadvantage. On + * another system, the BIOS writer used OSI(Linux) to infer native OS + * support for IPMI! On other systems, OSI(Linux) simply got in the way of + * Linux claiming to be compatible with other operating systems, exposing + * BIOS issues such as skipped device initialization. + * + * So "Linux" turned out to be a really poor chose of OSI string, and from + * Linux-2.6.23 onward we respond FALSE. + * + * BIOS writers should NOT query _OSI(Linux) on future systems. Linux will + * complain on the console when it sees it, and return FALSE. To get Linux + * to return TRUE for your system will require a kernel source update to + * add a DMI entry, or boot with "acpi_osi=Linux" + */ +static void __init __acpi_osi_setup_linux(bool enable) +{ + osi_config.linux_enable = !!enable; + if (enable) + acpi_osi_setup("Linux"); + else + acpi_osi_setup("!Linux"); +} + +static void __init acpi_osi_setup_linux(bool enable) +{ + /* Override acpi_osi_dmi_blacklisted() */ + osi_config.linux_dmi = 0; + osi_config.linux_cmdline = 1; + __acpi_osi_setup_linux(enable); +} + +/* + * Modify the list of "OS Interfaces" reported to BIOS via _OSI + * + * empty string disables _OSI + * string starting with '!' disables that string + * otherwise string is added to list, augmenting built-in strings + */ +static void __init acpi_osi_setup_late(void) +{ + struct acpi_osi_entry *osi; + char *str; + int i; + acpi_status status; + + if (osi_config.default_disabling) { + status = acpi_update_interfaces(osi_config.default_disabling); + if (ACPI_SUCCESS(status)) + pr_info("Disabled all _OSI OS vendors%s\n", + osi_config.default_disabling == + ACPI_DISABLE_ALL_STRINGS ? + " and feature groups" : ""); + } + + for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { + osi = &osi_setup_entries[i]; + str = osi->string; + if (*str == '\0') + break; + if (osi->enable) { + status = acpi_install_interface(str); + if (ACPI_SUCCESS(status)) + pr_info("Added _OSI(%s)\n", str); + } else { + status = acpi_remove_interface(str); + if (ACPI_SUCCESS(status)) + pr_info("Deleted _OSI(%s)\n", str); + } + } +} + +static int __init osi_setup(char *str) +{ + if (str && !strcmp("Linux", str)) + acpi_osi_setup_linux(true); + else if (str && !strcmp("!Linux", str)) + acpi_osi_setup_linux(false); + else if (str && !strcmp("Darwin", str)) + acpi_osi_setup_darwin(true); + else if (str && !strcmp("!Darwin", str)) + acpi_osi_setup_darwin(false); + else + acpi_osi_setup(str); + + return 1; +} +__setup("acpi_osi=", osi_setup); + +bool acpi_osi_is_win8(void) +{ + return acpi_gbl_osi_data >= ACPI_OSI_WIN_8; +} +EXPORT_SYMBOL(acpi_osi_is_win8); + +static void __init acpi_osi_dmi_darwin(bool enable, + const struct dmi_system_id *d) +{ + pr_notice("DMI detected to setup _OSI(\"Darwin\"): %s\n", d->ident); + osi_config.darwin_dmi = 1; + __acpi_osi_setup_darwin(enable); +} + +void __init acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d) +{ + pr_notice("DMI detected to setup _OSI(\"Linux\"): %s\n", d->ident); + osi_config.linux_dmi = 1; + __acpi_osi_setup_linux(enable); +} + +static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d) +{ + acpi_osi_dmi_darwin(true, d); + + return 0; +} + +static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) +{ + acpi_osi_dmi_linux(true, d); + + return 0; +} + +static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) +{ + pr_notice("DMI detected: %s\n", d->ident); + acpi_osi_setup("!Windows 2006"); + acpi_osi_setup("!Windows 2006 SP1"); + acpi_osi_setup("!Windows 2006 SP2"); + + return 0; +} + +static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) +{ + pr_notice("DMI detected: %s\n", d->ident); + acpi_osi_setup("!Windows 2009"); + + return 0; +} + +static int __init dmi_disable_osi_win8(const struct dmi_system_id *d) +{ + pr_notice("DMI detected: %s\n", d->ident); + acpi_osi_setup("!Windows 2012"); + + return 0; +} + +/* + * Linux default _OSI response behavior is determined by this DMI table. + * + * Note that _OSI("Linux")/_OSI("Darwin") determined here can be overridden + * by acpi_osi=!Linux/acpi_osi=!Darwin command line options. + */ +static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { + { + .callback = dmi_disable_osi_vista, + .ident = "Fujitsu Siemens", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), + }, + }, + { + /* + * There have a NVIF method in MSI GX723 DSDT need call by Nvidia + * driver (e.g. nouveau) when user press brightness hotkey. + * Currently, nouveau driver didn't do the job and it causes there + * have a infinite while loop in DSDT when user press hotkey. + * We add MSI GX723's dmi information to this table for workaround + * this issue. + * Will remove MSI GX723 from the table after nouveau grows support. + */ + .callback = dmi_disable_osi_vista, + .ident = "MSI GX723", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), + DMI_MATCH(DMI_PRODUCT_NAME, "GX723"), + }, + }, + { + .callback = dmi_disable_osi_vista, + .ident = "Sony VGN-NS10J_S", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"), + }, + }, + { + .callback = dmi_disable_osi_vista, + .ident = "Sony VGN-SR290J", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"), + }, + }, + { + .callback = dmi_disable_osi_vista, + .ident = "VGN-NS50B_L", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"), + }, + }, + { + .callback = dmi_disable_osi_vista, + .ident = "VGN-SR19XN", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"), + }, + }, + { + .callback = dmi_disable_osi_vista, + .ident = "Toshiba Satellite L355", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), + }, + }, + { + .callback = dmi_disable_osi_win7, + .ident = "ASUS K50IJ", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), + }, + }, + { + .callback = dmi_disable_osi_vista, + .ident = "Toshiba P305D", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), + }, + }, + { + .callback = dmi_disable_osi_vista, + .ident = "Toshiba NB100", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "NB100"), + }, + }, + + /* + * The wireless hotkey does not work on those machines when + * returning true for _OSI("Windows 2012") + */ + { + .callback = dmi_disable_osi_win8, + .ident = "Dell Inspiron 7737", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Dell Inspiron 7537", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Dell Inspiron 5437", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5437"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Dell Inspiron 3437", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3437"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Dell Vostro 3446", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Dell Vostro 3546", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"), + }, + }, + + /* + * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. + * Linux ignores it, except for the machines enumerated below. + */ + + /* + * Without this this EEEpc exports a non working WMI interface, with + * this it exports a working "good old" eeepc_laptop interface, fixing + * both brightness control, and rfkill not working. + */ + { + .callback = dmi_enable_osi_linux, + .ident = "Asus EEE PC 1015PX", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"), + }, + }, + + /* + * Enable _OSI("Darwin") for all apple platforms. + */ + { + .callback = dmi_enable_osi_darwin, + .ident = "Apple hardware", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + }, + }, + { + .callback = dmi_enable_osi_darwin, + .ident = "Apple hardware", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), + }, + }, + {} +}; + +static __init void acpi_osi_dmi_blacklisted(void) +{ + dmi_check_system(acpi_osi_dmi_table); +} + +int __init early_acpi_osi_init(void) +{ + acpi_osi_dmi_blacklisted(); + + return 0; +} + +int __init acpi_osi_init(void) +{ + acpi_install_interface_handler(acpi_osi_handler); + acpi_osi_setup_late(); + + return 0; +} diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 134051689d72..29af6b40c93f 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -96,74 +96,6 @@ struct acpi_ioremap { static LIST_HEAD(acpi_ioremaps); static DEFINE_MUTEX(acpi_ioremap_lock); -static void __init acpi_osi_setup_late(void); - -/* - * The story of _OSI(Linux) - * - * From pre-history through Linux-2.6.22, - * Linux responded TRUE upon a BIOS OSI(Linux) query. - * - * Unfortunately, reference BIOS writers got wind of this - * and put OSI(Linux) in their example code, quickly exposing - * this string as ill-conceived and opening the door to - * an un-bounded number of BIOS incompatibilities. - * - * For example, OSI(Linux) was used on resume to re-POST a - * video card on one system, because Linux at that time - * could not do a speedy restore in its native driver. - * But then upon gaining quick native restore capability, - * Linux has no way to tell the BIOS to skip the time-consuming - * POST -- putting Linux at a permanent performance disadvantage. - * On another system, the BIOS writer used OSI(Linux) - * to infer native OS support for IPMI! On other systems, - * OSI(Linux) simply got in the way of Linux claiming to - * be compatible with other operating systems, exposing - * BIOS issues such as skipped device initialization. - * - * So "Linux" turned out to be a really poor chose of - * OSI string, and from Linux-2.6.23 onward we respond FALSE. - * - * BIOS writers should NOT query _OSI(Linux) on future systems. - * Linux will complain on the console when it sees it, and return FALSE. - * To get Linux to return TRUE for your system will require - * a kernel source update to add a DMI entry, - * or boot with "acpi_osi=Linux" - */ - -static struct acpi_osi_config { - unsigned int linux_enable:1; - unsigned int linux_dmi:1; - unsigned int linux_cmdline:1; - unsigned int darwin_enable:1; - unsigned int darwin_dmi:1; - unsigned int darwin_cmdline:1; - u8 default_disabling; -} osi_config; - -static u32 acpi_osi_handler(acpi_string interface, u32 supported) -{ - if (!strcmp("Linux", interface)) { - - pr_notice_once(FW_BUG PREFIX - "BIOS _OSI(Linux) query %s%s\n", - osi_config.linux_enable ? "honored" : "ignored", - osi_config.linux_cmdline ? " via cmdline" : - osi_config.linux_dmi ? " via DMI" : ""); - } - - if (!strcmp("Darwin", interface)) { - - pr_notice_once(PREFIX - "BIOS _OSI(Darwin) query %s%s\n", - osi_config.darwin_enable ? "honored" : "ignored", - osi_config.darwin_cmdline ? " via cmdline" : - osi_config.darwin_dmi ? " via DMI" : ""); - } - - return supported; -} - static void __init acpi_request_region (struct acpi_generic_address *gas, unsigned int length, char *desc) { @@ -1719,185 +1651,6 @@ static int __init acpi_os_name_setup(char *str) __setup("acpi_os_name=", acpi_os_name_setup); -#define OSI_STRING_LENGTH_MAX 64 -#define OSI_STRING_ENTRIES_MAX 16 - -struct acpi_osi_entry { - char string[OSI_STRING_LENGTH_MAX]; - bool enable; -}; - -static struct acpi_osi_entry - osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { - {"Module Device", true}, - {"Processor Device", true}, - {"3.0 _SCP Extensions", true}, - {"Processor Aggregator Device", true}, -}; - -void __init acpi_osi_setup(char *str) -{ - struct acpi_osi_entry *osi; - bool enable = true; - int i; - - if (!acpi_gbl_create_osi_method) - return; - - if (str == NULL || *str == '\0') { - pr_info(PREFIX "_OSI method disabled\n"); - acpi_gbl_create_osi_method = FALSE; - return; - } - - if (*str == '!') { - str++; - if (*str == '\0') { - /* Do not override acpi_osi=!* */ - if (!osi_config.default_disabling) - osi_config.default_disabling = - ACPI_DISABLE_ALL_VENDOR_STRINGS; - return; - } else if (*str == '*') { - osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS; - for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { - osi = &osi_setup_entries[i]; - osi->enable = false; - } - return; - } else if (*str == '!') { - osi_config.default_disabling = 0; - return; - } - enable = false; - } - - for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { - osi = &osi_setup_entries[i]; - if (!strcmp(osi->string, str)) { - osi->enable = enable; - break; - } else if (osi->string[0] == '\0') { - osi->enable = enable; - strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); - break; - } - } -} - -static void __init __acpi_osi_setup_darwin(bool enable) -{ - osi_config.darwin_enable = !!enable; - if (enable) { - acpi_osi_setup("!"); - acpi_osi_setup("Darwin"); - } else { - acpi_osi_setup("!!"); - acpi_osi_setup("!Darwin"); - } -} - -static void __init acpi_osi_setup_darwin(bool enable) -{ - osi_config.darwin_cmdline = 1; - osi_config.darwin_dmi = 0; - __acpi_osi_setup_darwin(enable); -} - -void __init acpi_osi_dmi_darwin(bool enable, const struct dmi_system_id *d) -{ - pr_notice(PREFIX "DMI detected to setup _OSI(\"Darwin\"): %s\n", - d->ident); - osi_config.darwin_dmi = 1; - __acpi_osi_setup_darwin(enable); -} - -static void __init __acpi_osi_setup_linux(bool enable) -{ - osi_config.linux_enable = !!enable; - if (enable) - acpi_osi_setup("Linux"); - else - acpi_osi_setup("!Linux"); -} - -static void __init acpi_osi_setup_linux(bool enable) -{ - osi_config.linux_cmdline = 1; - osi_config.linux_dmi = 0; - __acpi_osi_setup_linux(enable); -} - -void __init acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d) -{ - pr_notice(PREFIX "DMI detected to setup _OSI(\"Linux\"): %s\n", - d->ident); - osi_config.linux_dmi = 1; - __acpi_osi_setup_linux(enable); -} - -/* - * Modify the list of "OS Interfaces" reported to BIOS via _OSI - * - * empty string disables _OSI - * string starting with '!' disables that string - * otherwise string is added to list, augmenting built-in strings - */ -static void __init acpi_osi_setup_late(void) -{ - struct acpi_osi_entry *osi; - char *str; - int i; - acpi_status status; - - if (osi_config.default_disabling) { - status = acpi_update_interfaces(osi_config.default_disabling); - - if (ACPI_SUCCESS(status)) - pr_info(PREFIX "Disabled all _OSI OS vendors%s\n", - osi_config.default_disabling == - ACPI_DISABLE_ALL_STRINGS ? - " and feature groups" : ""); - } - - for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { - osi = &osi_setup_entries[i]; - str = osi->string; - - if (*str == '\0') - break; - if (osi->enable) { - status = acpi_install_interface(str); - - if (ACPI_SUCCESS(status)) - pr_info(PREFIX "Added _OSI(%s)\n", str); - } else { - status = acpi_remove_interface(str); - - if (ACPI_SUCCESS(status)) - pr_info(PREFIX "Deleted _OSI(%s)\n", str); - } - } -} - -static int __init osi_setup(char *str) -{ - if (str && !strcmp("Linux", str)) - acpi_osi_setup_linux(true); - else if (str && !strcmp("!Linux", str)) - acpi_osi_setup_linux(false); - else if (str && !strcmp("Darwin", str)) - acpi_osi_setup_darwin(true); - else if (str && !strcmp("!Darwin", str)) - acpi_osi_setup_darwin(false); - else - acpi_osi_setup(str); - - return 1; -} - -__setup("acpi_osi=", osi_setup); - /* * Disable the auto-serialization of named objects creation methods. * @@ -2017,12 +1770,6 @@ int acpi_resources_are_enforced(void) } EXPORT_SYMBOL(acpi_resources_are_enforced); -bool acpi_osi_is_win8(void) -{ - return acpi_gbl_osi_data >= ACPI_OSI_WIN_8; -} -EXPORT_SYMBOL(acpi_osi_is_win8); - /* * Deallocate the memory for a spinlock. */ @@ -2188,8 +1935,7 @@ acpi_status __init acpi_os_initialize1(void) BUG_ON(!kacpid_wq); BUG_ON(!kacpi_notify_wq); BUG_ON(!kacpi_hotplug_wq); - acpi_install_interface_handler(acpi_osi_handler); - acpi_osi_setup_late(); + acpi_osi_init(); return AE_OK; } -- cgit v1.2.3 From 74216699ddcca13541e8494cb2b995e6a44a04d9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 6 May 2016 01:27:09 +0200 Subject: ACPI / tables: Fix DSDT override mechanism Commit 5ae74f2cc2f1 (ACPI / tables: Move table override mechanisms to tables.c) forgot to move the CONFIG_ACPI_CUSTOM_DSDT_FILE inclusion directive from osl.c to tables.c. Fix that. Fixes: 5ae74f2cc2f1 (ACPI / tables: Move table override mechanisms to tables.c) Signed-off-by: Rafael J. Wysocki Acked-by: Lv Zheng --- drivers/acpi/osl.c | 4 ---- drivers/acpi/tables.c | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 0796ad96dc32..0155f8b8a79a 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -56,10 +56,6 @@ struct acpi_os_dpc { struct work_struct work; }; -#ifdef CONFIG_ACPI_CUSTOM_DSDT -#include CONFIG_ACPI_CUSTOM_DSDT_FILE -#endif - #ifdef ENABLE_DEBUGGER #include diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 08795fbde3fa..a372f9eaa15d 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -36,6 +36,10 @@ #include #include "internal.h" +#ifdef CONFIG_ACPI_CUSTOM_DSDT +#include CONFIG_ACPI_CUSTOM_DSDT_FILE +#endif + #define ACPI_MAX_TABLES 128 static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; -- cgit v1.2.3