Message ID | 20230118180338.6484-2-ajones@ventanamicro.com (mailing list archive) |
---|---|
State | Awaiting Upstream, archived |
Delegated to: | Palmer Dabbelt |
Headers | show |
Series | riscv: Introduce system suspend support | expand |
Context | Check | Description |
---|---|---|
conchuod/cover_letter | success | Series has a cover letter |
conchuod/tree_selection | success | Guessed tree name to be for-next |
conchuod/fixes_present | success | Fixes tag not required for -next series |
conchuod/maintainers_pattern | success | MAINTAINERS pattern errors before the patch: 13 and now 13 |
conchuod/verify_signedoff | success | Signed-off-by tag matches author and committer |
conchuod/kdoc | success | Errors and warnings before: 2 this patch: 2 |
conchuod/module_param | success | Was 0 now: 0 |
conchuod/build_rv64_gcc_allmodconfig | fail | Errors and warnings before: 2044 this patch: 2046 |
conchuod/alphanumeric_selects | success | Out of order selects before the patch: 57 and now 57 |
conchuod/build_rv32_defconfig | success | Build OK |
conchuod/dtb_warn_rv64 | success | Errors and warnings before: 2 this patch: 2 |
conchuod/header_inline | success | No static functions without inline keyword in header files |
conchuod/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 92 lines checked |
conchuod/source_inline | success | Was 0 now: 0 |
conchuod/build_rv64_nommu_k210_defconfig | success | Build OK |
conchuod/verify_fixes | success | No Fixes tag |
conchuod/build_rv64_nommu_virt_defconfig | success | Build OK |
On Wed, 18 Jan 2023 10:03:38 PST (-0800), ajones@ventanamicro.com wrote: > When the SUSP SBI extension is present it implies that the standard > "suspend to RAM" type is available. Wire it up to the generic > platform suspend support, also applying the already present support > for non-retentive CPU suspend. When the kernel is built with > CONFIG_SUSPEND, one can do 'echo mem > /sys/power/state' to suspend. > Resumption will occur when a platform-specific wake-up event arrives. > > Signed-off-by: Andrew Jones <ajones@ventanamicro.com> > --- > arch/riscv/Kconfig | 5 ++++- > arch/riscv/include/asm/sbi.h | 9 ++++++++ > arch/riscv/kernel/suspend.c | 43 ++++++++++++++++++++++++++++++++++++ > 3 files changed, 56 insertions(+), 1 deletion(-) > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > index e2b656043abf..28f182b611a7 100644 > --- a/arch/riscv/Kconfig > +++ b/arch/riscv/Kconfig > @@ -52,7 +52,7 @@ config RISCV > select CLONE_BACKWARDS > select CLINT_TIMER if !MMU > select COMMON_CLK > - select CPU_PM if CPU_IDLE > + select CPU_PM if (SUSPEND || CPU_IDLE) > select EDAC_SUPPORT > select GENERIC_ARCH_TOPOLOGY > select GENERIC_ATOMIC64 if !64BIT > @@ -686,6 +686,9 @@ config PORTABLE > select OF > select MMU > > +config ARCH_SUSPEND_POSSIBLE > + def_bool RISCV_SBI > + > menu "Power management options" > > source "kernel/power/Kconfig" > diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h > index 4ca7fbacff42..1250321e4e6c 100644 > --- a/arch/riscv/include/asm/sbi.h > +++ b/arch/riscv/include/asm/sbi.h > @@ -29,6 +29,7 @@ enum sbi_ext_id { > SBI_EXT_RFENCE = 0x52464E43, > SBI_EXT_HSM = 0x48534D, > SBI_EXT_SRST = 0x53525354, > + SBI_EXT_SUSP = 0x53555350, > SBI_EXT_PMU = 0x504D55, > > /* Experimentals extensions must lie within this range */ > @@ -113,6 +114,14 @@ enum sbi_srst_reset_reason { > SBI_SRST_RESET_REASON_SYS_FAILURE, > }; > > +enum sbi_ext_susp_fid { > + SBI_EXT_SUSP_SYSTEM_SUSPEND = 0, > +}; > + > +enum sbi_ext_susp_sleep_type { > + SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM = 0, > +}; > + > enum sbi_ext_pmu_fid { > SBI_EXT_PMU_NUM_COUNTERS = 0, > SBI_EXT_PMU_COUNTER_GET_INFO, > diff --git a/arch/riscv/kernel/suspend.c b/arch/riscv/kernel/suspend.c > index 9ba24fb8cc93..2109adeae594 100644 > --- a/arch/riscv/kernel/suspend.c > +++ b/arch/riscv/kernel/suspend.c > @@ -4,8 +4,12 @@ > * Copyright (c) 2022 Ventana Micro Systems Inc. > */ > > +#define pr_fmt(fmt) "suspend: " fmt > + > #include <linux/ftrace.h> > +#include <linux/suspend.h> > #include <asm/csr.h> > +#include <asm/sbi.h> > #include <asm/suspend.h> > > static void suspend_save_csrs(struct suspend_context *context) > @@ -85,3 +89,42 @@ int cpu_suspend(unsigned long arg, > > return rc; > } > + > +#ifdef CONFIG_RISCV_SBI > +static int sbi_system_suspend(unsigned long sleep_type, > + unsigned long resume_addr, > + unsigned long opaque) > +{ > + struct sbiret ret; > + > + ret = sbi_ecall(SBI_EXT_SUSP, SBI_EXT_SUSP_SYSTEM_SUSPEND, > + sleep_type, resume_addr, opaque, 0, 0, 0); > + if (ret.error) > + return sbi_err_map_linux_errno(ret.error); > + > + return ret.value; > +} > + > +static int sbi_system_suspend_enter(suspend_state_t state) > +{ > + return cpu_suspend(SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM, sbi_system_suspend); > +} > + > +static const struct platform_suspend_ops sbi_system_suspend_ops = { > + .valid = suspend_valid_only_mem, > + .enter = sbi_system_suspend_enter, > +}; > + > +static int __init sbi_system_suspend_init(void) > +{ > + if (!sbi_spec_is_0_1() && sbi_probe_extension(SBI_EXT_SUSP) > 0) { > + pr_info("SBI SUSP extension detected\n"); > + if (IS_ENABLED(CONFIG_SUSPEND)) > + suspend_set_ops(&sbi_system_suspend_ops); > + } > + > + return 0; > +} > + > +arch_initcall(sbi_system_suspend_init); > +#endif /* CONFIG_RISCV_SBI */ The code looks fine, but I can't find the SUSP extension anywhere. There's just hart suspend in <https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/riscv-sbi.adoc>.
On Tue, Feb 28, 2023 at 07:54:56AM -0800, Palmer Dabbelt wrote: > On Wed, 18 Jan 2023 10:03:38 PST (-0800), ajones@ventanamicro.com wrote: > > When the SUSP SBI extension is present it implies that the standard > > "suspend to RAM" type is available. Wire it up to the generic > > platform suspend support, also applying the already present support > > for non-retentive CPU suspend. When the kernel is built with > > CONFIG_SUSPEND, one can do 'echo mem > /sys/power/state' to suspend. > > Resumption will occur when a platform-specific wake-up event arrives. > > > The code looks fine, but I can't find the SUSP extension anywhere. There's > just hart suspend in > <https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/riscv-sbi.adoc>. It's not merged yet, so: https://lists.riscv.org/g/tech-prs/message/222 & https://lists.riscv.org/g/tech-prs/message/228 Or on GitHub for those who are not members of the RVI stuff: https://github.com/jones-drew/riscv-sbi-doc/commits/susp-v1
On Tue, Feb 28, 2023 at 07:54:56AM -0800, Palmer Dabbelt wrote: > On Wed, 18 Jan 2023 10:03:38 PST (-0800), ajones@ventanamicro.com wrote: > > +#endif /* CONFIG_RISCV_SBI */ > > The code looks fine, but I can't find the SUSP extension anywhere. There's > just hart suspend in > <https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/riscv-sbi.adoc>. Thanks for looking, Palmer. It looks like Conor got you pointed at the draft spec addition[1]. When the spec addition gets accepted, I'll rebase and repost this patch without the RFC. [1] https://github.com/jones-drew/riscv-sbi-doc/commit/0a7ddb1786b0566287efaa6b55321dafecc885ca Thanks, drew
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index e2b656043abf..28f182b611a7 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -52,7 +52,7 @@ config RISCV select CLONE_BACKWARDS select CLINT_TIMER if !MMU select COMMON_CLK - select CPU_PM if CPU_IDLE + select CPU_PM if (SUSPEND || CPU_IDLE) select EDAC_SUPPORT select GENERIC_ARCH_TOPOLOGY select GENERIC_ATOMIC64 if !64BIT @@ -686,6 +686,9 @@ config PORTABLE select OF select MMU +config ARCH_SUSPEND_POSSIBLE + def_bool RISCV_SBI + menu "Power management options" source "kernel/power/Kconfig" diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 4ca7fbacff42..1250321e4e6c 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -29,6 +29,7 @@ enum sbi_ext_id { SBI_EXT_RFENCE = 0x52464E43, SBI_EXT_HSM = 0x48534D, SBI_EXT_SRST = 0x53525354, + SBI_EXT_SUSP = 0x53555350, SBI_EXT_PMU = 0x504D55, /* Experimentals extensions must lie within this range */ @@ -113,6 +114,14 @@ enum sbi_srst_reset_reason { SBI_SRST_RESET_REASON_SYS_FAILURE, }; +enum sbi_ext_susp_fid { + SBI_EXT_SUSP_SYSTEM_SUSPEND = 0, +}; + +enum sbi_ext_susp_sleep_type { + SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM = 0, +}; + enum sbi_ext_pmu_fid { SBI_EXT_PMU_NUM_COUNTERS = 0, SBI_EXT_PMU_COUNTER_GET_INFO, diff --git a/arch/riscv/kernel/suspend.c b/arch/riscv/kernel/suspend.c index 9ba24fb8cc93..2109adeae594 100644 --- a/arch/riscv/kernel/suspend.c +++ b/arch/riscv/kernel/suspend.c @@ -4,8 +4,12 @@ * Copyright (c) 2022 Ventana Micro Systems Inc. */ +#define pr_fmt(fmt) "suspend: " fmt + #include <linux/ftrace.h> +#include <linux/suspend.h> #include <asm/csr.h> +#include <asm/sbi.h> #include <asm/suspend.h> static void suspend_save_csrs(struct suspend_context *context) @@ -85,3 +89,42 @@ int cpu_suspend(unsigned long arg, return rc; } + +#ifdef CONFIG_RISCV_SBI +static int sbi_system_suspend(unsigned long sleep_type, + unsigned long resume_addr, + unsigned long opaque) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_SUSP, SBI_EXT_SUSP_SYSTEM_SUSPEND, + sleep_type, resume_addr, opaque, 0, 0, 0); + if (ret.error) + return sbi_err_map_linux_errno(ret.error); + + return ret.value; +} + +static int sbi_system_suspend_enter(suspend_state_t state) +{ + return cpu_suspend(SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM, sbi_system_suspend); +} + +static const struct platform_suspend_ops sbi_system_suspend_ops = { + .valid = suspend_valid_only_mem, + .enter = sbi_system_suspend_enter, +}; + +static int __init sbi_system_suspend_init(void) +{ + if (!sbi_spec_is_0_1() && sbi_probe_extension(SBI_EXT_SUSP) > 0) { + pr_info("SBI SUSP extension detected\n"); + if (IS_ENABLED(CONFIG_SUSPEND)) + suspend_set_ops(&sbi_system_suspend_ops); + } + + return 0; +} + +arch_initcall(sbi_system_suspend_init); +#endif /* CONFIG_RISCV_SBI */
When the SUSP SBI extension is present it implies that the standard "suspend to RAM" type is available. Wire it up to the generic platform suspend support, also applying the already present support for non-retentive CPU suspend. When the kernel is built with CONFIG_SUSPEND, one can do 'echo mem > /sys/power/state' to suspend. Resumption will occur when a platform-specific wake-up event arrives. Signed-off-by: Andrew Jones <ajones@ventanamicro.com> --- arch/riscv/Kconfig | 5 ++++- arch/riscv/include/asm/sbi.h | 9 ++++++++ arch/riscv/kernel/suspend.c | 43 ++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-)