aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/psci.c
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2015-03-06 06:08:30 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2015-03-29 18:11:17 -0400
commitc097877319ab61dd045b6497953b4e3df8f2bb44 (patch)
tree869acdb8ebded7e0d5469fc9c6cb7bb9f09972c0 /arch/arm/kernel/psci.c
parent15955e70320bdc5d60b153a572ee4d89ab34e3d3 (diff)
ARM: 8307/1: psci: move psci firmware calls out of line
arm64 builds with GCC 5 have caused the __asmeq assertions in the PSCI calling code to fire, so move the ARM PSCI calls out of line into their own assembly file for consistency and to safeguard against the same issue occuring with the 32-bit toolchain. [will: brought into line with arm64 implementation] Reported-by: Andy Whitcroft <apw@canonical.com> Signed-off-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/psci.c')
-rw-r--r--arch/arm/kernel/psci.c39
1 files changed, 3 insertions, 36 deletions
diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c
index f73891b6b730..f90fdf4ce7c7 100644
--- a/arch/arm/kernel/psci.c
+++ b/arch/arm/kernel/psci.c
@@ -23,8 +23,6 @@
23 23
24#include <asm/compiler.h> 24#include <asm/compiler.h>
25#include <asm/errno.h> 25#include <asm/errno.h>
26#include <asm/opcodes-sec.h>
27#include <asm/opcodes-virt.h>
28#include <asm/psci.h> 26#include <asm/psci.h>
29#include <asm/system_misc.h> 27#include <asm/system_misc.h>
30 28
@@ -33,6 +31,9 @@ struct psci_operations psci_ops;
33static int (*invoke_psci_fn)(u32, u32, u32, u32); 31static int (*invoke_psci_fn)(u32, u32, u32, u32);
34typedef int (*psci_initcall_t)(const struct device_node *); 32typedef int (*psci_initcall_t)(const struct device_node *);
35 33
34asmlinkage int __invoke_psci_fn_hvc(u32, u32, u32, u32);
35asmlinkage int __invoke_psci_fn_smc(u32, u32, u32, u32);
36
36enum psci_function { 37enum psci_function {
37 PSCI_FN_CPU_SUSPEND, 38 PSCI_FN_CPU_SUSPEND,
38 PSCI_FN_CPU_ON, 39 PSCI_FN_CPU_ON,
@@ -71,40 +72,6 @@ static u32 psci_power_state_pack(struct psci_power_state state)
71 & PSCI_0_2_POWER_STATE_AFFL_MASK); 72 & PSCI_0_2_POWER_STATE_AFFL_MASK);
72} 73}
73 74
74/*
75 * The following two functions are invoked via the invoke_psci_fn pointer
76 * and will not be inlined, allowing us to piggyback on the AAPCS.
77 */
78static noinline int __invoke_psci_fn_hvc(u32 function_id, u32 arg0, u32 arg1,
79 u32 arg2)
80{
81 asm volatile(
82 __asmeq("%0", "r0")
83 __asmeq("%1", "r1")
84 __asmeq("%2", "r2")
85 __asmeq("%3", "r3")
86 __HVC(0)
87 : "+r" (function_id)
88 : "r" (arg0), "r" (arg1), "r" (arg2));
89
90 return function_id;
91}
92
93static noinline int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1,
94 u32 arg2)
95{
96 asm volatile(
97 __asmeq("%0", "r0")
98 __asmeq("%1", "r1")
99 __asmeq("%2", "r2")
100 __asmeq("%3", "r3")
101 __SMC(0)
102 : "+r" (function_id)
103 : "r" (arg0), "r" (arg1), "r" (arg2));
104
105 return function_id;
106}
107
108static int psci_get_version(void) 75static int psci_get_version(void)
109{ 76{
110 int err; 77 int err;