Merge tag 'mac80211-for-davem-2016-07-06' of git://git.kernel.org/pub/scm/linux/kerne...
[cascardo/linux.git] / drivers / watchdog / imx2_wdt.c
index 331aed8..62f346b 100644 (file)
@@ -37,6 +37,8 @@
 
 #define IMX2_WDT_WCR           0x00            /* Control Register */
 #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_WDE       (1 << 2)        /* -> Watchdog Enable */
 #define IMX2_WDT_WCR_WDZST     (1 << 0)        /* -> Watchdog timer Suspend */
@@ -59,6 +61,7 @@ struct imx2_wdt_device {
        struct clk *clk;
        struct regmap *regmap;
        struct watchdog_device wdog;
+       bool ext_reset;
 };
 
 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);
        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 */
        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;
        /* Strip the old watchdog Time-Out value */
        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 */
        val &= ~IMX2_WDT_WCR_WDE;
        /* 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);
        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);
        if (wdog->timeout != timeout)
                dev_warn(&pdev->dev, "Initial timeout out of range! Clamped from %u to %u\n",