diff --git a/arch/arm/cpu/armv8/fwcall.c b/arch/arm/cpu/armv8/fwcall.c index b0aca1b72a3b9fbf732d733446941127f0551331..cbd35b7f4a2a89d19b02139fc4c15d0ce8e81265 100644 --- a/arch/arm/cpu/armv8/fwcall.c +++ b/arch/arm/cpu/armv8/fwcall.c @@ -98,6 +98,22 @@ void __noreturn psci_system_reset(void) ; } +void __noreturn psci_system_reset2(u32 reset_level, u32 cookie) +{ + struct pt_regs regs; + + regs.regs[0] = ARM_PSCI_0_2_FN64_SYSTEM_RESET2; + regs.regs[1] = PSCI_RESET2_TYPE_VENDOR | reset_level; + regs.regs[2] = cookie; + if (use_smc_for_psci) + smc_call(®s); + else + hvc_call(®s); + + while (1) + ; +} + void __noreturn psci_system_off(void) { struct pt_regs regs; diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index 95f18e8cbcc9b3c01cfac6211ca699676c3665c8..3ddcd95a26d0ff65d5dc19836bdec138c0acf3e2 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -64,6 +64,7 @@ #define ARM_PSCI_0_2_FN64_AFFINITY_INFO ARM_PSCI_0_2_FN64(4) #define ARM_PSCI_0_2_FN64_MIGRATE ARM_PSCI_0_2_FN64(5) #define ARM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU ARM_PSCI_0_2_FN64(7) +#define ARM_PSCI_0_2_FN64_SYSTEM_RESET2 ARM_PSCI_0_2_FN64(18) /* PSCI 1.0 interface */ #define ARM_PSCI_1_0_FN_PSCI_FEATURES ARM_PSCI_0_2_FN(10) @@ -90,6 +91,9 @@ #define PSCI_AFFINITY_LEVEL_OFF 1 #define PSCI_AFFINITY_LEVEL_ON_PENDING 2 +#define PSCI_RESET2_TYPE_VENDOR_SHIFT 31 +#define PSCI_RESET2_TYPE_VENDOR BIT(PSCI_RESET2_TYPE_VENDOR_SHIFT) + #ifndef __ASSEMBLY__ #include diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index a1a5e35ef6fdc847e19f3faec57a61ef705b95e6..81ccead1127d7729b954176d6a06b8ea60280eb0 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -254,6 +254,7 @@ void mmu_change_region_attr(phys_addr_t start, size_t size, u64 attrs); void smc_call(struct pt_regs *args); void __noreturn psci_system_reset(void); +void __noreturn psci_system_reset2(u32 reset_level, u32 cookie); void __noreturn psci_system_off(void); #ifdef CONFIG_ARMV8_PSCI