summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2017-01-19 14:45:10 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2017-01-20 09:10:30 +0100
commitaadb845958bdc35d262b1e329289331d4ccfba8f (patch)
treea4ca6ebd1326291bb87a65639960b59c5b6788a6
parent626408b487260801afc01b6098135ecee227a2dd (diff)
downloadbarebox-aadb845958bdc35d262b1e329289331d4ccfba8f.tar.gz
watchdog: i.MX: add soc_reset operation
On i.MX21 watchdog type the reset operation is really different from the watchdog enable/set timeout operation, so create an extra callback for this instead of folding both things together. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--drivers/watchdog/imxwd.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index 03e116e..d1b98e6 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -25,7 +25,8 @@
struct imx_wd;
struct imx_wd_ops {
- int (*set_timeout)(struct imx_wd *, int);
+ int (*set_timeout)(struct imx_wd *, unsigned);
+ void (*soc_reset)(struct imx_wd *);
int (*init)(struct imx_wd *);
};
@@ -62,7 +63,7 @@ struct imx_wd {
/* 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)
+static int imx1_watchdog_set_timeout(struct imx_wd *priv, unsigned timeout)
{
u16 val;
@@ -76,10 +77,7 @@ static int imx1_watchdog_set_timeout(struct imx_wd *priv, int timeout)
return 0;
}
- if (timeout > 0)
- val = (timeout * 2 - 1) << 8;
- else
- val = 0;
+ val = (timeout * 2 - 1) << 8;
writew(val, priv->base + IMX1_WDOG_WCR);
writew(IMX1_WDOG_WCR_WDE | val, priv->base + IMX1_WDOG_WCR);
@@ -91,25 +89,26 @@ static int imx1_watchdog_set_timeout(struct imx_wd *priv, int timeout)
return 0;
}
-static int imx21_watchdog_set_timeout(struct imx_wd *priv, int timeout)
+static void imx1_soc_reset(struct imx_wd *priv)
+{
+ writew(IMX1_WDOG_WCR_WDE, priv->base + IMX1_WDOG_WCR);
+}
+
+static int imx21_watchdog_set_timeout(struct imx_wd *priv, unsigned timeout)
{
u16 val;
dev_dbg(priv->dev, "%s: %d\n", __func__, timeout);
- if (timeout < -1 || timeout > 128)
+ if (timeout > 128)
return -EINVAL;
if (timeout == 0) /* bit 2 (WDE) cannot be set to 0 again */
return -ENOSYS;
- if (timeout > 0)
- val = ((timeout * 2 - 1) << 8) | IMX21_WDOG_WCR_SRS |
- IMX21_WDOG_WCR_WDA;
- else
- val = 0;
+ val = ((timeout * 2 - 1) << 8) | IMX21_WDOG_WCR_SRS |
+ IMX21_WDOG_WCR_WDA;
- writew(val, priv->base + IMX21_WDOG_WCR);
writew(IMX21_WDOG_WCR_WDE | val, priv->base + IMX21_WDOG_WCR);
/* Write Service Sequence */
@@ -119,6 +118,15 @@ static int imx21_watchdog_set_timeout(struct imx_wd *priv, int timeout)
return 0;
}
+static void imx21_soc_reset(struct imx_wd *priv)
+{
+ u16 val;
+
+ val = IMX21_WDOG_WCR_SRS | IMX21_WDOG_WCR_WDA;
+
+ writew(val, priv->base + IMX21_WDOG_WCR);
+}
+
static int imx_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
{
struct imx_wd *priv = (struct imx_wd *)to_imx_wd(wd);
@@ -130,7 +138,7 @@ static void __noreturn imxwd_force_soc_reset(struct restart_handler *rst)
{
struct imx_wd *priv = container_of(rst, struct imx_wd, restart);
- priv->ops->set_timeout(priv, -1);
+ priv->ops->soc_reset(priv);
mdelay(1000);
@@ -227,11 +235,13 @@ on_error:
static const struct imx_wd_ops imx21_wd_ops = {
.set_timeout = imx21_watchdog_set_timeout,
+ .soc_reset = imx21_soc_reset,
.init = imx21_wd_init,
};
static const struct imx_wd_ops imx1_wd_ops = {
.set_timeout = imx1_watchdog_set_timeout,
+ .soc_reset = imx1_soc_reset,
};
static __maybe_unused struct of_device_id imx_wdt_dt_ids[] = {