diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2011-10-20 11:57:46 -0400 |
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2011-10-20 11:57:46 -0400 |
| commit | fcd467137ea2da46ffe5cbfdb42e8a2b35f13dad (patch) | |
| tree | 9d8336ee0fba2fade8b5a7d07011e74294256838 | |
| parent | bda2487997c3b7828a3765e7f2c37fdd6b7bdcbe (diff) | |
| parent | 5a567d78c437e3be1c512734cdfe64b4ae6b82d7 (diff) | |
Merge branch 'depends/rmk/smp' into tmp
| -rw-r--r-- | arch/arm/Kconfig | 25 | ||||
| -rw-r--r-- | arch/arm/common/gic.c | 17 | ||||
| -rw-r--r-- | arch/arm/include/asm/cputype.h | 6 | ||||
| -rw-r--r-- | arch/arm/include/asm/exception.h | 19 | ||||
| -rw-r--r-- | arch/arm/include/asm/localtimer.h | 4 | ||||
| -rw-r--r-- | arch/arm/include/asm/smp.h | 11 | ||||
| -rw-r--r-- | arch/arm/include/asm/system.h | 7 | ||||
| -rw-r--r-- | arch/arm/include/asm/topology.h | 33 | ||||
| -rw-r--r-- | arch/arm/kernel/Makefile | 1 | ||||
| -rw-r--r-- | arch/arm/kernel/irq.c | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/smp.c | 32 | ||||
| -rw-r--r-- | arch/arm/kernel/smp_scu.c | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/topology.c | 148 | ||||
| -rw-r--r-- | arch/arm/kernel/traps.c | 1 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/irq.c | 2 | ||||
| -rw-r--r-- | arch/arm/mm/fault.c | 1 |
16 files changed, 298 insertions, 13 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3146ed3f6eca..0d21f79b2fed 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -1407,6 +1407,31 @@ config SMP_ON_UP | |||
| 1407 | 1407 | ||
| 1408 | If you don't know what to do here, say Y. | 1408 | If you don't know what to do here, say Y. |
| 1409 | 1409 | ||
| 1410 | config ARM_CPU_TOPOLOGY | ||
| 1411 | bool "Support cpu topology definition" | ||
| 1412 | depends on SMP && CPU_V7 | ||
| 1413 | default y | ||
| 1414 | help | ||
| 1415 | Support ARM cpu topology definition. The MPIDR register defines | ||
| 1416 | affinity between processors which is then used to describe the cpu | ||
| 1417 | topology of an ARM System. | ||
| 1418 | |||
| 1419 | config SCHED_MC | ||
| 1420 | bool "Multi-core scheduler support" | ||
| 1421 | depends on ARM_CPU_TOPOLOGY | ||
| 1422 | help | ||
| 1423 | Multi-core scheduler support improves the CPU scheduler's decision | ||
| 1424 | making when dealing with multi-core CPU chips at a cost of slightly | ||
| 1425 | increased overhead in some places. If unsure say N here. | ||
| 1426 | |||
| 1427 | config SCHED_SMT | ||
| 1428 | bool "SMT scheduler support" | ||
| 1429 | depends on ARM_CPU_TOPOLOGY | ||
| 1430 | help | ||
| 1431 | Improves the CPU scheduler's decision making when dealing with | ||
| 1432 | MultiThreading at a cost of slightly increased overhead in some | ||
| 1433 | places. If unsure say N here. | ||
| 1434 | |||
| 1410 | config HAVE_ARM_SCU | 1435 | config HAVE_ARM_SCU |
| 1411 | bool | 1436 | bool |
| 1412 | help | 1437 | help |
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 3227ca952a12..666b278e56d7 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
| @@ -180,7 +180,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, | |||
| 180 | return -EINVAL; | 180 | return -EINVAL; |
| 181 | 181 | ||
| 182 | mask = 0xff << shift; | 182 | mask = 0xff << shift; |
| 183 | bit = 1 << (cpu + shift); | 183 | bit = 1 << (cpu_logical_map(cpu) + shift); |
| 184 | 184 | ||
| 185 | spin_lock(&irq_controller_lock); | 185 | spin_lock(&irq_controller_lock); |
| 186 | val = readl_relaxed(reg) & ~mask; | 186 | val = readl_relaxed(reg) & ~mask; |
| @@ -259,9 +259,15 @@ static void __init gic_dist_init(struct gic_chip_data *gic, | |||
| 259 | unsigned int irq_start) | 259 | unsigned int irq_start) |
| 260 | { | 260 | { |
| 261 | unsigned int gic_irqs, irq_limit, i; | 261 | unsigned int gic_irqs, irq_limit, i; |
| 262 | u32 cpumask; | ||
| 262 | void __iomem *base = gic->dist_base; | 263 | void __iomem *base = gic->dist_base; |
| 263 | u32 cpumask = 1 << smp_processor_id(); | 264 | u32 cpu = 0; |
| 264 | 265 | ||
| 266 | #ifdef CONFIG_SMP | ||
| 267 | cpu = cpu_logical_map(smp_processor_id()); | ||
| 268 | #endif | ||
| 269 | |||
| 270 | cpumask = 1 << cpu; | ||
| 265 | cpumask |= cpumask << 8; | 271 | cpumask |= cpumask << 8; |
| 266 | cpumask |= cpumask << 16; | 272 | cpumask |= cpumask << 16; |
| 267 | 273 | ||
| @@ -382,7 +388,12 @@ void __cpuinit gic_enable_ppi(unsigned int irq) | |||
| 382 | #ifdef CONFIG_SMP | 388 | #ifdef CONFIG_SMP |
| 383 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | 389 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) |
| 384 | { | 390 | { |
| 385 | unsigned long map = *cpus_addr(*mask); | 391 | int cpu; |
| 392 | unsigned long map = 0; | ||
| 393 | |||
| 394 | /* Convert our logical CPU mask into a physical one. */ | ||
| 395 | for_each_cpu(cpu, mask) | ||
| 396 | map |= 1 << cpu_logical_map(cpu); | ||
| 386 | 397 | ||
| 387 | /* | 398 | /* |
| 388 | * Ensure that stores to Normal memory are visible to the | 399 | * Ensure that stores to Normal memory are visible to the |
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index cd4458f64171..cb47d28cbe1f 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #define CPUID_CACHETYPE 1 | 8 | #define CPUID_CACHETYPE 1 |
| 9 | #define CPUID_TCM 2 | 9 | #define CPUID_TCM 2 |
| 10 | #define CPUID_TLBTYPE 3 | 10 | #define CPUID_TLBTYPE 3 |
| 11 | #define CPUID_MPIDR 5 | ||
| 11 | 12 | ||
| 12 | #define CPUID_EXT_PFR0 "c1, 0" | 13 | #define CPUID_EXT_PFR0 "c1, 0" |
| 13 | #define CPUID_EXT_PFR1 "c1, 1" | 14 | #define CPUID_EXT_PFR1 "c1, 1" |
| @@ -70,6 +71,11 @@ static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void) | |||
| 70 | return read_cpuid(CPUID_TCM); | 71 | return read_cpuid(CPUID_TCM); |
| 71 | } | 72 | } |
| 72 | 73 | ||
| 74 | static inline unsigned int __attribute_const__ read_cpuid_mpidr(void) | ||
| 75 | { | ||
| 76 | return read_cpuid(CPUID_MPIDR); | ||
| 77 | } | ||
| 78 | |||
| 73 | /* | 79 | /* |
| 74 | * Intel's XScale3 core supports some v6 features (supersections, L2) | 80 | * Intel's XScale3 core supports some v6 features (supersections, L2) |
| 75 | * but advertises itself as v5 as it does not support the v6 ISA. For | 81 | * but advertises itself as v5 as it does not support the v6 ISA. For |
diff --git a/arch/arm/include/asm/exception.h b/arch/arm/include/asm/exception.h new file mode 100644 index 000000000000..5abaf5bbd985 --- /dev/null +++ b/arch/arm/include/asm/exception.h | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* | ||
| 2 | * Annotations for marking C functions as exception handlers. | ||
| 3 | * | ||
| 4 | * These should only be used for C functions that are called from the low | ||
| 5 | * level exception entry code and not any intervening C code. | ||
| 6 | */ | ||
| 7 | #ifndef __ASM_ARM_EXCEPTION_H | ||
| 8 | #define __ASM_ARM_EXCEPTION_H | ||
| 9 | |||
| 10 | #include <linux/ftrace.h> | ||
| 11 | |||
| 12 | #define __exception __attribute__((section(".exception.text"))) | ||
| 13 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 14 | #define __exception_irq_entry __irq_entry | ||
| 15 | #else | ||
| 16 | #define __exception_irq_entry __exception | ||
| 17 | #endif | ||
| 18 | |||
| 19 | #endif /* __ASM_ARM_EXCEPTION_H */ | ||
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h index 080d74f8128d..3306f281333c 100644 --- a/arch/arm/include/asm/localtimer.h +++ b/arch/arm/include/asm/localtimer.h | |||
| @@ -22,6 +22,10 @@ void percpu_timer_setup(void); | |||
| 22 | */ | 22 | */ |
| 23 | asmlinkage void do_local_timer(struct pt_regs *); | 23 | asmlinkage void do_local_timer(struct pt_regs *); |
| 24 | 24 | ||
| 25 | /* | ||
| 26 | * Called from C code | ||
| 27 | */ | ||
| 28 | void handle_local_timer(struct pt_regs *); | ||
| 25 | 29 | ||
| 26 | #ifdef CONFIG_LOCAL_TIMERS | 30 | #ifdef CONFIG_LOCAL_TIMERS |
| 27 | 31 | ||
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index e42d96a45d3e..0a17b62538c2 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h | |||
| @@ -33,6 +33,11 @@ extern void show_ipi_list(struct seq_file *, int); | |||
| 33 | asmlinkage void do_IPI(int ipinr, struct pt_regs *regs); | 33 | asmlinkage void do_IPI(int ipinr, struct pt_regs *regs); |
| 34 | 34 | ||
| 35 | /* | 35 | /* |
| 36 | * Called from C code, this handles an IPI. | ||
| 37 | */ | ||
| 38 | void handle_IPI(int ipinr, struct pt_regs *regs); | ||
| 39 | |||
| 40 | /* | ||
| 36 | * Setup the set of possible CPUs (via set_cpu_possible) | 41 | * Setup the set of possible CPUs (via set_cpu_possible) |
| 37 | */ | 42 | */ |
| 38 | extern void smp_init_cpus(void); | 43 | extern void smp_init_cpus(void); |
| @@ -66,6 +71,12 @@ extern void platform_secondary_init(unsigned int cpu); | |||
| 66 | extern void platform_smp_prepare_cpus(unsigned int); | 71 | extern void platform_smp_prepare_cpus(unsigned int); |
| 67 | 72 | ||
| 68 | /* | 73 | /* |
| 74 | * Logical CPU mapping. | ||
| 75 | */ | ||
| 76 | extern int __cpu_logical_map[NR_CPUS]; | ||
| 77 | #define cpu_logical_map(cpu) __cpu_logical_map[cpu] | ||
| 78 | |||
| 79 | /* | ||
| 69 | * Initial data for bringing up a secondary CPU. | 80 | * Initial data for bringing up a secondary CPU. |
| 70 | */ | 81 | */ |
| 71 | struct secondary_data { | 82 | struct secondary_data { |
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 832888d0c20c..ed6b0499a106 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h | |||
| @@ -62,13 +62,6 @@ | |||
| 62 | 62 | ||
| 63 | #include <asm/outercache.h> | 63 | #include <asm/outercache.h> |
| 64 | 64 | ||
| 65 | #define __exception __attribute__((section(".exception.text"))) | ||
| 66 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 67 | #define __exception_irq_entry __irq_entry | ||
| 68 | #else | ||
| 69 | #define __exception_irq_entry __exception | ||
| 70 | #endif | ||
| 71 | |||
| 72 | struct thread_info; | 65 | struct thread_info; |
| 73 | struct task_struct; | 66 | struct task_struct; |
| 74 | 67 | ||
diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h index accbd7cad9b5..a7e457ed27c3 100644 --- a/arch/arm/include/asm/topology.h +++ b/arch/arm/include/asm/topology.h | |||
| @@ -1,6 +1,39 @@ | |||
| 1 | #ifndef _ASM_ARM_TOPOLOGY_H | 1 | #ifndef _ASM_ARM_TOPOLOGY_H |
| 2 | #define _ASM_ARM_TOPOLOGY_H | 2 | #define _ASM_ARM_TOPOLOGY_H |
| 3 | 3 | ||
| 4 | #ifdef CONFIG_ARM_CPU_TOPOLOGY | ||
| 5 | |||
| 6 | #include <linux/cpumask.h> | ||
| 7 | |||
| 8 | struct cputopo_arm { | ||
| 9 | int thread_id; | ||
| 10 | int core_id; | ||
| 11 | int socket_id; | ||
| 12 | cpumask_t thread_sibling; | ||
| 13 | cpumask_t core_sibling; | ||
| 14 | }; | ||
| 15 | |||
| 16 | extern struct cputopo_arm cpu_topology[NR_CPUS]; | ||
| 17 | |||
| 18 | #define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id) | ||
| 19 | #define topology_core_id(cpu) (cpu_topology[cpu].core_id) | ||
| 20 | #define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling) | ||
| 21 | #define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling) | ||
| 22 | |||
| 23 | #define mc_capable() (cpu_topology[0].socket_id != -1) | ||
| 24 | #define smt_capable() (cpu_topology[0].thread_id != -1) | ||
| 25 | |||
| 26 | void init_cpu_topology(void); | ||
| 27 | void store_cpu_topology(unsigned int cpuid); | ||
| 28 | const struct cpumask *cpu_coregroup_mask(unsigned int cpu); | ||
| 29 | |||
| 30 | #else | ||
| 31 | |||
| 32 | static inline void init_cpu_topology(void) { } | ||
| 33 | static inline void store_cpu_topology(unsigned int cpuid) { } | ||
| 34 | |||
| 35 | #endif | ||
| 36 | |||
| 4 | #include <asm-generic/topology.h> | 37 | #include <asm-generic/topology.h> |
| 5 | 38 | ||
| 6 | #endif /* _ASM_ARM_TOPOLOGY_H */ | 39 | #endif /* _ASM_ARM_TOPOLOGY_H */ |
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index f7887dc53c1f..c687bceba7da 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
| @@ -66,6 +66,7 @@ obj-$(CONFIG_IWMMXT) += iwmmxt.o | |||
| 66 | obj-$(CONFIG_CPU_HAS_PMU) += pmu.o | 66 | obj-$(CONFIG_CPU_HAS_PMU) += pmu.o |
| 67 | obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o | 67 | obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o |
| 68 | AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt | 68 | AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt |
| 69 | obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o | ||
| 69 | 70 | ||
| 70 | ifneq ($(CONFIG_ARCH_EBSA110),y) | 71 | ifneq ($(CONFIG_ARCH_EBSA110),y) |
| 71 | obj-y += io.o | 72 | obj-y += io.o |
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index de3dcab8610b..53919b230e8b 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
| @@ -35,8 +35,8 @@ | |||
| 35 | #include <linux/list.h> | 35 | #include <linux/list.h> |
| 36 | #include <linux/kallsyms.h> | 36 | #include <linux/kallsyms.h> |
| 37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
| 38 | #include <linux/ftrace.h> | ||
| 39 | 38 | ||
| 39 | #include <asm/exception.h> | ||
| 40 | #include <asm/system.h> | 40 | #include <asm/system.h> |
| 41 | #include <asm/mach/arch.h> | 41 | #include <asm/mach/arch.h> |
| 42 | #include <asm/mach/irq.h> | 42 | #include <asm/mach/irq.h> |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index d88ff0230e82..35417d0fb8ab 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include <linux/cache.h> | 16 | #include <linux/cache.h> |
| 17 | #include <linux/profile.h> | 17 | #include <linux/profile.h> |
| 18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
| 19 | #include <linux/ftrace.h> | ||
| 20 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
| 21 | #include <linux/err.h> | 20 | #include <linux/err.h> |
| 22 | #include <linux/cpu.h> | 21 | #include <linux/cpu.h> |
| @@ -31,6 +30,8 @@ | |||
| 31 | #include <asm/cacheflush.h> | 30 | #include <asm/cacheflush.h> |
| 32 | #include <asm/cpu.h> | 31 | #include <asm/cpu.h> |
| 33 | #include <asm/cputype.h> | 32 | #include <asm/cputype.h> |
| 33 | #include <asm/exception.h> | ||
| 34 | #include <asm/topology.h> | ||
| 34 | #include <asm/mmu_context.h> | 35 | #include <asm/mmu_context.h> |
| 35 | #include <asm/pgtable.h> | 36 | #include <asm/pgtable.h> |
| 36 | #include <asm/pgalloc.h> | 37 | #include <asm/pgalloc.h> |
| @@ -39,6 +40,7 @@ | |||
| 39 | #include <asm/tlbflush.h> | 40 | #include <asm/tlbflush.h> |
| 40 | #include <asm/ptrace.h> | 41 | #include <asm/ptrace.h> |
| 41 | #include <asm/localtimer.h> | 42 | #include <asm/localtimer.h> |
| 43 | #include <asm/smp_plat.h> | ||
| 42 | 44 | ||
| 43 | /* | 45 | /* |
| 44 | * as from 2.5, kernels no longer have an init_tasks structure | 46 | * as from 2.5, kernels no longer have an init_tasks structure |
| @@ -259,6 +261,20 @@ void __ref cpu_die(void) | |||
| 259 | } | 261 | } |
| 260 | #endif /* CONFIG_HOTPLUG_CPU */ | 262 | #endif /* CONFIG_HOTPLUG_CPU */ |
| 261 | 263 | ||
| 264 | int __cpu_logical_map[NR_CPUS]; | ||
| 265 | |||
| 266 | void __init smp_setup_processor_id(void) | ||
| 267 | { | ||
| 268 | int i; | ||
| 269 | u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0; | ||
| 270 | |||
| 271 | cpu_logical_map(0) = cpu; | ||
| 272 | for (i = 1; i < NR_CPUS; ++i) | ||
| 273 | cpu_logical_map(i) = i == cpu ? 0 : i; | ||
| 274 | |||
| 275 | printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu); | ||
| 276 | } | ||
| 277 | |||
| 262 | /* | 278 | /* |
| 263 | * Called by both boot and secondaries to move global data into | 279 | * Called by both boot and secondaries to move global data into |
| 264 | * per-processor storage. | 280 | * per-processor storage. |
| @@ -268,6 +284,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid) | |||
| 268 | struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid); | 284 | struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid); |
| 269 | 285 | ||
| 270 | cpu_info->loops_per_jiffy = loops_per_jiffy; | 286 | cpu_info->loops_per_jiffy = loops_per_jiffy; |
| 287 | |||
| 288 | store_cpu_topology(cpuid); | ||
| 271 | } | 289 | } |
| 272 | 290 | ||
| 273 | /* | 291 | /* |
| @@ -358,6 +376,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
| 358 | { | 376 | { |
| 359 | unsigned int ncores = num_possible_cpus(); | 377 | unsigned int ncores = num_possible_cpus(); |
| 360 | 378 | ||
| 379 | init_cpu_topology(); | ||
| 380 | |||
| 361 | smp_store_cpu_info(smp_processor_id()); | 381 | smp_store_cpu_info(smp_processor_id()); |
| 362 | 382 | ||
| 363 | /* | 383 | /* |
| @@ -460,6 +480,11 @@ static void ipi_timer(void) | |||
| 460 | #ifdef CONFIG_LOCAL_TIMERS | 480 | #ifdef CONFIG_LOCAL_TIMERS |
| 461 | asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) | 481 | asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) |
| 462 | { | 482 | { |
| 483 | handle_local_timer(regs); | ||
| 484 | } | ||
| 485 | |||
| 486 | void handle_local_timer(struct pt_regs *regs) | ||
| 487 | { | ||
| 463 | struct pt_regs *old_regs = set_irq_regs(regs); | 488 | struct pt_regs *old_regs = set_irq_regs(regs); |
| 464 | int cpu = smp_processor_id(); | 489 | int cpu = smp_processor_id(); |
| 465 | 490 | ||
| @@ -567,6 +592,11 @@ static void ipi_cpu_stop(unsigned int cpu) | |||
| 567 | */ | 592 | */ |
| 568 | asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) | 593 | asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) |
| 569 | { | 594 | { |
| 595 | handle_IPI(ipinr, regs); | ||
| 596 | } | ||
| 597 | |||
| 598 | void handle_IPI(int ipinr, struct pt_regs *regs) | ||
| 599 | { | ||
| 570 | unsigned int cpu = smp_processor_id(); | 600 | unsigned int cpu = smp_processor_id(); |
| 571 | struct pt_regs *old_regs = set_irq_regs(regs); | 601 | struct pt_regs *old_regs = set_irq_regs(regs); |
| 572 | 602 | ||
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c index 7fcddb75c877..8f5dd7963356 100644 --- a/arch/arm/kernel/smp_scu.c +++ b/arch/arm/kernel/smp_scu.c | |||
| @@ -34,7 +34,7 @@ unsigned int __init scu_get_core_count(void __iomem *scu_base) | |||
| 34 | /* | 34 | /* |
| 35 | * Enable the SCU | 35 | * Enable the SCU |
| 36 | */ | 36 | */ |
| 37 | void __init scu_enable(void __iomem *scu_base) | 37 | void scu_enable(void __iomem *scu_base) |
| 38 | { | 38 | { |
| 39 | u32 scu_ctrl; | 39 | u32 scu_ctrl; |
| 40 | 40 | ||
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c new file mode 100644 index 000000000000..1040c00405d0 --- /dev/null +++ b/arch/arm/kernel/topology.c | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/kernel/topology.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 Linaro Limited. | ||
| 5 | * Written by: Vincent Guittot | ||
| 6 | * | ||
| 7 | * based on arch/sh/kernel/topology.c | ||
| 8 | * | ||
| 9 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 10 | * License. See the file "COPYING" in the main directory of this archive | ||
| 11 | * for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/cpu.h> | ||
| 15 | #include <linux/cpumask.h> | ||
| 16 | #include <linux/init.h> | ||
| 17 | #include <linux/percpu.h> | ||
| 18 | #include <linux/node.h> | ||
| 19 | #include <linux/nodemask.h> | ||
| 20 | #include <linux/sched.h> | ||
| 21 | |||
| 22 | #include <asm/cputype.h> | ||
| 23 | #include <asm/topology.h> | ||
| 24 | |||
| 25 | #define MPIDR_SMP_BITMASK (0x3 << 30) | ||
| 26 | #define MPIDR_SMP_VALUE (0x2 << 30) | ||
| 27 | |||
| 28 | #define MPIDR_MT_BITMASK (0x1 << 24) | ||
| 29 | |||
| 30 | /* | ||
| 31 | * These masks reflect the current use of the affinity levels. | ||
| 32 | * The affinity level can be up to 16 bits according to ARM ARM | ||
| 33 | */ | ||
| 34 | |||
| 35 | #define MPIDR_LEVEL0_MASK 0x3 | ||
| 36 | #define MPIDR_LEVEL0_SHIFT 0 | ||
| 37 | |||
| 38 | #define MPIDR_LEVEL1_MASK 0xF | ||
| 39 | #define MPIDR_LEVEL1_SHIFT 8 | ||
| 40 | |||
| 41 | #define MPIDR_LEVEL2_MASK 0xFF | ||
| 42 | #define MPIDR_LEVEL2_SHIFT 16 | ||
| 43 | |||
| 44 | struct cputopo_arm cpu_topology[NR_CPUS]; | ||
| 45 | |||
| 46 | const struct cpumask *cpu_coregroup_mask(unsigned int cpu) | ||
| 47 | { | ||
| 48 | return &cpu_topology[cpu].core_sibling; | ||
| 49 | } | ||
| 50 | |||
| 51 | /* | ||
| 52 | * store_cpu_topology is called at boot when only one cpu is running | ||
| 53 | * and with the mutex cpu_hotplug.lock locked, when several cpus have booted, | ||
| 54 | * which prevents simultaneous write access to cpu_topology array | ||
| 55 | */ | ||
| 56 | void store_cpu_topology(unsigned int cpuid) | ||
| 57 | { | ||
| 58 | struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid]; | ||
| 59 | unsigned int mpidr; | ||
| 60 | unsigned int cpu; | ||
| 61 | |||
| 62 | /* If the cpu topology has been already set, just return */ | ||
| 63 | if (cpuid_topo->core_id != -1) | ||
| 64 | return; | ||
| 65 | |||
| 66 | mpidr = read_cpuid_mpidr(); | ||
| 67 | |||
| 68 | /* create cpu topology mapping */ | ||
| 69 | if ((mpidr & MPIDR_SMP_BITMASK) == MPIDR_SMP_VALUE) { | ||
| 70 | /* | ||
| 71 | * This is a multiprocessor system | ||
| 72 | * multiprocessor format & multiprocessor mode field are set | ||
| 73 | */ | ||
| 74 | |||
| 75 | if (mpidr & MPIDR_MT_BITMASK) { | ||
| 76 | /* core performance interdependency */ | ||
| 77 | cpuid_topo->thread_id = (mpidr >> MPIDR_LEVEL0_SHIFT) | ||
| 78 | & MPIDR_LEVEL0_MASK; | ||
| 79 | cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL1_SHIFT) | ||
| 80 | & MPIDR_LEVEL1_MASK; | ||
| 81 | cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL2_SHIFT) | ||
| 82 | & MPIDR_LEVEL2_MASK; | ||
| 83 | } else { | ||
| 84 | /* largely independent cores */ | ||
| 85 | cpuid_topo->thread_id = -1; | ||
| 86 | cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL0_SHIFT) | ||
| 87 | & MPIDR_LEVEL0_MASK; | ||
| 88 | cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL1_SHIFT) | ||
| 89 | & MPIDR_LEVEL1_MASK; | ||
| 90 | } | ||
| 91 | } else { | ||
| 92 | /* | ||
| 93 | * This is an uniprocessor system | ||
| 94 | * we are in multiprocessor format but uniprocessor system | ||
| 95 | * or in the old uniprocessor format | ||
| 96 | */ | ||
| 97 | cpuid_topo->thread_id = -1; | ||
| 98 | cpuid_topo->core_id = 0; | ||
| 99 | cpuid_topo->socket_id = -1; | ||
| 100 | } | ||
| 101 | |||
| 102 | /* update core and thread sibling masks */ | ||
| 103 | for_each_possible_cpu(cpu) { | ||
| 104 | struct cputopo_arm *cpu_topo = &cpu_topology[cpu]; | ||
| 105 | |||
| 106 | if (cpuid_topo->socket_id == cpu_topo->socket_id) { | ||
| 107 | cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); | ||
| 108 | if (cpu != cpuid) | ||
| 109 | cpumask_set_cpu(cpu, | ||
| 110 | &cpuid_topo->core_sibling); | ||
| 111 | |||
| 112 | if (cpuid_topo->core_id == cpu_topo->core_id) { | ||
| 113 | cpumask_set_cpu(cpuid, | ||
| 114 | &cpu_topo->thread_sibling); | ||
| 115 | if (cpu != cpuid) | ||
| 116 | cpumask_set_cpu(cpu, | ||
| 117 | &cpuid_topo->thread_sibling); | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
| 121 | smp_wmb(); | ||
| 122 | |||
| 123 | printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", | ||
| 124 | cpuid, cpu_topology[cpuid].thread_id, | ||
| 125 | cpu_topology[cpuid].core_id, | ||
| 126 | cpu_topology[cpuid].socket_id, mpidr); | ||
| 127 | } | ||
| 128 | |||
| 129 | /* | ||
| 130 | * init_cpu_topology is called at boot when only one cpu is running | ||
| 131 | * which prevent simultaneous write access to cpu_topology array | ||
| 132 | */ | ||
| 133 | void init_cpu_topology(void) | ||
| 134 | { | ||
| 135 | unsigned int cpu; | ||
| 136 | |||
| 137 | /* init core mask */ | ||
| 138 | for_each_possible_cpu(cpu) { | ||
| 139 | struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]); | ||
| 140 | |||
| 141 | cpu_topo->thread_id = -1; | ||
| 142 | cpu_topo->core_id = -1; | ||
| 143 | cpu_topo->socket_id = -1; | ||
| 144 | cpumask_clear(&cpu_topo->core_sibling); | ||
| 145 | cpumask_clear(&cpu_topo->thread_sibling); | ||
| 146 | } | ||
| 147 | smp_wmb(); | ||
| 148 | } | ||
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index bc9f9da782cb..210382555af1 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | #include <linux/atomic.h> | 28 | #include <linux/atomic.h> |
| 29 | #include <asm/cacheflush.h> | 29 | #include <asm/cacheflush.h> |
| 30 | #include <asm/exception.h> | ||
| 30 | #include <asm/system.h> | 31 | #include <asm/system.h> |
| 31 | #include <asm/unistd.h> | 32 | #include <asm/unistd.h> |
| 32 | #include <asm/traps.h> | 33 | #include <asm/traps.h> |
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index b09e848eb6c6..ca6075717824 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
| 20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
| 21 | 21 | ||
| 22 | #include <asm/exception.h> | ||
| 23 | |||
| 22 | #include <mach/hardware.h> | 24 | #include <mach/hardware.h> |
| 23 | #include <mach/irqs.h> | 25 | #include <mach/irqs.h> |
| 24 | #include <mach/gpio.h> | 26 | #include <mach/gpio.h> |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 3b5ea68acbb8..aa33949fef60 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/highmem.h> | 20 | #include <linux/highmem.h> |
| 21 | #include <linux/perf_event.h> | 21 | #include <linux/perf_event.h> |
| 22 | 22 | ||
| 23 | #include <asm/exception.h> | ||
| 23 | #include <asm/system.h> | 24 | #include <asm/system.h> |
| 24 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
| 25 | #include <asm/tlbflush.h> | 26 | #include <asm/tlbflush.h> |
