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 /arch/arm | |
parent | bda2487997c3b7828a3765e7f2c37fdd6b7bdcbe (diff) | |
parent | 5a567d78c437e3be1c512734cdfe64b4ae6b82d7 (diff) |
Merge branch 'depends/rmk/smp' into tmp
Diffstat (limited to 'arch/arm')
-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> |