1 /* 2 * PSCI API 3 * From arch/arm[64]/kernel/psci.c 4 * 5 * Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com> 6 * 7 * This work is licensed under the terms of the GNU LGPL, version 2. 8 */ 9 #include <asm/psci.h> 10 #include <asm/setup.h> 11 #include <asm/page.h> 12 13 #define T PSCI_INVOKE_ARG_TYPE 14 __attribute__((noinline)) 15 int psci_invoke(T function_id, T arg0, T arg1, T arg2) 16 { 17 asm volatile( 18 "hvc #0" 19 : "+r" (function_id) 20 : "r" (arg0), "r" (arg1), "r" (arg2)); 21 return function_id; 22 } 23 24 int psci_cpu_on(unsigned long cpuid, unsigned long entry_point) 25 { 26 return psci_invoke(PSCI_FN_CPU_ON, cpuid, entry_point, 0); 27 } 28 29 extern void secondary_entry(void); 30 int cpu_psci_cpu_boot(unsigned int cpu) 31 { 32 int err = psci_cpu_on(cpus[cpu], __pa(secondary_entry)); 33 if (err) 34 printf("failed to boot CPU%d (%d)\n", cpu, err); 35 return err; 36 } 37 38 #define PSCI_POWER_STATE_TYPE_POWER_DOWN (1U << 16) 39 void cpu_psci_cpu_die(unsigned int cpu) 40 { 41 int err = psci_invoke(PSCI_0_2_FN_CPU_OFF, 42 PSCI_POWER_STATE_TYPE_POWER_DOWN, 0, 0); 43 printf("unable to power off CPU%d (%d)\n", cpu, err); 44 } 45 46 void psci_sys_reset(void) 47 { 48 psci_invoke(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0); 49 } 50