summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-vexpress/platsmp.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 8b8d0724f6c6..98e29dee91e8 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -26,19 +26,37 @@
bool __init vexpress_smp_init_ops(void)
{
#ifdef CONFIG_MCPM
+ int cpu;
+ struct device_node *cpu_node, *cci_node;
+
/*
- * The best way to detect a multi-cluster configuration at the moment
- * is to look for the presence of a CCI in the system.
+ * The best way to detect a multi-cluster configuration
+ * is to detect if the kernel can take over CCI ports
+ * control. Loop over possible CPUs and check if CCI
+ * port control is available.
* Override the default vexpress_smp_ops if so.
*/
- struct device_node *node;
- node = of_find_compatible_node(NULL, NULL, "arm,cci-400");
- if (node && of_device_is_available(node)) {
- mcpm_smp_set_ops();
- return true;
+ for_each_possible_cpu(cpu) {
+ bool available;
+
+ cpu_node = of_get_cpu_node(cpu, NULL);
+ if (WARN(!cpu_node, "Missing cpu device node!"))
+ return false;
+
+ cci_node = of_parse_phandle(cpu_node, "cci-control-port", 0);
+ available = cci_node && of_device_is_available(cci_node);
+ of_node_put(cci_node);
+ of_node_put(cpu_node);
+
+ if (!available)
+ return false;
}
-#endif
+
+ mcpm_smp_set_ops();
+ return true;
+#else
return false;
+#endif
}
static const struct of_device_id vexpress_smp_dt_scu_match[] __initconst = {