From: Dimitri John Ledkov dimitri.ledkov@canonical.com
stable inclusion from stable-v5.10.137 commit 3ff605513f3116b78b8648a60ea97f1836ce1125 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I60PLB
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit f2928e224d85e7cc139009ab17cefdfec2df5d11 upstream.
Set pm_power_off to NULL like on all other architectures, check if it is set in machine_halt() and machine_power_off() and fallback to default_power_off if no other power driver got registered.
This brings riscv architecture inline with all other architectures, and allows to reuse exiting power drivers unmodified.
Kernels without legacy SBI v0.1 extensions (CONFIG_RISCV_SBI_V01 is not set), do not set pm_power_off to sbi_shutdown(). There is no support for SBI v0.3 system reset extension either. This prevents using gpio_poweroff on SiFive HiFive Unmatched.
Tested on SiFive HiFive unmatched, with a dtb specifying gpio-poweroff node and kernel complied without CONFIG_RISCV_SBI_V01.
BugLink: https://bugs.launchpad.net/bugs/1942806 Signed-off-by: Dimitri John Ledkov dimitri.ledkov@canonical.com Reviewed-by: Anup Patel anup@brainfault.org Tested-by: Ron Economos w6rz@comcast.net Signed-off-by: Palmer Dabbelt palmerdabbelt@google.com Cc: Nathan Chancellor nathan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Reviewed-by: Wei Li liwei391@huawei.com --- arch/riscv/kernel/reset.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/riscv/kernel/reset.c b/arch/riscv/kernel/reset.c index ee5878d968cc..9c842c41684a 100644 --- a/arch/riscv/kernel/reset.c +++ b/arch/riscv/kernel/reset.c @@ -12,7 +12,7 @@ static void default_power_off(void) wait_for_interrupt(); }
-void (*pm_power_off)(void) = default_power_off; +void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off);
void machine_restart(char *cmd) @@ -23,10 +23,16 @@ void machine_restart(char *cmd)
void machine_halt(void) { - pm_power_off(); + if (pm_power_off != NULL) + pm_power_off(); + else + default_power_off(); }
void machine_power_off(void) { - pm_power_off(); + if (pm_power_off != NULL) + pm_power_off(); + else + default_power_off(); }