forked from Mirrors/opensbi
		
	lib: sbi: Add system suspend skeleton
Add the SUSP extension probe and ecall support, but for now the system suspend function is just a stub. Signed-off-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
		@@ -22,6 +22,10 @@ config SBI_ECALL_SRST
 | 
			
		||||
	bool "System Reset extension"
 | 
			
		||||
	default y
 | 
			
		||||
 | 
			
		||||
config SBI_ECALL_SUSP
 | 
			
		||||
	bool "System Suspend extension"
 | 
			
		||||
	default y
 | 
			
		||||
 | 
			
		||||
config SBI_ECALL_PMU
 | 
			
		||||
	bool "Performance Monitoring Unit extension"
 | 
			
		||||
	default y
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,9 @@ libsbi-objs-$(CONFIG_SBI_ECALL_HSM) += sbi_ecall_hsm.o
 | 
			
		||||
carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_SRST) += ecall_srst
 | 
			
		||||
libsbi-objs-$(CONFIG_SBI_ECALL_SRST) += sbi_ecall_srst.o
 | 
			
		||||
 | 
			
		||||
carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_SUSP) += ecall_susp
 | 
			
		||||
libsbi-objs-$(CONFIG_SBI_ECALL_SUSP) += sbi_ecall_susp.o
 | 
			
		||||
 | 
			
		||||
carray-sbi_ecall_exts-$(CONFIG_SBI_ECALL_PMU) += ecall_pmu
 | 
			
		||||
libsbi-objs-$(CONFIG_SBI_ECALL_PMU) += sbi_ecall_pmu.o
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								lib/sbi/sbi_ecall_susp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								lib/sbi/sbi_ecall_susp.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
// SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#include <sbi/sbi_ecall.h>
 | 
			
		||||
#include <sbi/sbi_ecall_interface.h>
 | 
			
		||||
#include <sbi/sbi_error.h>
 | 
			
		||||
#include <sbi/sbi_trap.h>
 | 
			
		||||
#include <sbi/sbi_system.h>
 | 
			
		||||
 | 
			
		||||
static int sbi_ecall_susp_handler(unsigned long extid, unsigned long funcid,
 | 
			
		||||
				  const struct sbi_trap_regs *regs,
 | 
			
		||||
				  unsigned long *out_val,
 | 
			
		||||
				  struct sbi_trap_info *out_trap)
 | 
			
		||||
{
 | 
			
		||||
	int ret = SBI_ENOTSUPP;
 | 
			
		||||
 | 
			
		||||
	if (funcid == SBI_EXT_SUSP_SUSPEND)
 | 
			
		||||
		ret = sbi_system_suspend(regs->a0, regs->a1, regs->a2);
 | 
			
		||||
 | 
			
		||||
	if (ret >= 0) {
 | 
			
		||||
		*out_val = ret;
 | 
			
		||||
		ret = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sbi_ecall_susp_probe(unsigned long extid, unsigned long *out_val)
 | 
			
		||||
{
 | 
			
		||||
	u32 type, count = 0;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * At least one suspend type should be supported by the
 | 
			
		||||
	 * platform for the SBI SUSP extension to be usable.
 | 
			
		||||
	 */
 | 
			
		||||
	for (type = 0; type <= SBI_SUSP_SLEEP_TYPE_LAST; type++) {
 | 
			
		||||
		if (sbi_system_suspend_supported(type))
 | 
			
		||||
			count++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*out_val = count ? 1 : 0;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct sbi_ecall_extension ecall_susp = {
 | 
			
		||||
	.extid_start = SBI_EXT_SUSP,
 | 
			
		||||
	.extid_end = SBI_EXT_SUSP,
 | 
			
		||||
	.handle = sbi_ecall_susp_handler,
 | 
			
		||||
	.probe = sbi_ecall_susp_probe,
 | 
			
		||||
};
 | 
			
		||||
@@ -69,6 +69,7 @@ static void sbi_boot_print_general(struct sbi_scratch *scratch)
 | 
			
		||||
	const struct sbi_timer_device *tdev;
 | 
			
		||||
	const struct sbi_console_device *cdev;
 | 
			
		||||
	const struct sbi_system_reset_device *srdev;
 | 
			
		||||
	const struct sbi_system_suspend_device *susp_dev;
 | 
			
		||||
	const struct sbi_platform *plat = sbi_platform_ptr(scratch);
 | 
			
		||||
 | 
			
		||||
	if (scratch->options & SBI_SCRATCH_NO_BOOT_PRINTS)
 | 
			
		||||
@@ -103,6 +104,9 @@ static void sbi_boot_print_general(struct sbi_scratch *scratch)
 | 
			
		||||
	srdev = sbi_system_reset_get_device(SBI_SRST_RESET_TYPE_SHUTDOWN, 0);
 | 
			
		||||
	sbi_printf("Platform Shutdown Device  : %s\n",
 | 
			
		||||
		   (srdev) ? srdev->name : "---");
 | 
			
		||||
	susp_dev = sbi_system_suspend_get_device();
 | 
			
		||||
	sbi_printf("Platform Suspend Device   : %s\n",
 | 
			
		||||
		   (susp_dev) ? susp_dev->name : "---");
 | 
			
		||||
 | 
			
		||||
	/* Firmware details */
 | 
			
		||||
	sbi_printf("Firmware Base             : 0x%lx\n", scratch->fw_start);
 | 
			
		||||
 
 | 
			
		||||
@@ -92,3 +92,29 @@ void __noreturn sbi_system_reset(u32 reset_type, u32 reset_reason)
 | 
			
		||||
	/* If platform specific reset did not work then do sbi_exit() */
 | 
			
		||||
	sbi_exit(scratch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct sbi_system_suspend_device *suspend_dev = NULL;
 | 
			
		||||
 | 
			
		||||
const struct sbi_system_suspend_device *sbi_system_suspend_get_device(void)
 | 
			
		||||
{
 | 
			
		||||
	return suspend_dev;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sbi_system_suspend_set_device(struct sbi_system_suspend_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	if (!dev || suspend_dev)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	suspend_dev = dev;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool sbi_system_suspend_supported(u32 sleep_type)
 | 
			
		||||
{
 | 
			
		||||
	return suspend_dev && suspend_dev->system_suspend_check &&
 | 
			
		||||
	       suspend_dev->system_suspend_check(sleep_type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sbi_system_suspend(u32 sleep_type, ulong resume_addr, ulong opaque)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user