|
@@ -37,6 +37,8 @@
|
|
|
|
|
|
#define IMX2_WDT_WCR 0x00 /* Control Register */
|
|
#define IMX2_WDT_WCR 0x00 /* Control Register */
|
|
#define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */
|
|
#define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */
|
|
|
|
+#define IMX2_WDT_WCR_WDA (1 << 5) /* -> External Reset WDOG_B */
|
|
|
|
+#define IMX2_WDT_WCR_SRS (1 << 4) /* -> Software Reset Signal */
|
|
#define IMX2_WDT_WCR_WRE (1 << 3) /* -> WDOG Reset Enable */
|
|
#define IMX2_WDT_WCR_WRE (1 << 3) /* -> WDOG Reset Enable */
|
|
#define IMX2_WDT_WCR_WDE (1 << 2) /* -> Watchdog Enable */
|
|
#define IMX2_WDT_WCR_WDE (1 << 2) /* -> Watchdog Enable */
|
|
#define IMX2_WDT_WCR_WDZST (1 << 0) /* -> Watchdog timer Suspend */
|
|
#define IMX2_WDT_WCR_WDZST (1 << 0) /* -> Watchdog timer Suspend */
|
|
@@ -59,6 +61,7 @@ struct imx2_wdt_device {
|
|
struct clk *clk;
|
|
struct clk *clk;
|
|
struct regmap *regmap;
|
|
struct regmap *regmap;
|
|
struct watchdog_device wdog;
|
|
struct watchdog_device wdog;
|
|
|
|
+ bool ext_reset;
|
|
};
|
|
};
|
|
|
|
|
|
static bool nowayout = WATCHDOG_NOWAYOUT;
|
|
static bool nowayout = WATCHDOG_NOWAYOUT;
|
|
@@ -83,6 +86,12 @@ static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action,
|
|
struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
|
|
struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
|
|
unsigned int wcr_enable = IMX2_WDT_WCR_WDE;
|
|
unsigned int wcr_enable = IMX2_WDT_WCR_WDE;
|
|
|
|
|
|
|
|
+ /* Use internal reset or external - not both */
|
|
|
|
+ if (wdev->ext_reset)
|
|
|
|
+ wcr_enable |= IMX2_WDT_WCR_SRS; /* do not assert int reset */
|
|
|
|
+ else
|
|
|
|
+ wcr_enable |= IMX2_WDT_WCR_WDA; /* do not assert ext-reset */
|
|
|
|
+
|
|
/* Assert SRS signal */
|
|
/* Assert SRS signal */
|
|
regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable);
|
|
regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable);
|
|
/*
|
|
/*
|
|
@@ -112,8 +121,12 @@ static inline void imx2_wdt_setup(struct watchdog_device *wdog)
|
|
val |= IMX2_WDT_WCR_WDZST;
|
|
val |= IMX2_WDT_WCR_WDZST;
|
|
/* Strip the old watchdog Time-Out value */
|
|
/* Strip the old watchdog Time-Out value */
|
|
val &= ~IMX2_WDT_WCR_WT;
|
|
val &= ~IMX2_WDT_WCR_WT;
|
|
- /* Generate reset if WDOG times out */
|
|
|
|
- val &= ~IMX2_WDT_WCR_WRE;
|
|
|
|
|
|
+ /* Generate internal chip-level reset if WDOG times out */
|
|
|
|
+ if (!wdev->ext_reset)
|
|
|
|
+ val &= ~IMX2_WDT_WCR_WRE;
|
|
|
|
+ /* Or if external-reset assert WDOG_B reset only on time-out */
|
|
|
|
+ else
|
|
|
|
+ val |= IMX2_WDT_WCR_WRE;
|
|
/* Keep Watchdog Disabled */
|
|
/* Keep Watchdog Disabled */
|
|
val &= ~IMX2_WDT_WCR_WDE;
|
|
val &= ~IMX2_WDT_WCR_WDE;
|
|
/* Set the watchdog's Time-Out value */
|
|
/* Set the watchdog's Time-Out value */
|
|
@@ -230,6 +243,8 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
|
|
regmap_read(wdev->regmap, IMX2_WDT_WRSR, &val);
|
|
regmap_read(wdev->regmap, IMX2_WDT_WRSR, &val);
|
|
wdog->bootstatus = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0;
|
|
wdog->bootstatus = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0;
|
|
|
|
|
|
|
|
+ wdev->ext_reset = of_property_read_bool(pdev->dev.of_node,
|
|
|
|
+ "fsl,ext-reset-output");
|
|
wdog->timeout = clamp_t(unsigned, timeout, 1, IMX2_WDT_MAX_TIME);
|
|
wdog->timeout = clamp_t(unsigned, timeout, 1, IMX2_WDT_MAX_TIME);
|
|
if (wdog->timeout != timeout)
|
|
if (wdog->timeout != timeout)
|
|
dev_warn(&pdev->dev, "Initial timeout out of range! Clamped from %u to %u\n",
|
|
dev_warn(&pdev->dev, "Initial timeout out of range! Clamped from %u to %u\n",
|