From 85a804c59e2c7d60ddd21e843defb77e402db7c8 Mon Sep 17 00:00:00 2001 From: wangchenlu2236 Date: Wed, 4 Nov 2026 10:23:46 +0800 Subject: [PATCH] PM: power: Add a standby system state on Phytium platforms This patch adds a "standby" system state on phytium SoCs, This state has a power consumption level between S2idle and S3, but it provides better system responsiveness. Mainline: NA Signed-off-by: Wang Xu Signed-off-by: Wang Yinfeng Signed-off-by: Wang Chenlu --- drivers/firmware/psci/psci.c | 38 +++++++++++++++++++++++++++++++++++- include/linux/suspend.h | 3 +++ kernel/power/suspend.c | 16 +++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c index d6701d81cf68..ac8916d92a1e 100644 --- a/drivers/firmware/psci/psci.c +++ b/drivers/firmware/psci/psci.c @@ -28,7 +28,9 @@ #include #include #include - +#ifdef CONFIG_ARCH_PHYTIUM +#include +#endif /* * While a 64-bit OS can make calls with SMC32 calling conventions, for some * calls it is necessary to use SMC64 to pass or return 64-bit values. @@ -495,6 +497,31 @@ int psci_cpu_suspend_enter(u32 state) } #endif +#ifdef CONFIG_ARCH_PHYTIUM +static int phytium_psci_system_suspend(unsigned long state) +{ + phys_addr_t pa_cpu_resume = __pa_symbol(cpu_resume); + + if (state == PM_SUSPEND_STANDBY) + return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), + pa_cpu_resume, 0x544600c2, 0); + else + return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), + pa_cpu_resume, 0, 0); +} + +static int phytium_psci_system_suspend_enter(suspend_state_t state) +{ + return cpu_suspend(state, phytium_psci_system_suspend); +} + + +static const struct platform_suspend_ops phytium_psci_suspend_ops = { + .valid = phytium_suspend_valid_mem, + .enter = phytium_psci_system_suspend_enter, +}; +#endif + static int psci_system_suspend(unsigned long unused) { int err; @@ -535,7 +562,16 @@ static void __init psci_init_system_suspend(void) ret = psci_features(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND)); if (ret != PSCI_RET_NOT_SUPPORTED) + { +#ifdef CONFIG_ARCH_PHYTIUM + if (is_pd2408()) + suspend_set_ops(&phytium_psci_suspend_ops); + else + suspend_set_ops(&psci_suspend_ops); +#else suspend_set_ops(&psci_suspend_ops); +#endif + } } static void __init psci_init_cpu_suspend(void) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index ef503088942d..6b51f5665de8 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -212,6 +212,9 @@ extern suspend_state_t mem_sleep_default; */ extern void suspend_set_ops(const struct platform_suspend_ops *ops); extern int suspend_valid_only_mem(suspend_state_t state); +#ifdef CONFIG_ARCH_PHYTIUM +extern int phytium_suspend_valid_mem(suspend_state_t state); +#endif extern unsigned int pm_suspend_global_flags; diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 3aae526cc4aa..7e855ad243aa 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -248,6 +248,22 @@ int suspend_valid_only_mem(suspend_state_t state) } EXPORT_SYMBOL_GPL(suspend_valid_only_mem); +#ifdef CONFIG_ARCH_PHYTIUM +int phytium_suspend_valid_mem(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_MEM: + return state == PM_SUSPEND_MEM; + case PM_SUSPEND_STANDBY: + return state == PM_SUSPEND_STANDBY; + default: + pr_err("no valid state support\n"); + return 0; + } +} +EXPORT_SYMBOL_GPL(phytium_suspend_valid_mem); +#endif + static bool sleep_state_supported(suspend_state_t state) { return state == PM_SUSPEND_TO_IDLE ||