Root/target/linux/brcm47xx/patches-3.6/544-watchdog-bcm47xx_wdt.c-add-hard-timer.patch

1--- a/drivers/watchdog/bcm47xx_wdt.c
2+++ b/drivers/watchdog/bcm47xx_wdt.c
3@@ -31,6 +31,7 @@
4 
5 #define WDT_DEFAULT_TIME 30 /* seconds */
6 #define WDT_SOFTTIMER_MAX 255 /* seconds */
7+#define WDT_SOFTTIMER_THRESHOLD 60 /* seconds */
8 
9 static int timeout = WDT_DEFAULT_TIME;
10 static bool nowayout = WATCHDOG_NOWAYOUT;
11@@ -49,6 +50,53 @@ static inline struct bcm47xx_wdt *bcm47x
12     return container_of(wdd, struct bcm47xx_wdt, wdd);
13 }
14 
15+static int bcm47xx_wdt_hard_keepalive(struct watchdog_device *wdd)
16+{
17+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
18+
19+ wdt->timer_set_ms(wdt, wdd->timeout * 1000);
20+
21+ return 0;
22+}
23+
24+static int bcm47xx_wdt_hard_start(struct watchdog_device *wdd)
25+{
26+ return 0;
27+}
28+
29+static int bcm47xx_wdt_hard_stop(struct watchdog_device *wdd)
30+{
31+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
32+
33+ wdt->timer_set(wdt, 0);
34+
35+ return 0;
36+}
37+
38+static int bcm47xx_wdt_hard_set_timeout(struct watchdog_device *wdd,
39+ unsigned int new_time)
40+{
41+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
42+ u32 max_timer = wdt->max_timer_ms;
43+
44+ if (new_time < 1 || new_time > max_timer / 1000) {
45+ pr_warn("timeout value must be 1<=x<=%d, using %d\n",
46+ max_timer / 1000, new_time);
47+ return -EINVAL;
48+ }
49+
50+ wdd->timeout = new_time;
51+ return 0;
52+}
53+
54+static struct watchdog_ops bcm47xx_wdt_hard_ops = {
55+ .owner = THIS_MODULE,
56+ .start = bcm47xx_wdt_hard_start,
57+ .stop = bcm47xx_wdt_hard_stop,
58+ .ping = bcm47xx_wdt_hard_keepalive,
59+ .set_timeout = bcm47xx_wdt_hard_set_timeout,
60+};
61+
62 static void bcm47xx_wdt_soft_timer_tick(unsigned long data)
63 {
64     struct bcm47xx_wdt *wdt = (struct bcm47xx_wdt *)data;
65@@ -133,15 +181,22 @@ static struct watchdog_ops bcm47xx_wdt_s
66 static int __devinit bcm47xx_wdt_probe(struct platform_device *pdev)
67 {
68     int ret;
69+ bool soft;
70     struct bcm47xx_wdt *wdt = dev_get_platdata(&pdev->dev);
71 
72     if (!wdt)
73         return -ENXIO;
74 
75- setup_timer(&wdt->soft_timer, bcm47xx_wdt_soft_timer_tick,
76- (long unsigned int)wdt);
77+ soft = wdt->max_timer_ms < WDT_SOFTTIMER_THRESHOLD * 1000;
78+
79+ if (soft) {
80+ wdt->wdd.ops = &bcm47xx_wdt_soft_ops;
81+ setup_timer(&wdt->soft_timer, bcm47xx_wdt_soft_timer_tick,
82+ (long unsigned int)wdt);
83+ } else {
84+ wdt->wdd.ops = &bcm47xx_wdt_hard_ops;
85+ }
86 
87- wdt->wdd.ops = &bcm47xx_wdt_soft_ops;
88     wdt->wdd.info = &bcm47xx_wdt_info;
89     wdt->wdd.timeout = WDT_DEFAULT_TIME;
90     ret = wdt->wdd.ops->set_timeout(&wdt->wdd, timeout);
91@@ -159,14 +214,16 @@ static int __devinit bcm47xx_wdt_probe(s
92     if (ret)
93         goto err_notifier;
94 
95- pr_info("BCM47xx Watchdog Timer enabled (%d seconds%s)\n",
96- timeout, nowayout ? ", nowayout" : "");
97+ dev_info(&pdev->dev, "BCM47xx Watchdog Timer enabled (%d seconds%s%s)\n",
98+ timeout, nowayout ? ", nowayout" : "",
99+ soft ? ", Software Timer" : "");
100     return 0;
101 
102 err_notifier:
103     unregister_reboot_notifier(&wdt->notifier);
104 err_timer:
105- del_timer_sync(&wdt->soft_timer);
106+ if (soft)
107+ del_timer_sync(&wdt->soft_timer);
108 
109     return ret;
110 }
111

Archive Download this file



interactive