summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorFabio Estevam <fabio.estevam@freescale.com>2015-10-03 14:21:00 -0300
committerTom Rini <trini@konsulko.com>2015-10-12 12:56:32 -0400
commitf861f51c4673d35908e4e330a86c81d7d909b51c (patch)
tree458a3dbe0522d27746ea843e55e94f9ba447b34e /arch/arm
parentf532727d16ebd3f8f9464aa503a1990f2f3b3211 (diff)
ls102xa: Fix reset hang
Since commit 623d96e89aca6("imx: wdog: correct wcr register settings") issuing a 'reset' command causes the system to hang. Unlike i.MX and Vybrid, the watchdog controller on LS102x is big-endian. This means that the watchdog on LS1021 has been working by accident as it does not use the big-endian accessors in drivers/watchdog/imx_watchdog.c. Commit 623d96e89aca6("imx: wdog: correct wcr register settings") only revelead the endianness problem on LS102x. In order to fix the reset hang, introduce a reset_cpu() implementation that is specific for ls102x, which accesses the watchdog WCR register in big-endian format. All that is required to reset LS102x is to clear the SRS bit. This approach is a temporary workaround to avoid a regression for LS102x in the 2015.10 release. The proper fix is to make the watchdog driver endian-aware, so that it can work for i.MX, Vybrid and LS102x. Reported-by: Sinan Akman <sinan@writeme.com> Tested-by: Sinan Akman <sinan@writeme.com> Reviewed-by: Wolfgang Denk <wd@denx.de> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/cpu/armv7/ls102xa/cpu.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/ls102xa/cpu.c b/arch/arm/cpu/armv7/ls102xa/cpu.c
index 8dd95d9879..e2eb5f383a 100644
--- a/arch/arm/cpu/armv7/ls102xa/cpu.c
+++ b/arch/arm/cpu/armv7/ls102xa/cpu.c
@@ -13,6 +13,8 @@
#include <tsec.h>
#include <netdev.h>
#include <fsl_esdhc.h>
+#include <config.h>
+#include <fsl_wdog.h>
#include "fsl_epu.h"
@@ -354,3 +356,16 @@ void smp_kick_all_cpus(void)
asm volatile("sev");
}
#endif
+
+void reset_cpu(ulong addr)
+{
+ struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
+
+ clrbits_be16(&wdog->wcr, WCR_SRS);
+
+ while (1) {
+ /*
+ * Let the watchdog trigger
+ */
+ }
+}