aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2015-04-20 09:51:00 -0400
committerMark Rutland <mark.rutland@arm.com>2015-05-27 08:22:02 -0400
commita06eed3e90c272675f2ef50f5bc5b3ec91652d77 (patch)
treef497d099c7422369f8eee6e32fb4a8aefec0a2d1 /arch
parent2a7cd0ebfc0a5ac2e692e63871e0ff6a50d5de46 (diff)
arm64: psci: support unsigned return values
PSCI_VERSION and MIGRATE_INFO_TYPE_UP_CPU return unsigned values, with the latter returning a 64-bit value. However, the PSCI invocation functions have prototypes returning int. This patch upgrades the invocation functions to return unsigned long, with a new typedef to keep things legible. As PSCI_VERSION cannot return a negative value, the erroneous check against PSCI_RET_NOT_SUPPORTED is also removed. The unrelated psci_initcall_t typedef is moved closer to its first user, to avoid confusion with the invocation functions. In preparation for sharing the code with ARM, unsigned long is used in preference of u64. In the SMC32 calling convention, the relevant fields will be 32 bits wide. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org> Tested-by: Hanjun Guo <hanjun.guo@linaro.org> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm64/kernel/psci.c47
1 files changed, 18 insertions, 29 deletions
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 0c1efb662a71..7d441b3439a7 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -56,11 +56,11 @@ struct psci_operations {
56 56
57static struct psci_operations psci_ops; 57static struct psci_operations psci_ops;
58 58
59static int (*invoke_psci_fn)(u64, u64, u64, u64); 59typedef unsigned long (psci_fn)(unsigned long, unsigned long,
60typedef int (*psci_initcall_t)(const struct device_node *); 60 unsigned long, unsigned long);
61 61asmlinkage psci_fn __invoke_psci_fn_hvc;
62asmlinkage int __invoke_psci_fn_hvc(u64, u64, u64, u64); 62asmlinkage psci_fn __invoke_psci_fn_smc;
63asmlinkage int __invoke_psci_fn_smc(u64, u64, u64, u64); 63static psci_fn *invoke_psci_fn;
64 64
65enum psci_function { 65enum psci_function {
66 PSCI_FN_CPU_SUSPEND, 66 PSCI_FN_CPU_SUSPEND,
@@ -112,12 +112,9 @@ static void psci_power_state_unpack(u32 power_state,
112 PSCI_0_2_POWER_STATE_AFFL_SHIFT; 112 PSCI_0_2_POWER_STATE_AFFL_SHIFT;
113} 113}
114 114
115static int psci_get_version(void) 115static u32 psci_get_version(void)
116{ 116{
117 int err; 117 return invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
118
119 err = invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
120 return err;
121} 118}
122 119
123static int psci_cpu_suspend(struct psci_power_state state, 120static int psci_cpu_suspend(struct psci_power_state state,
@@ -296,25 +293,15 @@ static void __init psci_0_2_set_functions(void)
296 */ 293 */
297static int __init psci_probe(void) 294static int __init psci_probe(void)
298{ 295{
299 int ver = psci_get_version(); 296 u32 ver = psci_get_version();
300 297
301 if (ver == PSCI_RET_NOT_SUPPORTED) { 298 pr_info("PSCIv%d.%d detected in firmware.\n",
302 /* 299 PSCI_VERSION_MAJOR(ver),
303 * PSCI versions >=0.2 mandates implementation of 300 PSCI_VERSION_MINOR(ver));
304 * PSCI_VERSION. 301
305 */ 302 if (PSCI_VERSION_MAJOR(ver) == 0 && PSCI_VERSION_MINOR(ver) < 2) {
306 pr_err("PSCI firmware does not comply with the v0.2 spec.\n"); 303 pr_err("Conflicting PSCI version detected.\n");
307 return -EOPNOTSUPP; 304 return -EINVAL;
308 } else {
309 pr_info("PSCIv%d.%d detected in firmware.\n",
310 PSCI_VERSION_MAJOR(ver),
311 PSCI_VERSION_MINOR(ver));
312
313 if (PSCI_VERSION_MAJOR(ver) == 0 &&
314 PSCI_VERSION_MINOR(ver) < 2) {
315 pr_err("Conflicting PSCI version detected.\n");
316 return -EINVAL;
317 }
318 } 305 }
319 306
320 psci_0_2_set_functions(); 307 psci_0_2_set_functions();
@@ -322,6 +309,8 @@ static int __init psci_probe(void)
322 return 0; 309 return 0;
323} 310}
324 311
312typedef int (*psci_initcall_t)(const struct device_node *);
313
325/* 314/*
326 * PSCI init function for PSCI versions >=0.2 315 * PSCI init function for PSCI versions >=0.2
327 * 316 *