diff mbox series

[RFC,1/1] riscv: sbi: Introduce system suspend support

Message ID 20230106113216.443057-2-ajones@ventanamicro.com (mailing list archive)
State Superseded
Delegated to: Palmer Dabbelt
Headers show
Series riscv: Introduce system suspend support | expand

Checks

Context Check Description
conchuod/patch_count success Link
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/alphanumeric_selects success Out of order selects before the patch: 57 and now 57
conchuod/build_rv32_defconfig success Build OK
conchuod/build_warn_rv64 fail Errors and warnings before: 2054 this patch: 2056
conchuod/dtb_warn_rv64 success Errors and warnings before: 0 this patch: 0
conchuod/header_inline success No static functions without inline keyword in header files
conchuod/checkpatch success total: 0 errors, 0 warnings, 0 checks, 90 lines checked
conchuod/source_inline success Was 0 now: 0
conchuod/build_rv64_nommu_k210_defconfig fail Build failed
conchuod/verify_fixes success No Fixes tag
conchuod/build_rv64_nommu_virt_defconfig fail Build failed

Commit Message

Andrew Jones Jan. 6, 2023, 11:32 a.m. UTC
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  | 41 ++++++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+), 1 deletion(-)

Comments

Ley Foon Tan Jan. 10, 2023, 2:55 p.m. UTC | #1
> 
>  source "kernel/power/Kconfig"
> diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index
> 4ca7fbacff42..9834ba4ce3e4 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_SUSPEND = 0,

Macro name with "*_SYSTEM_SUSPEND" is better? Avoid confusing with CPU suspend.

> +};
> +
> +enum sbi_ext_susp_sleep_type {
> +	SBI_SUSP_SLEEP_TYPE_SUSPEND = 0,
This should be SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM?


Regards
Ley Foon
Andrew Jones Jan. 10, 2023, 3:52 p.m. UTC | #2
On Tue, Jan 10, 2023 at 02:55:20PM +0000, Leyfoon Tan wrote:
> 
> > 
> >  source "kernel/power/Kconfig"
> > diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index
> > 4ca7fbacff42..9834ba4ce3e4 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_SUSPEND = 0,
> 
> Macro name with "*_SYSTEM_SUSPEND" is better? Avoid confusing with CPU suspend.

The _SUSP_ part should cover that, but I'm OK with adding SYSTEM as well.

> 
> > +};
> > +
> > +enum sbi_ext_susp_sleep_type {
> > +	SBI_SUSP_SLEEP_TYPE_SUSPEND = 0,
> This should be SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM?

Yes, that would be better. I'll change that for the next version.

Thanks,
drew
Conor Dooley Jan. 10, 2023, 10:23 p.m. UTC | #3
Hey Drew!

On Fri, Jan 06, 2023 at 12:32:16PM +0100, Andrew Jones 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>

First things first, anything SBI depends on !m-mode, so you've gotta add
some sort of gating unfortunately around those ECALLs. But I figure you
may have already seen the build failures on patchwork for nommu?

Also, when there's an actual spec would you mind doing a Link: spec.pdf?

> ---
>  arch/riscv/Kconfig           |  5 ++++-
>  arch/riscv/include/asm/sbi.h |  9 ++++++++
>  arch/riscv/kernel/suspend.c  | 41 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 54 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index e2b656043abf..a53d94c1953e 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 y

Since the content you're adding depends on having an SBI extention,
does this need to be s/y/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..9834ba4ce3e4 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_SUSPEND = 0,
> +};
> +
> +enum sbi_ext_susp_sleep_type {
> +	SBI_SUSP_SLEEP_TYPE_SUSPEND = 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..bc26e9ae4782 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,40 @@ int cpu_suspend(unsigned long arg,
>  
>  	return rc;
>  }

And then from here down needs to be #ifdef RISCV_SBI?

Anyways, probably stating the obvious on an RFC, but ¯\_(ツ)_/¯

Thanks,
Conor.

> +
> +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_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, 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);
> -- 
> 2.39.0
> 
> 
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
Andrew Jones Jan. 11, 2023, 8:52 a.m. UTC | #4
On Tue, Jan 10, 2023 at 10:23:00PM +0000, Conor Dooley wrote:
> Hey Drew!
> 
> On Fri, Jan 06, 2023 at 12:32:16PM +0100, Andrew Jones 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>
> 
> First things first, anything SBI depends on !m-mode, so you've gotta add
> some sort of gating unfortunately around those ECALLs. But I figure you
> may have already seen the build failures on patchwork for nommu?

Actually, no, and I think I missed other emails like that in the past. I
assume I'm on the To: of these messages, so it's odd they're not showing
up. Can you forward me this message? I'll inspect the headers and try to
figure what's going on.

> 
> Also, when there's an actual spec would you mind doing a Link: spec.pdf?

Will do

> 
> > ---
> >  arch/riscv/Kconfig           |  5 ++++-
> >  arch/riscv/include/asm/sbi.h |  9 ++++++++
> >  arch/riscv/kernel/suspend.c  | 41 ++++++++++++++++++++++++++++++++++++
> >  3 files changed, 54 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> > index e2b656043abf..a53d94c1953e 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 y
> 
> Since the content you're adding depends on having an SBI extention,
> does this need to be s/y/RISCV_SBI/?

Indeed. Will do.

> 
> >  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..9834ba4ce3e4 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_SUSPEND = 0,
> > +};
> > +
> > +enum sbi_ext_susp_sleep_type {
> > +	SBI_SUSP_SLEEP_TYPE_SUSPEND = 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..bc26e9ae4782 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,40 @@ int cpu_suspend(unsigned long arg,
> >  
> >  	return rc;
> >  }
> 
> And then from here down needs to be #ifdef RISCV_SBI?
> 
> Anyways, probably stating the obvious on an RFC, but ¯\_(ツ)_/¯

Thanks for pointing this out. I made a last minute change to move
the content from arch/riscv/kernel/sbi.c to arch/riscv/kernel/suspend.c
and forgot I needed to worry about RISCV_SBI.

Thanks,
drew
Conor Dooley Jan. 11, 2023, 9:06 a.m. UTC | #5
On Wed, Jan 11, 2023 at 09:52:11AM +0100, Andrew Jones wrote:
> On Tue, Jan 10, 2023 at 10:23:00PM +0000, Conor Dooley wrote:
> > On Fri, Jan 06, 2023 at 12:32:16PM +0100, Andrew Jones 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>
> > 
> > First things first, anything SBI depends on !m-mode, so you've gotta add
> > some sort of gating unfortunately around those ECALLs. But I figure you
> > may have already seen the build failures on patchwork for nommu?
> 
> Actually, no, and I think I missed other emails like that in the past. I
> assume I'm on the To: of these messages, so it's odd they're not showing
> up. Can you forward me this message? I'll inspect the headers and try to
> figure what's going on.

Oh my bad, I assumed that you'd look on patchwork. I haven't made it send
emails as I don't trust it not to spam people with build issues that are
not their fault.

Sorry!
Conor.
Andrew Jones Jan. 11, 2023, 9:16 a.m. UTC | #6
On Wed, Jan 11, 2023 at 09:06:30AM +0000, Conor Dooley wrote:
> On Wed, Jan 11, 2023 at 09:52:11AM +0100, Andrew Jones wrote:
> > On Tue, Jan 10, 2023 at 10:23:00PM +0000, Conor Dooley wrote:
> > > On Fri, Jan 06, 2023 at 12:32:16PM +0100, Andrew Jones 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>
> > > 
> > > First things first, anything SBI depends on !m-mode, so you've gotta add
> > > some sort of gating unfortunately around those ECALLs. But I figure you
> > > may have already seen the build failures on patchwork for nommu?
> > 
> > Actually, no, and I think I missed other emails like that in the past. I
> > assume I'm on the To: of these messages, so it's odd they're not showing
> > up. Can you forward me this message? I'll inspect the headers and try to
> > figure what's going on.
> 
> Oh my bad, I assumed that you'd look on patchwork. I haven't made it send
> emails as I don't trust it not to spam people with build issues that are
> not their fault.

Ah, OK. I'll add a patchwork check to my patch submission workflow!

Thanks,
drew
diff mbox series

Patch

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index e2b656043abf..a53d94c1953e 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 y
+
 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..9834ba4ce3e4 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_SUSPEND = 0,
+};
+
+enum sbi_ext_susp_sleep_type {
+	SBI_SUSP_SLEEP_TYPE_SUSPEND = 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..bc26e9ae4782 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,40 @@  int cpu_suspend(unsigned long arg,
 
 	return rc;
 }
+
+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_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, 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);