diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-11-20 15:18:51 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-11-20 15:18:51 -0500 |
commit | e38eb34aab13a81b91400c75c703252473100bc4 (patch) | |
tree | a250c6071dba9bb1cdb2cff143b33906230e6439 | |
parent | 2079f30e9e83887ca95fa129d0bc734b2c4b406d (diff) | |
parent | 384a290283fde63ba8dc671fca5420111cdac19a (diff) |
Merge branch 'cluster-boot-protocol' of git://linux-arm.org/linux-2.6-lp into devel-stable
-rw-r--r-- | Documentation/devicetree/bindings/arm/cpus.txt | 77 | ||||
-rw-r--r-- | arch/arm/common/gic.c | 45 | ||||
-rw-r--r-- | arch/arm/include/asm/cputype.h | 13 | ||||
-rw-r--r-- | arch/arm/include/asm/prom.h | 2 | ||||
-rw-r--r-- | arch/arm/include/asm/smp_plat.h | 17 | ||||
-rw-r--r-- | arch/arm/kernel/devtree.c | 100 | ||||
-rw-r--r-- | arch/arm/kernel/setup.c | 8 | ||||
-rw-r--r-- | arch/arm/kernel/topology.c | 42 |
8 files changed, 256 insertions, 48 deletions
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt new file mode 100644 index 000000000000..f32494dbfe19 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/cpus.txt | |||
@@ -0,0 +1,77 @@ | |||
1 | * ARM CPUs binding description | ||
2 | |||
3 | The device tree allows to describe the layout of CPUs in a system through | ||
4 | the "cpus" node, which in turn contains a number of subnodes (ie "cpu") | ||
5 | defining properties for every cpu. | ||
6 | |||
7 | Bindings for CPU nodes follow the ePAPR standard, available from: | ||
8 | |||
9 | http://devicetree.org | ||
10 | |||
11 | For the ARM architecture every CPU node must contain the following properties: | ||
12 | |||
13 | - device_type: must be "cpu" | ||
14 | - reg: property matching the CPU MPIDR[23:0] register bits | ||
15 | reg[31:24] bits must be set to 0 | ||
16 | - compatible: should be one of: | ||
17 | "arm,arm1020" | ||
18 | "arm,arm1020e" | ||
19 | "arm,arm1022" | ||
20 | "arm,arm1026" | ||
21 | "arm,arm720" | ||
22 | "arm,arm740" | ||
23 | "arm,arm7tdmi" | ||
24 | "arm,arm920" | ||
25 | "arm,arm922" | ||
26 | "arm,arm925" | ||
27 | "arm,arm926" | ||
28 | "arm,arm940" | ||
29 | "arm,arm946" | ||
30 | "arm,arm9tdmi" | ||
31 | "arm,cortex-a5" | ||
32 | "arm,cortex-a7" | ||
33 | "arm,cortex-a8" | ||
34 | "arm,cortex-a9" | ||
35 | "arm,cortex-a15" | ||
36 | "arm,arm1136" | ||
37 | "arm,arm1156" | ||
38 | "arm,arm1176" | ||
39 | "arm,arm11mpcore" | ||
40 | "faraday,fa526" | ||
41 | "intel,sa110" | ||
42 | "intel,sa1100" | ||
43 | "marvell,feroceon" | ||
44 | "marvell,mohawk" | ||
45 | "marvell,xsc3" | ||
46 | "marvell,xscale" | ||
47 | |||
48 | Example: | ||
49 | |||
50 | cpus { | ||
51 | #size-cells = <0>; | ||
52 | #address-cells = <1>; | ||
53 | |||
54 | CPU0: cpu@0 { | ||
55 | device_type = "cpu"; | ||
56 | compatible = "arm,cortex-a15"; | ||
57 | reg = <0x0>; | ||
58 | }; | ||
59 | |||
60 | CPU1: cpu@1 { | ||
61 | device_type = "cpu"; | ||
62 | compatible = "arm,cortex-a15"; | ||
63 | reg = <0x1>; | ||
64 | }; | ||
65 | |||
66 | CPU2: cpu@100 { | ||
67 | device_type = "cpu"; | ||
68 | compatible = "arm,cortex-a7"; | ||
69 | reg = <0x100>; | ||
70 | }; | ||
71 | |||
72 | CPU3: cpu@101 { | ||
73 | device_type = "cpu"; | ||
74 | compatible = "arm,cortex-a7"; | ||
75 | reg = <0x101>; | ||
76 | }; | ||
77 | }; | ||
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index aa5269984187..36ae03a3f5d1 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
@@ -70,6 +70,14 @@ struct gic_chip_data { | |||
70 | static DEFINE_RAW_SPINLOCK(irq_controller_lock); | 70 | static DEFINE_RAW_SPINLOCK(irq_controller_lock); |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * The GIC mapping of CPU interfaces does not necessarily match | ||
74 | * the logical CPU numbering. Let's use a mapping as returned | ||
75 | * by the GIC itself. | ||
76 | */ | ||
77 | #define NR_GIC_CPU_IF 8 | ||
78 | static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly; | ||
79 | |||
80 | /* | ||
73 | * Supported arch specific GIC irq extension. | 81 | * Supported arch specific GIC irq extension. |
74 | * Default make them NULL. | 82 | * Default make them NULL. |
75 | */ | 83 | */ |
@@ -238,11 +246,11 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, | |||
238 | unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); | 246 | unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); |
239 | u32 val, mask, bit; | 247 | u32 val, mask, bit; |
240 | 248 | ||
241 | if (cpu >= 8 || cpu >= nr_cpu_ids) | 249 | if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) |
242 | return -EINVAL; | 250 | return -EINVAL; |
243 | 251 | ||
244 | mask = 0xff << shift; | 252 | mask = 0xff << shift; |
245 | bit = 1 << (cpu_logical_map(cpu) + shift); | 253 | bit = gic_cpu_map[cpu] << shift; |
246 | 254 | ||
247 | raw_spin_lock(&irq_controller_lock); | 255 | raw_spin_lock(&irq_controller_lock); |
248 | val = readl_relaxed(reg) & ~mask; | 256 | val = readl_relaxed(reg) & ~mask; |
@@ -349,11 +357,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic) | |||
349 | u32 cpumask; | 357 | u32 cpumask; |
350 | unsigned int gic_irqs = gic->gic_irqs; | 358 | unsigned int gic_irqs = gic->gic_irqs; |
351 | void __iomem *base = gic_data_dist_base(gic); | 359 | void __iomem *base = gic_data_dist_base(gic); |
352 | u32 cpu = cpu_logical_map(smp_processor_id()); | ||
353 | |||
354 | cpumask = 1 << cpu; | ||
355 | cpumask |= cpumask << 8; | ||
356 | cpumask |= cpumask << 16; | ||
357 | 360 | ||
358 | writel_relaxed(0, base + GIC_DIST_CTRL); | 361 | writel_relaxed(0, base + GIC_DIST_CTRL); |
359 | 362 | ||
@@ -366,6 +369,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic) | |||
366 | /* | 369 | /* |
367 | * Set all global interrupts to this CPU only. | 370 | * Set all global interrupts to this CPU only. |
368 | */ | 371 | */ |
372 | cpumask = readl_relaxed(base + GIC_DIST_TARGET + 0); | ||
369 | for (i = 32; i < gic_irqs; i += 4) | 373 | for (i = 32; i < gic_irqs; i += 4) |
370 | writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); | 374 | writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); |
371 | 375 | ||
@@ -389,9 +393,25 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic) | |||
389 | { | 393 | { |
390 | void __iomem *dist_base = gic_data_dist_base(gic); | 394 | void __iomem *dist_base = gic_data_dist_base(gic); |
391 | void __iomem *base = gic_data_cpu_base(gic); | 395 | void __iomem *base = gic_data_cpu_base(gic); |
396 | unsigned int cpu_mask, cpu = smp_processor_id(); | ||
392 | int i; | 397 | int i; |
393 | 398 | ||
394 | /* | 399 | /* |
400 | * Get what the GIC says our CPU mask is. | ||
401 | */ | ||
402 | BUG_ON(cpu >= NR_GIC_CPU_IF); | ||
403 | cpu_mask = readl_relaxed(dist_base + GIC_DIST_TARGET + 0); | ||
404 | gic_cpu_map[cpu] = cpu_mask; | ||
405 | |||
406 | /* | ||
407 | * Clear our mask from the other map entries in case they're | ||
408 | * still undefined. | ||
409 | */ | ||
410 | for (i = 0; i < NR_GIC_CPU_IF; i++) | ||
411 | if (i != cpu) | ||
412 | gic_cpu_map[i] &= ~cpu_mask; | ||
413 | |||
414 | /* | ||
395 | * Deal with the banked PPI and SGI interrupts - disable all | 415 | * Deal with the banked PPI and SGI interrupts - disable all |
396 | * PPI interrupts, ensure all SGI interrupts are enabled. | 416 | * PPI interrupts, ensure all SGI interrupts are enabled. |
397 | */ | 417 | */ |
@@ -646,7 +666,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | |||
646 | { | 666 | { |
647 | irq_hw_number_t hwirq_base; | 667 | irq_hw_number_t hwirq_base; |
648 | struct gic_chip_data *gic; | 668 | struct gic_chip_data *gic; |
649 | int gic_irqs, irq_base; | 669 | int gic_irqs, irq_base, i; |
650 | 670 | ||
651 | BUG_ON(gic_nr >= MAX_GIC_NR); | 671 | BUG_ON(gic_nr >= MAX_GIC_NR); |
652 | 672 | ||
@@ -683,6 +703,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | |||
683 | } | 703 | } |
684 | 704 | ||
685 | /* | 705 | /* |
706 | * Initialize the CPU interface map to all CPUs. | ||
707 | * It will be refined as each CPU probes its ID. | ||
708 | */ | ||
709 | for (i = 0; i < NR_GIC_CPU_IF; i++) | ||
710 | gic_cpu_map[i] = 0xff; | ||
711 | |||
712 | /* | ||
686 | * For primary GICs, skip over SGIs. | 713 | * For primary GICs, skip over SGIs. |
687 | * For secondary GICs, skip over PPIs, too. | 714 | * For secondary GICs, skip over PPIs, too. |
688 | */ | 715 | */ |
@@ -737,7 +764,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | |||
737 | 764 | ||
738 | /* Convert our logical CPU mask into a physical one. */ | 765 | /* Convert our logical CPU mask into a physical one. */ |
739 | for_each_cpu(cpu, mask) | 766 | for_each_cpu(cpu, mask) |
740 | map |= 1 << cpu_logical_map(cpu); | 767 | map |= gic_cpu_map[cpu]; |
741 | 768 | ||
742 | /* | 769 | /* |
743 | * Ensure that stores to Normal memory are visible to the | 770 | * 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 cb47d28cbe1f..a59dcb5ab5fc 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h | |||
@@ -25,6 +25,19 @@ | |||
25 | #define CPUID_EXT_ISAR4 "c2, 4" | 25 | #define CPUID_EXT_ISAR4 "c2, 4" |
26 | #define CPUID_EXT_ISAR5 "c2, 5" | 26 | #define CPUID_EXT_ISAR5 "c2, 5" |
27 | 27 | ||
28 | #define MPIDR_SMP_BITMASK (0x3 << 30) | ||
29 | #define MPIDR_SMP_VALUE (0x2 << 30) | ||
30 | |||
31 | #define MPIDR_MT_BITMASK (0x1 << 24) | ||
32 | |||
33 | #define MPIDR_HWID_BITMASK 0xFFFFFF | ||
34 | |||
35 | #define MPIDR_LEVEL_BITS 8 | ||
36 | #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1) | ||
37 | |||
38 | #define MPIDR_AFFINITY_LEVEL(mpidr, level) \ | ||
39 | ((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK) | ||
40 | |||
28 | extern unsigned int processor_id; | 41 | extern unsigned int processor_id; |
29 | 42 | ||
30 | #ifdef CONFIG_CPU_CP15 | 43 | #ifdef CONFIG_CPU_CP15 |
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h index aeae9c609df4..8dd51dc1a367 100644 --- a/arch/arm/include/asm/prom.h +++ b/arch/arm/include/asm/prom.h | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); | 16 | extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); |
17 | extern void arm_dt_memblock_reserve(void); | 17 | extern void arm_dt_memblock_reserve(void); |
18 | extern void __init arm_dt_init_cpu_maps(void); | ||
18 | 19 | ||
19 | #else /* CONFIG_OF */ | 20 | #else /* CONFIG_OF */ |
20 | 21 | ||
@@ -24,6 +25,7 @@ static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys) | |||
24 | } | 25 | } |
25 | 26 | ||
26 | static inline void arm_dt_memblock_reserve(void) { } | 27 | static inline void arm_dt_memblock_reserve(void) { } |
28 | static inline void arm_dt_init_cpu_maps(void) { } | ||
27 | 29 | ||
28 | #endif /* CONFIG_OF */ | 30 | #endif /* CONFIG_OF */ |
29 | #endif /* ASMARM_PROM_H */ | 31 | #endif /* ASMARM_PROM_H */ |
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h index 558d6c80aca9..aaa61b6f50ff 100644 --- a/arch/arm/include/asm/smp_plat.h +++ b/arch/arm/include/asm/smp_plat.h | |||
@@ -5,6 +5,9 @@ | |||
5 | #ifndef __ASMARM_SMP_PLAT_H | 5 | #ifndef __ASMARM_SMP_PLAT_H |
6 | #define __ASMARM_SMP_PLAT_H | 6 | #define __ASMARM_SMP_PLAT_H |
7 | 7 | ||
8 | #include <linux/cpumask.h> | ||
9 | #include <linux/err.h> | ||
10 | |||
8 | #include <asm/cputype.h> | 11 | #include <asm/cputype.h> |
9 | 12 | ||
10 | /* | 13 | /* |
@@ -48,5 +51,19 @@ static inline int cache_ops_need_broadcast(void) | |||
48 | */ | 51 | */ |
49 | extern int __cpu_logical_map[]; | 52 | extern int __cpu_logical_map[]; |
50 | #define cpu_logical_map(cpu) __cpu_logical_map[cpu] | 53 | #define cpu_logical_map(cpu) __cpu_logical_map[cpu] |
54 | /* | ||
55 | * Retrieve logical cpu index corresponding to a given MPIDR[23:0] | ||
56 | * - mpidr: MPIDR[23:0] to be used for the look-up | ||
57 | * | ||
58 | * Returns the cpu logical index or -EINVAL on look-up error | ||
59 | */ | ||
60 | static inline int get_logical_index(u32 mpidr) | ||
61 | { | ||
62 | int cpu; | ||
63 | for (cpu = 0; cpu < nr_cpu_ids; cpu++) | ||
64 | if (cpu_logical_map(cpu) == mpidr) | ||
65 | return cpu; | ||
66 | return -EINVAL; | ||
67 | } | ||
51 | 68 | ||
52 | #endif | 69 | #endif |
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index bee7f9d47f02..aaf9add497fe 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c | |||
@@ -19,8 +19,10 @@ | |||
19 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
20 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
21 | 21 | ||
22 | #include <asm/cputype.h> | ||
22 | #include <asm/setup.h> | 23 | #include <asm/setup.h> |
23 | #include <asm/page.h> | 24 | #include <asm/page.h> |
25 | #include <asm/smp_plat.h> | ||
24 | #include <asm/mach/arch.h> | 26 | #include <asm/mach/arch.h> |
25 | #include <asm/mach-types.h> | 27 | #include <asm/mach-types.h> |
26 | 28 | ||
@@ -61,6 +63,104 @@ void __init arm_dt_memblock_reserve(void) | |||
61 | } | 63 | } |
62 | } | 64 | } |
63 | 65 | ||
66 | /* | ||
67 | * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree | ||
68 | * and builds the cpu logical map array containing MPIDR values related to | ||
69 | * logical cpus | ||
70 | * | ||
71 | * Updates the cpu possible mask with the number of parsed cpu nodes | ||
72 | */ | ||
73 | void __init arm_dt_init_cpu_maps(void) | ||
74 | { | ||
75 | /* | ||
76 | * Temp logical map is initialized with UINT_MAX values that are | ||
77 | * considered invalid logical map entries since the logical map must | ||
78 | * contain a list of MPIDR[23:0] values where MPIDR[31:24] must | ||
79 | * read as 0. | ||
80 | */ | ||
81 | struct device_node *cpu, *cpus; | ||
82 | u32 i, j, cpuidx = 1; | ||
83 | u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0; | ||
84 | |||
85 | u32 tmp_map[NR_CPUS] = { [0 ... NR_CPUS-1] = UINT_MAX }; | ||
86 | bool bootcpu_valid = false; | ||
87 | cpus = of_find_node_by_path("/cpus"); | ||
88 | |||
89 | if (!cpus) | ||
90 | return; | ||
91 | |||
92 | for_each_child_of_node(cpus, cpu) { | ||
93 | u32 hwid; | ||
94 | |||
95 | pr_debug(" * %s...\n", cpu->full_name); | ||
96 | /* | ||
97 | * A device tree containing CPU nodes with missing "reg" | ||
98 | * properties is considered invalid to build the | ||
99 | * cpu_logical_map. | ||
100 | */ | ||
101 | if (of_property_read_u32(cpu, "reg", &hwid)) { | ||
102 | pr_debug(" * %s missing reg property\n", | ||
103 | cpu->full_name); | ||
104 | return; | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * 8 MSBs must be set to 0 in the DT since the reg property | ||
109 | * defines the MPIDR[23:0]. | ||
110 | */ | ||
111 | if (hwid & ~MPIDR_HWID_BITMASK) | ||
112 | return; | ||
113 | |||
114 | /* | ||
115 | * Duplicate MPIDRs are a recipe for disaster. | ||
116 | * Scan all initialized entries and check for | ||
117 | * duplicates. If any is found just bail out. | ||
118 | * temp values were initialized to UINT_MAX | ||
119 | * to avoid matching valid MPIDR[23:0] values. | ||
120 | */ | ||
121 | for (j = 0; j < cpuidx; j++) | ||
122 | if (WARN(tmp_map[j] == hwid, "Duplicate /cpu reg " | ||
123 | "properties in the DT\n")) | ||
124 | return; | ||
125 | |||
126 | /* | ||
127 | * Build a stashed array of MPIDR values. Numbering scheme | ||
128 | * requires that if detected the boot CPU must be assigned | ||
129 | * logical id 0. Other CPUs get sequential indexes starting | ||
130 | * from 1. If a CPU node with a reg property matching the | ||
131 | * boot CPU MPIDR is detected, this is recorded so that the | ||
132 | * logical map built from DT is validated and can be used | ||
133 | * to override the map created in smp_setup_processor_id(). | ||
134 | */ | ||
135 | if (hwid == mpidr) { | ||
136 | i = 0; | ||
137 | bootcpu_valid = true; | ||
138 | } else { | ||
139 | i = cpuidx++; | ||
140 | } | ||
141 | |||
142 | tmp_map[i] = hwid; | ||
143 | |||
144 | if (cpuidx > nr_cpu_ids) | ||
145 | break; | ||
146 | } | ||
147 | |||
148 | if (WARN(!bootcpu_valid, "DT missing boot CPU MPIDR[23:0], " | ||
149 | "fall back to default cpu_logical_map\n")) | ||
150 | return; | ||
151 | |||
152 | /* | ||
153 | * Since the boot CPU node contains proper data, and all nodes have | ||
154 | * a reg property, the DT CPU list can be considered valid and the | ||
155 | * logical map created in smp_setup_processor_id() can be overridden | ||
156 | */ | ||
157 | for (i = 0; i < cpuidx; i++) { | ||
158 | set_cpu_possible(i, true); | ||
159 | cpu_logical_map(i) = tmp_map[i]; | ||
160 | pr_debug("cpu logical map 0x%x\n", cpu_logical_map(i)); | ||
161 | } | ||
162 | } | ||
163 | |||
64 | /** | 164 | /** |
65 | * setup_machine_fdt - Machine setup when an dtb was passed to the kernel | 165 | * setup_machine_fdt - Machine setup when an dtb was passed to the kernel |
66 | * @dt_phys: physical address of dt blob | 166 | * @dt_phys: physical address of dt blob |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index da1d1aa20ad9..d15f1c503f3d 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -426,13 +426,14 @@ int __cpu_logical_map[NR_CPUS]; | |||
426 | void __init smp_setup_processor_id(void) | 426 | void __init smp_setup_processor_id(void) |
427 | { | 427 | { |
428 | int i; | 428 | int i; |
429 | u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0; | 429 | u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0; |
430 | u32 cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); | ||
430 | 431 | ||
431 | cpu_logical_map(0) = cpu; | 432 | cpu_logical_map(0) = cpu; |
432 | for (i = 1; i < NR_CPUS; ++i) | 433 | for (i = 1; i < nr_cpu_ids; ++i) |
433 | cpu_logical_map(i) = i == cpu ? 0 : i; | 434 | cpu_logical_map(i) = i == cpu ? 0 : i; |
434 | 435 | ||
435 | printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu); | 436 | printk(KERN_INFO "Booting Linux on physical CPU 0x%x\n", mpidr); |
436 | } | 437 | } |
437 | 438 | ||
438 | static void __init setup_processor(void) | 439 | static void __init setup_processor(void) |
@@ -758,6 +759,7 @@ void __init setup_arch(char **cmdline_p) | |||
758 | 759 | ||
759 | unflatten_device_tree(); | 760 | unflatten_device_tree(); |
760 | 761 | ||
762 | arm_dt_init_cpu_maps(); | ||
761 | #ifdef CONFIG_SMP | 763 | #ifdef CONFIG_SMP |
762 | if (is_smp()) { | 764 | if (is_smp()) { |
763 | smp_set_ops(mdesc->smp); | 765 | smp_set_ops(mdesc->smp); |
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 26c12c6440fc..79282ebcd939 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c | |||
@@ -196,32 +196,7 @@ static inline void parse_dt_topology(void) {} | |||
196 | static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {} | 196 | static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {} |
197 | #endif | 197 | #endif |
198 | 198 | ||
199 | 199 | /* | |
200 | /* | ||
201 | * cpu topology management | ||
202 | */ | ||
203 | |||
204 | #define MPIDR_SMP_BITMASK (0x3 << 30) | ||
205 | #define MPIDR_SMP_VALUE (0x2 << 30) | ||
206 | |||
207 | #define MPIDR_MT_BITMASK (0x1 << 24) | ||
208 | |||
209 | /* | ||
210 | * These masks reflect the current use of the affinity levels. | ||
211 | * The affinity level can be up to 16 bits according to ARM ARM | ||
212 | */ | ||
213 | #define MPIDR_HWID_BITMASK 0xFFFFFF | ||
214 | |||
215 | #define MPIDR_LEVEL0_MASK 0x3 | ||
216 | #define MPIDR_LEVEL0_SHIFT 0 | ||
217 | |||
218 | #define MPIDR_LEVEL1_MASK 0xF | ||
219 | #define MPIDR_LEVEL1_SHIFT 8 | ||
220 | |||
221 | #define MPIDR_LEVEL2_MASK 0xFF | ||
222 | #define MPIDR_LEVEL2_SHIFT 16 | ||
223 | |||
224 | /* | ||
225 | * cpu topology table | 200 | * cpu topology table |
226 | */ | 201 | */ |
227 | struct cputopo_arm cpu_topology[NR_CPUS]; | 202 | struct cputopo_arm cpu_topology[NR_CPUS]; |
@@ -282,19 +257,14 @@ void store_cpu_topology(unsigned int cpuid) | |||
282 | 257 | ||
283 | if (mpidr & MPIDR_MT_BITMASK) { | 258 | if (mpidr & MPIDR_MT_BITMASK) { |
284 | /* core performance interdependency */ | 259 | /* core performance interdependency */ |
285 | cpuid_topo->thread_id = (mpidr >> MPIDR_LEVEL0_SHIFT) | 260 | cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); |
286 | & MPIDR_LEVEL0_MASK; | 261 | cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1); |
287 | cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL1_SHIFT) | 262 | cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL(mpidr, 2); |
288 | & MPIDR_LEVEL1_MASK; | ||
289 | cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL2_SHIFT) | ||
290 | & MPIDR_LEVEL2_MASK; | ||
291 | } else { | 263 | } else { |
292 | /* largely independent cores */ | 264 | /* largely independent cores */ |
293 | cpuid_topo->thread_id = -1; | 265 | cpuid_topo->thread_id = -1; |
294 | cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL0_SHIFT) | 266 | cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); |
295 | & MPIDR_LEVEL0_MASK; | 267 | cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL(mpidr, 1); |
296 | cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL1_SHIFT) | ||
297 | & MPIDR_LEVEL1_MASK; | ||
298 | } | 268 | } |
299 | } else { | 269 | } else { |
300 | /* | 270 | /* |