Messages in this thread Patch in this message | | | From | Samuel Holland <> | Subject | [PATCH 3/3] riscv: sbi: Switch to the sys-off handler API | Date | Wed, 28 Dec 2022 10:19:15 -0600 |
| |
Any other poweroff handlers registered at the default priority will run before the legacy pm_power_off() function. Register the SBI poweroff handler with the correct priority to ensure it runs first.
Signed-off-by: Samuel Holland <samuel@sholland.org> ---
arch/riscv/include/asm/sbi.h | 1 - arch/riscv/kernel/sbi.c | 52 +++++++++++++++++++++--------------- 2 files changed, 30 insertions(+), 23 deletions(-)
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 4ca7fbacff42..2915a3ddf7c6 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -267,7 +267,6 @@ long sbi_get_mvendorid(void); long sbi_get_marchid(void); long sbi_get_mimpid(void); void sbi_set_timer(uint64_t stime_value); -void sbi_shutdown(void); void sbi_clear_ipi(void); int sbi_send_ipi(const struct cpumask *cpu_mask); int sbi_remote_fence_i(const struct cpumask *cpu_mask); diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c index 1196c12299f6..9574851eae6e 100644 --- a/arch/riscv/kernel/sbi.c +++ b/arch/riscv/kernel/sbi.c @@ -7,7 +7,6 @@ #include <linux/bits.h> #include <linux/init.h> -#include <linux/pm.h> #include <linux/reboot.h> #include <asm/sbi.h> #include <asm/smp.h> @@ -120,15 +119,16 @@ int sbi_console_getchar(void) EXPORT_SYMBOL(sbi_console_getchar); /** - * sbi_shutdown() - Remove all the harts from executing supervisor code. + * __sbi_shutdown_v01() - Remove all the harts from executing supervisor code. * - * Return: None + * Return: NOTIFY_DONE */ -void sbi_shutdown(void) +static int __sbi_shutdown_v01(struct sys_off_data *data) { sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0); + + return NOTIFY_DONE; } -EXPORT_SYMBOL(sbi_shutdown); /** * sbi_clear_ipi() - Clear any pending IPIs for the calling hart. @@ -204,11 +204,6 @@ static int __sbi_rfence_v01(int fid, const struct cpumask *cpu_mask, return result; } - -static void sbi_set_power_off(void) -{ - pm_power_off = sbi_shutdown; -} #else static void __sbi_warn_unsupported(const char *extension) { @@ -216,6 +211,13 @@ static void __sbi_warn_unsupported(const char *extension) extension, sbi_major_version(), sbi_minor_version()); } +static int __sbi_shutdown_v01(struct sys_off_data *data) +{ + __sbi_warn_unsupported("Shutdown"); + + return NOTIFY_DONE; +} + static void __sbi_set_timer_v01(uint64_t stime_value) { __sbi_warn_unsupported("Timer"); @@ -236,8 +238,6 @@ static int __sbi_rfence_v01(int fid, const struct cpumask *cpu_mask, return 0; } - -static void sbi_set_power_off(void) {} #endif /* CONFIG_RISCV_SBI_V01 */ static void __sbi_set_timer_v02(uint64_t stime_value) @@ -574,10 +574,12 @@ static int sbi_srst_reboot(struct notifier_block *this, static struct notifier_block sbi_srst_reboot_nb; -static void sbi_srst_power_off(void) +static int sbi_srst_power_off(struct sys_off_data *data) { sbi_srst_reset(SBI_SRST_RESET_TYPE_SHUTDOWN, SBI_SRST_RESET_REASON_NONE); + + return NOTIFY_DONE; } /** @@ -657,7 +659,6 @@ void __init sbi_init(void) { int ret; - sbi_set_power_off(); ret = sbi_get_spec_version(); if (ret > 0) sbi_spec_version = ret; @@ -686,19 +687,26 @@ void __init sbi_init(void) } else { __sbi_rfence = __sbi_rfence_v01; } - if ((sbi_spec_version >= sbi_mk_version(0, 3)) && - (sbi_probe_extension(SBI_EXT_SRST) > 0)) { - pr_info("SBI SRST extension detected\n"); - pm_power_off = sbi_srst_power_off; - sbi_srst_reboot_nb.notifier_call = sbi_srst_reboot; - sbi_srst_reboot_nb.priority = 192; - register_restart_handler(&sbi_srst_reboot_nb); - } } else { __sbi_set_timer = __sbi_set_timer_v01; __sbi_send_ipi = __sbi_send_ipi_v01; __sbi_rfence = __sbi_rfence_v01; } + if ((sbi_spec_version >= sbi_mk_version(0, 3)) && + (sbi_probe_extension(SBI_EXT_SRST) > 0)) { + pr_info("SBI SRST extension detected\n"); + sbi_srst_reboot_nb.notifier_call = sbi_srst_reboot; + sbi_srst_reboot_nb.priority = 192; + register_restart_handler(&sbi_srst_reboot_nb); + register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_FIRMWARE, + sbi_srst_power_off, NULL); + } else { + register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_FIRMWARE, + __sbi_shutdown_v01, NULL); + } + riscv_set_ipi_ops(&sbi_ipi_ops); } -- 2.37.4
| |