aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAchin Gupta <achin.gupta@arm.com>2013-03-10 22:04:29 +0000
committerJon Medhurst <tixy@linaro.org>2013-04-29 09:43:17 +0100
commite69ddf69e1d383cf0cd160c5e0d7c2d9993c5a1e (patch)
treee1edd7b098cfd612993e95d5a3e6fa19dee4c38a
parent165e90de39107bc42493facb88aeab90d56b917e (diff)
ARM: psci: add cmdline option to enable use of psci
This patch adds the 'psci' kernel command line option. Secure firmware cannot yet add a psci device node in the dt to indicate whether it supports psci or not. So in the current dt, the psci device node is present by default. The probe function will always indicate that the secure firmware implements psci irrespective of the address space linux runs in as the same device tree will be used in either case. Hence a kernel cmdline option is required to choose either the native or psci power api backend depending upon the address space linux is running in. Specifying 'psci=enable' in the cmdline will allow Linux running in the non-secure address space to use the same dt but use the psci backend instead of the native backend. It effectively overrides the presence of the native implementation by ensuring registration of the psci backend. Linux running in the secure address space will use the native backend for power management when 'psci=disable' in the cmdline (also the default value i.e. psci backend is disabled by default) or the psci node in the dt is absent. Signed-off-by: Achin Gupta <achin.gupta@arm.com> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
-rw-r--r--arch/arm/kernel/psci.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c
index 03c10f65add..1180801468d 100644
--- a/arch/arm/kernel/psci.c
+++ b/arch/arm/kernel/psci.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/of.h>
+#include <linux/string.h>
#include <asm/compiler.h>
#include <asm/errno.h>
@@ -26,6 +27,11 @@
struct psci_operations psci_ops;
+/* Type of psci support. Currently can only be enabled or disabled */
+#define PSCI_SUP_DISABLED 0
+#define PSCI_SUP_ENABLED 1
+
+static unsigned int psci;
static int (*invoke_psci_fn)(u32, u32, u32, u32);
enum psci_function {
@@ -167,6 +173,9 @@ static int __init psci_init(void)
const char *method;
u32 id;
+ if (psci == PSCI_SUP_DISABLED)
+ return 0;
+
np = of_find_matching_node(NULL, psci_of_match);
if (!np)
return 0;
@@ -218,10 +227,27 @@ int __init psci_probe(void)
struct device_node *np;
int ret = -ENODEV;
- np = of_find_matching_node(NULL, psci_of_match);
- if (np)
- ret = 0;
+ if (psci == PSCI_SUP_ENABLED) {
+ np = of_find_matching_node(NULL, psci_of_match);
+ if (np)
+ ret = 0;
+ }
of_node_put(np);
return ret;
}
+
+static int __init early_psci(char *val)
+{
+ int ret = 0;
+
+ if (strcmp(val, "enable") == 0)
+ psci = PSCI_SUP_ENABLED;
+ else if (strcmp(val, "disable") == 0)
+ psci = PSCI_SUP_DISABLED;
+ else
+ ret = -EINVAL;
+
+ return ret;
+}
+early_param("psci", early_psci);