summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2021-08-01 10:36:59 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-10-27 09:33:59 +0200
commitf40e21ef9da3ca9b75a37feac3ffa2125813a268 (patch)
tree448ff9184e629731c18ad6fe94976149b36de82c
parent4722f7320a1f8758751da141c81e73a36031f27d (diff)
downloadcommon-f40e21ef9da3ca9b75a37feac3ffa2125813a268.tar.gz
xtensa: xtfpga: Try software restart before simulating CPU reset
[ Upstream commit 012e974501a270d8dfd4ee2039e1fdf7579c907e ] Rebooting xtensa images loaded with the '-kernel' option in qemu does not work. When executing a reboot command, the qemu session either hangs or experiences an endless sequence of error messages. Kernel panic - not syncing: Unrecoverable error in exception handler Reset code jumps to the CPU restart address, but Linux can not recover from there because code and data in the kernel init sections have been discarded and overwritten at this point. XTFPGA platforms have a means to reset the CPU by writing 0xdead into a specific FPGA IO address. When used in QEMU the kernel image loaded with the '-kernel' option gets restored to its original state allowing the machine to boot successfully. Use that mechanism to attempt a platform reset. If it does not work, fall back to the existing mechanism. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--arch/xtensa/platforms/xtfpga/setup.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c
index 982e7c22e7ca..db5122765f16 100644
--- a/arch/xtensa/platforms/xtfpga/setup.c
+++ b/arch/xtensa/platforms/xtfpga/setup.c
@@ -54,8 +54,12 @@ void platform_power_off(void)
void platform_restart(void)
{
- /* Flush and reset the mmu, simulate a processor reset, and
- * jump to the reset vector. */
+ /* Try software reset first. */
+ WRITE_ONCE(*(u32 *)XTFPGA_SWRST_VADDR, 0xdead);
+
+ /* If software reset did not work, flush and reset the mmu,
+ * simulate a processor reset, and jump to the reset vector.
+ */
cpu_reset();
/* control never gets here */
}