aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAchin Gupta <achin.gupta@arm.com>2013-03-10 22:04:29 +0000
committerJon Medhurst <tixy@linaro.org>2013-07-01 11:05:02 +0100
commitb5fdc36b35130308bd62a18b4682b51708a7f378 (patch)
treea3e83aa51129ab2ea47a5ba5b6f2a04d81bb0f07 /arch
parent25366fe14faa30941b28f3d724438d6ec9a7cf4d (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>
Diffstat (limited to 'arch')
-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);