summaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/imxwd.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-10-08 00:01:01 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2012-10-08 21:41:36 +0200
commit2155bc5ba83aa94949ddf5bc5873475842289f64 (patch)
tree312703e1f85359e36e032154c2a855b910db65ae /drivers/watchdog/imxwd.c
parent90e9f773c186854adfdef852809f82517dc032da (diff)
downloadbarebox-2155bc5ba83aa94949ddf5bc5873475842289f64.tar.gz
barebox-2155bc5ba83aa94949ddf5bc5873475842289f64.tar.xz
ARM i.MX: move reset source detection code
- for i.MX1 the register is in the System Control unit, so move the code to arch/arm/mach-imx/imx1.c - for the other i.MX the register is in the watchdog unit, so move the code to drivers/watchdog/imxwd.c Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/watchdog/imxwd.c')
-rw-r--r--drivers/watchdog/imxwd.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index 7bbb86c405..c422f9819c 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -42,6 +42,15 @@ struct imx_wd {
#define IMX21_WDOG_WCR_SRS (1 << 4)
#define IMX21_WDOG_WCR_WDA (1 << 5)
+/* valid for i.MX25, i.MX27, i.MX31, i.MX35, i.MX51 */
+#define WSTR_WARMSTART (1 << 0)
+/* valid for i.MX25, i.MX27, i.MX31, i.MX35, i.MX51 */
+#define WSTR_WDOG (1 << 1)
+/* valid for i.MX27, i.MX31, always '0' on i.MX25, i.MX35, i.MX51 */
+#define WSTR_HARDRESET (1 << 3)
+/* valid for i.MX27, i.MX31, always '0' on i.MX25, i.MX35, i.MX51 */
+#define WSTR_COLDSTART (1 << 4)
+
static int imx1_watchdog_set_timeout(struct imx_wd *priv, int timeout)
{
u16 val;
@@ -115,6 +124,28 @@ void __noreturn reset_cpu(unsigned long addr)
hang();
}
+static void imx_watchdog_detect_reset_source(struct imx_wd *priv)
+{
+ u16 val = readw(priv->base + IMX21_WDOG_WSTR);
+
+ if (val & WSTR_COLDSTART) {
+ set_reset_source(RESET_POR);
+ return;
+ }
+
+ if (val & (WSTR_HARDRESET | WSTR_WARMSTART)) {
+ set_reset_source(RESET_RST);
+ return;
+ }
+
+ if (val & WSTR_WDOG) {
+ set_reset_source(RESET_WDG);
+ return;
+ }
+
+ /* else keep the default 'unknown' state */
+}
+
static int imx_wd_probe(struct device_d *dev)
{
struct imx_wd *priv;
@@ -140,6 +171,9 @@ static int imx_wd_probe(struct device_d *dev)
goto on_error;
}
+ if (fn != imx1_watchdog_set_timeout)
+ imx_watchdog_detect_reset_source(priv);
+
dev->priv = priv;
return 0;