aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2011-10-20 10:07:27 -0400
committerArnd Bergmann <arnd@arndb.de>2011-10-20 10:07:27 -0400
commit97c24c1aa403e0d4ef7c1958db8459e488862b46 (patch)
tree15214db3c82fffcdbad1d0ef109c9c7558982ebb /arch
parentf350b86121c7a004a5f866333fa1d23fe30263a6 (diff)
parent4a139b64703115e41e1a4e16ebf7eb93d0a0e349 (diff)
Merge branches 'cross-platform/debug_ll' and 'cross-platform/cpu-mapping' into next/cross-platform
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig25
-rw-r--r--arch/arm/common/gic.c17
-rw-r--r--arch/arm/include/asm/cputype.h6
-rw-r--r--arch/arm/include/asm/exception.h19
-rw-r--r--arch/arm/include/asm/localtimer.h4
-rw-r--r--arch/arm/include/asm/smp.h11
-rw-r--r--arch/arm/include/asm/system.h7
-rw-r--r--arch/arm/include/asm/topology.h33
-rw-r--r--arch/arm/kernel/Makefile1
-rw-r--r--arch/arm/kernel/irq.c2
-rw-r--r--arch/arm/kernel/smp.c32
-rw-r--r--arch/arm/kernel/smp_scu.c2
-rw-r--r--arch/arm/kernel/topology.c148
-rw-r--r--arch/arm/kernel/traps.c1
-rw-r--r--arch/arm/mach-exynos4/hotplug.c2
-rw-r--r--arch/arm/mach-exynos4/platsmp.c2
-rw-r--r--arch/arm/mach-msm/hotplug.c2
-rw-r--r--arch/arm/mach-msm/platsmp.c2
-rw-r--r--arch/arm/mach-pxa/irq.c2
-rw-r--r--arch/arm/mach-realview/hotplug.c2
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c6
-rw-r--r--arch/arm/mach-ux500/hotplug.c2
-rw-r--r--arch/arm/mach-ux500/platsmp.c2
-rw-r--r--arch/arm/mach-vexpress/hotplug.c2
-rw-r--r--arch/arm/mm/fault.c1
-rw-r--r--arch/arm/plat-versatile/platsmp.c2
26 files changed, 312 insertions, 23 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3269576dbfa8..c208fd97c180 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1393,6 +1393,31 @@ config SMP_ON_UP
1393 1393
1394 If you don't know what to do here, say Y. 1394 If you don't know what to do here, say Y.
1395 1395
1396config ARM_CPU_TOPOLOGY
1397 bool "Support cpu topology definition"
1398 depends on SMP && CPU_V7
1399 default y
1400 help
1401 Support ARM cpu topology definition. The MPIDR register defines
1402 affinity between processors which is then used to describe the cpu
1403 topology of an ARM System.
1404
1405config SCHED_MC
1406 bool "Multi-core scheduler support"
1407 depends on ARM_CPU_TOPOLOGY
1408 help
1409 Multi-core scheduler support improves the CPU scheduler's decision
1410 making when dealing with multi-core CPU chips at a cost of slightly
1411 increased overhead in some places. If unsure say N here.
1412
1413config SCHED_SMT
1414 bool "SMT scheduler support"
1415 depends on ARM_CPU_TOPOLOGY
1416 help
1417 Improves the CPU scheduler's decision making when dealing with
1418 MultiThreading at a cost of slightly increased overhead in some
1419 places. If unsure say N here.
1420
1396config HAVE_ARM_SCU 1421config HAVE_ARM_SCU
1397 bool 1422 bool
1398 help 1423 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
383void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) 389void 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
74static 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 */
23asmlinkage void do_local_timer(struct pt_regs *); 23asmlinkage void do_local_timer(struct pt_regs *);
24 24
25/*
26 * Called from C code
27 */
28void 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);
33asmlinkage void do_IPI(int ipinr, struct pt_regs *regs); 33asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
34 34
35/* 35/*
36 * Called from C code, this handles an IPI.
37 */
38void 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 */
38extern void smp_init_cpus(void); 43extern void smp_init_cpus(void);
@@ -66,6 +71,12 @@ extern void platform_secondary_init(unsigned int cpu);
66extern void platform_smp_prepare_cpus(unsigned int); 71extern void platform_smp_prepare_cpus(unsigned int);
67 72
68/* 73/*
74 * Logical CPU mapping.
75 */
76extern 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 */
71struct secondary_data { 82struct 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
72struct thread_info; 65struct thread_info;
73struct task_struct; 66struct 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
8struct 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
16extern 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
26void init_cpu_topology(void);
27void store_cpu_topology(unsigned int cpuid);
28const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
29
30#else
31
32static inline void init_cpu_topology(void) { }
33static 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
66obj-$(CONFIG_CPU_HAS_PMU) += pmu.o 66obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
67obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o 67obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
68AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt 68AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
69obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
69 70
70ifneq ($(CONFIG_ARCH_EBSA110),y) 71ifneq ($(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
264int __cpu_logical_map[NR_CPUS];
265
266void __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
461asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) 481asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
462{ 482{
483 handle_local_timer(regs);
484}
485
486void 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 */
568asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) 593asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
569{ 594{
595 handle_IPI(ipinr, regs);
596}
597
598void 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 79ed5e7f204a..5b6d536cbfe3 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -33,7 +33,7 @@ unsigned int __init scu_get_core_count(void __iomem *scu_base)
33/* 33/*
34 * Enable the SCU 34 * Enable the SCU
35 */ 35 */
36void __init scu_enable(void __iomem *scu_base) 36void scu_enable(void __iomem *scu_base)
37{ 37{
38 u32 scu_ctrl; 38 u32 scu_ctrl;
39 39
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
44struct cputopo_arm cpu_topology[NR_CPUS];
45
46const 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 */
56void 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 */
133void 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-exynos4/hotplug.c b/arch/arm/mach-exynos4/hotplug.c
index 7490789784c9..da70e7e39937 100644
--- a/arch/arm/mach-exynos4/hotplug.c
+++ b/arch/arm/mach-exynos4/hotplug.c
@@ -75,7 +75,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
75 : 75 :
76 : "memory", "cc"); 76 : "memory", "cc");
77 77
78 if (pen_release == cpu) { 78 if (pen_release == cpu_logical_map(cpu)) {
79 /* 79 /*
80 * OK, proper wakeup, we're done 80 * OK, proper wakeup, we're done
81 */ 81 */
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
index 7c2282c6ba81..073381469c9d 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -126,7 +126,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
126 * Note that "pen_release" is the hardware CPU ID, whereas 126 * Note that "pen_release" is the hardware CPU ID, whereas
127 * "cpu" is Linux's internal ID. 127 * "cpu" is Linux's internal ID.
128 */ 128 */
129 write_pen_release(cpu); 129 write_pen_release(cpu_logical_map(cpu));
130 130
131 if (!(__raw_readl(S5P_ARM_CORE1_STATUS) & S5P_CORE_LOCAL_PWR_EN)) { 131 if (!(__raw_readl(S5P_ARM_CORE1_STATUS) & S5P_CORE_LOCAL_PWR_EN)) {
132 __raw_writel(S5P_CORE_LOCAL_PWR_EN, 132 __raw_writel(S5P_CORE_LOCAL_PWR_EN,
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index 5a31f70dfb8e..41c252de0215 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -37,7 +37,7 @@ static inline void platform_do_lowpower(unsigned int cpu)
37 : 37 :
38 : "memory", "cc"); 38 : "memory", "cc");
39 39
40 if (pen_release == cpu) { 40 if (pen_release == cpu_logical_map(cpu)) {
41 /* 41 /*
42 * OK, proper wakeup, we're done 42 * OK, proper wakeup, we're done
43 */ 43 */
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 1a1af9e56250..e3375ee7841e 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -117,7 +117,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
117 * Note that "pen_release" is the hardware CPU ID, whereas 117 * Note that "pen_release" is the hardware CPU ID, whereas
118 * "cpu" is Linux's internal ID. 118 * "cpu" is Linux's internal ID.
119 */ 119 */
120 pen_release = cpu; 120 pen_release = cpu_logical_map(cpu);
121 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); 121 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
122 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); 122 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
123 123
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/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
index a87523d095e6..ac1aed2a8da4 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -69,7 +69,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
69 : 69 :
70 : "memory", "cc"); 70 : "memory", "cc");
71 71
72 if (pen_release == cpu) { 72 if (pen_release == cpu_logical_map(cpu)) {
73 /* 73 /*
74 * OK, proper wakeup, we're done 74 * OK, proper wakeup, we're done
75 */ 75 */
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index 3ffdbc92ba82..be1ade76ccc8 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -74,6 +74,8 @@ void __cpuinit sh73a0_secondary_init(unsigned int cpu)
74 74
75int __cpuinit sh73a0_boot_secondary(unsigned int cpu) 75int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
76{ 76{
77 cpu = cpu_logical_map(cpu);
78
77 /* enable cache coherency */ 79 /* enable cache coherency */
78 modify_scu_cpu_psr(0, 3 << (cpu * 8)); 80 modify_scu_cpu_psr(0, 3 << (cpu * 8));
79 81
@@ -87,6 +89,8 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
87 89
88void __init sh73a0_smp_prepare_cpus(void) 90void __init sh73a0_smp_prepare_cpus(void)
89{ 91{
92 int cpu = cpu_logical_map(0);
93
90 scu_enable(scu_base_addr()); 94 scu_enable(scu_base_addr());
91 95
92 /* Map the reset vector (in headsmp.S) */ 96 /* Map the reset vector (in headsmp.S) */
@@ -94,5 +98,5 @@ void __init sh73a0_smp_prepare_cpus(void)
94 __raw_writel(__pa(shmobile_secondary_vector), __io(SBAR)); 98 __raw_writel(__pa(shmobile_secondary_vector), __io(SBAR));
95 99
96 /* enable cache coherency on CPU0 */ 100 /* enable cache coherency on CPU0 */
97 modify_scu_cpu_psr(0, 3 << (0 * 8)); 101 modify_scu_cpu_psr(0, 3 << (cpu * 8));
98} 102}
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c
index dd8037ebccf8..572015e57cd9 100644
--- a/arch/arm/mach-ux500/hotplug.c
+++ b/arch/arm/mach-ux500/hotplug.c
@@ -24,7 +24,7 @@ static inline void platform_do_lowpower(unsigned int cpu)
24 for (;;) { 24 for (;;) {
25 __asm__ __volatile__("dsb\n\t" "wfi\n\t" 25 __asm__ __volatile__("dsb\n\t" "wfi\n\t"
26 : : : "memory"); 26 : : : "memory");
27 if (pen_release == cpu) { 27 if (pen_release == cpu_logical_map(cpu)) {
28 /* 28 /*
29 * OK, proper wakeup, we're done 29 * OK, proper wakeup, we're done
30 */ 30 */
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index a33df5f4c27a..27e5281cd55d 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -96,7 +96,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
96 * the holding pen - release it, then wait for it to flag 96 * the holding pen - release it, then wait for it to flag
97 * that it has been released by resetting pen_release. 97 * that it has been released by resetting pen_release.
98 */ 98 */
99 write_pen_release(cpu); 99 write_pen_release(cpu_logical_map(cpu));
100 100
101 gic_raise_softirq(cpumask_of(cpu), 1); 101 gic_raise_softirq(cpumask_of(cpu), 1);
102 102
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
index ea4cbfb90a66..2866ed8c4b05 100644
--- a/arch/arm/mach-vexpress/hotplug.c
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -70,7 +70,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
70 : 70 :
71 : "memory", "cc"); 71 : "memory", "cc");
72 72
73 if (pen_release == cpu) { 73 if (pen_release == cpu_logical_map(cpu)) {
74 /* 74 /*
75 * OK, proper wakeup, we're done 75 * OK, proper wakeup, we're done
76 */ 76 */
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>
diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c
index 51ecfea09b27..92f18d372b69 100644
--- a/arch/arm/plat-versatile/platsmp.c
+++ b/arch/arm/plat-versatile/platsmp.c
@@ -77,7 +77,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
77 * since we haven't sent them a soft interrupt, they shouldn't 77 * since we haven't sent them a soft interrupt, they shouldn't
78 * be there. 78 * be there.
79 */ 79 */
80 write_pen_release(cpu); 80 write_pen_release(cpu_logical_map(cpu));
81 81
82 /* 82 /*
83 * Send the secondary CPU a soft interrupt, thereby causing 83 * Send the secondary CPU a soft interrupt, thereby causing