]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/watchdog/omap_wdt.c
Merge branch 'rc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
[karo-tx-linux.git] / drivers / watchdog / omap_wdt.c
index 7498c35266ee4b6ac5ae8ca2224558fc0ab59068..de911c7e477c2875fe3633bce5a72a6b45fb95c0 100644 (file)
@@ -55,6 +55,11 @@ MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
 
 #define to_omap_wdt_dev(_wdog) container_of(_wdog, struct omap_wdt_dev, wdog)
 
+static bool early_enable;
+module_param(early_enable, bool, 0);
+MODULE_PARM_DESC(early_enable,
+       "Watchdog is started on module insertion (default=0)");
+
 struct omap_wdt_dev {
        struct watchdog_device wdog;
        void __iomem    *base;          /* physical */
@@ -135,6 +140,13 @@ static int omap_wdt_start(struct watchdog_device *wdog)
 
        pm_runtime_get_sync(wdev->dev);
 
+       /*
+        * Make sure the watchdog is disabled. This is unfortunately required
+        * because writing to various registers with the watchdog running has no
+        * effect.
+        */
+       omap_wdt_disable(wdev);
+
        /* initialize prescaler */
        while (readl_relaxed(base + OMAP_WATCHDOG_WPS) & 0x01)
                cpu_relax();
@@ -191,6 +203,16 @@ static int omap_wdt_set_timeout(struct watchdog_device *wdog,
        return 0;
 }
 
+static unsigned int omap_wdt_get_timeleft(struct watchdog_device *wdog)
+{
+       struct omap_wdt_dev *wdev = watchdog_get_drvdata(wdog);
+       void __iomem *base = wdev->base;
+       u32 value;
+
+       value = readl_relaxed(base + OMAP_WATCHDOG_CRR);
+       return GET_WCCR_SECS(value);
+}
+
 static const struct watchdog_info omap_wdt_info = {
        .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
        .identity = "OMAP Watchdog",
@@ -202,6 +224,7 @@ static const struct watchdog_ops omap_wdt_ops = {
        .stop           = omap_wdt_stop,
        .ping           = omap_wdt_ping,
        .set_timeout    = omap_wdt_set_timeout,
+       .get_timeleft   = omap_wdt_get_timeleft,
 };
 
 static int omap_wdt_probe(struct platform_device *pdev)
@@ -261,6 +284,9 @@ static int omap_wdt_probe(struct platform_device *pdev)
 
        pm_runtime_put_sync(wdev->dev);
 
+       if (early_enable)
+               omap_wdt_start(&wdev->wdog);
+
        return 0;
 }