summaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/imxwd.c
diff options
context:
space:
mode:
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;