summaryrefslogtreecommitdiff
path: root/target/linux/cns3xxx/patches-3.0/053-cns3xxx_wdt.patch
blob: 85a73ab1ddc95e87f12a73ff8c04ff01fa8c0c6d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -188,7 +188,7 @@ config SA1100_WATCHDOG
 
 config MPCORE_WATCHDOG
 	tristate "MPcore watchdog"
-	depends on HAVE_ARM_TWD
+	depends on ARCH_CNS3XXX
 	help
 	  Watchdog timer embedded into the MPcore system.
 
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -32,11 +32,14 @@
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
 
 #include <asm/smp_twd.h>
 
 struct mpcore_wdt {
 	unsigned long	timer_alive;
+	unsigned long	timer_rate;
 	struct device	*dev;
 	void __iomem	*base;
 	int		irq;
@@ -98,14 +101,12 @@ static void mpcore_wdt_keepalive(struct
 	unsigned long count;
 
 	spin_lock(&wdt_lock);
-	/* Assume prescale is set to 256 */
-	count =  __raw_readl(wdt->base + TWD_WDOG_COUNTER);
-	count = (0xFFFFFFFFU - count) * (HZ / 5);
-	count = (count / 256) * mpcore_margin;
+	count = (wdt->timer_rate / 256) * mpcore_margin;
 
 	/* Reload the counter */
 	writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
 	wdt->perturb = wdt->perturb ? 0 : 1;
+
 	spin_unlock(&wdt_lock);
 }
 
@@ -329,6 +330,8 @@ static int __devinit mpcore_wdt_probe(st
 	struct mpcore_wdt *wdt;
 	struct resource *res;
 	int ret;
+	unsigned long count;
+	u64 waitjiffies;
 
 	/* We only accept one device, and it must have an id of -1 */
 	if (dev->id != -1)
@@ -375,6 +378,22 @@ static int __devinit mpcore_wdt_probe(st
 		goto err_irq;
 	}
 
+	waitjiffies = get_jiffies_64() + 1;
+	while (get_jiffies_64() < waitjiffies)
+		udelay(10);
+
+	waitjiffies += 5;
+
+	__raw_writel(0x00000001, wdt->base + TWD_WDOG_CONTROL);
+	__raw_writel(0xFFFFFFFFU, wdt->base + TWD_WDOG_LOAD);
+
+	while (get_jiffies_64() < waitjiffies)
+		udelay(10);
+
+	count =  __raw_readl(wdt->base + TWD_WDOG_COUNTER);
+
+	wdt->timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
+
 	mpcore_wdt_stop(wdt);
 	platform_set_drvdata(dev, wdt);
 	mpcore_wdt_dev = dev;