From 1373718194ebebc43c00d8f117e03885749495b0 Mon Sep 17 00:00:00 2001 From: Chen Yu Date: Tue, 22 Mar 2016 08:51:10 +0800 Subject: ACPI / PM: Introduce efi poweroff for HW-full platforms without _S5 The problem is Linux registers pm_power_off = efi_power_off only if we are in hardware reduced mode. Actually, what we also want is to do this when ACPI S5 is simply not supported on non-legacy platforms. Since some future Intel platforms are HW-full mode where the DSDT fails to supply an _S5 object(without SLP_TYP), we should let such kind of platform to leverage efi runtime service to poweroff. This patch uses efi power off as first choice when S5 is unavailable, even if there is a customized poweroff(driver provided, eg). Meanwhile, the legacy platforms will not be affected because there is no path for them to overwrite the pm_power_off to efi power off. Suggested-by: Len Brown Reviewed-by: Matt Fleming Signed-off-by: Chen Yu Signed-off-by: Rafael J. Wysocki --- arch/x86/platform/efi/quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index ab50ada1d56e..818d12ad7761 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -373,5 +373,5 @@ bool efi_reboot_required(void) bool efi_poweroff_required(void) { - return !!acpi_gbl_reduced_hardware; + return acpi_gbl_reduced_hardware || acpi_no_s5; } -- cgit v1.2.3 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 --- arch/x86/kernel/setup.c | 2 +- drivers/acpi/internal.h | 1 - drivers/acpi/osl.c | 274 --------------------------------------------- drivers/acpi/tables.c | 292 +++++++++++++++++++++++++++++++++++++++++++++++- include/linux/acpi.h | 10 +- 5 files changed, 294 insertions(+), 285 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 2367ae07eb76..902a6f7b1c04 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1139,7 +1139,7 @@ void __init setup_arch(char **cmdline_p) reserve_initrd(); #if defined(CONFIG_ACPI) && defined(CONFIG_BLK_DEV_INITRD) - acpi_initrd_override((void *)initrd_start, initrd_end - initrd_start); + early_acpi_table_init((void *)initrd_start, initrd_end - initrd_start); #endif vsmp_init(); 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; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 06ed7e54033e..7718c04aa09f 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -190,14 +190,6 @@ static inline int acpi_debugger_notify_command_complete(void) } #endif -#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE -void acpi_initrd_override(void *data, size_t size); -#else -static inline void acpi_initrd_override(void *data, size_t size) -{ -} -#endif - #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) @@ -216,6 +208,7 @@ void acpi_boot_table_init (void); int acpi_mps_check (void); int acpi_numa_init (void); +void early_acpi_table_init(void *data, size_t size); int acpi_table_init (void); int acpi_table_parse(char *id, acpi_tbl_table_handler handler); int __init acpi_parse_entries(char *id, unsigned long table_size, @@ -596,6 +589,7 @@ static inline const char *acpi_dev_name(struct acpi_device *adev) return NULL; } +static inline void early_acpi_table_init(void *data, size_t size) { } static inline void acpi_early_init(void) { } static inline void acpi_subsystem_init(void) { } -- cgit v1.2.3 From af06f8b7a102417e93dc57ee7affb9fedcf5d83f Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Mon, 11 Apr 2016 10:13:27 +0800 Subject: ACPI / x86: Cleanup initrd related code In arch/x86/kernel/setup.c, the #ifdef kept for CONFIG_ACPI actually is related to the accessibility of initrd_start/initrd_end, so the stub should be provided from this source file and should only be dependent on CONFIG_BLK_DEV_INITRD. Note that when ACPI=n and BLK_DEV_INITRD=y, early_initrd_acpi_init() is still a stub because of the stub prepared for early_acpi_table_init(). Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- arch/x86/kernel/setup.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 902a6f7b1c04..c4e7b3991b60 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -398,6 +398,11 @@ static void __init reserve_initrd(void) memblock_free(ramdisk_image, ramdisk_end - ramdisk_image); } + +static void __init early_initrd_acpi_init(void) +{ + early_acpi_table_init((void *)initrd_start, initrd_end - initrd_start); +} #else static void __init early_reserve_initrd(void) { @@ -405,6 +410,9 @@ static void __init early_reserve_initrd(void) static void __init reserve_initrd(void) { } +static void __init early_initrd_acpi_init(void) +{ +} #endif /* CONFIG_BLK_DEV_INITRD */ static void __init parse_setup_data(void) @@ -1138,9 +1146,7 @@ void __init setup_arch(char **cmdline_p) reserve_initrd(); -#if defined(CONFIG_ACPI) && defined(CONFIG_BLK_DEV_INITRD) - early_acpi_table_init((void *)initrd_start, initrd_end - initrd_start); -#endif + early_initrd_acpi_init(); vsmp_init(); -- cgit v1.2.3 From 2b13f01b90fc07334911b424709901bb88517746 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 15 Apr 2016 08:53:43 +0100 Subject: arm64: defconfig: Enable ACPI Enable ACPI by default to support testing of ACPI only systems and ensure that defconfig will boot on anything, for arm64 this is not done in Kconfig since a very large proportion of arm64 systems have no ACPI at all. Signed-off-by: Mark Brown Acked-by: Catalin Marinas Acked-by: Hanjun Guo Acked-by: Roy Franz Signed-off-by: Rafael J. Wysocki --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index a44ef995d8ae..c5e0132eec57 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -264,6 +264,7 @@ CONFIG_PHY_RCAR_GEN3_USB2=y CONFIG_PHY_HI6220_USB=y CONFIG_PHY_XGENE=y CONFIG_ARM_SCPI_PROTOCOL=y +CONFIG_ACPI=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_FANOTIFY=y -- cgit v1.2.3 From 1fcb6a813c4f67a0ba189b0d057b70ba084f6e1a Mon Sep 17 00:00:00 2001 From: Sinan Kaya Date: Sun, 17 Apr 2016 13:36:55 -0400 Subject: ACPI,PCI,IRQ: remove redundant code in acpi_irq_penalty_init() acpi_irq_get_penalty is now calculating the penalty on the fly now. No need to maintain global list of penalties or calculate them at the init time. Removing duplicate code in acpi_irq_penalty_init. Signed-off-by: Sinan Kaya Acked-by: Bjorn Helgaas Signed-off-by: Rafael J. Wysocki --- arch/x86/pci/acpi.c | 1 - drivers/acpi/pci_link.c | 36 ------------------------------------ include/acpi/acpi_drivers.h | 1 - 3 files changed, 38 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 3cd69832d7f4..b2a4e2a61f6b 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -396,7 +396,6 @@ int __init pci_acpi_init(void) return -ENODEV; printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); - acpi_irq_penalty_init(); pcibios_enable_irq = acpi_pci_irq_enable; pcibios_disable_irq = acpi_pci_irq_disable; x86_init.pci.init_irq = x86_init_noop; diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 12ea78495b47..ab39208ba7e5 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -520,42 +520,6 @@ static int acpi_irq_get_penalty(int irq) return penalty; } -int __init acpi_irq_penalty_init(void) -{ - struct acpi_pci_link *link; - int i; - - /* - * Update penalties to facilitate IRQ balancing. - */ - list_for_each_entry(link, &acpi_link_list, list) { - - /* - * reflect the possible and active irqs in the penalty table -- - * useful for breaking ties. - */ - if (link->irq.possible_count) { - int penalty = - PIRQ_PENALTY_PCI_POSSIBLE / - link->irq.possible_count; - - for (i = 0; i < link->irq.possible_count; i++) { - if (link->irq.possible[i] < ACPI_MAX_ISA_IRQS) - acpi_isa_irq_penalty[link->irq. - possible[i]] += - penalty; - } - - } else if (link->irq.active && - (link->irq.active < ACPI_MAX_ISA_IRQS)) { - acpi_isa_irq_penalty[link->irq.active] += - PIRQ_PENALTY_PCI_POSSIBLE; - } - } - - return 0; -} - static int acpi_irq_balance = -1; /* 0: static, 1: balance */ static int acpi_pci_link_allocate(struct acpi_pci_link *link) diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 29c691265b49..797ae2ec8eee 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -78,7 +78,6 @@ /* ACPI PCI Interrupt Link (pci_link.c) */ -int acpi_irq_penalty_init(void); int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering, int *polarity, char **name); int acpi_pci_link_free_irq(acpi_handle handle); -- cgit v1.2.3 From 9e5ed6d1fb87dc3ff0c2a94ed75fe82027a9f597 Mon Sep 17 00:00:00 2001 From: Sinan Kaya Date: Sun, 17 Apr 2016 13:36:56 -0400 Subject: ACPI,PCI,IRQ: remove SCI penalize function Removing the SCI penalize function as the penalty is now calculated on the fly. Signed-off-by: Sinan Kaya Acked-by: Bjorn Helgaas Signed-off-by: Rafael J. Wysocki --- arch/x86/kernel/acpi/boot.c | 1 - drivers/acpi/pci_link.c | 4 ---- include/linux/acpi.h | 1 - 3 files changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 8c2f1ef6ca23..edf48404d15d 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -445,7 +445,6 @@ static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK; mp_override_legacy_irq(bus_irq, polarity, trigger, gsi); - acpi_penalize_sci_irq(bus_irq, trigger, polarity); /* * stash over-ride to indicate we've been here diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index ab39208ba7e5..8fc7323ed3e8 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -848,10 +848,6 @@ bool acpi_isa_irq_available(int irq) acpi_irq_get_penalty(irq) < PIRQ_PENALTY_ISA_ALWAYS); } -void acpi_penalize_sci_irq(int irq, int trigger, int polarity) -{ -} - /* * Over-ride default table to reserve additional IRQs for use by ISA * e.g. acpi_irq_isa=5 diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 06ed7e54033e..0f413170c8f9 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -311,7 +311,6 @@ struct pci_dev; int acpi_pci_irq_enable (struct pci_dev *dev); void acpi_penalize_isa_irq(int irq, int active); bool acpi_isa_irq_available(int irq); -void acpi_penalize_sci_irq(int irq, int trigger, int polarity); void acpi_pci_irq_disable (struct pci_dev *dev); extern int ec_read(u8 addr, u8 *val); -- cgit v1.2.3