diff options
author | Jon Medhurst <tixy@linaro.org> | 2013-05-09 14:06:55 +0100 |
---|---|---|
committer | Jon Medhurst <tixy@linaro.org> | 2013-05-09 14:06:55 +0100 |
commit | 7d101db765ff1df9ef09503d80a725d8b4880d85 (patch) | |
tree | d053a0a5be1ff94849f1f7fa096843fbae948369 | |
parent | f246e1387929e03e0b5128d4eb0e73af9f035cd0 (diff) | |
parent | e69ddf69e1d383cf0cd160c5e0d7c2d9993c5a1e (diff) |
Merge branch 'tracking-armlt-psci' into lsk-3.9-vexpress
-rw-r--r-- | arch/arm/include/asm/psci.h | 12 | ||||
-rw-r--r-- | arch/arm/kernel/psci.c | 42 |
2 files changed, 54 insertions, 0 deletions
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index ce0dbe7c162..a079cbee427 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -16,6 +16,10 @@ #define PSCI_POWER_STATE_TYPE_STANDBY 0 #define PSCI_POWER_STATE_TYPE_POWER_DOWN 1 +#define PSCI_POWER_STATE_AFFINITY_LEVEL0 0 +#define PSCI_POWER_STATE_AFFINITY_LEVEL1 1 +#define PSCI_POWER_STATE_AFFINITY_LEVEL2 2 +#define PSCI_POWER_STATE_AFFINITY_LEVEL3 3 struct psci_power_state { u16 id; @@ -33,4 +37,12 @@ struct psci_operations { extern struct psci_operations psci_ops; +#ifdef CONFIG_ARM_PSCI +extern int __init psci_probe(void); +#else +static inline int psci_probe(void) +{ + return -ENODEV; +} +#endif #endif /* __ASM_ARM_PSCI_H */ diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c index 36531643cc2..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 { @@ -42,6 +48,7 @@ static u32 psci_function_id[PSCI_FN_MAX]; #define PSCI_RET_EOPNOTSUPP -1 #define PSCI_RET_EINVAL -2 #define PSCI_RET_EPERM -3 +#define PSCI_RET_EALREADYON -4 static int psci_to_linux_errno(int errno) { @@ -54,6 +61,8 @@ static int psci_to_linux_errno(int errno) return -EINVAL; case PSCI_RET_EPERM: return -EPERM; + case PSCI_RET_EALREADYON: + return -EAGAIN; }; return -EINVAL; @@ -164,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; @@ -209,3 +221,33 @@ out_put_node: return 0; } early_initcall(psci_init); + +int __init psci_probe(void) +{ + struct device_node *np; + int ret = -ENODEV; + + 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); |