remarkable-linux/arch/arm64/kernel/acpi.c
Linus Torvalds 54ce685cae More ACPI updates for v4.16-rc1
- Update the ACPICA kernel code to upstream revision 20180105 including:
    * Assorted fixes (Jung-uk Kim).
    * Support for X32 ABI compilation (Anuj Mittal).
    * Update of ACPICA copyrights to 2018 (Bob Moore).
 
  - Prepare for future modifications to avoid executing the _STA control
    method too early (Hans de Goede).
 
  - Make the processor performance control library code ignore _PPC
    notifications if they cannot be handled and fix up the C1 idle
    state definition when it is used as a fallback state (Chen Yu,
    Yazen Ghannam).
 
  - Make it possible to use the SPCR table on x86 and to replace the
    original IORT table with a new one from initrd (Prarit Bhargava,
    Shunyong Yang).
 
  - Add battery-related quirks for Asus UX360UA and UX410UAK and add
    quirks for table parsing on Dell XPS 9570 and Precision M5530
    (Kai Heng Feng).
 
  - Address static checker warnings in the CPPC code (Gustavo Silva).
 
  - Avoid printing a raw pointer to the kernel log in the smart
    battery driver (Greg Kroah-Hartman).
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABCAAGBQJafGvJAAoJEILEb/54YlRxiusQAKUa+OM/oxTJkOEfGGRM8NlS
 Hq/PaL/TnAj3nCoZN9fM38mI4gkxqu3eVMv6kfiqRe8VYmUX9r9tRbQ9kxvEYa7n
 s6Dl+wdC9UND20QJkYVzPlaXbPuZyLFHt4Fkb1hp+HAGgNNYqc4e0lJvI82F2pdo
 im1UFI84jg9UQV4WpUJL6ny2c/RMNtpUV5fOKFD8lkvBvVe7mtZTZ+1nZDeqXGkV
 jzdrVTHLUEDhjS1o0TBmEsJGNeGOqnK/f+m8Rq4397guPAQQq18MYNC68SzhuGjP
 iqhvIvI9sF197i66l/qgsubBifOV4At8Wb0LA5cU8CQLLpEW8GDktz/kucVHyzJ4
 cVKuPXptBwwtPbNFHWO8reTUFMAnP7IpjtC31ntr6xWRQCiXv0/i2hRRN54g9T7e
 FAOBmmys5DKFOq50OB5WdD3/Qz5OUuVgdbrSxNFARIZpQFtUn7Np2/nmNpPgrrcl
 77hO8dpeXUTVvM4HpRQN1+r0KOTLfTAvWV7LYLAjCF9ivc0Vop/tYZQ2VEMSUEFD
 SGKC30mGC4pphAjxcSYV282JR7Jx7arQ71ZA5uYTRRuxnEQd/2MC71fNjrFmCgUW
 1Pumw0Pw6eZRjj1FZ/pj0X5lm7AlZj0dVzsJFgNb0FcJW0nOhN3czQrA4igoSVng
 B2sRv9U8YDnDtzHyTPrY
 =rVdp
 -----END PGP SIGNATURE-----

Merge tag 'acpi-part2-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more ACPI updates from Rafael Wysocki:
 "These are mostly fixes and cleanups, a few new quirks, a couple of
  updates related to the handling of ACPI tables and ACPICA copyrights
  refreshment.

  Specifics:

   - Update the ACPICA kernel code to upstream revision 20180105
     including:
       * Assorted fixes (Jung-uk Kim)
       * Support for X32 ABI compilation (Anuj Mittal)
       * Update of ACPICA copyrights to 2018 (Bob Moore)

   - Prepare for future modifications to avoid executing the _STA
     control method too early (Hans de Goede)

   - Make the processor performance control library code ignore _PPC
     notifications if they cannot be handled and fix up the C1 idle
     state definition when it is used as a fallback state (Chen Yu,
     Yazen Ghannam)

   - Make it possible to use the SPCR table on x86 and to replace the
     original IORT table with a new one from initrd (Prarit Bhargava,
     Shunyong Yang)

   - Add battery-related quirks for Asus UX360UA and UX410UAK and add
     quirks for table parsing on Dell XPS 9570 and Precision M5530 (Kai
     Heng Feng)

   - Address static checker warnings in the CPPC code (Gustavo Silva)

   - Avoid printing a raw pointer to the kernel log in the smart battery
     driver (Greg Kroah-Hartman)"

* tag 'acpi-part2-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI: sbshc: remove raw pointer from printk() message
  ACPI: SPCR: Make SPCR available to x86
  ACPI / CPPC: Use 64-bit arithmetic instead of 32-bit
  ACPI / tables: Add IORT to injectable table list
  ACPI / bus: Parse tables as term_list for Dell XPS 9570 and Precision M5530
  ACPICA: Update version to 20180105
  ACPICA: All acpica: Update copyrights to 2018
  ACPI / processor: Set default C1 idle state description
  ACPI / battery: Add quirk for Asus UX360UA and UX410UAK
  ACPI: processor_perflib: Do not send _PPC change notification if not ready
  ACPI / scan: Use acpi_bus_get_status() to initialize ACPI_TYPE_DEVICE devs
  ACPI / bus: Do not call _STA on battery devices with unmet dependencies
  PCI: acpiphp_ibm: prepare for acpi_get_object_info() no longer returning status
  ACPI: export acpi_bus_get_status_handle()
  ACPICA: Add a missing pair of parentheses
  ACPICA: Prefer ACPI_TO_POINTER() over ACPI_ADD_PTR()
  ACPICA: Avoid NULL pointer arithmetic
  ACPICA: Linux: add support for X32 ABI compilation
  ACPI / video: Use true for boolean value
2018-02-09 09:44:25 -08:00

265 lines
6.9 KiB
C

/*
* ARM64 Specific Low-Level ACPI Boot Support
*
* Copyright (C) 2013-2014, Linaro Ltd.
* Author: Al Stone <al.stone@linaro.org>
* Author: Graeme Gregory <graeme.gregory@linaro.org>
* Author: Hanjun Guo <hanjun.guo@linaro.org>
* Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
* Author: Naresh Bhat <naresh.bhat@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/acpi.h>
#include <linux/bootmem.h>
#include <linux/cpumask.h>
#include <linux/efi-bgrt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/memblock.h>
#include <linux/of_fdt.h>
#include <linux/smp.h>
#include <linux/serial_core.h>
#include <asm/cputype.h>
#include <asm/cpu_ops.h>
#include <asm/smp_plat.h>
#ifdef CONFIG_ACPI_APEI
# include <linux/efi.h>
# include <asm/pgtable.h>
#endif
int acpi_noirq = 1; /* skip ACPI IRQ initialization */
int acpi_disabled = 1;
EXPORT_SYMBOL(acpi_disabled);
int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */
EXPORT_SYMBOL(acpi_pci_disabled);
static bool param_acpi_off __initdata;
static bool param_acpi_on __initdata;
static bool param_acpi_force __initdata;
static int __init parse_acpi(char *arg)
{
if (!arg)
return -EINVAL;
/* "acpi=off" disables both ACPI table parsing and interpreter */
if (strcmp(arg, "off") == 0)
param_acpi_off = true;
else if (strcmp(arg, "on") == 0) /* prefer ACPI over DT */
param_acpi_on = true;
else if (strcmp(arg, "force") == 0) /* force ACPI to be enabled */
param_acpi_force = true;
else
return -EINVAL; /* Core will print when we return error */
return 0;
}
early_param("acpi", parse_acpi);
static int __init dt_scan_depth1_nodes(unsigned long node,
const char *uname, int depth,
void *data)
{
/*
* Ignore anything not directly under the root node; we'll
* catch its parent instead.
*/
if (depth != 1)
return 0;
if (strcmp(uname, "chosen") == 0)
return 0;
if (strcmp(uname, "hypervisor") == 0 &&
of_flat_dt_is_compatible(node, "xen,xen"))
return 0;
/*
* This node at depth 1 is neither a chosen node nor a xen node,
* which we do not expect.
*/
return 1;
}
/*
* __acpi_map_table() will be called before page_init(), so early_ioremap()
* or early_memremap() should be called here to for ACPI table mapping.
*/
void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size)
{
if (!size)
return NULL;
return early_memremap(phys, size);
}
void __init __acpi_unmap_table(void __iomem *map, unsigned long size)
{
if (!map || !size)
return;
early_memunmap(map, size);
}
bool __init acpi_psci_present(void)
{
return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT;
}
/* Whether HVC must be used instead of SMC as the PSCI conduit */
bool acpi_psci_use_hvc(void)
{
return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC;
}
/*
* acpi_fadt_sanity_check() - Check FADT presence and carry out sanity
* checks on it
*
* Return 0 on success, <0 on failure
*/
static int __init acpi_fadt_sanity_check(void)
{
struct acpi_table_header *table;
struct acpi_table_fadt *fadt;
acpi_status status;
int ret = 0;
/*
* FADT is required on arm64; retrieve it to check its presence
* and carry out revision and ACPI HW reduced compliancy tests
*/
status = acpi_get_table(ACPI_SIG_FADT, 0, &table);
if (ACPI_FAILURE(status)) {
const char *msg = acpi_format_exception(status);
pr_err("Failed to get FADT table, %s\n", msg);
return -ENODEV;
}
fadt = (struct acpi_table_fadt *)table;
/*
* Revision in table header is the FADT Major revision, and there
* is a minor revision of FADT which was introduced by ACPI 5.1,
* we only deal with ACPI 5.1 or newer revision to get GIC and SMP
* boot protocol configuration data.
*/
if (table->revision < 5 ||
(table->revision == 5 && fadt->minor_revision < 1)) {
pr_err("Unsupported FADT revision %d.%d, should be 5.1+\n",
table->revision, fadt->minor_revision);
ret = -EINVAL;
goto out;
}
if (!(fadt->flags & ACPI_FADT_HW_REDUCED)) {
pr_err("FADT not ACPI hardware reduced compliant\n");
ret = -EINVAL;
}
out:
/*
* acpi_get_table() creates FADT table mapping that
* should be released after parsing and before resuming boot
*/
acpi_put_table(table);
return ret;
}
/*
* acpi_boot_table_init() called from setup_arch(), always.
* 1. find RSDP and get its address, and then find XSDT
* 2. extract all tables and checksums them all
* 3. check ACPI FADT revision
* 4. check ACPI FADT HW reduced flag
*
* We can parse ACPI boot-time tables such as MADT after
* this function is called.
*
* On return ACPI is enabled if either:
*
* - ACPI tables are initialized and sanity checks passed
* - acpi=force was passed in the command line and ACPI was not disabled
* explicitly through acpi=off command line parameter
*
* ACPI is disabled on function return otherwise
*/
void __init acpi_boot_table_init(void)
{
/*
* Enable ACPI instead of device tree unless
* - ACPI has been disabled explicitly (acpi=off), or
* - the device tree is not empty (it has more than just a /chosen node,
* and a /hypervisor node when running on Xen)
* and ACPI has not been [force] enabled (acpi=on|force)
*/
if (param_acpi_off ||
(!param_acpi_on && !param_acpi_force &&
of_scan_flat_dt(dt_scan_depth1_nodes, NULL)))
goto done;
/*
* ACPI is disabled at this point. Enable it in order to parse
* the ACPI tables and carry out sanity checks
*/
enable_acpi();
/*
* If ACPI tables are initialized and FADT sanity checks passed,
* leave ACPI enabled and carry on booting; otherwise disable ACPI
* on initialization error.
* If acpi=force was passed on the command line it forces ACPI
* to be enabled even if its initialization failed.
*/
if (acpi_table_init() || acpi_fadt_sanity_check()) {
pr_err("Failed to init ACPI tables\n");
if (!param_acpi_force)
disable_acpi();
}
done:
if (acpi_disabled) {
if (earlycon_acpi_spcr_enable)
early_init_dt_scan_chosen_stdout();
} else {
acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
if (IS_ENABLED(CONFIG_ACPI_BGRT))
acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
}
}
#ifdef CONFIG_ACPI_APEI
pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
{
/*
* According to "Table 8 Map: EFI memory types to AArch64 memory
* types" of UEFI 2.5 section 2.3.6.1, each EFI memory type is
* mapped to a corresponding MAIR attribute encoding.
* The EFI memory attribute advises all possible capabilities
* of a memory region. We use the most efficient capability.
*/
u64 attr;
attr = efi_mem_attributes(addr);
if (attr & EFI_MEMORY_WB)
return PAGE_KERNEL;
if (attr & EFI_MEMORY_WT)
return __pgprot(PROT_NORMAL_WT);
if (attr & EFI_MEMORY_WC)
return __pgprot(PROT_NORMAL_NC);
return __pgprot(PROT_DEVICE_nGnRnE);
}
#endif