diff options
| -rw-r--r-- | arch/arm64/kernel/Makefile | 5 | ||||
| -rw-r--r-- | arch/arm64/kernel/psci-call.S | 28 | ||||
| -rw-r--r-- | arch/arm64/kernel/psci.c | 37 |
3 files changed, 34 insertions, 36 deletions
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index bef04afd6031..5ee07eee80c2 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile | |||
| @@ -15,8 +15,9 @@ CFLAGS_REMOVE_return_address.o = -pg | |||
| 15 | arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ | 15 | arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ |
| 16 | entry-fpsimd.o process.o ptrace.o setup.o signal.o \ | 16 | entry-fpsimd.o process.o ptrace.o setup.o signal.o \ |
| 17 | sys.o stacktrace.o time.o traps.o io.o vdso.o \ | 17 | sys.o stacktrace.o time.o traps.o io.o vdso.o \ |
| 18 | hyp-stub.o psci.o cpu_ops.o insn.o return_address.o \ | 18 | hyp-stub.o psci.o psci-call.o cpu_ops.o insn.o \ |
| 19 | cpuinfo.o cpu_errata.o alternative.o cacheinfo.o | 19 | return_address.o cpuinfo.o cpu_errata.o \ |
| 20 | alternative.o cacheinfo.o | ||
| 20 | 21 | ||
| 21 | arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ | 22 | arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ |
| 22 | sys_compat.o entry32.o \ | 23 | sys_compat.o entry32.o \ |
diff --git a/arch/arm64/kernel/psci-call.S b/arch/arm64/kernel/psci-call.S new file mode 100644 index 000000000000..cf83e61cd3b5 --- /dev/null +++ b/arch/arm64/kernel/psci-call.S | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License version 2 as | ||
| 4 | * published by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * This program is distributed in the hope that it will be useful, | ||
| 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 9 | * GNU General Public License for more details. | ||
| 10 | * | ||
| 11 | * Copyright (C) 2015 ARM Limited | ||
| 12 | * | ||
| 13 | * Author: Will Deacon <will.deacon@arm.com> | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/linkage.h> | ||
| 17 | |||
| 18 | /* int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */ | ||
| 19 | ENTRY(__invoke_psci_fn_hvc) | ||
| 20 | hvc #0 | ||
| 21 | ret | ||
| 22 | ENDPROC(__invoke_psci_fn_hvc) | ||
| 23 | |||
| 24 | /* int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */ | ||
| 25 | ENTRY(__invoke_psci_fn_smc) | ||
| 26 | smc #0 | ||
| 27 | ret | ||
| 28 | ENDPROC(__invoke_psci_fn_smc) | ||
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index 3425f311c49e..9b8a70ae64a1 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c | |||
| @@ -57,6 +57,9 @@ static struct psci_operations psci_ops; | |||
| 57 | static int (*invoke_psci_fn)(u64, u64, u64, u64); | 57 | static int (*invoke_psci_fn)(u64, u64, u64, u64); |
| 58 | typedef int (*psci_initcall_t)(const struct device_node *); | 58 | typedef int (*psci_initcall_t)(const struct device_node *); |
| 59 | 59 | ||
| 60 | asmlinkage int __invoke_psci_fn_hvc(u64, u64, u64, u64); | ||
| 61 | asmlinkage int __invoke_psci_fn_smc(u64, u64, u64, u64); | ||
| 62 | |||
| 60 | enum psci_function { | 63 | enum psci_function { |
| 61 | PSCI_FN_CPU_SUSPEND, | 64 | PSCI_FN_CPU_SUSPEND, |
| 62 | PSCI_FN_CPU_ON, | 65 | PSCI_FN_CPU_ON, |
| @@ -109,40 +112,6 @@ static void psci_power_state_unpack(u32 power_state, | |||
| 109 | PSCI_0_2_POWER_STATE_AFFL_SHIFT; | 112 | PSCI_0_2_POWER_STATE_AFFL_SHIFT; |
| 110 | } | 113 | } |
| 111 | 114 | ||
| 112 | /* | ||
| 113 | * The following two functions are invoked via the invoke_psci_fn pointer | ||
| 114 | * and will not be inlined, allowing us to piggyback on the AAPCS. | ||
| 115 | */ | ||
| 116 | static noinline int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, | ||
| 117 | u64 arg2) | ||
| 118 | { | ||
| 119 | asm volatile( | ||
| 120 | __asmeq("%0", "x0") | ||
| 121 | __asmeq("%1", "x1") | ||
| 122 | __asmeq("%2", "x2") | ||
| 123 | __asmeq("%3", "x3") | ||
| 124 | "hvc #0\n" | ||
| 125 | : "+r" (function_id) | ||
| 126 | : "r" (arg0), "r" (arg1), "r" (arg2)); | ||
| 127 | |||
| 128 | return function_id; | ||
| 129 | } | ||
| 130 | |||
| 131 | static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, | ||
| 132 | u64 arg2) | ||
| 133 | { | ||
| 134 | asm volatile( | ||
| 135 | __asmeq("%0", "x0") | ||
| 136 | __asmeq("%1", "x1") | ||
| 137 | __asmeq("%2", "x2") | ||
| 138 | __asmeq("%3", "x3") | ||
| 139 | "smc #0\n" | ||
| 140 | : "+r" (function_id) | ||
| 141 | : "r" (arg0), "r" (arg1), "r" (arg2)); | ||
| 142 | |||
| 143 | return function_id; | ||
| 144 | } | ||
| 145 | |||
| 146 | static int psci_get_version(void) | 115 | static int psci_get_version(void) |
| 147 | { | 116 | { |
| 148 | int err; | 117 | int err; |
