[PATCH 3/4] microblaze: reset: Provide a power off handler through an unaligned PC
Thomas Weißschuh <[email protected]> Tue, 04 Aug 2026 07:32:35 +0200
| Newsgroups | org.kernel.vger.linux-kselftest,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
microblaze is missing a generic architecture-wide power off mechanism. To enable KUnit for microblaze it is necessary for KUnit to shut down the machine in a way that QEMU will recognize. The machines emulated by QEMU do not provide machine-specific power off functionality which could be used. However at least the petalogix-s3adsp1800 machine will abort if an unaligned instruction is executed. An ugly message will be printed but that is not an issue for KUnit. Make use of this to provide a power off handler. Signed-off-by: Thomas Weißschuh <[email protected]> --- This is quite hacky. But I didn't find a better solution. --- arch/microblaze/Kconfig | 9 +++++++++ arch/microblaze/kernel/reset.c | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 484ebb3baedf..0ca8999dd770 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -216,3 +216,12 @@ config MB_MANAGER Say N here unless you know what you are doing. endmenu + +config MB_POWER_OFF_THROUGH_UNALIGNED_PC + bool "Power off through unaligned PC" + help + This options adds a power off handler which executes an unaligned PC + so the machine resets in a generic way. This works for the + petalogix-s3adsp1800 QEMU machine. + + Say N here unless you know what you are doing. diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c index 3612a20ca16d..4af660deed3b 100644 --- a/arch/microblaze/kernel/reset.c +++ b/arch/microblaze/kernel/reset.c @@ -41,3 +41,24 @@ void machine_restart(char *cmd) pr_emerg("Reboot failed -- System halted\n"); while (1); } + +#ifdef CONFIG_MB_POWER_OFF_THROUGH_UNALIGNED_PC +static int unaligned_pc_sys_off(struct sys_off_data *data) +{ + __asm__( + "bri 1\n" + ); + + return NOTIFY_DONE; +} + +static int __init register_unaligned_pc_sys_off(void) +{ + struct sys_off_handler *sys_off; + + sys_off = register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_LOW, + unaligned_pc_sys_off, NULL); + return PTR_ERR_OR_ZERO(sys_off); +} +device_initcall(register_unaligned_pc_sys_off); +#endif /* CONFIG_MB_POWER_OFF_THROUGH_UNALIGNED_PC */ -- 2.55.0