Up until now we have open-coded checks for whether CPUs are siblings,
with slight variations on whether we consider the package ID or not.
This will only get more complex when we introduce cluster support, so in
preparation for that this patch introduces a cpus_are_siblings()
function which can be used to check whether or not 2 CPUs are siblings
in a consistent manner.
By checking globalnumber with the VP ID masked out this also has the
neat side effect of being ready for multi-cluster systems already.
Signed-off-by: Paul Burton <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Acked-by: Thomas Gleixner <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/17011/
Signed-off-by: Ralf Baechle <[email protected]>
extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
+static inline bool cpus_are_siblings(int cpua, int cpub)
+{
+ struct cpuinfo_mips *infoa = &cpu_data[cpua];
+ struct cpuinfo_mips *infob = &cpu_data[cpub];
+ unsigned int gnuma, gnumb;
+
+ if (infoa->package != infob->package)
+ return false;
+
+ gnuma = infoa->globalnumber & ~MIPS_GLOBALNUMBER_VP;
+ gnumb = infob->globalnumber & ~MIPS_GLOBALNUMBER_VP;
+ if (gnuma != gnumb)
+ return false;
+
+ return true;
+}
+
static inline unsigned long cpu_asid_inc(void)
{
return 1 << CONFIG_MIPS_ASID_SHIFT;
cpu_has_dc_aliases ? "dcache aliasing" : "");
for_each_present_cpu(c) {
- if (cpu_core(&cpu_data[c]))
+ if (!cpus_are_siblings(smp_processor_id(), c))
set_cpu_present(c, false);
}
}
mips_cm_unlock_other();
}
- if (core != cpu_core(¤t_cpu_data)) {
+ if (!cpus_are_siblings(cpu, smp_processor_id())) {
/* Boot a VPE on another powered up core */
for (remote = 0; remote < NR_CPUS; remote++) {
- if (cpu_core(&cpu_data[remote]) != core)
+ if (!cpus_are_siblings(cpu, remote))
continue;
if (cpu_online(remote))
break;
/* Look for another online VPE within the core */
for_each_online_cpu(cpu_death_sibling) {
- if (cpu_core(&cpu_data[cpu_death_sibling]) != core)
+ if (!cpus_are_siblings(cpu, cpu_death_sibling))
continue;
/*
if (smp_num_siblings > 1) {
for_each_cpu(i, &cpu_sibling_setup_map) {
- if (cpu_data[cpu].package == cpu_data[i].package &&
- cpu_core(&cpu_data[cpu]) == cpu_core(&cpu_data[i])) {
+ if (cpus_are_siblings(cpu, i)) {
cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
}
for_each_online_cpu(i) {
core_present = 0;
for_each_cpu(k, &temp_foreign_map)
- if (cpu_data[i].package == cpu_data[k].package &&
- cpu_core(&cpu_data[i]) == cpu_core(&cpu_data[k]))
+ if (cpus_are_siblings(i, k))
core_present = 1;
if (!core_present)
cpumask_set_cpu(i, &temp_foreign_map);
if (mips_cpc_present()) {
for_each_cpu(cpu, mask) {
- core = cpu_core(&cpu_data[cpu]);
-
- if (core == cpu_core(¤t_cpu_data))
+ if (cpus_are_siblings(cpu, smp_processor_id()))
continue;
+ core = cpu_core(&cpu_data[cpu]);
+
while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
mips_cm_lock_other(core, 0);
mips_cpc_lock_other(core);
* TODO: don't treat core 0 specially, just prevent the final core
* TODO: remap interrupt affinity temporarily
*/
- if (!cpu_core(&cpu_data[dev->cpu]) && (index > STATE_NC_WAIT))
+ if (cpus_are_siblings(0, dev->cpu) && (index > STATE_NC_WAIT))
index = STATE_NC_WAIT;
/* Select the appropriate cps_pm_state */
local_irq_save(flags);
/* We can only send IPIs to VPEs within the local core */
- WARN_ON(cpu_data[cpu].core != current_cpu_data.core);
+ WARN_ON(!cpus_are_siblings(smp_processor_id(), cpu));
vpflags = dvpe();
settc(cpu_vpe_id(&cpu_data[cpu]));