aboutsummaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorGraeme Gregory <graeme.gregory@linaro.org>2013-10-23 16:07:20 +0100
committerGraeme Gregory <graeme.gregory@linaro.org>2013-10-24 01:46:57 +0100
commit84a982e37e9f76c5632f23726cca2cd4826f2c20 (patch)
treed5568bc1c2a6c3398975ed5c5c8c89abdbc7cb46 /arch/arm
parent1857c8849bf548ba9c696a2b6d8188eb7ae753e2 (diff)
parentf9de2a656b3d170e0f385ea9566ff27e21466f55 (diff)
Merge branch 'acpi' of git://git.linaro.org/arm/acpi/acpi into leg-kernelleg-20131023.1
Conflicts: arch/arm/Kconfig arch/arm/include/asm/io.h arch/arm/kernel/setup.c arch/arm/mm/early_ioremap.c arch/arm/mm/mmu.c arch/arm64/Kconfig arch/arm64/include/asm/io.h arch/arm64/kernel/setup.c arch/arm64/mm/ioremap.c
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/include/asm/acpi.h163
-rw-r--r--arch/arm/include/asm/cpu.h6
-rw-r--r--arch/arm/include/asm/fixmap.h2
-rw-r--r--arch/arm/include/asm/io.h7
-rw-r--r--arch/arm/include/asm/processor.h13
-rw-r--r--arch/arm/include/asm/topology.h2
-rw-r--r--arch/arm/kernel/devtree.c7
-rw-r--r--arch/arm/kernel/process.c8
-rw-r--r--arch/arm/kernel/setup.c31
-rw-r--r--arch/arm/kernel/topology.c50
11 files changed, 275 insertions, 18 deletions
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);
+