aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlof Johansson <[email protected]>2016-10-29 11:40:52 -0700
committerOlof Johansson <[email protected]>2016-10-29 11:40:52 -0700
commit21dbf0b34d9c95022289cc6acad7f791479c4653 (patch)
tree197d155994a0d7583cd699711c7cdb9207c936a0
parent07d9a380680d1c0eb51ef87ff2eab5c994949e69 (diff)
parent801f33be8e902d8cea75cb7ac056d07c4fdd25f8 (diff)
Merge tag 'vexpress-fixes-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into next/soc
ARMv7 Vexpress fixes for v4.10 Couple of fixes to MCPM/CCI drivers to check and ensure that the kernel is actually allowed to take control over CCI ports(i.e. running in secure mode) before enabling MCPM. This is needed to boot Linux in HYP mode (very useful for development on virtualization) with CONFIG_MCPM enabled kernel. * tag 'vexpress-fixes-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: drivers: cci: add missing CCI port availability firmware check ARM: vexpress: refine MCPM smp operations override criteria Signed-off-by: Olof Johansson <[email protected]>
-rw-r--r--arch/arm/mach-vexpress/platsmp.c34
-rw-r--r--drivers/bus/arm-cci.c10
2 files changed, 36 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 = {
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 890082315054..231633328dfa 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -2190,6 +2190,9 @@ static int cci_probe_ports(struct device_node *np)
if (!of_match_node(arm_cci_ctrl_if_matches, cp))
continue;
+ if (!of_device_is_available(cp))
+ continue;
+
i = nb_ace + nb_ace_lite;
if (i >= nb_cci_ports)
@@ -2232,6 +2235,13 @@ static int cci_probe_ports(struct device_node *np)
ports[i].dn = cp;
}
+ /*
+ * If there is no CCI port that is under kernel control
+ * return early and report probe status.
+ */
+ if (!nb_ace && !nb_ace_lite)
+ return -ENODEV;
+
/* initialize a stashed array of ACE ports to speed-up look-up */
cci_ace_init_ports();