|
@@ -116,6 +116,31 @@ static int davinci_wdt_ping(struct watchdog_device *wdd)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static unsigned int davinci_wdt_get_timeleft(struct watchdog_device *wdd)
|
|
|
|
+{
|
|
|
|
+ u64 timer_counter;
|
|
|
|
+ unsigned long freq;
|
|
|
|
+ u32 val;
|
|
|
|
+ struct davinci_wdt_device *davinci_wdt = watchdog_get_drvdata(wdd);
|
|
|
|
+
|
|
|
|
+ /* if timeout has occured then return 0 */
|
|
|
|
+ val = ioread32(davinci_wdt->base + WDTCR);
|
|
|
|
+ if (val & WDFLAG)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ freq = clk_get_rate(davinci_wdt->clk);
|
|
|
|
+
|
|
|
|
+ if (!freq)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ timer_counter = ioread32(davinci_wdt->base + TIM12);
|
|
|
|
+ timer_counter |= ((u64)ioread32(davinci_wdt->base + TIM34) << 32);
|
|
|
|
+
|
|
|
|
+ do_div(timer_counter, freq);
|
|
|
|
+
|
|
|
|
+ return wdd->timeout - timer_counter;
|
|
|
|
+}
|
|
|
|
+
|
|
static const struct watchdog_info davinci_wdt_info = {
|
|
static const struct watchdog_info davinci_wdt_info = {
|
|
.options = WDIOF_KEEPALIVEPING,
|
|
.options = WDIOF_KEEPALIVEPING,
|
|
.identity = "DaVinci Watchdog",
|
|
.identity = "DaVinci Watchdog",
|
|
@@ -126,6 +151,7 @@ static const struct watchdog_ops davinci_wdt_ops = {
|
|
.start = davinci_wdt_start,
|
|
.start = davinci_wdt_start,
|
|
.stop = davinci_wdt_ping,
|
|
.stop = davinci_wdt_ping,
|
|
.ping = davinci_wdt_ping,
|
|
.ping = davinci_wdt_ping,
|
|
|
|
+ .get_timeleft = davinci_wdt_get_timeleft,
|
|
};
|
|
};
|
|
|
|
|
|
static int davinci_wdt_probe(struct platform_device *pdev)
|
|
static int davinci_wdt_probe(struct platform_device *pdev)
|