Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware/psci: add support for SYSTEM_RESET2

PSCI v1.1 introduced SYSTEM_RESET2 to allow both architectural resets
where the semantics are described by the PSCI specification itself as
well as vendor-specific resets. Currently only system warm reset
semantics is defined as part of architectural resets by the specification.

This patch implements support for SYSTEM_RESET2 by making using of
reboot_mode passed by the reboot infrastructure in the kernel.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Sudeep Holla and committed by
Rafael J. Wysocki
4302e381 60dd1ead

+25 -1
+23 -1
drivers/firmware/psci/psci.c
··· 88 88 PSCI_1_0_EXT_POWER_STATE_TYPE_MASK) 89 89 90 90 static u32 psci_cpu_suspend_feature; 91 + static bool psci_system_reset2_supported; 91 92 92 93 static inline bool psci_has_ext_power_state(void) 93 94 { ··· 259 258 260 259 static void psci_sys_reset(enum reboot_mode reboot_mode, const char *cmd) 261 260 { 262 - invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0); 261 + if ((reboot_mode == REBOOT_WARM || reboot_mode == REBOOT_SOFT) && 262 + psci_system_reset2_supported) { 263 + /* 264 + * reset_type[31] = 0 (architectural) 265 + * reset_type[30:0] = 0 (SYSTEM_WARM_RESET) 266 + * cookie = 0 (ignored by the implementation) 267 + */ 268 + invoke_psci_fn(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2), 0, 0, 0); 269 + } else { 270 + invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0); 271 + } 263 272 } 264 273 265 274 static void psci_sys_poweroff(void) ··· 471 460 .enter = psci_system_suspend_enter, 472 461 }; 473 462 463 + static void __init psci_init_system_reset2(void) 464 + { 465 + int ret; 466 + 467 + ret = psci_features(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2)); 468 + 469 + if (ret != PSCI_RET_NOT_SUPPORTED) 470 + psci_system_reset2_supported = true; 471 + } 472 + 474 473 static void __init psci_init_system_suspend(void) 475 474 { 476 475 int ret; ··· 618 597 psci_init_smccc(); 619 598 psci_init_cpu_suspend(); 620 599 psci_init_system_suspend(); 600 + psci_init_system_reset2(); 621 601 } 622 602 623 603 return 0;
+2
include/uapi/linux/psci.h
··· 50 50 #define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10) 51 51 #define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14) 52 52 #define PSCI_1_0_FN_SET_SUSPEND_MODE PSCI_0_2_FN(15) 53 + #define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) 53 54 54 55 #define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) 56 + #define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) 55 57 56 58 /* PSCI v0.2 power state encoding for CPU_SUSPEND function */ 57 59 #define PSCI_0_2_POWER_STATE_ID_MASK 0xffff