aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firmware/psci/psci.c24
-rw-r--r--include/uapi/linux/psci.h2
2 files changed, 25 insertions, 1 deletions
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index eabd01383cd6..fe090ef43d28 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -88,6 +88,7 @@ static u32 psci_function_id[PSCI_FN_MAX];
88 PSCI_1_0_EXT_POWER_STATE_TYPE_MASK) 88 PSCI_1_0_EXT_POWER_STATE_TYPE_MASK)
89 89
90static u32 psci_cpu_suspend_feature; 90static u32 psci_cpu_suspend_feature;
91static bool psci_system_reset2_supported;
91 92
92static inline bool psci_has_ext_power_state(void) 93static inline bool psci_has_ext_power_state(void)
93{ 94{
@@ -258,7 +259,17 @@ static int get_set_conduit_method(struct device_node *np)
258 259
259static void psci_sys_reset(enum reboot_mode reboot_mode, const char *cmd) 260static void psci_sys_reset(enum reboot_mode reboot_mode, const char *cmd)
260{ 261{
261 invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0); 262 if ((reboot_mode == REBOOT_WARM || reboot_mode == REBOOT_SOFT) &&
263 psci_system_reset2_supported) {
264 /*
265 * reset_type[31] = 0 (architectural)
266 * reset_type[30:0] = 0 (SYSTEM_WARM_RESET)
267 * cookie = 0 (ignored by the implementation)
268 */
269 invoke_psci_fn(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2), 0, 0, 0);
270 } else {
271 invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
272 }
262} 273}
263 274
264static void psci_sys_poweroff(void) 275static void psci_sys_poweroff(void)
@@ -460,6 +471,16 @@ static const struct platform_suspend_ops psci_suspend_ops = {
460 .enter = psci_system_suspend_enter, 471 .enter = psci_system_suspend_enter,
461}; 472};
462 473
474static void __init psci_init_system_reset2(void)
475{
476 int ret;
477
478 ret = psci_features(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2));
479
480 if (ret != PSCI_RET_NOT_SUPPORTED)
481 psci_system_reset2_supported = true;
482}
483
463static void __init psci_init_system_suspend(void) 484static void __init psci_init_system_suspend(void)
464{ 485{
465 int ret; 486 int ret;
@@ -597,6 +618,7 @@ static int __init psci_probe(void)
597 psci_init_smccc(); 618 psci_init_smccc();
598 psci_init_cpu_suspend(); 619 psci_init_cpu_suspend();
599 psci_init_system_suspend(); 620 psci_init_system_suspend();
621 psci_init_system_reset2();
600 } 622 }
601 623
602 return 0; 624 return 0;
diff --git a/include/uapi/linux/psci.h b/include/uapi/linux/psci.h
index 581f72085c33..2fcad1dd0b0e 100644
--- a/include/uapi/linux/psci.h
+++ b/include/uapi/linux/psci.h
@@ -50,8 +50,10 @@
50#define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10) 50#define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10)
51#define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14) 51#define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14)
52#define PSCI_1_0_FN_SET_SUSPEND_MODE PSCI_0_2_FN(15) 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#define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) 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/* PSCI v0.2 power state encoding for CPU_SUSPEND function */ 58/* PSCI v0.2 power state encoding for CPU_SUSPEND function */
57#define PSCI_0_2_POWER_STATE_ID_MASK 0xffff 59#define PSCI_0_2_POWER_STATE_ID_MASK 0xffff