diff options
71 files changed, 4958 insertions, 168 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index fcbb736d55fe..0832e29ab145 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -491,6 +491,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. bootmem_debug [KNL] Enable bootmem allocator debug messages. + bert_disable [ACPI] + Disable Boot Error Record Table (BEST) support. + bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards) bttv.radio= Most important insmod options are available as kernel args too. diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8e6954f80afd..59320c63e8ea 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -2327,10 +2327,12 @@ config ARTHUR endmenu -menu "Power management options" +menu "Power management and ACPI options" source "kernel/power/Kconfig" +source "drivers/acpi/Kconfig" + config ARCH_SUSPEND_POSSIBLE depends on !ARCH_S5PC100 depends on CPU_ARM920T || CPU_ARM926T || CPU_FEROCEON || CPU_SA1100 || \ diff --git a/arch/arm/include/asm/acpi.h b/arch/arm/include/asm/acpi.h new file mode 100644 index 000000000000..ca7efaa09cce --- /dev/null +++ b/arch/arm/include/asm/acpi.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2013, Al Stone <ahs3@redhat.com> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#ifndef _ASM_ARM_ACPI_H +#define _ASM_ARM_ACPI_H + +#ifdef __KERNEL__ + +#include <acpi/pdc_arm.h> + +#include <asm/cacheflush.h> + +#include <linux/init.h> + +#include <asm/div64.h> + +#define COMPILER_DEPENDENT_INT64 long long +#define COMPILER_DEPENDENT_UINT64 unsigned long long + +#define MAX_LOCAL_APIC 256 +#define MAX_IO_APICS 64 + +/* + * Calling conventions: + * + * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) + * ACPI_EXTERNAL_XFACE - External ACPI interfaces + * ACPI_INTERNAL_XFACE - Internal ACPI interfaces + * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces + */ +#define ACPI_SYSTEM_XFACE +#define ACPI_EXTERNAL_XFACE +#define ACPI_INTERNAL_XFACE +#define ACPI_INTERNAL_VAR_XFACE + +/* Asm macros */ +#define ACPI_ASM_MACROS +#define BREAKPOINT3 +#define ACPI_DISABLE_IRQS() local_irq_disable() +#define ACPI_ENABLE_IRQS() local_irq_enable() +#define ACPI_FLUSH_CPU_CACHE() flush_cache_all() + +#define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) { \ + u64 value = (u64)n_hi << 32 | n_lo; \ + r32 = do_div(value, d32); \ + q32 = value; \ + } + +#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \ + asm ("mov r0, %2\n" \ + "mov r1, %3\n" \ + "and r2, r0, #1\n" \ + "lsr r0, r0, #1\n" \ + "lsr r1, r1, #1\n" \ + "orr r1, r1, r2, lsl #31\n" \ + "mov %0, r0\n" \ + "mov %1, r1\n" \ + : "=r"(n_hi), "=r"(n_lo) /* output operands */ \ + : "0"(n_hi), "1"(n_lo) /* input operands */ \ + : "r0", "r1", "r2" /* clobbered registers */ \ + ) + +/* Blob handling macros */ +#define ACPI_BLOB_HEADER_SIZE 8 + +int __acpi_acquire_global_lock(unsigned int *lock); +int __acpi_release_global_lock(unsigned int *lock); + +#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ + ((Acq) = __acpi_acquire_global_lock(&facs->global_lock)) + +#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ + ((Acq) = __acpi_release_global_lock(&facs->global_lock)) + +/* Basic configuration for ACPI */ +/* BOZO: hardware reduced acpi only? */ +#ifdef CONFIG_ACPI +extern int acpi_disabled; +extern int acpi_noirq; +extern int acpi_pci_disabled; +extern int acpi_strict; + +/* map logic cpu id to physical APIC id + * APIC = GIC cpu interface on ARM + */ +extern volatile int arm_cpu_to_apicid[NR_CPUS]; +extern int boot_cpu_apic_id; +#define cpu_physical_id(cpu) arm_cpu_to_apicid[cpu] + +struct acpi_arm_root { + phys_addr_t phys_address; + unsigned long size; +}; +extern struct acpi_arm_root acpi_arm_rsdp_info; + +void arm_acpi_reserve_memory(void); + +/* Low-level suspend routine. */ +extern int acpi_suspend_lowlevel(void); + +extern void prefill_possible_map(void); + +/* Physical address to resume after wakeup */ +/* BOZO: was... +#define acpi_wakeup_address ((unsigned long)(real_mode_header->wakeup_start)) +*/ +#define acpi_wakeup_address (0) + + +static inline void disable_acpi(void) +{ + acpi_disabled = 1; + acpi_pci_disabled = 1; + acpi_noirq = 1; +} + +static inline bool arch_has_acpi_pdc(void) +{ + /* BOZO: replace x86 specific-ness here */ + return 0; /* always false for now */ +} + +static inline void arch_acpi_set_pdc_bits(u32 *buf) +{ + /* BOZO: replace x86 specific-ness here */ +} + +static inline void acpi_noirq_set(void) { acpi_noirq = 1; } +static inline void acpi_disable_pci(void) +{ + acpi_pci_disabled = 1; + acpi_noirq_set(); +} + +#else /* !CONFIG_ACPI */ +#define acpi_disabled 1 /* ACPI sometimes enabled on ARM */ +#define acpi_noirq 1 /* ACPI sometimes enabled on ARM */ +#define acpi_pci_disabled 1 /* ACPI PCI sometimes enabled on ARM */ +#define acpi_strict 1 /* no ACPI spec workarounds on ARM */ +#endif + +#endif /*__KERNEL__*/ + +#endif /*_ASM_ARM_ACPI_H*/ diff --git a/arch/arm/include/asm/cpu.h b/arch/arm/include/asm/cpu.h index 2744f0602550..a72f974d33a5 100644 --- a/arch/arm/include/asm/cpu.h +++ b/arch/arm/include/asm/cpu.h @@ -12,6 +12,7 @@ #include <linux/percpu.h> #include <linux/cpu.h> +#include <linux/topology.h> struct cpuinfo_arm { struct cpu cpu; @@ -21,6 +22,11 @@ struct cpuinfo_arm { #endif }; +#ifdef CONFIG_HOTPLUG_CPU +extern int arch_register_cpu(int cpu); +extern void arch_unregister_cpu(int cpu); +#endif + DECLARE_PER_CPU(struct cpuinfo_arm, cpu_data); #endif diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h index 8b2507e517cf..a2a5f50cc509 100644 --- a/arch/arm/include/asm/fixmap.h +++ b/arch/arm/include/asm/fixmap.h @@ -65,4 +65,4 @@ static inline unsigned int virt_to_fix(const unsigned long vaddr) return __virt_to_fix(vaddr); } -#endif +#endif /* _ASM_FIXMAP_H */ diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 826cd88fd798..5145667d1582 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -328,7 +328,12 @@ extern void _memset_io(volatile void __iomem *, int, size_t); */ #define ioremap(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE) #define ioremap_nocache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE) -#define ioremap_cached(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED) +/* + * BOZO: is this just mis-named as ioremap_cached()? + * renaming it to ioremap_cache() to find out for now. + #define ioremap_cached(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED) + */ +#define ioremap_cache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED) #define ioremap_wc(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_WC) #define iounmap __arm_iounmap diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index 413f3876341c..abff94afa776 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -108,6 +108,19 @@ static inline void prefetch(const void *ptr) #define ARCH_HAS_SPINLOCK_PREFETCH #define spin_lock_prefetch(x) do { } while (0) +/* + * Not all ARM devices have ACPI, but some do + * BOZO: is this correct? + */ +#ifdef CONFIG_ACPI +enum idle_boot_override { IDLE_NO_OVERRIDE = 0, IDLE_HALT, IDLE_NOMWAIT, + IDLE_POLL, IDLE_FORCE_MWAIT }; + +extern unsigned long boot_option_idle_override; +#endif + +/* end BOZO */ + #endif #define HAVE_ARCH_PICK_MMAP_LAYOUT diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h index 611edefaeaf1..079dfd0e1c96 100644 --- a/arch/arm/include/asm/topology.h +++ b/arch/arm/include/asm/topology.h @@ -27,6 +27,7 @@ void init_cpu_topology(void); void store_cpu_topology(unsigned int cpuid); const struct cpumask *cpu_coregroup_mask(int cpu); int cluster_to_logical_mask(unsigned int socket_id, cpumask_t *cluster_mask); +void arch_fix_phys_package_id(int num, u32 slot); #else @@ -34,6 +35,7 @@ static inline void init_cpu_topology(void) { } static inline void store_cpu_topology(unsigned int cpuid) { } static inline int cluster_to_logical_mask(unsigned int socket_id, cpumask_t *cluster_mask) { return -EINVAL; } +static inline void arch_fix_phys_package_id(int num, u32 slot) { }; #endif diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index f35906b3d8c9..b231510db238 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -26,6 +26,10 @@ #include <asm/mach/arch.h> #include <asm/mach-types.h> +#ifdef CONFIG_ACPI +#include <asm/acpi.h> +#endif + void __init early_init_dt_add_memory_arch(u64 base, u64 size) { arm_add_memory(base, size); @@ -242,6 +246,9 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) /* Retrieve various information from the /chosen node */ of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); +#ifdef CONFIG_ACPI + of_scan_flat_dt(early_init_dt_scan_acpi, &acpi_arm_rsdp_info); +#endif /* Initialize {size,address}-cells info */ of_scan_flat_dt(early_init_dt_scan_root, NULL); /* Setup memory, calling early_init_dt_add_memory_arch */ diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 6bd2ffeb4236..39804ddb4c26 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -634,3 +634,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) return ret; } #endif + +#ifdef CONFIG_ACPI + +unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; +EXPORT_SYMBOL(boot_option_idle_override); + +#endif + diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 87ff95d0ccb2..0bde4e33f50f 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -31,6 +31,9 @@ #include <linux/compiler.h> #include <linux/sort.h> #include <linux/efi.h> +#ifdef CONFIG_ACPI +#include <linux/acpi.h> +#endif #include <asm/unified.h> #include <asm/cp15.h> @@ -886,10 +889,23 @@ void __init setup_arch(char **cmdline_p) sanity_check_meminfo(); arm_memblock_init(&meminfo, mdesc); +#ifdef CONFIG_ACPI + arm_acpi_reserve_memory(); +#endif + #ifdef CONFIG_EFI efi_memblock_arm_reserve_range(); #endif +#ifdef CONFIG_ACPI + /* + * Parse the ACPI tables for possible boot-time configuration + */ + acpi_boot_table_init(); + early_acpi_boot_init(); + acpi_boot_init(); +#endif + paging_init(mdesc); request_standard_resources(mdesc); @@ -934,21 +950,6 @@ void __init setup_arch(char **cmdline_p) mdesc->init_early(); } - -static int __init topology_init(void) -{ - int cpu; - - for_each_possible_cpu(cpu) { - struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu); - cpuinfo->cpu.hotpluggable = 1; - register_cpu(&cpuinfo->cpu, cpu); - } - - return 0; -} -subsys_initcall(topology_init); - #ifdef CONFIG_HAVE_PROC_CPU static int __init proc_cpu_init(void) { diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 77c06ad0fb5b..e89426e5ab3f 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -24,6 +24,7 @@ #include <asm/cputype.h> #include <asm/topology.h> +#include <asm/cpu.h> /* * cpu power scale management @@ -266,6 +267,17 @@ void store_cpu_topology(unsigned int cpuid) cpu_topology[cpuid].socket_id, mpidr); } +void arch_fix_phys_package_id(int num, u32 slot) +{ +#ifdef CONFIG_SMP + struct cputopo_arm *cpuid_topo = &cpu_topology[num]; + + if (cpuid_topo->socket_id == -1) + cpuid_topo->socket_id = slot; +#endif +} +EXPORT_SYMBOL_GPL(arch_fix_phys_package_id); + /* * cluster_to_logical_mask - return cpu logical mask of CPUs in a cluster * @socket_id: cluster HW identifier @@ -317,3 +329,41 @@ void __init init_cpu_topology(void) parse_dt_topology(); } + +#ifdef CONFIG_HOTPLUG_CPU +int __ref arch_register_cpu(int cpu) +{ + struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu); + + /* BSP cann't be taken down on arm */ + if (cpu) + cpuinfo->cpu.hotpluggable = 1; + + return register_cpu(&cpuinfo->cpu, cpu); +} +EXPORT_SYMBOL(arch_register_cpu); + +void arch_unregister_cpu(int cpu) +{ + unregister_cpu(&per_cpu(cpu_data, cpu).cpu); +} +EXPORT_SYMBOL(arch_unregister_cpu); +#else /* CONFIG_HOTPLUG_CPU */ + +static int __init arch_register_cpu(int cpu) +{ + return register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu); +} +#endif /* CONFIG_HOTPLUG_CPU */ + +static int __init topology_init(void) +{ + int cpu; + + for_each_present_cpu(cpu) + arch_register_cpu(cpu); + + return 0; +} +subsys_initcall(topology_init); + diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index bce0e922ad36..9c340980a756 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -152,6 +152,31 @@ config SMP If you don't know what to do here, say N. +config ARM64_CPU_TOPOLOGY + bool "Support cpu topology definition" + depends on SMP && ARM64 + default y + help + Support ARM64 cpu topology definition. The MPIDR register defines + affinity between processors which is then used to describe the cpu + topology of an ARM64 System. + +config SCHED_MC + bool "Multi-core scheduler support" + depends on ARM64_CPU_TOPOLOGY + help + Multi-core scheduler support improves the CPU scheduler's decision + making when dealing with multi-core CPU chips at a cost of slightly + increased overhead in some places. If unsure say N here. + +config SCHED_SMT + bool "SMT scheduler support" + depends on ARM64_CPU_TOPOLOGY + help + Improves the CPU scheduler's decision making when dealing with + MultiThreading at a cost of slightly increased overhead in some + places. If unsure say N here. + config NR_CPUS int "Maximum number of CPUs (2-32)" range 2 32 @@ -160,6 +185,13 @@ config NR_CPUS default "8" if ARCH_XGENE default "4" +config HOTPLUG_CPU + bool "Support for hot-pluggable CPUs" + depends on SMP + help + Say Y here to experiment with turning CPUs off and on. CPUs + can be controlled through /sys/devices/system/cpu. + source kernel/Kconfig.preempt config HZ @@ -291,6 +323,12 @@ source "net/Kconfig" source "drivers/Kconfig" +menu "Power management and ACPI options" + +source "drivers/acpi/Kconfig" + +endmenu + source "drivers/firmware/Kconfig" source "fs/Kconfig" diff --git a/arch/arm64/boot/dts/foundation-v8-acpi.dts b/arch/arm64/boot/dts/foundation-v8-acpi.dts new file mode 100644 index 000000000000..7f57c53579e9 --- /dev/null +++ b/arch/arm64/boot/dts/foundation-v8-acpi.dts @@ -0,0 +1,241 @@ +/* + * ARM Ltd. + * + * ARMv8 Foundation model DTS + */ + +/dts-v1/; + +/ { + model = "Foundation-v8A"; + compatible = "arm,foundation-aarch64", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x80000000>, + <0x00000008 0x80000000 0 0x80000000>; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0x2c001000 0 0x1000>, + <0x0 0x2c002000 0 0x1000>, + <0x0 0x2c004000 0 0x2000>, + <0x0 0x2c006000 0 0x2000>; + interrupts = <1 9 0xf04>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xff01>, + <1 14 0xff01>, + <1 11 0xff01>, + <1 10 0xff01>; + clock-frequency = <100000000>; + }; + + /* + * Removed for ACPI + * + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + */ + + smb { + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + arm,v2m-memory-map = "rs1"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + + /* + * Removed for ACPI + * + ethernet@2,02000000 { + compatible = "smsc,lan91c111"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + }; + */ + + v2m_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "v2m:clk24mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "v2m:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "v2m:refclk32khz"; + }; + + iofpga@3,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + v2m_sysreg: sysreg@010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + }; + + v2m_serial0: uart@090000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial1: uart@0a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial2: uart@0b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial3: uart@0c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + /* + * Removed for ACPI + * + virtio_block@0130000 { + compatible = "virtio,mmio"; + reg = <0x130000 0x1000>; + interrupts = <42>; + }; + */ + }; + }; +}; diff --git a/arch/arm64/boot/dts/foundation-v8.dts b/arch/arm64/boot/dts/foundation-v8.dts index 84fcc5018284..335a88fc403d 100644 --- a/arch/arm64/boot/dts/foundation-v8.dts +++ b/arch/arm64/boot/dts/foundation-v8.dts @@ -22,6 +22,13 @@ serial3 = &v2m_serial3; }; + psci { + compatible = "arm,psci"; + method = "smc"; + cpu_off = <0x84000001>; + cpu_on = <0x84000002>; + }; + cpus { #address-cells = <2>; #size-cells = <0>; @@ -30,29 +37,25 @@ device_type = "cpu"; compatible = "arm,armv8"; reg = <0x0 0x0>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; + enable-method = "psci"; }; cpu@1 { device_type = "cpu"; compatible = "arm,armv8"; reg = <0x0 0x1>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; + enable-method = "psci"; }; cpu@2 { device_type = "cpu"; compatible = "arm,armv8"; reg = <0x0 0x2>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; + enable-method = "psci"; }; cpu@3 { device_type = "cpu"; compatible = "arm,armv8"; reg = <0x0 0x3>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; + enable-method = "psci"; }; }; diff --git a/arch/arm64/boot/dts/rtsm_ve-aemv8a-acpi.dts b/arch/arm64/boot/dts/rtsm_ve-aemv8a-acpi.dts new file mode 100644 index 000000000000..7f348ebc83b4 --- /dev/null +++ b/arch/arm64/boot/dts/rtsm_ve-aemv8a-acpi.dts @@ -0,0 +1,163 @@ +/* + * ARM Ltd. Fast Models + * + * Architecture Envelope Model (AEM) ARMv8-A + * ARMAEMv8AMPCT + * + * RTSM_VE_AEMv8A.lisa + */ + +/dts-v1/; + +/memreserve/ 0x80000000 0x00010000; + +/ { + model = "RTSM_VE_AEMv8A"; + compatible = "arm,rtsm_ve,aemv8a", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x80000000>, + <0x00000008 0x80000000 0 0x80000000>; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0x2c001000 0 0x1000>, + <0x0 0x2c002000 0 0x1000>, + <0x0 0x2c004000 0 0x2000>, + <0x0 0x2c006000 0 0x2000>; + interrupts = <1 9 0xf04>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xff01>, + <1 14 0xff01>, + <1 11 0xff01>, + <1 10 0xff01>; + clock-frequency = <100000000>; + }; + + /* + * Removed for ACPI + * + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + */ + + smb { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + + /include/ "rtsm_ve-motherboard-acpi.dtsi" + }; +}; diff --git a/arch/arm64/boot/dts/rtsm_ve-motherboard-acpi.dtsi b/arch/arm64/boot/dts/rtsm_ve-motherboard-acpi.dtsi new file mode 100644 index 000000000000..bbaaa8e75d42 --- /dev/null +++ b/arch/arm64/boot/dts/rtsm_ve-motherboard-acpi.dtsi @@ -0,0 +1,238 @@ +/* + * ARM Ltd. Fast Models + * + * Versatile Express (VE) system model + * Motherboard component + * + * VEMotherBoard.lisa + */ + + motherboard { + arm,v2m-memory-map = "rs1"; + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + #interrupt-cells = <1>; + ranges; + + flash@0,00000000 { + compatible = "arm,vexpress-flash", "cfi-flash"; + reg = <0 0x00000000 0x04000000>, + <4 0x00000000 0x04000000>; + bank-width = <4>; + }; + + vram@2,00000000 { + compatible = "arm,vexpress-vram"; + reg = <2 0x00000000 0x00800000>; + }; + + /* + * Removed for ACPI + * + ethernet@2,02000000 { + compatible = "smsc,lan91c111"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + }; + */ + + v2m_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "v2m:clk24mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "v2m:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "v2m:refclk32khz"; + }; + + iofpga@3,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + v2m_sysreg: sysreg@010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + gpio-controller; + #gpio-cells = <2>; + }; + + v2m_sysctl: sysctl@020000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x020000 0x1000>; + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>; + clock-names = "refclk", "timclk", "apb_pclk"; + #clock-cells = <1>; + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3"; + }; + + aaci@040000 { + compatible = "arm,pl041", "arm,primecell"; + reg = <0x040000 0x1000>; + interrupts = <11>; + clocks = <&v2m_clk24mhz>; + clock-names = "apb_pclk"; + }; + + mmci@050000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x050000 0x1000>; + interrupts = <9 10>; + cd-gpios = <&v2m_sysreg 0 0>; + wp-gpios = <&v2m_sysreg 1 0>; + max-frequency = <12000000>; + vmmc-supply = <&v2m_fixed_3v3>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "mclk", "apb_pclk"; + }; + + kmi@060000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x060000 0x1000>; + interrupts = <12>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + kmi@070000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x070000 0x1000>; + interrupts = <13>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + v2m_serial0: uart@090000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial1: uart@0a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial2: uart@0b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial3: uart@0c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + wdt@0f0000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f0000 0x1000>; + interrupts = <0>; + clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>; + clock-names = "wdogclk", "apb_pclk"; + }; + + v2m_timer01: timer@110000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x110000 0x1000>; + interrupts = <2>; + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + v2m_timer23: timer@120000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x120000 0x1000>; + interrupts = <3>; + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + rtc@170000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x170000 0x1000>; + interrupts = <4>; + clocks = <&v2m_clk24mhz>; + clock-names = "apb_pclk"; + }; + + clcd@1f0000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x1f0000 0x1000>; + interrupts = <14>; + clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>; + clock-names = "clcdclk", "apb_pclk"; + }; + }; + + v2m_fixed_3v3: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + mcc { + compatible = "arm,vexpress,config-bus", "simple-bus"; + arm,vexpress,config-bridge = <&v2m_sysreg>; + + v2m_oscclk1: osc@1 { + /* CLCD clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 1>; + freq-range = <23750000 63500000>; + #clock-cells = <0>; + clock-output-names = "v2m:oscclk1"; + }; + + reset@0 { + compatible = "arm,vexpress-reset"; + arm,vexpress-sysreg,func = <5 0>; + }; + + muxfpga@0 { + compatible = "arm,vexpress-muxfpga"; + arm,vexpress-sysreg,func = <7 0>; + }; + + shutdown@0 { + compatible = "arm,vexpress-shutdown"; + arm,vexpress-sysreg,func = <8 0>; + }; + + reboot@0 { + compatible = "arm,vexpress-reboot"; + arm,vexpress-sysreg,func = <9 0>; + }; + + dvimode@0 { + compatible = "arm,vexpress-dvimode"; + arm,vexpress-sysreg,func = <11 0>; + }; + }; + }; diff --git a/arch/arm64/configs/acpi_defconfig b/arch/arm64/configs/acpi_defconfig new file mode 100644 index 000000000000..222e051d510d --- /dev/null +++ b/arch/arm64/configs/acpi_defconfig @@ -0,0 +1,1445 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm64 3.11.0-rc5 Kernel Configuration +# +CONFIG_ARM64=y +CONFIG_64BIT=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_MMU=y +CONFIG_NO_IOPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA32=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_DEFAULT_HOSTNAME="(none)" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_FHANDLE is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_SPARSE_IRQ=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_PREEMPT_RCU is not set +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_FANOUT=64 +CONFIG_RCU_FANOUT_LEAF=16 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_RCU_FAST_NO_HZ is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_NOCB_CPU is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CPUSETS is not set +# CONFIG_CGROUP_CPUACCT is not set +# CONFIG_RESOURCE_COUNTERS is not set +# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_CFS_BANDWIDTH is not set +# CONFIG_RT_GROUP_SCHED is not set +# CONFIG_BLK_CGROUP is not set +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set +CONFIG_UIDGID_CONVERTED=y +# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set +CONFIG_SCHED_AUTOGROUP=y +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_XZ=y +CONFIG_RD_LZO=y +CONFIG_RD_LZ4=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +# CONFIG_EXPERT is not set +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +# CONFIG_EMBEDDED is not set +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +CONFIG_SLUB_CPU_PARTIAL=y +CONFIG_PROFILING=y +CONFIG_HAVE_64BIT_ALIGNED_ACCESS=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +CONFIG_INLINE_READ_UNLOCK=y +CONFIG_INLINE_READ_UNLOCK_IRQ=y +CONFIG_INLINE_WRITE_UNLOCK=y +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +# CONFIG_FREEZER is not set + +# +# Platform selection +# +CONFIG_ARCH_VEXPRESS=y +# CONFIG_ARCH_XGENE is not set + +# +# Bus support +# +CONFIG_ARM_AMBA=y + +# +# Kernel Features +# +# CONFIG_ARM64_64K_PAGES is not set +CONFIG_SMP=y +CONFIG_ARM64_CPU_TOPOLOGY=y +# CONFIG_SCHED_MC is not set +# CONFIG_SCHED_SMT is not set +CONFIG_NR_CPUS=4 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_HZ=100 +CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_NO_BOOTMEM=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=0 +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_TRANSPARENT_HUGEPAGE is not set +CONFIG_CROSS_MEMORY_ATTACH=y +# CONFIG_CLEANCACHE is not set +# CONFIG_ZBUD is not set +# CONFIG_XEN is not set +CONFIG_FORCE_MAX_ZONEORDER=11 + +# +# Boot options +# +CONFIG_CMDLINE="console=ttyAMA0" +# CONFIG_CMDLINE_FORCE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_SCRIPT=y +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_COREDUMP=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_NET_IP_TUNNEL is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_NET_IPVTI is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +CONFIG_HAVE_NET_DSA=y +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_MMAP is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_NET_MPLS_GSO is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_NETPRIO_CGROUP is not set +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FW_LOADER_USER_HELPER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +# CONFIG_DMA_SHARED_BUFFER is not set + +# +# Bus devices +# +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +CONFIG_DTC=y +CONFIG_OF=y + +# +# Device Tree and Open Firmware support +# +# CONFIG_PROC_DEVICETREE is not set +# CONFIG_OF_SELFTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_NET=y +# CONFIG_PARPORT is not set +CONFIG_PNP=y +CONFIG_PNP_DEBUG_MESSAGES=y + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_VIRTIO_BLK=y +# CONFIG_BLK_DEV_RBD is not set + +# +# Misc devices +# +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_ATMEL_PWM is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_ATMEL_SSC is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_SRAM is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set + +# +# Altera FPGA firmware download module +# + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_VXLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_VIRTIO_NET is not set +# CONFIG_NLMON is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +# CONFIG_NET_DSA_MV88E6XXX is not set +# CONFIG_NET_DSA_MV88E6060 is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +# CONFIG_NET_DSA_MV88E6131 is not set +# CONFIG_NET_DSA_MV88E6123_61_65 is not set +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_ARC=y +# CONFIG_ARC_EMAC is not set +CONFIG_NET_CADENCE=y +# CONFIG_ARM_AT91_ETHER is not set +# CONFIG_MACB is not set +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_INTEL=y +CONFIG_NET_VENDOR_I825XX=y +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_MVMDIO is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8851_MLL is not set +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NET_VENDOR_8390=y +# CONFIG_ETHOC is not set +# CONFIG_SH_ETH is not set +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SMSC=y +CONFIG_SMC91X=y +# CONFIG_SMSC911X is not set +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_VIA=y +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +# CONFIG_NET_SB1000 is not set +# CONFIG_PHYLIB is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set +# CONFIG_INPUT_MATRIXKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_GPIO_POLLED is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_CYPRESS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_AMBAKMI is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_APBPS2 is not set +# CONFIG_SERIO_OLPC_APSP is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_VIRTIO_CONSOLE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set + +# +# PCMCIA character devices +# +# CONFIG_RAW_DRIVER is not set +# CONFIG_HPET is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_HSI is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +# CONFIG_PTP_1588_CLOCK is not set + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIO_DEVRES=y +CONFIG_GPIOLIB=y +CONFIG_OF_GPIO=y +CONFIG_GPIO_ACPI=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_TS5500 is not set +# CONFIG_GPIO_GRGPIO is not set + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# + +# +# USB GPIO expanders: +# +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_BATTERY_GOLDFISH is not set +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_GPIO is not set +CONFIG_POWER_RESET_VEXPRESS=y +# CONFIG_POWER_AVS is not set +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_EMULATION is not set + +# +# Texas Instruments thermal drivers +# +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_CROS_EC is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_SYSCON is not set +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_TPS65912 is not set +# CONFIG_MFD_TMIO is not set +CONFIG_VEXPRESS_CONFIG=y +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_GOLDFISH is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_AUO_K190X is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_SOUND is not set + +# +# HID support +# +CONFIG_HID=y +# CONFIG_HID_BATTERY_STRENGTH is not set +# CONFIG_HIDRAW is not set +# CONFIG_UHID is not set +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +# CONFIG_HID_ACRUX is not set +CONFIG_HID_APPLE=y +# CONFIG_HID_AUREAL is not set +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELECOM is not set +CONFIG_HID_EZKEY=y +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_TWINHAN is not set +CONFIG_HID_KENSINGTON=y +# CONFIG_HID_LCPOWER is not set +CONFIG_HID_LOGITECH=y +# CONFIG_HID_LOGITECH_DJ is not set +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set +# CONFIG_LOGIWHEELS_FF is not set +# CONFIG_HID_MAGICMOUSE is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HID_SENSOR_HUB is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VIRT_DRIVERS is not set +CONFIG_VIRTIO=y + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +CONFIG_VIRTIO_MMIO=y +# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set + +# +# Microsoft Hyper-V guest support +# +# CONFIG_STAGING is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_COMMON_CLK_DEBUG is not set +CONFIG_COMMON_CLK_VERSATILE=y + +# +# Hardware Spinlock drivers +# +CONFIG_CLKSRC_OF=y +CONFIG_ARM_ARCH_TIMER=y +# CONFIG_MAILBOX is not set +# CONFIG_IOMMU_SUPPORT is not set + +# +# Remoteproc drivers +# +# CONFIG_STE_MODEM_RPROC is not set + +# +# Rpmsg drivers +# +# CONFIG_PM_DEVFREQ is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_PWM is not set +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +# CONFIG_IPACK_BUS is not set +# CONFIG_RESET_CONTROLLER is not set +# CONFIG_FMC is not set + +# +# Power management and ACPI options +# +CONFIG_MAB=y +CONFIG_ACPI_ARM=y +CONFIG_ACPI=y +CONFIG_ACPI_EC_DEBUGFS=y +CONFIG_ACPI_AC=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_PROCESSOR_AGGREGATOR=y +CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_BLACKLIST_YEAR=0 +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_CONTAINER=y +CONFIG_ACPI_SBS=y +CONFIG_ACPI_HED=y +CONFIG_ACPI_CUSTOM_METHOD=y + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=y +CONFIG_CUSE=y + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_SWAP is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_VIRTUALIZATION is not set + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_DYNAMIC_DEBUG is not set + +# +# Compile-time checks and compiler options +# +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO_REDUCED is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=2048 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y + +# +# Memory Debugging +# +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Lockups and Hangs +# +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_HAVE_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set + +# +# RCU Debugging +# +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +# CONFIG_RCU_CPU_STALL_INFO is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set + +# +# Runtime Testing +# +# CONFIG_LKDTM is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_RBTREE_TEST is not set +# CONFIG_INTERVAL_TREE_TEST is not set +CONFIG_ATOMIC64_SELFTEST=y +# CONFIG_TEST_STRING_HELPERS is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_PID_IN_CONTEXTIDR is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=m +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_USER is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCRYPT is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_CMAC is not set +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32 is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IO=y +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_CRC8 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_XZ_DEC=y +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_SPARC is not set +# CONFIG_XZ_DEC_BCJ is not set +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_DECOMPRESS_LZ4=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +# CONFIG_AVERAGE is not set +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h new file mode 100644 index 000000000000..a19b73faa1fc --- /dev/null +++ b/arch/arm64/include/asm/acpi.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2013, Al Stone <al.stone@linaro.org> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#ifndef _ASM_ARM_ACPI_H +#define _ASM_ARM_ACPI_H + +#ifdef __KERNEL__ + +#include <acpi/pdc_arm64.h> + +#include <asm/cacheflush.h> + +#include <linux/init.h> + +#define COMPILER_DEPENDENT_INT64 long long +#define COMPILER_DEPENDENT_UINT64 unsigned long long + +#define MAX_LOCAL_APIC 256 +#define MAX_IO_APICS 64 + +/* + * Calling conventions: + * + * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) + * ACPI_EXTERNAL_XFACE - External ACPI interfaces + * ACPI_INTERNAL_XFACE - Internal ACPI interfaces + * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces + */ +#define ACPI_SYSTEM_XFACE +#define ACPI_EXTERNAL_XFACE +#define ACPI_INTERNAL_XFACE +#define ACPI_INTERNAL_VAR_XFACE + +/* Asm macros */ +#define ACPI_ASM_MACROS +#define BREAKPOINT3 +#define ACPI_DISABLE_IRQS() local_irq_disable() +#define ACPI_ENABLE_IRQS() local_irq_enable() +#define ACPI_FLUSH_CPU_CACHE() flush_cache_all() + +/* Blob handling macros */ +#define ACPI_BLOB_HEADER_SIZE 8 + +int __acpi_acquire_global_lock(unsigned int *lock); +int __acpi_release_global_lock(unsigned int *lock); + +#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ + ((Acq) = __acpi_acquire_global_lock(&facs->global_lock)) + +#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ + ((Acq) = __acpi_release_global_lock(&facs->global_lock)) + +/* Basic configuration for ACPI */ +/* BOZO: hardware reduced acpi only? */ +#ifdef CONFIG_ACPI +extern int acpi_disabled; +extern int acpi_noirq; +extern int acpi_pci_disabled; +extern int acpi_strict; + +/* map logic cpu id to physical APIC id + * APIC = GIC cpu interface on ARM + */ +extern volatile int arm_cpu_to_apicid[NR_CPUS]; +extern int boot_cpu_apic_id; +#define cpu_physical_id(cpu) arm_cpu_to_apicid[cpu] + +struct acpi_arm_root { + phys_addr_t phys_address; + unsigned long size; +}; +extern struct acpi_arm_root acpi_arm_rsdp_info; + +void arm_acpi_reserve_memory(void); + +/* Low-level suspend routine. */ +extern int acpi_suspend_lowlevel(void); + +extern void prefill_possible_map(void); + +/* Physical address to resume after wakeup */ +/* BOZO: was... +#define acpi_wakeup_address ((unsigned long)(real_mode_header->wakeup_start)) +*/ +#define acpi_wakeup_address (0) + + +static inline void disable_acpi(void) +{ + acpi_disabled = 1; + acpi_pci_disabled = 1; + acpi_noirq = 1; +} + +static inline bool arch_has_acpi_pdc(void) +{ + /* BOZO: replace x86 specific-ness here */ + return 0; /* always false for now */ +} + +static inline void arch_acpi_set_pdc_bits(u32 *buf) +{ + /* BOZO: replace x86 specific-ness here */ +} + +static inline void acpi_noirq_set(void) { acpi_noirq = 1; } +static inline void acpi_disable_pci(void) +{ + acpi_pci_disabled = 1; + acpi_noirq_set(); +} + +#else /* !CONFIG_ACPI */ +#define acpi_disabled 1 /* ACPI sometimes enabled on ARM */ +#define acpi_noirq 1 /* ACPI sometimes enabled on ARM */ +#define acpi_pci_disabled 1 /* ACPI PCI sometimes enabled on ARM */ +#define acpi_strict 1 /* no ACPI spec workarounds on ARM */ +#endif + +#endif /*__KERNEL__*/ + +#endif /*_ASM_ARM_ACPI_H*/ diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h new file mode 100644 index 000000000000..5613e097933a --- /dev/null +++ b/arch/arm64/include/asm/cpu.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2004-2005 ARM Ltd. + * + * 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. + */ +#ifndef __ASM_ARM_CPU_H +#define __ASM_ARM_CPU_H + +#include <linux/percpu.h> +#include <linux/cpu.h> +#include <linux/topology.h> + +struct cpuinfo_arm { + struct cpu cpu; + u32 cpuid; +#ifdef CONFIG_SMP + unsigned int loops_per_jiffy; +#endif +}; + +#ifdef CONFIG_HOTPLUG_CPU +extern int arch_register_cpu(int cpu); +extern void arch_unregister_cpu(int cpu); +#endif + +DECLARE_PER_CPU(struct cpuinfo_arm, cpu_data); + +#endif diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 5fe138e0b828..58a595f8be4d 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -30,6 +30,17 @@ #define MPIDR_HWID_BITMASK 0xff00ffffff +#define MPIDR_SMP_BITMASK (0x1 << 30) +#define MPIDR_MT_BITMASK (0x1 << 24) + +#define MPIDR_LEVEL_BITS 8 +#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1) + +#define MPIDR_AFFINITY_LEVEL_0(mpidr) ((mpidr) & MPIDR_LEVEL_MASK) +#define MPIDR_AFFINITY_LEVEL_1(mpidr) ((mpidr >> 8) & MPIDR_LEVEL_MASK) +#define MPIDR_AFFINITY_LEVEL_2(mpidr) ((mpidr >> 16) & MPIDR_LEVEL_MASK) +#define MPIDR_AFFINITY_LEVEL_3(mpidr) ((mpidr >> 32) & MPIDR_LEVEL_MASK) + #define read_cpuid(reg) ({ \ u64 __val; \ asm("mrs %0, " reg : "=r" (__val)); \ diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h index 0332fc077f6e..e1f7ecdde11f 100644 --- a/arch/arm64/include/asm/irq.h +++ b/arch/arm64/include/asm/irq.h @@ -4,6 +4,7 @@ #include <asm-generic/irq.h> extern void (*handle_arch_irq)(struct pt_regs *); +extern void migrate_irqs(void); extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); #endif diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index ab239b2c456f..53326fd81897 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -155,6 +155,19 @@ static inline void spin_lock_prefetch(const void *x) prefetchw(x); } +/* + * Not all ARM devices have ACPI, but some do + * BOZO: is this correct? + */ +#ifdef CONFIG_ACPI +enum idle_boot_override { IDLE_NO_OVERRIDE = 0, IDLE_HALT, IDLE_NOMWAIT, + IDLE_POLL, IDLE_FORCE_MWAIT }; + +extern unsigned long boot_option_idle_override; +#endif + +/* end BOZO */ + #define HAVE_ARCH_PICK_MMAP_LAYOUT #endif diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 4b8023c5d146..d2ef02e67f61 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -60,21 +60,50 @@ struct secondary_data { void *stack; }; extern struct secondary_data secondary_data; -extern void secondary_holding_pen(void); -extern volatile unsigned long secondary_holding_pen_release; +extern void secondary_entry(void); extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); struct device_node; -struct smp_enable_ops { +extern int __cpu_disable(void); + +extern void __cpu_die(unsigned int cpu); +extern void cpu_die(void); + +/** + * struct smp_operations - Callback operations for hotplugging CPUs. + * + * @name: Name of the property as appears in a devicetree cpu node's + * enable-method property. + * @cpu_init: Reads any data necessary for a specific enable-method form the + * devicetree, for a given cpu node and proposed logical id. + * @cpu_prepare: Early one-time preparation step for a cpu. If there is a + * mechanism for doing so, tests whether it is possible to boot + * the given CPU. + * @cpu_boot: Boots a cpu into the kernel. + * @cpu_postboot: Optionally, perform any post-boot cleanup or necesary + * synchronisation. Called from the cpu being booted. + * @cpu_disable: Prepares a cpu to die. May fail for some mechanism-specific + * reason, which will cause the hot unplug to be aborted. Called + * from the cpu to be killed. + * @cpu_die: Makes the a leave the kernel. Must not fail. Called from the + * cpu being killed. + */ +struct smp_operations { const char *name; - int (*init_cpu)(struct device_node *, int); - int (*prepare_cpu)(int); + int (*cpu_init)(struct device_node *, unsigned int); + int (*cpu_prepare)(unsigned int); + int (*cpu_boot)(unsigned int); + void (*cpu_postboot)(void); +#ifdef CONFIG_HOTPLUG_CPU + int (*cpu_disable)(unsigned int cpu); + void (*cpu_die)(unsigned int cpu); +#endif }; -extern const struct smp_enable_ops smp_spin_table_ops; -extern const struct smp_enable_ops smp_psci_ops; +extern const struct smp_operations smp_spin_table_ops; +extern const struct smp_operations smp_psci_ops; #endif /* ifndef __ASM_SMP_H */ diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h new file mode 100644 index 000000000000..06440d4c54c1 --- /dev/null +++ b/arch/arm64/include/asm/topology.h @@ -0,0 +1,43 @@ +#ifndef _ASM_ARM64_TOPOLOGY_H +#define _ASM_ARM64_TOPOLOGY_H + +#ifdef CONFIG_ARM64_CPU_TOPOLOGY + +#include <linux/cpumask.h> + +struct cputopo_arm64 { + int thread_id; + int core_id; + int socket_id; + cpumask_t thread_sibling; + cpumask_t core_sibling; +}; + +DECLARE_PER_CPU(struct cputopo_arm64, cpu_topology); + +#define cpu_topo(cpu) per_cpu(cpu_topology, cpu) + +#define topology_physical_package_id(cpu) (cpu_topo(cpu).socket_id) +#define topology_core_id(cpu) (cpu_topo(cpu).core_id) +#define topology_core_cpumask(cpu) (&cpu_topo(cpu).core_sibling) +#define topology_thread_cpumask(cpu) (&cpu_topo(cpu).thread_sibling) + +#define mc_capable() (cpu_topo(0).socket_id != -1) +#define smt_capable() (cpu_topo(0).thread_id != -1) + +void init_cpu_topology(void); +void store_cpu_topology(unsigned int cpuid); +const struct cpumask *cpu_coregroup_mask(int cpu); +void arch_fix_phys_package_id(int num, u32 slot); + +#else + +static inline void arch_fix_phys_package_id(int num, u32 slot) {} +static inline void init_cpu_topology(void) { } +static inline void store_cpu_topology(unsigned int cpuid) { } + +#endif + +#include <asm-generic/topology.h> + +#endif /* _ASM_ARM64_TOPOLOGY_H */ diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 7b4b564961d4..a47c35962749 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -18,6 +18,7 @@ arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o smp_psci.o arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +arm64-obj-$(CONFIG_ARM64_CPU_TOPOLOGY) += topology.o obj-y += $(arm64-obj-y) vdso/ obj-m += $(arm64-obj-m) diff --git a/arch/arm64/kernel/cputable.c b/arch/arm64/kernel/cputable.c index 63cfc4a43f4e..fd3993cb060f 100644 --- a/arch/arm64/kernel/cputable.c +++ b/arch/arm64/kernel/cputable.c @@ -22,7 +22,7 @@ extern unsigned long __cpu_setup(void); -struct cpu_info __initdata cpu_table[] = { +struct cpu_info cpu_table[] = { { .cpu_id_val = 0x000f0000, .cpu_id_mask = 0x000f0000, diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index cd961927461c..a32a9abf63a0 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -330,7 +330,6 @@ ENTRY(__boot_cpu_mode) .quad PAGE_OFFSET #ifdef CONFIG_SMP - .pushsection .smp.pen.text, "ax" .align 3 1: .quad . .quad secondary_holding_pen_release @@ -355,7 +354,16 @@ pen: ldr x4, [x3] wfe b pen ENDPROC(secondary_holding_pen) - .popsection + + /* + * Secondary entry point that jumps straight into the kernel. Only to + * be used where CPUs are brought online dynamically by the kernel. + */ +ENTRY(secondary_entry) + bl __calc_phys_offset // x2=phys offset + bl el2_setup // Drop to EL1 + b secondary_startup +ENDPROC(secondary_entry) ENTRY(secondary_startup) /* diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index ecb3354292ed..473e5dbf8f39 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c @@ -81,3 +81,64 @@ void __init init_IRQ(void) if (!handle_arch_irq) panic("No interrupt controller found."); } + +#ifdef CONFIG_HOTPLUG_CPU +static bool migrate_one_irq(struct irq_desc *desc) +{ + struct irq_data *d = irq_desc_get_irq_data(desc); + const struct cpumask *affinity = d->affinity; + struct irq_chip *c; + bool ret = false; + + /* + * If this is a per-CPU interrupt, or the affinity does not + * include this CPU, then we have nothing to do. + */ + if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity)) + return false; + + if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { + affinity = cpu_online_mask; + ret = true; + } + + c = irq_data_get_irq_chip(d); + if (!c->irq_set_affinity) + pr_debug("IRQ%u: unable to set affinity\n", d->irq); + else if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret) + cpumask_copy(d->affinity, affinity); + + return ret; +} + +/* + * The current CPU has been marked offline. Migrate IRQs off this CPU. + * If the affinity settings do not allow other CPUs, force them onto any + * available CPU. + * + * Note: we must iterate over all IRQs, whether they have an attached + * action structure or not, as we need to get chained interrupts too. + */ +void migrate_irqs(void) +{ + unsigned int i; + struct irq_desc *desc; + unsigned long flags; + + local_irq_save(flags); + + for_each_irq_desc(i, desc) { + bool affinity_broken; + + raw_spin_lock(&desc->lock); + affinity_broken = migrate_one_irq(desc); + raw_spin_unlock(&desc->lock); + + if (affinity_broken) + pr_warn_ratelimited("IRQ%u no longer affine to CPU%u\n", + i, smp_processor_id()); + } + + local_irq_restore(flags); +} +#endif /* CONFIG_HOTPLUG_CPU */ diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index cea1594ff933..460f158cfb67 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -28,6 +28,9 @@ #include <linux/platform_device.h> #include <linux/spinlock.h> #include <linux/uaccess.h> +#ifdef CONFIG_ACPI +#include <linux/acpi.h> +#endif #include <asm/cputype.h> #include <asm/irq.h> @@ -1232,6 +1235,13 @@ static struct of_device_id armpmu_of_device_ids[] = { {}, }; +#ifdef CONFIG_ACPI +static const struct acpi_device_id armpmu_acpi_match[] = { + { "LINA0007", }, + {}, +}; +#endif + static int armpmu_device_probe(struct platform_device *pdev) { if (!cpu_pmu) @@ -1245,6 +1255,9 @@ static struct platform_driver armpmu_driver = { .driver = { .name = "arm-pmu", .of_match_table = armpmu_of_device_ids, +#ifdef CONFIG_ACPI + .acpi_match_table = ACPI_PTR(armpmu_acpi_match), +#endif }, .probe = armpmu_device_probe, }; diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 7ae8a1f00c3c..8ab9909a2b68 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -102,6 +102,13 @@ void arch_cpu_idle(void) local_irq_enable(); } +#ifdef CONFIG_HOTPLUG_CPU +void arch_cpu_idle_dead(void) +{ + cpu_die(); +} +#endif + void machine_shutdown(void) { #ifdef CONFIG_SMP @@ -340,3 +347,11 @@ unsigned long randomize_et_dyn(unsigned long base) { return randomize_base(base); } + +#ifdef CONFIG_ACPI + +unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; +EXPORT_SYMBOL(boot_option_idle_override); + +#endif + diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index fb8d90f2f5ba..f82cb1a2b3cb 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -42,6 +42,9 @@ #include <linux/of_fdt.h> #include <linux/of_platform.h> #include <linux/efi.h> +#ifdef CONFIG_ACPI +#include <linux/acpi.h> +#endif #include <asm/fixmap.h> #include <asm/cputype.h> @@ -56,6 +59,9 @@ #include <asm/memblock.h> #include <asm/psci.h> #include <asm/efi.h> +#ifdef CONFIG_ACPI +#include <asm/acpi.h> +#endif unsigned int processor_id; EXPORT_SYMBOL(processor_id); @@ -169,6 +175,10 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys) /* Retrieve various information from the /chosen node */ of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); +#ifdef CONFIG_ACPI + /* Retrieve ACPI pointers from /chosen node */ + of_scan_flat_dt(early_init_dt_scan_acpi, &acpi_arm_rsdp_info); +#endif /* Initialize {size,address}-cells info */ of_scan_flat_dt(early_init_dt_scan_root, NULL); /* Setup memory, calling early_init_dt_add_memory_arch */ @@ -260,7 +270,21 @@ void __init setup_arch(char **cmdline_p) arm64_memblock_init(); +#ifdef CONFIG_ACPI + arm_acpi_reserve_memory(); +#endif efi_init(); +#ifdef CONFIG_ACPI + /* + * Parse the ACPI tables for possible boot-time configuration + */ + acpi_boot_table_init(); + early_acpi_boot_init(); + boot_cpu_apic_id = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; + acpi_boot_init(); + prefill_possible_map(); +#endif + paging_init(); request_standard_resources(); diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 78db90dcc910..e671f33d5c05 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -39,6 +39,7 @@ #include <asm/atomic.h> #include <asm/cacheflush.h> #include <asm/cputype.h> +#include <asm/topology.h> #include <asm/mmu_context.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> @@ -54,7 +55,6 @@ * where to place its SVC stack */ struct secondary_data secondary_data; -volatile unsigned long secondary_holding_pen_release = INVALID_HWID; enum ipi_msg_type { IPI_RESCHEDULE, @@ -63,22 +63,7 @@ enum ipi_msg_type { IPI_CPU_STOP, }; -static DEFINE_RAW_SPINLOCK(boot_lock); - -/* - * Write secondary_holding_pen_release in a way that is guaranteed to be - * visible to all observers, irrespective of whether they're taking part - * in coherency or not. This is necessary for the hotplug code to work - * reliably. - */ -static void write_pen_release(u64 val) -{ - void *start = (void *)&secondary_holding_pen_release; - unsigned long size = sizeof(secondary_holding_pen_release); - - secondary_holding_pen_release = val; - __flush_dcache_area(start, size); -} +static const struct smp_operations *smp_ops[NR_CPUS]; /* * Boot a secondary CPU, and assign it the specified idle task. @@ -86,38 +71,10 @@ static void write_pen_release(u64 val) */ static int boot_secondary(unsigned int cpu, struct task_struct *idle) { - unsigned long timeout; - - /* - * Set synchronisation state between this boot processor - * and the secondary one - */ - raw_spin_lock(&boot_lock); - - /* - * Update the pen release flag. - */ - write_pen_release(cpu_logical_map(cpu)); - - /* - * Send an event, causing the secondaries to read pen_release. - */ - sev(); - - timeout = jiffies + (1 * HZ); - while (time_before(jiffies, timeout)) { - if (secondary_holding_pen_release == INVALID_HWID) - break; - udelay(10); - } - - /* - * Now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ - raw_spin_unlock(&boot_lock); + if (smp_ops[cpu]->cpu_boot) + return smp_ops[cpu]->cpu_boot(cpu); - return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0; + return -EOPNOTSUPP; } static DECLARE_COMPLETION(cpu_running); @@ -187,17 +144,10 @@ asmlinkage void secondary_start_kernel(void) preempt_disable(); trace_hardirqs_off(); - /* - * Let the primary processor know we're out of the - * pen, then head off into the C entry point - */ - write_pen_release(INVALID_HWID); + if (smp_ops[cpu]->cpu_postboot) + smp_ops[cpu]->cpu_postboot(); - /* - * Synchronise with the boot thread. - */ - raw_spin_lock(&boot_lock); - raw_spin_unlock(&boot_lock); + store_cpu_topology(cpu); /* * OK, now it's safe to let the boot CPU continue. Wait for @@ -221,6 +171,103 @@ asmlinkage void secondary_start_kernel(void) cpu_startup_entry(CPUHP_ONLINE); } +#ifdef CONFIG_HOTPLUG_CPU +static int op_cpu_disable(unsigned int cpu) +{ + /* + * If we don't have a cpu_die method, abort before we reach the point + * of no return. CPU0 may not have an smp_ops, so test for it. + */ + if (!smp_ops[cpu] || !smp_ops[cpu]->cpu_die) + return -EOPNOTSUPP; + + /* + * We may need to abort a hot unplug for some other mechanism-specific + * reason. + */ + if (smp_ops[cpu]->cpu_disable) + return smp_ops[cpu]->cpu_disable(cpu); + + return 0; +} + +/* + * __cpu_disable runs on the processor to be shutdown. + */ +int __cpu_disable(void) +{ + unsigned int cpu = smp_processor_id(); + int ret; + + ret = op_cpu_disable(cpu); + if (ret) + return ret; + + /* + * Take this CPU offline. Once we clear this, we can't return, + * and we must not schedule until we're ready to give up the cpu. + */ + set_cpu_online(cpu, false); + + /* + * OK - migrate IRQs away from this CPU + */ + migrate_irqs(); + + /* + * Remove this CPU from the vm mask set of all processes. + */ + clear_tasks_mm_cpumask(cpu); + + return 0; +} + +static DECLARE_COMPLETION(cpu_died); + +/* + * called on the thread which is asking for a CPU to be shutdown - + * waits until shutdown has completed, or it is timed out. + */ +void __cpu_die(unsigned int cpu) +{ + if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) { + pr_crit("CPU%u: cpu didn't die\n", cpu); + return; + } + pr_notice("CPU%u: shutdown\n", cpu); +} + +/* + * Called from the idle thread for the CPU which has been shutdown. + * + * Note that we disable IRQs here, but do not re-enable them + * before returning to the caller. This is also the behaviour + * of the other hotplug-cpu capable cores, so presumably coming + * out of idle fixes this. + */ +void __ref cpu_die(void) +{ + unsigned int cpu = smp_processor_id(); + + idle_task_exit(); + + local_irq_disable(); + mb(); + + /* Tell __cpu_die() that this CPU is now safe to dispose of */ + complete(&cpu_died); + + /* + * Actually shutdown the CPU. This must never fail. The specific hotplug + * mechanism must perform all required cache maintenance to ensure that + * no dirty lines are lost in the process of shutting down the CPU. + */ + smp_ops[cpu]->cpu_die(cpu); + + BUG(); +} +#endif + void __init smp_cpus_done(unsigned int max_cpus) { pr_info("SMP: Total of %d processors activated.\n", num_online_cpus()); @@ -232,17 +279,15 @@ void __init smp_prepare_boot_cpu(void) static void (*smp_cross_call)(const struct cpumask *, unsigned int); -static const struct smp_enable_ops *enable_ops[] __initconst = { +static const struct smp_operations *supported_smp_ops[] __initconst = { &smp_spin_table_ops, &smp_psci_ops, NULL, }; -static const struct smp_enable_ops *smp_enable_ops[NR_CPUS]; - -static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name) +static const struct smp_operations * __init smp_get_ops(const char *name) { - const struct smp_enable_ops **ops = enable_ops; + const struct smp_operations **ops = supported_smp_ops; while (*ops) { if (!strcmp(name, (*ops)->name)) @@ -263,7 +308,7 @@ void __init smp_init_cpus(void) { const char *enable_method; struct device_node *dn = NULL; - int i, cpu = 1; + unsigned int i, cpu = 1; bool bootcpu_valid = false; while ((dn = of_find_node_by_type(dn, "cpu"))) { @@ -305,6 +350,8 @@ void __init smp_init_cpus(void) } } + enable_method = of_get_property(dn, "enable-method", NULL); + /* * The numbering scheme requires that the boot CPU * must be assigned logical id 0. Record it so that @@ -320,11 +367,12 @@ void __init smp_init_cpus(void) bootcpu_valid = true; + if (enable_method) + smp_ops[0] = smp_get_ops(enable_method); + /* - * cpu_logical_map has already been - * initialized and the boot cpu doesn't need - * the enable-method so continue without - * incrementing cpu. + * cpu_logical_map has already been initialized so + * continue without incrementing cpu. */ continue; } @@ -332,25 +380,21 @@ void __init smp_init_cpus(void) if (cpu >= NR_CPUS) goto next; - /* - * We currently support only the "spin-table" enable-method. - */ - enable_method = of_get_property(dn, "enable-method", NULL); if (!enable_method) { pr_err("%s: missing enable-method property\n", dn->full_name); goto next; } - smp_enable_ops[cpu] = smp_get_enable_ops(enable_method); + smp_ops[cpu] = smp_get_ops(enable_method); - if (!smp_enable_ops[cpu]) { + if (!smp_ops[cpu]) { pr_err("%s: invalid enable-method property: %s\n", dn->full_name, enable_method); goto next; } - if (smp_enable_ops[cpu]->init_cpu(dn, cpu)) + if (smp_ops[cpu]->cpu_init(dn, cpu)) goto next; pr_debug("cpu logical map 0x%llx\n", hwid); @@ -380,8 +424,11 @@ next: void __init smp_prepare_cpus(unsigned int max_cpus) { - int cpu, err; - unsigned int ncores = num_possible_cpus(); + int err; + unsigned int cpu, ncores = num_possible_cpus(); + + init_cpu_topology(); + store_cpu_topology(smp_processor_id()); /* * are we trying to boot more cores than exist? @@ -408,14 +455,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus) if (cpu == smp_processor_id()) continue; - if (!smp_enable_ops[cpu]) + if (!smp_ops[cpu]) continue; - err = smp_enable_ops[cpu]->prepare_cpu(cpu); + err = smp_ops[cpu]->cpu_prepare(cpu); if (err) continue; +#ifndef CONFIG_ACPI set_cpu_present(cpu, true); +#endif max_cpus--; } } diff --git a/arch/arm64/kernel/smp_psci.c b/arch/arm64/kernel/smp_psci.c index 0c533301be77..e9e5890a26f5 100644 --- a/arch/arm64/kernel/smp_psci.c +++ b/arch/arm64/kernel/smp_psci.c @@ -23,31 +23,63 @@ #include <asm/psci.h> #include <asm/smp_plat.h> -static int __init smp_psci_init_cpu(struct device_node *dn, int cpu) +static int smp_psci_cpu_init(struct device_node *dn, unsigned int cpu) { return 0; } -static int __init smp_psci_prepare_cpu(int cpu) +static int smp_psci_cpu_prepare(unsigned int cpu) { - int err; - if (!psci_ops.cpu_on) { pr_err("psci: no cpu_on method, not booting CPU%d\n", cpu); return -ENODEV; } - err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_holding_pen)); - if (err) { + return 0; +} + +static int smp_psci_cpu_boot(unsigned int cpu) +{ + int err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_entry)); + if (err) pr_err("psci: failed to boot CPU%d (%d)\n", cpu, err); - return err; - } + return err; +} + +#ifdef CONFIG_HOTPLUG_CPU +static int smp_psci_cpu_disable(unsigned int cpu) +{ + /* Fail early if we don't have CPU_OFF support */ + if (!psci_ops.cpu_off) + return -EOPNOTSUPP; return 0; } -const struct smp_enable_ops smp_psci_ops __initconst = { +static void smp_psci_cpu_die(unsigned int cpu) +{ + int ret; + /* + * There are no known implementations of PSCI actually using the + * power state field, pass a sensible default for now. + */ + struct psci_power_state state = { + .type = PSCI_POWER_STATE_TYPE_POWER_DOWN, + }; + + ret = psci_ops.cpu_off(state); + + pr_crit("psci: unable to power off CPU%u (%d)\n", cpu, ret); +} +#endif + +const struct smp_operations smp_psci_ops = { .name = "psci", - .init_cpu = smp_psci_init_cpu, - .prepare_cpu = smp_psci_prepare_cpu, + .cpu_init = smp_psci_cpu_init, + .cpu_prepare = smp_psci_cpu_prepare, + .cpu_boot = smp_psci_cpu_boot, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = smp_psci_cpu_disable, + .cpu_die = smp_psci_cpu_die, +#endif }; diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c index 7c35fa682f76..87af6bb551a7 100644 --- a/arch/arm64/kernel/smp_spin_table.c +++ b/arch/arm64/kernel/smp_spin_table.c @@ -16,15 +16,38 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/delay.h> #include <linux/init.h> #include <linux/of.h> #include <linux/smp.h> #include <asm/cacheflush.h> +#include <asm/cputype.h> +#include <asm/smp_plat.h> + +extern void secondary_holding_pen(void); +volatile unsigned long secondary_holding_pen_release = INVALID_HWID; static phys_addr_t cpu_release_addr[NR_CPUS]; +static DEFINE_RAW_SPINLOCK(boot_lock); -static int __init smp_spin_table_init_cpu(struct device_node *dn, int cpu) +/* + * Write secondary_holding_pen_release in a way that is guaranteed to be + * visible to all observers, irrespective of whether they're taking part + * in coherency or not. This is necessary for the hotplug code to work + * reliably. + */ +static void write_pen_release(u64 val) +{ + void *start = (void *)&secondary_holding_pen_release; + unsigned long size = sizeof(secondary_holding_pen_release); + + secondary_holding_pen_release = val; + __flush_dcache_area(start, size); +} + + +static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu) { /* * Determine the address from which the CPU is polling. @@ -40,7 +63,7 @@ static int __init smp_spin_table_init_cpu(struct device_node *dn, int cpu) return 0; } -static int __init smp_spin_table_prepare_cpu(int cpu) +static int smp_spin_table_cpu_prepare(unsigned int cpu) { void **release_addr; @@ -59,8 +82,60 @@ static int __init smp_spin_table_prepare_cpu(int cpu) return 0; } -const struct smp_enable_ops smp_spin_table_ops __initconst = { +static int smp_spin_table_cpu_boot(unsigned int cpu) +{ + unsigned long timeout; + + /* + * Set synchronisation state between this boot processor + * and the secondary one + */ + raw_spin_lock(&boot_lock); + + /* + * Update the pen release flag. + */ + write_pen_release(cpu_logical_map(cpu)); + + /* + * Send an event, causing the secondaries to read pen_release. + */ + sev(); + + timeout = jiffies + (1 * HZ); + while (time_before(jiffies, timeout)) { + if (secondary_holding_pen_release == INVALID_HWID) + break; + udelay(10); + } + + /* + * Now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ + raw_spin_unlock(&boot_lock); + + return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0; +} + +void smp_spin_table_cpu_postboot(void) +{ + /* + * Let the primary processor know we're out of the pen. + */ + write_pen_release(INVALID_HWID); + + /* + * Synchronise with the boot thread. + */ + raw_spin_lock(&boot_lock); + raw_spin_unlock(&boot_lock); +} + +const struct smp_operations smp_spin_table_ops = { .name = "spin-table", - .init_cpu = smp_spin_table_init_cpu, - .prepare_cpu = smp_spin_table_prepare_cpu, + .cpu_init = smp_spin_table_cpu_init, + .cpu_prepare = smp_spin_table_cpu_prepare, + .cpu_boot = smp_spin_table_cpu_boot, + .cpu_postboot = smp_spin_table_cpu_postboot, }; diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c new file mode 100644 index 000000000000..947fcc28b952 --- /dev/null +++ b/arch/arm64/kernel/topology.c @@ -0,0 +1,166 @@ +/* + * arch/arm64/kernel/topology.c + * + * Copyright (C) 2013 Linaro Limited. + * Written by: Hanjun Guo + * + * based on arch/arm/kernel/topology.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/cpu.h> +#include <linux/cpumask.h> +#include <linux/export.h> +#include <linux/init.h> +#include <linux/percpu.h> +#include <linux/node.h> +#include <linux/nodemask.h> +#include <linux/of.h> +#include <linux/sched.h> +#include <linux/slab.h> + +#include <asm/cputype.h> +#include <asm/topology.h> +#include <asm/cpu.h> + +DEFINE_PER_CPU(struct cputopo_arm64, cpu_topology); + +const struct cpumask *cpu_coregroup_mask(int cpu) +{ + return &cpu_topo(cpu).core_sibling; +} + +void update_siblings_masks(unsigned int cpuid) +{ + struct cputopo_arm64 *topo, *cpuid_topo = &cpu_topo(cpuid); + int cpu; + + /* update core and thread sibling masks */ + for_each_possible_cpu(cpu) { + topo = &cpu_topo(cpu); + + if (cpuid_topo->socket_id != topo->socket_id) + continue; + + cpumask_set_cpu(cpuid, &topo->core_sibling); + if (cpu != cpuid) + cpumask_set_cpu(cpu, &cpuid_topo->core_sibling); + + if (cpuid_topo->core_id != topo->core_id) + continue; + + cpumask_set_cpu(cpuid, &topo->thread_sibling); + if (cpu != cpuid) + cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling); + } + smp_wmb(); +} + +/* + * store_cpu_topology is called at boot when only one cpu is running + * and with the mutex cpu_hotplug.lock locked, when several cpus have booted, + * which prevents simultaneous write access to cpu_topology array + */ +void store_cpu_topology(unsigned int cpuid) +{ + struct cputopo_arm64 *cpuid_topo = &cpu_topo(cpuid); + u64 mpidr; + + /* If the cpu topology has been already set, just return */ + if (cpuid_topo->core_id != -1) + return; + + mpidr = read_cpuid_mpidr(); + + /* create cpu topology mapping */ + if (!(mpidr & MPIDR_SMP_BITMASK)) { + /* + * This is a multiprocessor system + * multiprocessor format & multiprocessor mode field are set + */ + + if (mpidr & MPIDR_MT_BITMASK) { + /* core performance interdependency */ + cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL_0(mpidr); + cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL_1(mpidr); + cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL_2(mpidr); + } else { + /* largely independent cores */ + cpuid_topo->thread_id = -1; + cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL_0(mpidr); + cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL_1(mpidr); + } + } else { + /* + * This is an uniprocessor system + * we are in multiprocessor format but uniprocessor system + * or in the old uniprocessor format + */ + cpuid_topo->thread_id = -1; + cpuid_topo->core_id = 0; + cpuid_topo->socket_id = -1; + } + + update_siblings_masks(cpuid); + + pr_info("CPU%u: thread %d, cpu %d, socket %d, mpidr 0x%llx\n", + cpuid, cpu_topo(cpuid).thread_id, + cpu_topo(cpuid).core_id, + cpu_topo(cpuid).socket_id, mpidr); +} + +/* + * init_cpu_topology is called at boot when only one cpu is running + * which prevent simultaneous write access to cpu_topology array + */ +void __init init_cpu_topology(void) +{ + unsigned int cpu; + + /* init core mask */ + for_each_possible_cpu(cpu) { + struct cputopo_arm64 *topo = &cpu_topo(cpu); + + topo->thread_id = -1; + topo->core_id = -1; + topo->socket_id = -1; + cpumask_clear(&topo->core_sibling); + cpumask_clear(&topo->thread_sibling); + } + smp_wmb(); +} + +void arch_fix_phys_package_id(int num, u32 slot) +{ +} +EXPORT_SYMBOL_GPL(arch_fix_phys_package_id); + +#ifdef CONFIG_HOTPLUG_CPU +int __ref arch_register_cpu(int cpu) +{ + struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu); + + /* BSP cann't be taken down on arm */ + if (cpu) + cpuinfo->cpu.hotpluggable = 1; + + return register_cpu(&cpuinfo->cpu, cpu); +} +EXPORT_SYMBOL(arch_register_cpu); + +void arch_unregister_cpu(int cpu) +{ + unregister_cpu(&per_cpu(cpu_data, cpu).cpu); +} +EXPORT_SYMBOL(arch_unregister_cpu); +#else /* CONFIG_HOTPLUG_CPU */ + +static int __init arch_register_cpu(int cpu) +{ + return register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu); +} +#endif /* CONFIG_HOTPLUG_CPU */ + diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index f8ab9d8e2ea3..991ffddf49df 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -54,7 +54,6 @@ SECTIONS } .text : { /* Real text segment */ _stext = .; /* Text and read-only data */ - *(.smp.pen.text) __exception_text_start = .; *(.exception.text) __exception_text_end = .; diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 22327e6a7236..70813fe2ec81 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -2,13 +2,17 @@ # ACPI Configuration # +config ACPI_ARM + bool + select EARLY_IOREMAP + menuconfig ACPI bool "ACPI (Advanced Configuration and Power Interface) Support" depends on !IA64_HP_SIM - depends on IA64 || X86 - depends on PCI + depends on ((IA64 || X86) && PCI) || (ARM || ARM64) select PNP - default y + select ACPI_ARM if (ARM || ARM64) + default y if !(ARM || ARM64) help Advanced Configuration and Power Interface (ACPI) support for Linux requires an ACPI-compliant platform (hardware/firmware), @@ -46,6 +50,7 @@ config ACPI_SLEEP config ACPI_PROCFS bool "Deprecated /proc/acpi files" depends on PROC_FS + depends on IA64 || X86 help For backwards compatibility, this option allows deprecated /proc/acpi/ files to exist, even when @@ -59,6 +64,7 @@ config ACPI_PROCFS config ACPI_PROCFS_POWER bool "Deprecated power /proc/acpi directories" depends on PROC_FS + depends on IA64 || X86 help For backwards compatibility, this option allows deprecated power /proc/acpi/ directories to exist, even when @@ -93,9 +99,9 @@ config ACPI_EC_DEBUGFS config ACPI_AC tristate "AC Adapter" - depends on X86 + depends on X86 || ARM || ARM64 select POWER_SUPPLY - default y + default y if !(ARM || ARM64) help This driver supports the AC Adapter object, which indicates whether a system is on AC or not. If you have a system that can @@ -106,9 +112,9 @@ config ACPI_AC config ACPI_BATTERY tristate "Battery" - depends on X86 + depends on X86 || ARM || ARM64 select POWER_SUPPLY - default y + default y if !(ARM || ARM64) help This driver adds support for battery information through /proc/acpi/battery. If you have a mobile system with a battery, @@ -132,7 +138,8 @@ config ACPI_BUTTON config ACPI_VIDEO tristate "Video" - depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL + depends on (X86 || (ARM || ARM64)) && \ + BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL depends on INPUT select THERMAL help @@ -175,6 +182,7 @@ config ACPI_PROCESSOR To compile this driver as a module, choose M here: the module will be called processor. + config ACPI_IPMI tristate "IPMI" depends on IPMI_SI && IPMI_HANDLER @@ -196,7 +204,7 @@ config ACPI_HOTPLUG_CPU config ACPI_PROCESSOR_AGGREGATOR tristate "Processor Aggregator" depends on ACPI_PROCESSOR - depends on X86 + depends on X86 || ARM || ARM64 help ACPI 4.0 defines processor Aggregator, which enables OS to perform specific processor configuration and control that applies to all @@ -221,7 +229,7 @@ config ACPI_THERMAL config ACPI_NUMA bool "NUMA support" depends on NUMA - depends on (X86 || IA64) + depends on (X86 || IA64 || ARM64) default y if IA64_GENERIC || IA64_SGI_SN2 config ACPI_CUSTOM_DSDT_FILE @@ -262,6 +270,16 @@ config ACPI_BLACKLIST_YEAR Enter 0 to disable this mechanism and allow ACPI to run by default no matter what the year. (default) +config ACPI_SCI_EMULATE + bool "ACPI SCI Event Emulation Support" + depends on DEBUG_FS + default n + help + This will enable your system to emulate sci hotplug event + notification through proc file system. For example user needs to + echo "XXX 0" > /sys/kernel/debug/acpi/sci_notify (where, XXX is + a target ACPI device object name present under \_SB scope). + config ACPI_DEBUG bool "Debug Statements" default n @@ -277,6 +295,7 @@ config ACPI_DEBUG config ACPI_PCI_SLOT bool "PCI slot detection driver" depends on SYSFS + depends on PCI default n help This driver creates entries in /sys/bus/pci/slots/ for all PCI @@ -330,7 +349,7 @@ config ACPI_HOTPLUG_MEMORY config ACPI_SBS tristate "Smart Battery System" - depends on X86 + depends on X86 || ARM || ARM64 select POWER_SUPPLY help This driver supports the Smart Battery System, another diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index cdaf68b58b00..a792d00b568f 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -32,13 +32,14 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o # ACPI Bus and Device Drivers # acpi-y += bus.o glue.o +acpi-$(CONFIG_ACPI_SCI_EMULATE) += sci_emu.o acpi-y += scan.o acpi-y += resource.o acpi-y += acpi_processor.o acpi-y += processor_core.o acpi-y += ec.o acpi-$(CONFIG_ACPI_DOCK) += dock.o -acpi-y += pci_root.o pci_link.o pci_irq.o +acpi-$(CONFIG_PCI) += pci_root.o pci_link.o pci_irq.o acpi-$(CONFIG_X86_INTEL_LPSS) += acpi_lpss.o acpi-y += acpi_platform.o acpi-y += power.o @@ -82,3 +83,6 @@ processor-$(CONFIG_CPU_FREQ) += processor_perflib.o obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o obj-$(CONFIG_ACPI_APEI) += apei/ + +obj-$(CONFIG_ACPI_ARM) += plat/arm/ + diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index fc6008fbce35..36d993c1aee9 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -30,7 +30,10 @@ #include <linux/slab.h> #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ #include <asm/mwait.h> +#endif #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" @@ -47,6 +50,8 @@ static unsigned char lapic_marked_unstable; static void power_saving_mwait_init(void) { +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ unsigned int eax, ebx, ecx, edx; unsigned int highest_cstate = 0; unsigned int highest_subcstate = 0; @@ -72,6 +77,7 @@ static void power_saving_mwait_init(void) } power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | (highest_subcstate - 1); +#endif #if defined(CONFIG_X86) switch (boot_cpu_data.x86_vendor) { @@ -173,8 +179,11 @@ static int power_saving_thread(void *data) while (!need_resched()) { if (tsc_detected_unstable && !tsc_marked_unstable) { +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ /* TSC could halt in idle, so notify users */ mark_tsc_unstable("TSC halts in idle"); +#endif tsc_marked_unstable = 1; } if (lapic_detected_unstable && !lapic_marked_unstable) { @@ -193,10 +202,16 @@ static int power_saving_thread(void *data) CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); stop_critical_timings(); +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ __monitor((void *)¤t_thread_info()->flags, 0, 0); +#endif smp_mb(); +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ if (!need_resched()) __mwait(power_saving_mwait_eax, 1); +#endif start_critical_timings(); if (lapic_marked_unstable) diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 1bde12708f9e..24ee81139f20 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -30,6 +30,11 @@ static const struct acpi_device_id acpi_platform_device_ids[] = { { "PNP0D40" }, + /* arm64 platform devices */ + { "LINA0003" }, + { "LINA0005" }, + { "LINA0007" }, + { } }; diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index f0c1ce95a0ec..935d8231612d 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig @@ -2,7 +2,7 @@ config ACPI_APEI bool "ACPI Platform Error Interface (APEI)" select MISC_FILESYSTEMS select PSTORE - depends on X86 + depends on X86 || ARM || ARM64 help APEI allows to report errors (for example from the chipset) to the operating system. This improves NMI handling @@ -11,7 +11,7 @@ config ACPI_APEI config ACPI_APEI_GHES bool "APEI Generic Hardware Error Source" - depends on ACPI_APEI && X86 + depends on ACPI_APEI && (X86 || ARM || ARM64) select ACPI_HED select IRQ_WORK select GENERIC_ALLOCATOR diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile index d1d1bc0a4ee1..0eb590bc4ca1 100644 --- a/drivers/acpi/apei/Makefile +++ b/drivers/acpi/apei/Makefile @@ -3,4 +3,4 @@ obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o obj-$(CONFIG_ACPI_APEI_ERST_DEBUG) += erst-dbg.o -apei-y := apei-base.o hest.o cper.o erst.o +apei-y := apei-base.o hest.o cper.o erst.o bert.o diff --git a/drivers/acpi/apei/bert.c b/drivers/acpi/apei/bert.c new file mode 100644 index 000000000000..a06c99f89c78 --- /dev/null +++ b/drivers/acpi/apei/bert.c @@ -0,0 +1,172 @@ +/* + * APEI Boot Error Record Table (BERT) support + * + * Copyright 2011 Intel Corp. + * Author: Huang Ying <ying.huang@xxxxxxxxx> + * + * Under normal circumstances, when a hardware error occurs, kernel + * will be notified via NMI, MCE or some other method, then kernel + * will process the error condition, report it, and recover it if + * possible. But sometime, the situation is so bad, so that firmware + * may choose to reset directly without notifying Linux kernel. + * + * Linux kernel can use the Boot Error Record Table (BERT) to get the + * un-notified hardware errors that occurred in a previous boot. + * + * For more information about ERST, please refer to ACPI Specification + * version 4.0, section 17.3.1 + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/acpi.h> +#include <linux/io.h> + +#include "apei-internal.h" + +#define BERT_PFX "BERT: " + +int bert_disable; +EXPORT_SYMBOL_GPL(bert_disable); + +static void __init bert_print_all(struct acpi_hest_generic_status *region, + unsigned int region_len) +{ + int remain, first = 1; + u32 estatus_len; + struct acpi_hest_generic_status *estatus; + + remain = region_len; + estatus = region; + while (remain > sizeof(struct acpi_hest_generic_status)) { + /* No more error record */ + if (!estatus->block_status) + break; + + estatus_len = apei_estatus_len(estatus); + if (estatus_len < sizeof(struct acpi_hest_generic_status) || + remain < estatus_len) { + pr_err(FW_BUG BERT_PFX "Invalid error status block with length %u\n", + estatus_len); + return; + } + + if (apei_estatus_check(estatus)) { + pr_err(FW_BUG BERT_PFX "Invalid Error status block\n"); + goto next; + } + + if (first) { + pr_info(HW_ERR "Error record from previous boot:\n"); + first = 0; + } + apei_estatus_print(KERN_INFO HW_ERR, estatus); + + /* Clear error status */ + estatus->block_status = 0; +next: + estatus = (void *)estatus + estatus_len; + remain -= estatus_len; + } +} + +static int __init setup_bert_disable(char *str) +{ + bert_disable = 1; + return 0; +} +__setup("bert_disable", setup_bert_disable); + +static int __init bert_check_table(struct acpi_table_bert *bert_tab) +{ + if (bert_tab->header.length < sizeof(struct acpi_table_bert)) + return -EINVAL; + if (bert_tab->region_length != 0 && + bert_tab->region_length < sizeof(struct acpi_bert_region)) + return -EINVAL; + + return 0; +} + +static int __init bert_init(void) +{ + acpi_status status; + struct acpi_table_bert *bert_tab; + struct resource *r; + struct acpi_hest_generic_status *bert_region; + unsigned int region_len; + int rc = -EINVAL; + + if (acpi_disabled) + goto out; + + if (bert_disable) { + pr_info(BERT_PFX "Boot Error Record Table (BERT) support is disabled.\n"); + goto out; + } + + status = acpi_get_table(ACPI_SIG_BERT, 0, + (struct acpi_table_header **)&bert_tab); + if (status == AE_NOT_FOUND) { + pr_err(BERT_PFX "Table is not found!\n"); + goto out; + } else if (ACPI_FAILURE(status)) { + const char *msg = acpi_format_exception(status); + pr_err(BERT_PFX "Failed to get table, %s\n", msg); + goto out; + } + + rc = bert_check_table(bert_tab); + if (rc) { + pr_err(FW_BUG BERT_PFX "BERT table is invalid\n"); + goto out; + } + + region_len = bert_tab->region_length; + if (!region_len) { + rc = 0; + goto out; + } + + r = request_mem_region(bert_tab->address, region_len, "APEI BERT"); + if (!r) { + pr_err(BERT_PFX "Can not request iomem region <%016llx-%016llx> for BERT.\n", + (unsigned long long)bert_tab->address, + (unsigned long long)bert_tab->address + region_len); + rc = -EIO; + goto out; + } + + bert_region = ioremap_cache(bert_tab->address, region_len); + if (!bert_region) { + rc = -ENOMEM; + goto out_release; + } + + bert_print_all(bert_region, region_len); + + iounmap(bert_region); + +out_release: + release_mem_region(bert_tab->address, region_len); +out: + if (rc) + bert_disable = 1; + + return rc; +} +late_initcall(bert_init); diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 26311f23c824..7439734fcfb5 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -35,6 +35,7 @@ #include <linux/nmi.h> #include <linux/hardirq.h> #include <linux/pstore.h> +#include <linux/vmalloc.h> #include <acpi/apei.h> #include "apei-internal.h" diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 8ec37bbdd699..d827f2c7bcb8 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -50,9 +50,13 @@ #include <linux/aer.h> #include <acpi/ghes.h> +#ifdef CONFIG_X86 #include <asm/mce.h> +#endif #include <asm/tlbflush.h> +#ifdef CONFIG_X86 #include <asm/nmi.h> +#endif #include "apei-internal.h" @@ -87,7 +91,9 @@ bool ghes_disable; module_param_named(disable, ghes_disable, bool, 0); +#ifdef CONFIG_X86 static int ghes_panic_timeout __read_mostly = 30; +#endif /* * All error sources notified with SCI shares one notifier function, @@ -101,11 +107,13 @@ static LIST_HEAD(ghes_sci); static LIST_HEAD(ghes_nmi); static DEFINE_MUTEX(ghes_list_mutex); +#ifdef CONFIG_X86 /* * NMI may be triggered on any CPU, so ghes_nmi_lock is used for * mutual exclusion. */ static DEFINE_RAW_SPINLOCK(ghes_nmi_lock); +#endif /* * Because the memory area used to transfer hardware error information @@ -193,7 +201,7 @@ static void ghes_iounmap_nmi(void __iomem *vaddr_ptr) BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base)); unmap_kernel_range_noflush(vaddr, PAGE_SIZE); - __flush_tlb_one(vaddr); + flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE); } static void ghes_iounmap_irq(void __iomem *vaddr_ptr) @@ -203,7 +211,7 @@ static void ghes_iounmap_irq(void __iomem *vaddr_ptr) BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base)); unmap_kernel_range_noflush(vaddr, PAGE_SIZE); - __flush_tlb_one(vaddr); + flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE); } static int ghes_estatus_pool_init(void) @@ -250,10 +258,12 @@ static int ghes_estatus_pool_expand(unsigned long len) return 0; } +#ifdef CONFIG_X86 static void ghes_estatus_pool_shrink(unsigned long len) { ghes_estatus_pool_size_request -= PAGE_ALIGN(len); } +#endif static struct ghes *ghes_new(struct acpi_hest_generic *generic) { @@ -779,6 +789,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work) } } +#ifdef CONFIG_X86 static void ghes_print_queued_estatus(void) { struct llist_node *llnode; @@ -874,11 +885,13 @@ out: raw_spin_unlock(&ghes_nmi_lock); return ret; } +#endif static struct notifier_block ghes_notifier_sci = { .notifier_call = ghes_notify_sci, }; +#ifdef CONFIG_X86 static unsigned long ghes_esource_prealloc_size( const struct acpi_hest_generic *generic) { @@ -893,12 +906,15 @@ static unsigned long ghes_esource_prealloc_size( return prealloc_size; } +#endif static int ghes_probe(struct platform_device *ghes_dev) { struct acpi_hest_generic *generic; struct ghes *ghes = NULL; +#ifdef CONFIG_X86 unsigned long len; +#endif int rc = -EINVAL; generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data; @@ -970,6 +986,7 @@ static int ghes_probe(struct platform_device *ghes_dev) mutex_unlock(&ghes_list_mutex); break; case ACPI_HEST_NOTIFY_NMI: +#ifdef CONFIG_X86 len = ghes_esource_prealloc_size(generic); ghes_estatus_pool_expand(len); mutex_lock(&ghes_list_mutex); @@ -978,6 +995,7 @@ static int ghes_probe(struct platform_device *ghes_dev) "ghes"); list_add_rcu(&ghes->list, &ghes_nmi); mutex_unlock(&ghes_list_mutex); +#endif break; default: BUG(); @@ -999,7 +1017,9 @@ static int ghes_remove(struct platform_device *ghes_dev) { struct ghes *ghes; struct acpi_hest_generic *generic; +#ifdef CONFIG_X86 unsigned long len; +#endif ghes = platform_get_drvdata(ghes_dev); generic = ghes->generic; @@ -1020,6 +1040,7 @@ static int ghes_remove(struct platform_device *ghes_dev) mutex_unlock(&ghes_list_mutex); break; case ACPI_HEST_NOTIFY_NMI: +#ifdef CONFIG_X86 mutex_lock(&ghes_list_mutex); list_del_rcu(&ghes->list); if (list_empty(&ghes_nmi)) @@ -1032,6 +1053,7 @@ static int ghes_remove(struct platform_device *ghes_dev) synchronize_rcu(); len = ghes_esource_prealloc_size(generic); ghes_estatus_pool_shrink(len); +#endif break; default: BUG(); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index b587ec8257b2..439c3693127e 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -79,10 +79,6 @@ static struct dmi_system_id dsdt_dmi_table[] __initdata = { }, {} }; -#else -static struct dmi_system_id dsdt_dmi_table[] __initdata = { - {} -}; #endif /* -------------------------------------------------------------------------- @@ -479,6 +475,9 @@ static int __init acpi_bus_init_irq(void) case ACPI_IRQ_MODEL_PLATFORM: message = "platform specific model"; break; + case ACPI_IRQ_MODEL_GIC: + message = "GIC"; + break; default: printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n"); return -ENODEV; @@ -513,11 +512,15 @@ void __init acpi_early_init(void) acpi_gbl_permanent_mmap = 1; +#ifdef CONFIG_X86 /* + * NB: ARM does not use DMI; only older Intel products do. + * * If the machine falls into the DMI check table, * DSDT will be copied to memory */ dmi_check_system(dsdt_dmi_table); +#endif status = acpi_reallocate_root_table(); if (ACPI_FAILURE(status)) { diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e5f416c7f66e..34beeba2e6e6 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -246,6 +246,64 @@ static int __init setup_acpi_rsdp(char *arg) early_param("acpi_rsdp", setup_acpi_rsdp); #endif +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) +#include <asm/acpi.h> +#include <acpi/actbl.h> + +void acpi_find_arm_root_pointer(acpi_physical_address *pa) +{ + /* BOZO: temporarily clunky. + * What we do is, while using u-boot still, is use the values + * that have already been retrieved from the FDT node + * (/chosen/linux,acpi-start and /chosen/linux,acpi-len) which + * contain the address of the first byte of the RSDP after it + * has been loaded into RAM during u-boot (e.g., using something + * like fatload mmc 0:2 42008000 my.blob), and the size of the + * data in the complete ACPI blob. We only do this since we have + * to collaborate with FDT so we have to load FDT and the ACPI + * tables in but only have one address we can use via bootm. + * With UEFI, we should just be able to use the efi_enabled + * branch below in acpi_os_get_root_pointer(). + */ + + void *address; + struct acpi_table_rsdp *rp; + + if (!acpi_arm_rsdp_info.phys_address && !acpi_arm_rsdp_info.size) { + pr_err("failed to find rsdp info\n"); + *pa = (acpi_physical_address)NULL; + return; + } + + address = phys_to_virt(acpi_arm_rsdp_info.phys_address); + address += ACPI_BLOB_HEADER_SIZE; + *pa = (acpi_physical_address)address; + + rp = (struct acpi_table_rsdp *)address; + pr_debug("ACPI rsdp rp: 0x%08lx\n", (long unsigned int)rp); + if (rp) { + pr_debug("ACPI rsdp content:\n"); + pr_debug(" signature: %.8s\n", rp->signature); + pr_debug(" checksum: 0x%02x\n", rp->checksum); + pr_debug(" oem_id: %.6s\n", rp->oem_id); + pr_debug(" revision: %d\n", rp->revision); + pr_debug(" rsdt: 0x%08lX\n", + (long unsigned int)rp->rsdt_physical_address); + pr_debug(" length: %d\n", rp->length); + pr_debug(" xsdt: 0x%016llX\n", + (u64)rp->xsdt_physical_address); + pr_debug(" x_checksum: 0x%02x\n", rp->extended_checksum); + + *pa = (acpi_physical_address)(virt_to_phys(rp)); + } else { + pr_err("ACPI missing rsdp info\n"); + *pa = (acpi_physical_address)NULL; + } + + return; +} +#endif + acpi_physical_address __init acpi_os_get_root_pointer(void) { #ifdef CONFIG_KEXEC @@ -266,7 +324,11 @@ acpi_physical_address __init acpi_os_get_root_pointer(void) } else { acpi_physical_address pa = 0; +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) + acpi_find_arm_root_pointer(&pa); +#else acpi_find_root_pointer(&pa); +#endif return pa; } } @@ -328,11 +390,11 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size) return NULL; } -#ifndef CONFIG_IA64 -#define should_use_kmap(pfn) page_is_ram(pfn) -#else +#if defined(CONFIG_IA64) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) /* ioremap will take care of cache attributes */ #define should_use_kmap(pfn) 0 +#else +#define should_use_kmap(pfn) page_is_ram(pfn) #endif static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz) @@ -376,6 +438,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) return __acpi_map_table((unsigned long)phys, size); mutex_lock(&acpi_ioremap_lock); + /* Check if there's a suitable mapping already. */ map = acpi_map_lookup(phys, size); if (map) { @@ -1028,9 +1091,18 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, return AE_ERROR; } +#ifdef CONFIG_X86 + /* + * BOZO: probably should not call this function at all + * if there is no PCI... + */ result = raw_pci_read(pci_id->segment, pci_id->bus, PCI_DEVFN(pci_id->device, pci_id->function), reg, size, &value32); +#else + result = 0; + value32 = 0; +#endif *value = value32; return (result ? AE_ERROR : AE_OK); @@ -1056,9 +1128,14 @@ acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, return AE_ERROR; } +#ifdef CONFIG_X86 + /* BOZO: how do we handle not having PCI? */ result = raw_pci_write(pci_id->segment, pci_id->bus, PCI_DEVFN(pci_id->device, pci_id->function), reg, size, value); +#else + result = 0; +#endif return (result ? AE_ERROR : AE_OK); } @@ -1244,7 +1321,7 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) jiffies = MAX_SCHEDULE_TIMEOUT; else jiffies = msecs_to_jiffies(timeout); - + ret = down_timeout(sem, jiffies); if (ret) status = AE_TIME; diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index d3874f425653..837bc5ba55bd 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -567,8 +567,6 @@ static void acpi_pci_root_remove(struct acpi_device *device) void __init acpi_pci_root_init(void) { - acpi_hest_init(); - if (!acpi_pci_disabled) { pci_acpi_crs_quirks(); acpi_scan_add_handler(&pci_root_handler); diff --git a/drivers/acpi/plat/arm/Makefile b/drivers/acpi/plat/arm/Makefile new file mode 100644 index 000000000000..a1f056d4fcd1 --- /dev/null +++ b/drivers/acpi/plat/arm/Makefile @@ -0,0 +1,3 @@ +obj-y += boot.o +obj-y += sleep.o + diff --git a/drivers/acpi/plat/arm/boot.c b/drivers/acpi/plat/arm/boot.c new file mode 100644 index 000000000000..4fcdd9f35593 --- /dev/null +++ b/drivers/acpi/plat/arm/boot.c @@ -0,0 +1,809 @@ +/* + * boot.c - Architecture-Specific Low-Level ACPI Boot Support + * + * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> + * Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com> + * Copyright (C) 2013, Al Stone <al.stone@linaro.org> (ARM version) + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include <linux/init.h> +#include <linux/acpi.h> +#include <linux/acpi_pmtmr.h> +#include <linux/efi.h> +#include <linux/cpumask.h> +#include <linux/memblock.h> +#include <linux/module.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/slab.h> +#include <linux/bootmem.h> +#include <linux/ioport.h> +#include <linux/pci.h> + +#include <asm/pgtable.h> +#include <asm/io.h> +#include <asm/smp.h> +#include <asm/acpi.h> + +/* + * We never plan to use RSDT on arm/arm64 as its deprecated in spec but this + * variable is still required by the ACPI core + */ +u32 acpi_rsdt_forced; + +int acpi_disabled; +EXPORT_SYMBOL(acpi_disabled); + +/* available_cpus here means enabled cpu in MADT */ +int available_cpus; + +/* Map logic cpu id to physical APIC id. + * APIC = GIC cpu interface on ARM + */ +volatile int arm_cpu_to_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = -1 }; +int boot_cpu_apic_id = -1; + +#define BAD_MADT_ENTRY(entry, end) ( \ + (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ + ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) + +#define PREFIX "ACPI: " + +int acpi_noirq; /* skip ACPI IRQ initialization */ +int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */ +EXPORT_SYMBOL(acpi_pci_disabled); + +int acpi_lapic; +int acpi_ioapic; +int acpi_strict; + +u8 acpi_sci_flags __initdata; +int acpi_sci_override_gsi __initdata; +int acpi_skip_timer_override __initdata; +int acpi_use_timer_override __initdata; +int acpi_fix_pin2_polarity __initdata; +static u64 acpi_lapic_addr __initdata; + +struct acpi_arm_root acpi_arm_rsdp_info; /* info about RSDP from FDT */ + +/* + * Boot-time Configuration + */ + +/* + * The default interrupt routing model is PIC (8259). This gets + * overridden if IOAPICs are enumerated (below). + * + * Since we're on ARM, it clearly has to be GIC. + */ +enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_GIC; + +static unsigned int gsi_to_irq(unsigned int gsi) +{ + int irq = irq_create_mapping(NULL, gsi); + + return irq; +} + +char *__init __acpi_map_table(phys_addr_t phys, unsigned long size) +{ + if (!phys || !size) + return NULL; + + return early_memremap(phys, size); +} + +void __init __acpi_unmap_table(char *map, unsigned long size) +{ + if (!map || !size) + return; + + early_iounmap(map, size); + return; +} + +static int __init acpi_parse_madt(struct acpi_table_header *table) +{ + struct acpi_table_madt *madt = NULL; + + madt = (struct acpi_table_madt *)table; + if (!madt) { + pr_warn(PREFIX "Unable to map MADT\n"); + return -ENODEV; + } + + if (madt->address) { + acpi_lapic_addr = (u64) madt->address; + + pr_info(PREFIX "Local APIC address 0x%08x\n", madt->address); + } + + return 0; +} + +/* Local APIC = GIC cpu interface on ARM */ +static void acpi_register_lapic(int id, u8 enabled) +{ + int cpu; + + if (id >= MAX_LOCAL_APIC) { + pr_info(PREFIX "skipped apicid that is too big\n"); + return; + } + + total_cpus++; + if (!enabled) + return; + + available_cpus++; + + /* allocate a logic cpu id for the new comer */ + if (boot_cpu_apic_id == id) { + /* + * boot_cpu_init() already hold bit 0 in cpu_present_mask + * for BSP, no need to allocte again. + */ + cpu = 0; + } else { + cpu = cpumask_next_zero(-1, cpu_present_mask); + } + + /* map the logic cpu id to APIC id */ + arm_cpu_to_apicid[cpu] = id; + + set_cpu_present(cpu, true); + set_cpu_possible(cpu, true); +} + +static int __init +acpi_parse_gic(struct acpi_subtable_header *header, const unsigned long end) +{ + struct acpi_madt_generic_interrupt *processor = NULL; + + processor = (struct acpi_madt_generic_interrupt *)header; + + if (BAD_MADT_ENTRY(processor, end)) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + /* + * We need to register disabled CPU as well to permit + * counting disabled CPUs. This allows us to size + * cpus_possible_map more accurately, to permit + * to not preallocating memory for all NR_CPUS + * when we use CPU hotplug. + */ + acpi_register_lapic(processor->gic_id, + processor->flags & ACPI_MADT_ENABLED); + + return 0; +} + +static int __init +acpi_parse_gic_distributor(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct acpi_madt_generic_distributor *distributor = NULL; + + distributor = (struct acpi_madt_generic_distributor *)header; + + if (BAD_MADT_ENTRY(distributor, end)) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + /* TODO: handle with the base_address and irq_base for irq system */ + + return 0; +} + +int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) +{ + *irq = gsi_to_irq(gsi); + + return 0; +} +EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); + +static int acpi_register_gsi_pic(struct device *dev, u32 gsi, + int trigger, int polarity) +{ +#ifdef CONFIG_PCI + /* + * Make sure all (legacy) PCI IRQs are set as level-triggered. + */ + if (trigger == ACPI_LEVEL_SENSITIVE) + eisa_set_level_irq(gsi); +#endif + + return gsi; +} + +static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi, + int trigger, int polarity) +{ + return gsi; +} + +int (*__acpi_register_gsi)(struct device *dev, u32 gsi, + int trigger, int polarity) = acpi_register_gsi_pic; + +/* + * success: return IRQ number (>=0) + * failure: return < 0 + */ +int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) +{ + unsigned int irq; + unsigned int plat_gsi = gsi; + + plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity); + + irq = gsi_to_irq(plat_gsi); + + return irq; +} +EXPORT_SYMBOL_GPL(acpi_register_gsi); + +void acpi_unregister_gsi(u32 gsi) +{ +} +EXPORT_SYMBOL_GPL(acpi_unregister_gsi); + +void __init acpi_set_irq_model_pic(void) +{ + acpi_irq_model = ACPI_IRQ_MODEL_PIC; + __acpi_register_gsi = acpi_register_gsi_pic; + acpi_ioapic = 0; +} + +void __init acpi_set_irq_model_gic(void) +{ + acpi_irq_model = ACPI_IRQ_MODEL_GIC; + __acpi_register_gsi = acpi_register_gsi_ioapic; + acpi_ioapic = 1; +} + +static int __initdata setup_possible_cpus = -1; +static int __init _setup_possible_cpus(char *str) +{ + get_option(&str, &setup_possible_cpus); + return 0; +} +early_param("possible_cpus", _setup_possible_cpus); + +/* + * cpu_possible_mask should be static, it cannot change as cpu's + * are onlined, or offlined. The reason is per-cpu data-structures + * are allocated by some modules at init time, and dont expect to + * do this dynamically on cpu arrival/departure. + * cpu_present_mask on the other hand can change dynamically. + * In case when cpu_hotplug is not compiled, then we resort to current + * behaviour, which is cpu_possible == cpu_present. + * - Ashok Raj + * + * Three ways to find out the number of additional hotplug CPUs: + * - If the BIOS specified disabled CPUs in ACPI/mptables use that. + * - The user can overwrite it with possible_cpus=NUM + * - Otherwise don't reserve additional CPUs. + * We do this because additional CPUs waste a lot of memory. + * -AK + */ +void __init prefill_possible_map(void) +{ + int i; + int possible, disabled_cpus; + + disabled_cpus = total_cpus - available_cpus; + + if (setup_possible_cpus == -1) { + if (disabled_cpus > 0) + setup_possible_cpus = disabled_cpus; + else + setup_possible_cpus = 0; + } + + possible = available_cpus + setup_possible_cpus; + + pr_info("SMP: the system is limited to %d CPUs\n", nr_cpu_ids); + + /* + * On armv8 foundation model --cores=4 lets nr_cpu_ids=4, so we can't + * get possible map correctly when more than 4 APIC entries in MADT. + */ + if (possible > nr_cpu_ids) + possible = nr_cpu_ids; + + pr_info("SMP: Allowing %d CPUs, %d hotplug CPUs\n", + possible, max((possible - available_cpus), 0)); + + for (i = 0; i < possible; i++) + set_cpu_possible(i, true); + for (; i < NR_CPUS; i++) + set_cpu_possible(i, false); +} + +/* + * ACPI based hotplug support for CPU + */ +#ifdef CONFIG_ACPI_HOTPLUG_CPU +#include <acpi/processor.h> + +static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) +{ +#ifdef CONFIG_ACPI_NUMA + int nid; + + nid = acpi_get_node(handle); + if (nid == -1 || !node_online(nid)) + return; + set_apicid_to_node(physid, nid); + numa_set_node(cpu, nid); +#endif +} + +static int _acpi_map_lsapic(acpi_handle handle, int *pcpu) +{ + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + struct acpi_madt_generic_interrupt *lapic; + cpumask_var_t tmp_map, new_map; + u8 physid; + int cpu; + int retval = -ENOMEM; + + if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) + return -EINVAL; + + if (!buffer.length || !buffer.pointer) + return -EINVAL; + + obj = buffer.pointer; + if (obj->type != ACPI_TYPE_BUFFER || + obj->buffer.length < sizeof(*lapic)) { + kfree(buffer.pointer); + return -EINVAL; + } + + lapic = (struct acpi_madt_generic_interrupt *)obj->buffer.pointer; + + if (lapic->header.type != ACPI_MADT_TYPE_GENERIC_INTERRUPT || + !(lapic->flags & ACPI_MADT_ENABLED)) { + kfree(buffer.pointer); + return -EINVAL; + } + + physid = lapic->gic_id; + + kfree(buffer.pointer); + buffer.length = ACPI_ALLOCATE_BUFFER; + buffer.pointer = NULL; + lapic = NULL; + + if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL)) + goto out; + + if (!alloc_cpumask_var(&new_map, GFP_KERNEL)) + goto free_tmp_map; + + cpumask_copy(tmp_map, cpu_present_mask); + acpi_register_lapic(physid, ACPI_MADT_ENABLED); + + /* + * If acpi_register_lapic successfully generates a new logical cpu + * number, then the following will get us exactly what was mapped + */ + cpumask_andnot(new_map, cpu_present_mask, tmp_map); + if (cpumask_empty(new_map)) { + pr_err("Unable to map lapic to logical cpu number\n"); + retval = -EINVAL; + goto free_new_map; + } + + acpi_processor_set_pdc(handle); + + cpu = cpumask_first(new_map); + acpi_map_cpu2node(handle, cpu, physid); + + *pcpu = cpu; + retval = 0; + +free_new_map: + free_cpumask_var(new_map); +free_tmp_map: + free_cpumask_var(tmp_map); +out: + return retval; +} + +/* wrapper to silence section mismatch warning */ +int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu) +{ + return _acpi_map_lsapic(handle, pcpu); +} +EXPORT_SYMBOL(acpi_map_lsapic); + +int acpi_unmap_lsapic(int cpu) +{ + arm_cpu_to_apicid[cpu] = -1; + set_cpu_present(cpu, false); + available_cpus--; + + return 0; +} +EXPORT_SYMBOL(acpi_unmap_lsapic); +#endif /* CONFIG_ACPI_HOTPLUG_CPU */ + +static int __init acpi_parse_sbf(struct acpi_table_header *table) +{ + struct acpi_table_boot *sb; + + sb = (struct acpi_table_boot *)table; + if (!sb) { + printk(KERN_WARNING PREFIX "Unable to map SBF\n"); + return -ENODEV; + } + + return 0; +} + +#ifdef CONFIG_HPET_TIMER +#include <asm/hpet.h> + +static struct __initdata resource * hpet_res; + +static int __init acpi_parse_hpet(struct acpi_table_header *table) +{ + struct acpi_table_hpet *hpet_tbl; + + hpet_tbl = (struct acpi_table_hpet *)table; + if (!hpet_tbl) { + printk(KERN_WARNING PREFIX "Unable to map HPET\n"); + return -ENODEV; + } + + if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) { + printk(KERN_WARNING PREFIX "HPET timers must be located in " + "memory.\n"); + return -1; + } + + hpet_address = hpet_tbl->address.address; + hpet_blockid = hpet_tbl->sequence; + + /* + * Some broken BIOSes advertise HPET at 0x0. We really do not + * want to allocate a resource there. + */ + if (!hpet_address) { + printk(KERN_WARNING PREFIX + "HPET id: %#x base: %#lx is invalid\n", + hpet_tbl->id, hpet_address); + return 0; + } + printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", + hpet_tbl->id, hpet_address); + + /* + * Allocate and initialize the HPET firmware resource for adding into + * the resource tree during the lateinit timeframe. + */ +#define HPET_RESOURCE_NAME_SIZE 9 + hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE); + + hpet_res->name = (void *)&hpet_res[1]; + hpet_res->flags = IORESOURCE_MEM; + snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, "HPET %u", + hpet_tbl->sequence); + + hpet_res->start = hpet_address; + hpet_res->end = hpet_address + (1 * 1024) - 1; + + return 0; +} + +/* + * hpet_insert_resource inserts the HPET resources used into the resource + * tree. + */ +static int __init hpet_insert_resource(void) +{ + if (!hpet_res) + return 1; + + return insert_resource(&iomem_resource, hpet_res); +} + +late_initcall(hpet_insert_resource); + +#else +#define acpi_parse_hpet NULL +#endif + +/* Local APIC = GIC cpu interface on ARM */ +static int __init acpi_parse_madt_lapic_entries(void) +{ + int count; + + /* + * do a partial walk of MADT to determine how many CPUs + * we have including disabled CPUs + */ + count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, + acpi_parse_gic, MAX_LOCAL_APIC); + + if (!count) { + pr_err(PREFIX "No LAPIC entries present\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return -ENODEV; + } else if (count < 0) { + pr_err(PREFIX "Error parsing LAPIC entry\n"); + /* TBD: Cleanup to allow fallback to MPS */ + return count; + } + +#ifdef CONFIG_SMP + if (available_cpus == 0) { + pr_info(PREFIX "Found 0 CPUS; assuming 1\n"); + /* FIXME: should be the real GIC id read from hardware */ + arm_cpu_to_apicid[available_cpus] = 0; + available_cpus = 1; /* We've got at least one of these */ + } +#endif + /* Make boot-up look pretty */ + pr_info("%d CPUs available, %d CPUs total\n", available_cpus, + total_cpus); + + return 0; +} + +static int __init acpi_parse_fadt(struct acpi_table_header *table) +{ + return 0; +} + +/* + * Parse IOAPIC related entries in MADT + * returns 0 on success, < 0 on error + * IOAPIC = GIC distributor on ARM + */ +static int __init acpi_parse_madt_ioapic_entries(void) +{ + int count; + + /* + * ACPI interpreter is required to complete interrupt setup, + * so if it is off, don't enumerate the io-apics with ACPI. + * If MPS is present, it will handle them, + * otherwise the system will stay in PIC mode + */ + if (acpi_disabled || acpi_noirq) + return -ENODEV; + + count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, + acpi_parse_gic_distributor, MAX_IO_APICS); + + if (!count) { + pr_err(PREFIX "No IOAPIC entries present\n"); + return -ENODEV; + } else if (count < 0) { + pr_err(PREFIX "Error parsing IOAPIC entry\n"); + return count; + } + + return 0; +} + +static void __init early_acpi_process_madt(void) +{ + /* should I introduce CONFIG_ARM_LOCAL_APIC like x86 does? */ + acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt); +} + +static void __init acpi_process_madt(void) +{ + /* should I introduce CONFIG_ARM_LOCAL_APIC like x86 does? */ + int error; + + if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { + + /* + * Parse MADT LAPIC entries + */ + error = acpi_parse_madt_lapic_entries(); + if (!error) { + acpi_lapic = 1; + + /* + * Parse MADT IO-APIC entries + */ + error = acpi_parse_madt_ioapic_entries(); + if (!error) + acpi_set_irq_model_gic(); + } + } + + /* + * ACPI supports both logical (e.g. Hyper-Threading) and physical + * processors, where MPS only supports physical. + */ + if (acpi_lapic && acpi_ioapic) + pr_info("Using ACPI (MADT) for SMP configuration " + "information\n"); + else if (acpi_lapic) + pr_info("Using ACPI for processor (LAPIC) " + "configuration information\n"); + + return; +} + +/* + * ========== OLD COMMENTS FROM x86 ================================= + * acpi_boot_table_init() and acpi_boot_init() + * called from setup_arch(), always. + * 1. checksums all tables + * 2. enumerates lapics + * 3. enumerates io-apics + * + * acpi_table_init() is separate to allow reading SRAT without + * other side effects. + * + * side effects of acpi_boot_init: + * acpi_lapic = 1 if LAPIC found + * acpi_ioapic = 1 if IOAPIC found + * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; + * if acpi_blacklisted() acpi_disabled = 1; + * acpi_irq_model=... + * ... + * ================================================================== + * + * We have to approach this a little different on ARMv7. We are + * passed in an ACPI blob and we really have no idea where in RAM + * it will be located. So, what should have been the physical + * addresses of other tables cannot really be hardcoded into the + * tables. What we will do is put an offset in the blob that is + * the offset from the beginning of the RSDP structure. However, + * what that means is that we have to unpack the blob and do a + * bit of fixup work on the offsets to turn them into kernel + * virtual addresses so we can pass them on for later use. + */ +void __init acpi_boot_table_init(void) +{ + /* + * If acpi_disabled, bail out + */ + if (acpi_disabled) + return; + + /* + * Initialize the ACPI boot-time table parser. + */ + if (acpi_table_init()) { + disable_acpi(); + return; + } + + acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); +} + +int __init early_acpi_boot_init(void) +{ + /* + * If acpi_disabled, bail out + */ + if (acpi_disabled) + return 1; + + /* + * Process the Multiple APIC Description Table (MADT), if present + */ + early_acpi_process_madt(); + + return 0; +} + +int __init acpi_boot_init(void) +{ + /* + * If acpi_disabled, bail out + */ + if (acpi_disabled) + return 1; + + acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); + + /* + * set sci_int and PM timer address + */ + acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt); + + /* + * Process the Multiple APIC Description Table (MADT), if present + */ + acpi_process_madt(); + + acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet); + + return 0; +} + +/* + * make sure that the address passed for ACPI tables which is normall in + * system ram is removed from the kernel memory map + */ +void __init arm_acpi_reserve_memory() +{ + unsigned long section_offset; + unsigned long num_sections; + phys_addr_t addr = acpi_arm_rsdp_info.phys_address; + int size = acpi_arm_rsdp_info.size; + + /* if ACPI tables were not passed in FDT then escape here */ + if (!addr || !size) + return; + + section_offset = addr - (addr & SECTION_MASK); + num_sections = size / SECTION_SIZE; + if (size % SECTION_SIZE) + num_sections++; + + memblock_remove(addr - section_offset, num_sections * SECTION_SIZE); +} + +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) { + disable_acpi(); + } + /* acpi=strict disables out-of-spec workarounds */ + else if (strcmp(arg, "strict") == 0) { + acpi_strict = 1; + } + return 0; +} +early_param("acpi", parse_acpi); + +int __acpi_acquire_global_lock(unsigned int *lock) +{ + unsigned int old, new, val; + do { + old = *lock; + new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1)); + val = cmpxchg(lock, old, new); + } while (unlikely (val != old)); + return (new < 3) ? -1 : 0; +} + +int __acpi_release_global_lock(unsigned int *lock) +{ + unsigned int old, new, val; + do { + old = *lock; + new = old & ~0x3; + val = cmpxchg(lock, old, new); + } while (unlikely (val != old)); + return old & 0x1; +} diff --git a/drivers/acpi/plat/arm/sleep.c b/drivers/acpi/plat/arm/sleep.c new file mode 100644 index 000000000000..9129c7e95cd7 --- /dev/null +++ b/drivers/acpi/plat/arm/sleep.c @@ -0,0 +1,126 @@ +/* + * sleep.c - x86-specific ACPI sleep support. + * + * Copyright (C) 2001-2003 Patrick Mochel + * Copyright (C) 2001-2003 Pavel Machek <pavel@ucw.cz> + */ + +int acpi_suspend_lowlevel(void) +{ + /* BOZO: dummy routine; see below for actual */ + return 0; +} + +#ifdef CONFIG_X86 +/* BOZO: disable everything for now... */ + +#include <linux/acpi.h> +#include <linux/bootmem.h> +#include <linux/memblock.h> +#include <linux/dmi.h> +#include <linux/cpumask.h> +#include <asm/segment.h> +#include <asm/desc.h> +#include <asm/pgtable.h> +#include <asm/cacheflush.h> +#include <asm/realmode.h> + +#include "../../realmode/rm/wakeup.h" +#include "sleep.h" + +unsigned long acpi_realmode_flags; + +#if defined(CONFIG_SMP) && defined(CONFIG_64BIT) +static char temp_stack[4096]; +#endif + +/** + * acpi_suspend_lowlevel - save kernel state + * + * Create an identity mapped page table and copy the wakeup routine to + * low memory. + */ +int acpi_suspend_lowlevel(void) +{ + struct wakeup_header *header = + (struct wakeup_header *) __va(real_mode_header->wakeup_header); + + if (header->signature != WAKEUP_HEADER_SIGNATURE) { + printk(KERN_ERR "wakeup header does not match\n"); + return -EINVAL; + } + + header->video_mode = saved_video_mode; + + header->pmode_behavior = 0; + +#ifndef CONFIG_64BIT + store_gdt((struct desc_ptr *)&header->pmode_gdt); + + if (!rdmsr_safe(MSR_EFER, + &header->pmode_efer_low, + &header->pmode_efer_high)) + header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_EFER); +#endif /* !CONFIG_64BIT */ + + header->pmode_cr0 = read_cr0(); + if (__this_cpu_read(cpu_info.cpuid_level) >= 0) { + header->pmode_cr4 = read_cr4(); + header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_CR4); + } + if (!rdmsr_safe(MSR_IA32_MISC_ENABLE, + &header->pmode_misc_en_low, + &header->pmode_misc_en_high)) + header->pmode_behavior |= + (1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE); + header->realmode_flags = acpi_realmode_flags; + header->real_magic = 0x12345678; + +#ifndef CONFIG_64BIT + header->pmode_entry = (u32)&wakeup_pmode_return; + header->pmode_cr3 = (u32)__pa(&initial_page_table); + saved_magic = 0x12345678; +#else /* CONFIG_64BIT */ +#ifdef CONFIG_SMP + stack_start = (unsigned long)temp_stack + sizeof(temp_stack); + early_gdt_descr.address = + (unsigned long)get_cpu_gdt_table(smp_processor_id()); + initial_gs = per_cpu_offset(smp_processor_id()); +#endif + initial_code = (unsigned long)wakeup_long64; + saved_magic = 0x123456789abcdef0L; +#endif /* CONFIG_64BIT */ + + do_suspend_lowlevel(); + return 0; +} + +static int __init acpi_sleep_setup(char *str) +{ + while ((str != NULL) && (*str != '\0')) { + if (strncmp(str, "s3_bios", 7) == 0) + acpi_realmode_flags |= 1; + if (strncmp(str, "s3_mode", 7) == 0) + acpi_realmode_flags |= 2; + if (strncmp(str, "s3_beep", 7) == 0) + acpi_realmode_flags |= 4; +#ifdef CONFIG_HIBERNATION + if (strncmp(str, "s4_nohwsig", 10) == 0) + acpi_no_s4_hw_signature(); +#endif + if (strncmp(str, "nonvs", 5) == 0) + acpi_nvs_nosave(); + if (strncmp(str, "nonvs_s3", 8) == 0) + acpi_nvs_nosave_s3(); + if (strncmp(str, "old_ordering", 12) == 0) + acpi_old_suspend_ordering(); + str = strchr(str, ','); + if (str != NULL) + str += strspn(str, ", \t"); + } + return 1; +} + +__setup("acpi_sleep=", acpi_sleep_setup); + +#endif diff --git a/drivers/acpi/plat/arm/sleep.h b/drivers/acpi/plat/arm/sleep.h new file mode 100644 index 000000000000..67f59f8c6956 --- /dev/null +++ b/drivers/acpi/plat/arm/sleep.h @@ -0,0 +1,17 @@ +/* + * Variables and functions used by the code in sleep.c + */ + +#include <asm/realmode.h> + +extern unsigned long saved_video_mode; +extern long saved_magic; + +extern int wakeup_pmode_return; + +extern u8 wake_sleep_flags; + +extern unsigned long acpi_copy_wakeup_routine(unsigned long); +extern void wakeup_long64(void); + +extern void do_suspend_lowlevel(void); diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index cf34d903f4fb..2e299f27c1eb 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -90,6 +90,27 @@ static int map_lsapic_id(struct acpi_subtable_header *entry, return 1; } +static int map_gic_id(struct acpi_subtable_header *entry, + int device_declaration, u32 acpi_id, int *apic_id) +{ + struct acpi_madt_generic_interrupt *gic = + (struct acpi_madt_generic_interrupt *)entry; + + if (!(gic->flags & ACPI_MADT_ENABLED)) + return 0; + + /* In the GIC interrupt model, logical processors are + * required to have a Processor Device object in the DSDT, + * so we should check device_declaration here + */ + if (device_declaration && (gic->uid == acpi_id)) { + *apic_id = gic->gic_id; + return 1; + } + + return 0; +} + static int map_madt_entry(int type, u32 acpi_id) { unsigned long madt_end, entry; @@ -125,6 +146,9 @@ static int map_madt_entry(int type, u32 acpi_id) } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { if (map_lsapic_id(header, type, acpi_id, &apic_id)) break; + } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) { + if (map_gic_id(header, type, acpi_id, &apic_id)) + break; } entry += header->length; } @@ -155,6 +179,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) map_lapic_id(header, acpi_id, &apic_id); } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { map_lsapic_id(header, type, acpi_id, &apic_id); + } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) { + map_gic_id(header, type, acpi_id, &apic_id); } exit: @@ -209,6 +235,7 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) if (apic_id == 0) return apic_id; #endif + return -1; } EXPORT_SYMBOL_GPL(acpi_get_cpuid); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f98dd00b51a9..587f3cf3e8ab 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -119,17 +119,26 @@ static struct dmi_system_id processor_power_dmi_table[] = { */ static void acpi_safe_halt(void) { +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ current_thread_info()->status &= ~TS_POLLING; +#endif /* * TS_POLLING-cleared state must be visible before we * test NEED_RESCHED: */ smp_mb(); if (!need_resched()) { +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ safe_halt(); +#endif local_irq_disable(); } +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ current_thread_info()->status |= TS_POLLING; +#endif } #ifdef ARCH_APICTIMER_STOPS_ON_C3 @@ -759,6 +768,8 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) while (1) { +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ if (cx->entry_method == ACPI_CSTATE_HALT) safe_halt(); else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) { @@ -766,6 +777,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) /* See comment in acpi_idle_do_entry() */ inl(acpi_gbl_FADT.xpm_timer_block.address); } else +#endif return -ENODEV; } @@ -791,7 +803,10 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, return -EINVAL; if (cx->entry_method != ACPI_CSTATE_FFH) { +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ current_thread_info()->status &= ~TS_POLLING; +#endif /* * TS_POLLING-cleared state must be visible before we test * NEED_RESCHED: @@ -799,7 +814,10 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, smp_mb(); if (unlikely(need_resched())) { +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ current_thread_info()->status |= TS_POLLING; +#endif return -EINVAL; } } @@ -819,8 +837,11 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, sched_clock_idle_wakeup_event(0); +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ if (cx->entry_method != ACPI_CSTATE_FFH) current_thread_info()->status |= TS_POLLING; +#endif lapic_timer_state_broadcast(pr, cx, 0); return index; @@ -859,7 +880,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, } if (cx->entry_method != ACPI_CSTATE_FFH) { +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ current_thread_info()->status &= ~TS_POLLING; +#endif /* * TS_POLLING-cleared state must be visible before we test * NEED_RESCHED: @@ -867,12 +891,18 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, smp_mb(); if (unlikely(need_resched())) { +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ current_thread_info()->status |= TS_POLLING; +#endif return -EINVAL; } } +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ acpi_unlazy_tlb(smp_processor_id()); +#endif /* Tell the scheduler that we are going deep-idle: */ sched_clock_idle_sleep_event(); @@ -915,8 +945,11 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, sched_clock_idle_wakeup_event(0); +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ if (cx->entry_method != ACPI_CSTATE_FFH) current_thread_info()->status |= TS_POLLING; +#endif lapic_timer_state_broadcast(pr, cx, 0); return index; @@ -1175,7 +1208,10 @@ int acpi_processor_power_init(struct acpi_processor *pr) if (!first_run) { dmi_check_system(processor_power_dmi_table); +#ifdef CONFIG_X86 + /* BOZO: abstract out? */ max_cstate = acpi_processor_cstate_check(max_cstate); +#endif if (max_cstate < ACPI_C_STATES_MAX) printk(KERN_NOTICE "ACPI: processor limited to max C-state %d\n", diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index a6c77e8b37bd..410d0be99a04 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c @@ -6,9 +6,7 @@ void acpi_reboot(void) { struct acpi_generic_address *rr; - struct pci_bus *bus0; u8 reset_value; - unsigned int devfn; if (acpi_disabled) return; @@ -31,7 +29,15 @@ void acpi_reboot(void) /* The reset register can only exist in I/O, Memory or PCI config space * on a device on bus 0. */ switch (rr->space_id) { +/* + * There are some rare cases in the ARM world with PCI is not one + * of the buses available to us, even though we use ACPI. + */ +#ifdef CONFIG_PCI case ACPI_ADR_SPACE_PCI_CONFIG: + struct pci_bus *bus0; + unsigned int devfn; + /* The reset register can only live on bus 0. */ bus0 = pci_find_bus(0, 0); if (!bus0) @@ -44,6 +50,7 @@ void acpi_reboot(void) pci_bus_write_config_byte(bus0, devfn, (rr->address & 0xffff), reset_value); break; +#endif case ACPI_ADR_SPACE_SYSTEM_MEMORY: case ACPI_ADR_SPACE_SYSTEM_IO: diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 407ad13cac2f..a8247d118f7b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -13,6 +13,7 @@ #include <linux/nls.h> #include <acpi/acpi_drivers.h> +#include <acpi/apei.h> #include "internal.h" @@ -2060,8 +2061,11 @@ int __init acpi_scan_init(void) printk(KERN_ERR PREFIX "Could not register bus type\n"); } + acpi_hest_init(); +#if defined(CONFIG_PCI) acpi_pci_root_init(); acpi_pci_link_init(); +#endif acpi_processor_init(); acpi_platform_init(); acpi_lpss_init(); @@ -2090,7 +2094,9 @@ int __init acpi_scan_init(void) acpi_update_all_gpes(); +#if defined(CONFIG_PCI) acpi_pci_root_hp_init(); +#endif out: mutex_unlock(&acpi_scan_lock); diff --git a/drivers/acpi/sci_emu.c b/drivers/acpi/sci_emu.c new file mode 100644 index 000000000000..08af8e9c3959 --- /dev/null +++ b/drivers/acpi/sci_emu.c @@ -0,0 +1,148 @@ +/* + * Code to emulate SCI interrupt for Hotplug node insertion/removal + */ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/uaccess.h> +#include <linux/debugfs.h> +#include <acpi/acpi_drivers.h> + +#include "internal.h" + +#include "acpica/accommon.h" +#include "acpica/acnamesp.h" +#include "acpica/acevents.h" + +#define _COMPONENT ACPI_SYSTEM_COMPONENT +ACPI_MODULE_NAME("sci_emu"); +MODULE_LICENSE("GPL"); + +static struct dentry *sci_notify_dentry; + +static void sci_notify_client(char *acpi_name, u32 event) +{ + struct acpi_namespace_node *node; + acpi_status status, status1; + acpi_handle hlsb, hsb; + union acpi_operand_object *obj_desc; + + status = acpi_get_handle(NULL, "\\_SB", &hsb); + status1 = acpi_get_handle(hsb, acpi_name, &hlsb); + if (ACPI_FAILURE(status) || ACPI_FAILURE(status1)) { + pr_err(PREFIX + "acpi getting handle to <\\_SB.%s> failed inside notify_client\n", + acpi_name); + return; + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + pr_err(PREFIX "Acquiring acpi namespace mutext failed\n"); + return; + } + + node = acpi_ns_validate_handle(hlsb); + if (!node) { + acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + pr_err(PREFIX "Mapping handle to node failed\n"); + return; + } + + /* + * Check for internal object and make sure there is a handler + * registered for this object + */ + obj_desc = acpi_ns_get_attached_object(node); + if (obj_desc) { + if (((event <= ACPI_MAX_SYS_NOTIFY) && + obj_desc->common_notify.notify_list[ACPI_SYSTEM_HANDLER_LIST]) || + (((event > ACPI_MAX_SYS_NOTIFY) && + obj_desc->common_notify.notify_list[ACPI_DEVICE_HANDLER_LIST]))) { + /* + * Release the lock and queue the item for later + * exectuion + */ + acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + status = acpi_ev_queue_notify_request(node, event); + if (ACPI_FAILURE(status)) + pr_err(PREFIX "acpi_ev_queue_notify_request failed\n"); + else + pr_info(PREFIX "Notify event is queued\n"); + return; + } + } else { + pr_info(PREFIX "Notify handler not registered for this device\n"); + } + + acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return; +} + +static ssize_t sci_notify_write(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ + u32 event; + char *name1 = NULL; + char *name2 = NULL; + const char *delim = " "; + char *temp_buf = NULL; + char *temp_buf_addr = NULL; + + temp_buf = kmalloc(count+1, GFP_ATOMIC); + if (!temp_buf) { + pr_warn(PREFIX "sci_notify_wire: Memory allocation failed\n"); + return count; + } + temp_buf[count] = '\0'; + temp_buf_addr = temp_buf; + if (copy_from_user(temp_buf, user_buf, count)) + goto out; + + name1 = strsep(&temp_buf, delim); + name2 = strsep(&temp_buf, delim); + + if (name1 && name2) { + ssize_t ret; + unsigned long val; + + ret = kstrtoul(name2, 10, &val); + if (ret) { + pr_warn(PREFIX "unknown event\n"); + goto out; + } + + event = (u32)val; + } else { + pr_warn(PREFIX "unknown device\n"); + goto out; + } + + pr_info(PREFIX "ACPI device name is <%s>, event code is <%d>\n", + name1, event); + + sci_notify_client(name1, event); + +out: + kfree(temp_buf_addr); + return count; +} + +static const struct file_operations sci_notify_fops = { + .write = sci_notify_write, +}; + +static int __init acpi_sci_notify_init(void) +{ + if (acpi_debugfs_dir == NULL) + return -ENOENT; + + sci_notify_dentry = debugfs_create_file("sci_notify", S_IWUSR, + acpi_debugfs_dir, NULL, &sci_notify_fops); + if (sci_notify_dentry == NULL) + return -ENODEV; + + return 0; +} + +device_initcall(acpi_sci_notify_init); diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index d67a1fe07f0e..4613e8f08c74 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -191,6 +191,27 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) } break; + case ACPI_MADT_TYPE_GENERIC_INTERRUPT: + { + struct acpi_madt_generic_interrupt *p = + (struct acpi_madt_generic_interrupt *)header; + printk(KERN_INFO PREFIX + "GIC (acpi_id[0x%04x] gic_id[0x%04x] %s)\n", + p->uid, p->gic_id, + (p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + } + break; + + case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: + { + struct acpi_madt_generic_distributor *p = + (struct acpi_madt_generic_distributor *)header; + printk(KERN_INFO PREFIX + "GIC Distributor (id[0x%04x] address[0x%08llx] gsi_base[%d])\n", + p->gic_id, p->base_address, p->global_irq_base); + } + break; + default: printk(KERN_WARNING PREFIX "Found unsupported MADT entry (type = 0x%x)\n", diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 552248b0005b..fc2cd3284080 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -169,11 +169,20 @@ acpi_extract_package(union acpi_object *package, /* * Validate output buffer. */ - if (buffer->length < size_required) { + if (buffer->length == ACPI_ALLOCATE_BUFFER) { + buffer->pointer = ACPI_ALLOCATE(size_required); + if (!buffer->pointer) + return AE_NO_MEMORY; buffer->length = size_required; - return AE_BUFFER_OVERFLOW; - } else if (buffer->length != size_required || !buffer->pointer) { - return AE_BAD_PARAMETER; + memset(buffer->pointer, 0, size_required); + } else { + if (buffer->length < size_required) { + buffer->length = size_required; + return AE_BUFFER_OVERFLOW; + } else if (buffer->length != size_required || + !buffer->pointer) { + return AE_BAD_PARAMETER; + } } head = buffer->pointer; diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 9031171c141b..039b4a0a51ed 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -957,6 +957,10 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, if (WARN_ON(!gic->domain)) return; +#ifdef CONFIG_ACPI + irq_set_default_host(gic->domain); +#endif + #ifdef CONFIG_SMP set_smp_cross_call(gic_raise_softirq); register_cpu_notifier(&gic_cpu_notifier); diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 73be7f3982e6..7aa517da6da7 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -82,6 +82,7 @@ static const char version[] = #include <linux/mii.h> #include <linux/workqueue.h> #include <linux/of.h> +#include <linux/acpi.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> @@ -2384,6 +2385,14 @@ static const struct of_device_id smc91x_match[] = { MODULE_DEVICE_TABLE(of, smc91x_match); #endif +#ifdef CONFIG_ACPI +static const struct acpi_device_id smc91x_acpi_match[] = { + { "LINA0003", }, + { } +}; +MODULE_DEVICE_TABLE(acpi, smc91x_acpi_match); +#endif + static struct dev_pm_ops smc_drv_pm_ops = { .suspend = smc_drv_suspend, .resume = smc_drv_resume, @@ -2397,6 +2406,7 @@ static struct platform_driver smc_driver = { .owner = THIS_MODULE, .pm = &smc_drv_pm_ops, .of_match_table = of_match_ptr(smc91x_match), + .acpi_match_table = ACPI_PTR(smc91x_acpi_match), }, }; diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 229dd9d69e18..d1d17e05bf3d 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -785,6 +785,42 @@ void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align) } #endif +#if (defined(CONFIG_ARM64) || defined (CONFIG_ARM)) && defined(CONFIG_ACPI) +#include <linux/memblock.h> +#include <linux/acpi.h> +#include <asm/acpi.h> +#include <acpi/actbl.h> + +int __init early_init_dt_scan_acpi(unsigned long node, const char *uname, + int depth, void *data) +{ + unsigned long l; + unsigned int *p; + struct acpi_arm_root *pinfo; + unsigned char *sig; + + pr_debug("search \"chosen\" for acpi info, depth: %d, uname: %s\n", + depth, uname); + + if (depth != 1 || !data || + (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) + return 0; + + /* Retrieve acpi,address line */ + pinfo = (struct acpi_arm_root *)data; + p = of_get_flat_dt_prop(node, "linux,acpi-start", &l); + if (p) + pinfo->phys_address = of_read_ulong(p, l/4); + + /* Retrieve acpi,size line */ + p = of_get_flat_dt_prop(node, "linux,acpi-len", &l); + if (p) + pinfo->size = of_read_ulong(p, l/4); + + return 1; +} +#endif + /** * unflatten_device_tree - create tree of device_nodes from flat blob * diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 167f3d00c916..5804e7762d3a 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -113,8 +113,10 @@ static int dma_flags(struct pnp_dev *dev, int type, int bus_master, static void pnpacpi_add_irqresource(struct pnp_dev *dev, struct resource *r) { +#ifdef CONFIG_PCI if (!(r->flags & IORESOURCE_DISABLED)) pcibios_penalize_isa_irq(r->start, 1); +#endif pnp_add_resource(dev, r); } diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 1ba0d6831015..81d539f11783 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -100,8 +100,7 @@ #include <linux/virtio_config.h> #include <linux/virtio_mmio.h> #include <linux/virtio_ring.h> - - +#include <linux/acpi.h> /* The alignment to use between consumer and producer parts of vring. * Currently hardcoded to the page size. */ @@ -636,6 +635,15 @@ static struct of_device_id virtio_mmio_match[] = { }; MODULE_DEVICE_TABLE(of, virtio_mmio_match); +#ifdef CONFIG_ACPI +static const struct acpi_device_id virtio_mmio_acpi_match[] = { + { "LINA0005", }, + { } +}; +MODULE_DEVICE_TABLE(acpi, virtio_mmio_acpi_match); +#endif + + static struct platform_driver virtio_mmio_driver = { .probe = virtio_mmio_probe, .remove = virtio_mmio_remove, @@ -643,6 +651,7 @@ static struct platform_driver virtio_mmio_driver = { .name = "virtio-mmio", .owner = THIS_MODULE, .of_match_table = virtio_mmio_match, + .acpi_match_table = ACPI_PTR(virtio_mmio_acpi_match), }, }; diff --git a/include/acpi/apei.h b/include/acpi/apei.h index 04f349d8da73..b6398913b2d6 100644 --- a/include/acpi/apei.h +++ b/include/acpi/apei.h @@ -23,6 +23,7 @@ extern bool ghes_disable; #else #define ghes_disable 1 #endif +extern int bert_disable; #ifdef CONFIG_ACPI_APEI void __init acpi_hest_init(void); diff --git a/include/acpi/pdc_arm.h b/include/acpi/pdc_arm.h new file mode 100644 index 000000000000..ac8f197f82ff --- /dev/null +++ b/include/acpi/pdc_arm.h @@ -0,0 +1,39 @@ + +/* _PDC bit definition for ARMv7 processors */ + +#ifndef __PDC_ARM_H__ +#define __PDC_ARM_H__ + +/* BOZO: is this even necessary? */ + +/* _PDC bit definition for ARM processors */ + +#define ACPI_PDC_P_FFH (0x0001) +#define ACPI_PDC_C_C1_HALT (0x0002) +#define ACPI_PDC_T_FFH (0x0004) +#define ACPI_PDC_SMP_C1PT (0x0008) +#define ACPI_PDC_SMP_C2C3 (0x0010) +#define ACPI_PDC_SMP_P_SWCOORD (0x0020) +#define ACPI_PDC_SMP_C_SWCOORD (0x0040) +#define ACPI_PDC_SMP_T_SWCOORD (0x0080) +#define ACPI_PDC_C_C1_FFH (0x0100) +#define ACPI_PDC_C_C2C3_FFH (0x0200) +#define ACPI_PDC_SMP_P_HWCOORD (0x0800) + +#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ + ACPI_PDC_C_C1_HALT | \ + ACPI_PDC_P_FFH) + +#define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \ + ACPI_PDC_C_C1_HALT | \ + ACPI_PDC_SMP_P_SWCOORD | \ + ACPI_PDC_SMP_P_HWCOORD | \ + ACPI_PDC_P_FFH) + +#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ + ACPI_PDC_SMP_C1PT | \ + ACPI_PDC_C_C1_HALT | \ + ACPI_PDC_C_C1_FFH | \ + ACPI_PDC_C_C2C3_FFH) + +#endif /* __PDC_ARM_H__ */ diff --git a/include/acpi/pdc_arm64.h b/include/acpi/pdc_arm64.h new file mode 100644 index 000000000000..ac8f197f82ff --- /dev/null +++ b/include/acpi/pdc_arm64.h @@ -0,0 +1,39 @@ + +/* _PDC bit definition for ARMv7 processors */ + +#ifndef __PDC_ARM_H__ +#define __PDC_ARM_H__ + +/* BOZO: is this even necessary? */ + +/* _PDC bit definition for ARM processors */ + +#define ACPI_PDC_P_FFH (0x0001) +#define ACPI_PDC_C_C1_HALT (0x0002) +#define ACPI_PDC_T_FFH (0x0004) +#define ACPI_PDC_SMP_C1PT (0x0008) +#define ACPI_PDC_SMP_C2C3 (0x0010) +#define ACPI_PDC_SMP_P_SWCOORD (0x0020) +#define ACPI_PDC_SMP_C_SWCOORD (0x0040) +#define ACPI_PDC_SMP_T_SWCOORD (0x0080) +#define ACPI_PDC_C_C1_FFH (0x0100) +#define ACPI_PDC_C_C2C3_FFH (0x0200) +#define ACPI_PDC_SMP_P_HWCOORD (0x0800) + +#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ + ACPI_PDC_C_C1_HALT | \ + ACPI_PDC_P_FFH) + +#define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \ + ACPI_PDC_C_C1_HALT | \ + ACPI_PDC_SMP_P_SWCOORD | \ + ACPI_PDC_SMP_P_HWCOORD | \ + ACPI_PDC_P_FFH) + +#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ + ACPI_PDC_SMP_C1PT | \ + ACPI_PDC_C_C1_HALT | \ + ACPI_PDC_C_C1_FFH | \ + ACPI_PDC_C_C2C3_FFH) + +#endif /* __PDC_ARM_H__ */ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index a5db4aeefa36..6324f8bf8997 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -49,6 +49,7 @@ enum acpi_irq_model_id { ACPI_IRQ_MODEL_IOAPIC, ACPI_IRQ_MODEL_IOSAPIC, ACPI_IRQ_MODEL_PLATFORM, + ACPI_IRQ_MODEL_GIC, ACPI_IRQ_MODEL_COUNT }; @@ -87,7 +88,7 @@ static inline void acpi_initrd_override(void *data, size_t size) } #endif -char * __acpi_map_table (unsigned long phys_addr, unsigned long size); +char *__acpi_map_table(phys_addr_t phys_addr, unsigned long size); void __acpi_unmap_table(char *map, unsigned long size); int early_acpi_boot_init(void); int acpi_boot_init (void); diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index a478c62a2aab..d1ec52ff9151 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -96,6 +96,10 @@ extern int of_scan_flat_dt_by_path(const char *path, extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, int depth, void *data); +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) +extern int early_init_dt_scan_acpi(unsigned long node, const char *uname, + int depth, void *data); +#endif extern void early_init_dt_check_for_initrd(unsigned long node); extern int early_init_dt_scan_memory(unsigned long node, const char *uname, int depth, void *data); diff --git a/linaro/configs/acpi.conf b/linaro/configs/acpi.conf new file mode 100644 index 000000000000..2005afabe4c8 --- /dev/null +++ b/linaro/configs/acpi.conf @@ -0,0 +1,21 @@ +# +# Power management and ACPI options +# +CONFIG_ACPI_ARM=y +CONFIG_ACPI=y +CONFIG_ACPI_EC_DEBUGFS=y +CONFIG_ACPI_AC=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_PROCESSOR_AGGREGATOR=y +CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_BLACKLIST_YEAR=0 +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_CONTAINER=y +CONFIG_ACPI_SBS=y +CONFIG_ACPI_HED=y + |