|
@@ -20,6 +20,7 @@
|
|
|
#include <linux/of.h>
|
|
|
#include <linux/sched.h>
|
|
|
|
|
|
+#include <asm/cputype.h>
|
|
|
#include <asm/topology.h>
|
|
|
|
|
|
static int __init get_cpu_for_node(struct device_node *node)
|
|
@@ -188,13 +189,9 @@ static int __init parse_dt_topology(void)
|
|
|
* Check that all cores are in the topology; the SMP code will
|
|
|
* only mark cores described in the DT as possible.
|
|
|
*/
|
|
|
- for_each_possible_cpu(cpu) {
|
|
|
- if (cpu_topology[cpu].cluster_id == -1) {
|
|
|
- pr_err("CPU%d: No topology information specified\n",
|
|
|
- cpu);
|
|
|
+ for_each_possible_cpu(cpu)
|
|
|
+ if (cpu_topology[cpu].cluster_id == -1)
|
|
|
ret = -EINVAL;
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
out_map:
|
|
|
of_node_put(map);
|
|
@@ -219,14 +216,6 @@ static void update_siblings_masks(unsigned int cpuid)
|
|
|
struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
|
|
|
int cpu;
|
|
|
|
|
|
- if (cpuid_topo->cluster_id == -1) {
|
|
|
- /*
|
|
|
- * DT does not contain topology information for this cpu.
|
|
|
- */
|
|
|
- pr_debug("CPU%u: No topology information configured\n", cpuid);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
/* update core and thread sibling masks */
|
|
|
for_each_possible_cpu(cpu) {
|
|
|
cpu_topo = &cpu_topology[cpu];
|
|
@@ -249,6 +238,36 @@ static void update_siblings_masks(unsigned int cpuid)
|
|
|
|
|
|
void store_cpu_topology(unsigned int cpuid)
|
|
|
{
|
|
|
+ struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
|
|
|
+ u64 mpidr;
|
|
|
+
|
|
|
+ if (cpuid_topo->cluster_id != -1)
|
|
|
+ goto topology_populated;
|
|
|
+
|
|
|
+ mpidr = read_cpuid_mpidr();
|
|
|
+
|
|
|
+ /* Uniprocessor systems can rely on default topology values */
|
|
|
+ if (mpidr & MPIDR_UP_BITMASK)
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* Create cpu topology mapping based on MPIDR. */
|
|
|
+ if (mpidr & MPIDR_MT_BITMASK) {
|
|
|
+ /* Multiprocessor system : Multi-threads per core */
|
|
|
+ cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
|
|
|
+ cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
|
|
|
+ cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
|
|
|
+ } else {
|
|
|
+ /* Multiprocessor system : Single-thread per core */
|
|
|
+ cpuid_topo->thread_id = -1;
|
|
|
+ cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
|
|
|
+ cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n",
|
|
|
+ cpuid, cpuid_topo->cluster_id, cpuid_topo->core_id,
|
|
|
+ cpuid_topo->thread_id, mpidr);
|
|
|
+
|
|
|
+topology_populated:
|
|
|
update_siblings_masks(cpuid);
|
|
|
}
|
|
|
|