aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/watchdog/00-INDEX2
-rw-r--r--Documentation/watchdog/convert_drivers_to_kernel_api.txt19
-rw-r--r--Documentation/watchdog/watchdog-kernel-api.txt10
-rw-r--r--drivers/watchdog/Kconfig13
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/ar7_wdt.c17
-rw-r--r--drivers/watchdog/ath79_wdt.c6
-rw-r--r--drivers/watchdog/bcm63xx_wdt.c13
-rw-r--r--drivers/watchdog/cpu5wdt.c3
-rw-r--r--drivers/watchdog/cpwd.c13
-rw-r--r--drivers/watchdog/davinci_wdt.c13
-rw-r--r--drivers/watchdog/dw_wdt.c12
-rw-r--r--drivers/watchdog/eurotechwdt.c4
-rw-r--r--drivers/watchdog/ibmasr.c4
-rw-r--r--drivers/watchdog/indydog.c4
-rw-r--r--drivers/watchdog/iop_wdt.c5
-rw-r--r--drivers/watchdog/ixp2000_wdt.c3
-rw-r--r--drivers/watchdog/ixp4xx_wdt.c1
-rw-r--r--drivers/watchdog/jz4740_wdt.c13
-rw-r--r--drivers/watchdog/ks8695_wdt.c3
-rw-r--r--drivers/watchdog/lantiq_wdt.c3
-rw-r--r--drivers/watchdog/max63xx_wdt.c13
-rw-r--r--drivers/watchdog/mtx-1_wdt.c13
-rw-r--r--drivers/watchdog/nuc900_wdt.c13
-rw-r--r--drivers/watchdog/of_xilinx_wdt.c13
-rw-r--r--drivers/watchdog/omap_wdt.c17
-rw-r--r--drivers/watchdog/orion_wdt.c16
-rw-r--r--drivers/watchdog/pnx4008_wdt.c13
-rw-r--r--drivers/watchdog/rc32434_wdt.c13
-rw-r--r--drivers/watchdog/rdc321x_wdt.c13
-rw-r--r--drivers/watchdog/riowd.c13
-rw-r--r--drivers/watchdog/s3c2410_wdt.c2
-rw-r--r--drivers/watchdog/stmp3xxx_wdt.c13
-rw-r--r--drivers/watchdog/ts72xx_wdt.c12
-rw-r--r--drivers/watchdog/twl4030_wdt.c12
-rw-r--r--drivers/watchdog/via_wdt.c267
-rw-r--r--drivers/watchdog/wm831x_wdt.c23
-rw-r--r--drivers/watchdog/wm8350_wdt.c12
-rw-r--r--include/linux/watchdog.h21
39 files changed, 371 insertions, 290 deletions
diff --git a/Documentation/watchdog/00-INDEX b/Documentation/watchdog/00-INDEX
index fc51128071c2..fc9082a1477a 100644
--- a/Documentation/watchdog/00-INDEX
+++ b/Documentation/watchdog/00-INDEX
@@ -1,5 +1,7 @@
100-INDEX 100-INDEX
2 - this file. 2 - this file.
3convert_drivers_to_kernel_api.txt
4 - how-to for converting old watchdog drivers to the new kernel API.
3hpwdt.txt 5hpwdt.txt
4 - information on the HP iLO2 NMI watchdog 6 - information on the HP iLO2 NMI watchdog
5pcwd-watchdog.txt 7pcwd-watchdog.txt
diff --git a/Documentation/watchdog/convert_drivers_to_kernel_api.txt b/Documentation/watchdog/convert_drivers_to_kernel_api.txt
index ae1e90036d06..be8119bb15d2 100644
--- a/Documentation/watchdog/convert_drivers_to_kernel_api.txt
+++ b/Documentation/watchdog/convert_drivers_to_kernel_api.txt
@@ -163,6 +163,25 @@ Here is a simple example for a watchdog device:
163+}; 163+};
164 164
165 165
166Handle the 'nowayout' feature
167-----------------------------
168
169A few drivers use nowayout statically, i.e. there is no module parameter for it
170and only CONFIG_WATCHDOG_NOWAYOUT determines if the feature is going to be
171used. This needs to be converted by initializing the status variable of the
172watchdog_device like this:
173
174 .status = WATCHDOG_NOWAYOUT_INIT_STATUS,
175
176Most drivers, however, also allow runtime configuration of nowayout, usually
177by adding a module parameter. The conversion for this would be something like:
178
179 watchdog_set_nowayout(&s3c2410_wdd, nowayout);
180
181The module parameter itself needs to stay, everything else related to nowayout
182can go, though. This will likely be some code in open(), close() or write().
183
184
166Register the watchdog device 185Register the watchdog device
167---------------------------- 186----------------------------
168 187
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
index 4f7c894244d2..4b93c28e35c6 100644
--- a/Documentation/watchdog/watchdog-kernel-api.txt
+++ b/Documentation/watchdog/watchdog-kernel-api.txt
@@ -1,6 +1,6 @@
1The Linux WatchDog Timer Driver Core kernel API. 1The Linux WatchDog Timer Driver Core kernel API.
2=============================================== 2===============================================
3Last reviewed: 22-Jul-2011 3Last reviewed: 29-Nov-2011
4 4
5Wim Van Sebroeck <wim@iguana.be> 5Wim Van Sebroeck <wim@iguana.be>
6 6
@@ -142,6 +142,14 @@ bit-operations. The status bits that are defined are:
142* WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog. 142* WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog.
143 If this bit is set then the watchdog timer will not be able to stop. 143 If this bit is set then the watchdog timer will not be able to stop.
144 144
145 To set the WDOG_NO_WAY_OUT status bit (before registering your watchdog
146 timer device) you can either:
147 * set it statically in your watchdog_device struct with
148 .status = WATCHDOG_NOWAYOUT_INIT_STATUS,
149 (this will set the value the same as CONFIG_WATCHDOG_NOWAYOUT) or
150 * use the following helper function:
151 static inline void watchdog_set_nowayout(struct watchdog_device *wdd, int nowayout)
152
145Note: The WatchDog Timer Driver Core supports the magic close feature and 153Note: The WatchDog Timer Driver Core supports the magic close feature and
146the nowayout feature. To use the magic close feature you must set the 154the nowayout feature. To use the magic close feature you must set the
147WDIOF_MAGICCLOSE bit in the options field of the watchdog's info structure. 155WDIOF_MAGICCLOSE bit in the options field of the watchdog's info structure.
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 79fd606b7cd5..877b107f77a7 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -772,6 +772,19 @@ config SMSC37B787_WDT
772 772
773 Most people will say N. 773 Most people will say N.
774 774
775config VIA_WDT
776 tristate "VIA Watchdog Timer"
777 depends on X86
778 select WATCHDOG_CORE
779 ---help---
780 This is the driver for the hardware watchdog timer on VIA
781 southbridge chipset CX700, VX800/VX820 or VX855/VX875.
782
783 To compile this driver as a module, choose M here; the module
784 will be called via_wdt.
785
786 Most people will say N.
787
775config W83627HF_WDT 788config W83627HF_WDT
776 tristate "W83627HF/W83627DHG Watchdog Timer" 789 tristate "W83627HF/W83627DHG Watchdog Timer"
777 depends on X86 790 depends on X86
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index fe893e91935b..e8f479a16402 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_SBC7240_WDT) += sbc7240_wdt.o
99obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o 99obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
100obj-$(CONFIG_SMSC_SCH311X_WDT) += sch311x_wdt.o 100obj-$(CONFIG_SMSC_SCH311X_WDT) += sch311x_wdt.o
101obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o 101obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o
102obj-$(CONFIG_VIA_WDT) += via_wdt.o
102obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o 103obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
103obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o 104obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o
104obj-$(CONFIG_W83697UG_WDT) += w83697ug_wdt.o 105obj-$(CONFIG_W83697UG_WDT) += w83697ug_wdt.o
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index b29221783598..502773ad5acd 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -70,8 +70,8 @@ struct ar7_wdt {
70}; 70};
71 71
72static unsigned long wdt_is_open; 72static unsigned long wdt_is_open;
73static spinlock_t wdt_lock;
74static unsigned expect_close; 73static unsigned expect_close;
74static DEFINE_SPINLOCK(wdt_lock);
75 75
76/* XXX currently fixed, allows max margin ~68.72 secs */ 76/* XXX currently fixed, allows max margin ~68.72 secs */
77#define prescale_value 0xffff 77#define prescale_value 0xffff
@@ -280,8 +280,6 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev)
280{ 280{
281 int rc; 281 int rc;
282 282
283 spin_lock_init(&wdt_lock);
284
285 ar7_regs_wdt = 283 ar7_regs_wdt =
286 platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); 284 platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
287 if (!ar7_regs_wdt) { 285 if (!ar7_regs_wdt) {
@@ -355,15 +353,4 @@ static struct platform_driver ar7_wdt_driver = {
355 }, 353 },
356}; 354};
357 355
358static int __init ar7_wdt_init(void) 356module_platform_driver(ar7_wdt_driver);
359{
360 return platform_driver_register(&ar7_wdt_driver);
361}
362
363static void __exit ar7_wdt_cleanup(void)
364{
365 platform_driver_unregister(&ar7_wdt_driver);
366}
367
368module_init(ar7_wdt_init);
369module_exit(ar7_wdt_cleanup);
diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c
index 725c84bfdd76..9db808349f8b 100644
--- a/drivers/watchdog/ath79_wdt.c
+++ b/drivers/watchdog/ath79_wdt.c
@@ -68,17 +68,23 @@ static int max_timeout;
68static inline void ath79_wdt_keepalive(void) 68static inline void ath79_wdt_keepalive(void)
69{ 69{
70 ath79_reset_wr(AR71XX_RESET_REG_WDOG, wdt_freq * timeout); 70 ath79_reset_wr(AR71XX_RESET_REG_WDOG, wdt_freq * timeout);
71 /* flush write */
72 ath79_reset_rr(AR71XX_RESET_REG_WDOG);
71} 73}
72 74
73static inline void ath79_wdt_enable(void) 75static inline void ath79_wdt_enable(void)
74{ 76{
75 ath79_wdt_keepalive(); 77 ath79_wdt_keepalive();
76 ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR); 78 ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
79 /* flush write */
80 ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL);
77} 81}
78 82
79static inline void ath79_wdt_disable(void) 83static inline void ath79_wdt_disable(void)
80{ 84{
81 ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE); 85 ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
86 /* flush write */
87 ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL);
82} 88}
83 89
84static int ath79_wdt_set_timeout(int val) 90static int ath79_wdt_set_timeout(int val)
diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c
index 5064e8317521..8dc7de641e26 100644
--- a/drivers/watchdog/bcm63xx_wdt.c
+++ b/drivers/watchdog/bcm63xx_wdt.c
@@ -311,18 +311,7 @@ static struct platform_driver bcm63xx_wdt = {
311 } 311 }
312}; 312};
313 313
314static int __init bcm63xx_wdt_init(void) 314module_platform_driver(bcm63xx_wdt);
315{
316 return platform_driver_register(&bcm63xx_wdt);
317}
318
319static void __exit bcm63xx_wdt_exit(void)
320{
321 platform_driver_unregister(&bcm63xx_wdt);
322}
323
324module_init(bcm63xx_wdt_init);
325module_exit(bcm63xx_wdt_exit);
326 315
327MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); 316MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>");
328MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); 317MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
index edd3475f41db..251c863d71dd 100644
--- a/drivers/watchdog/cpu5wdt.c
+++ b/drivers/watchdog/cpu5wdt.c
@@ -39,7 +39,7 @@
39static int verbose; 39static int verbose;
40static int port = 0x91; 40static int port = 0x91;
41static int ticks = 10000; 41static int ticks = 10000;
42static spinlock_t cpu5wdt_lock; 42static DEFINE_SPINLOCK(cpu5wdt_lock);
43 43
44#define PFX "cpu5wdt: " 44#define PFX "cpu5wdt: "
45 45
@@ -223,7 +223,6 @@ static int __devinit cpu5wdt_init(void)
223 "port=0x%x, verbose=%i\n", port, verbose); 223 "port=0x%x, verbose=%i\n", port, verbose);
224 224
225 init_completion(&cpu5wdt_device.stop); 225 init_completion(&cpu5wdt_device.stop);
226 spin_lock_init(&cpu5wdt_lock);
227 cpu5wdt_device.queue = 0; 226 cpu5wdt_device.queue = 0;
228 setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); 227 setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0);
229 cpu5wdt_device.default_ticks = ticks; 228 cpu5wdt_device.default_ticks = ticks;
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 1e013e8457b7..1b793dfd868f 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -687,15 +687,4 @@ static struct platform_driver cpwd_driver = {
687 .remove = __devexit_p(cpwd_remove), 687 .remove = __devexit_p(cpwd_remove),
688}; 688};
689 689
690static int __init cpwd_init(void) 690module_platform_driver(cpwd_driver);
691{
692 return platform_driver_register(&cpwd_driver);
693}
694
695static void __exit cpwd_exit(void)
696{
697 platform_driver_unregister(&cpwd_driver);
698}
699
700module_init(cpwd_init);
701module_exit(cpwd_exit);
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 51b5551b4e3f..c8c5c8032bcb 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -271,18 +271,7 @@ static struct platform_driver platform_wdt_driver = {
271 .remove = __devexit_p(davinci_wdt_remove), 271 .remove = __devexit_p(davinci_wdt_remove),
272}; 272};
273 273
274static int __init davinci_wdt_init(void) 274module_platform_driver(platform_wdt_driver);
275{
276 return platform_driver_register(&platform_wdt_driver);
277}
278
279static void __exit davinci_wdt_exit(void)
280{
281 platform_driver_unregister(&platform_wdt_driver);
282}
283
284module_init(davinci_wdt_init);
285module_exit(davinci_wdt_exit);
286 275
287MODULE_AUTHOR("Texas Instruments"); 276MODULE_AUTHOR("Texas Instruments");
288MODULE_DESCRIPTION("DaVinci Watchdog Driver"); 277MODULE_DESCRIPTION("DaVinci Watchdog Driver");
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index f10f8c0abba4..1b0e3dd81c1a 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -358,17 +358,7 @@ static struct platform_driver dw_wdt_driver = {
358 }, 358 },
359}; 359};
360 360
361static int __init dw_wdt_watchdog_init(void) 361module_platform_driver(dw_wdt_driver);
362{
363 return platform_driver_register(&dw_wdt_driver);
364}
365module_init(dw_wdt_watchdog_init);
366
367static void __exit dw_wdt_watchdog_exit(void)
368{
369 platform_driver_unregister(&dw_wdt_driver);
370}
371module_exit(dw_wdt_watchdog_exit);
372 362
373MODULE_AUTHOR("Jamie Iles"); 363MODULE_AUTHOR("Jamie Iles");
374MODULE_DESCRIPTION("Synopsys DesignWare Watchdog Driver"); 364MODULE_DESCRIPTION("Synopsys DesignWare Watchdog Driver");
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index 41018d429abb..3946c51099c0 100644
--- a/drivers/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
@@ -64,7 +64,7 @@
64static unsigned long eurwdt_is_open; 64static unsigned long eurwdt_is_open;
65static int eurwdt_timeout; 65static int eurwdt_timeout;
66static char eur_expect_close; 66static char eur_expect_close;
67static spinlock_t eurwdt_lock; 67static DEFINE_SPINLOCK(eurwdt_lock);
68 68
69/* 69/*
70 * You must set these - there is no sane way to probe for this board. 70 * You must set these - there is no sane way to probe for this board.
@@ -446,8 +446,6 @@ static int __init eurwdt_init(void)
446 goto outreg; 446 goto outreg;
447 } 447 }
448 448
449 spin_lock_init(&eurwdt_lock);
450
451 ret = misc_register(&eurwdt_miscdev); 449 ret = misc_register(&eurwdt_miscdev);
452 if (ret) { 450 if (ret) {
453 printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", 451 printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c
index 195e0f798e76..c7481ad51629 100644
--- a/drivers/watchdog/ibmasr.c
+++ b/drivers/watchdog/ibmasr.c
@@ -68,7 +68,7 @@ static char asr_expect_close;
68static unsigned int asr_type, asr_base, asr_length; 68static unsigned int asr_type, asr_base, asr_length;
69static unsigned int asr_read_addr, asr_write_addr; 69static unsigned int asr_read_addr, asr_write_addr;
70static unsigned char asr_toggle_mask, asr_disable_mask; 70static unsigned char asr_toggle_mask, asr_disable_mask;
71static spinlock_t asr_lock; 71static DEFINE_SPINLOCK(asr_lock);
72 72
73static void __asr_toggle(void) 73static void __asr_toggle(void)
74{ 74{
@@ -386,8 +386,6 @@ static int __init ibmasr_init(void)
386 if (!asr_type) 386 if (!asr_type)
387 return -ENODEV; 387 return -ENODEV;
388 388
389 spin_lock_init(&asr_lock);
390
391 rc = asr_get_base_address(); 389 rc = asr_get_base_address();
392 if (rc) 390 if (rc)
393 return rc; 391 return rc;
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c
index 1cc5609666d1..1475e09f9af2 100644
--- a/drivers/watchdog/indydog.c
+++ b/drivers/watchdog/indydog.c
@@ -28,7 +28,7 @@
28 28
29#define PFX "indydog: " 29#define PFX "indydog: "
30static unsigned long indydog_alive; 30static unsigned long indydog_alive;
31static spinlock_t indydog_lock; 31static DEFINE_SPINLOCK(indydog_lock);
32 32
33#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ 33#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
34 34
@@ -185,8 +185,6 @@ static int __init watchdog_init(void)
185{ 185{
186 int ret; 186 int ret;
187 187
188 spin_lock_init(&indydog_lock);
189
190 ret = register_reboot_notifier(&indydog_notifier); 188 ret = register_reboot_notifier(&indydog_notifier);
191 if (ret) { 189 if (ret) {
192 printk(KERN_ERR PFX 190 printk(KERN_ERR PFX
diff --git a/drivers/watchdog/iop_wdt.c b/drivers/watchdog/iop_wdt.c
index aef94789019f..82fa7a92a8d2 100644
--- a/drivers/watchdog/iop_wdt.c
+++ b/drivers/watchdog/iop_wdt.c
@@ -37,7 +37,7 @@
37static int nowayout = WATCHDOG_NOWAYOUT; 37static int nowayout = WATCHDOG_NOWAYOUT;
38static unsigned long wdt_status; 38static unsigned long wdt_status;
39static unsigned long boot_status; 39static unsigned long boot_status;
40static spinlock_t wdt_lock; 40static DEFINE_SPINLOCK(wdt_lock);
41 41
42#define WDT_IN_USE 0 42#define WDT_IN_USE 0
43#define WDT_OK_TO_CLOSE 1 43#define WDT_OK_TO_CLOSE 1
@@ -226,9 +226,6 @@ static int __init iop_wdt_init(void)
226{ 226{
227 int ret; 227 int ret;
228 228
229 spin_lock_init(&wdt_lock);
230
231
232 /* check if the reset was caused by the watchdog timer */ 229 /* check if the reset was caused by the watchdog timer */
233 boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; 230 boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0;
234 231
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
index e86952a7168c..084f71aa855a 100644
--- a/drivers/watchdog/ixp2000_wdt.c
+++ b/drivers/watchdog/ixp2000_wdt.c
@@ -32,7 +32,7 @@
32static int nowayout = WATCHDOG_NOWAYOUT; 32static int nowayout = WATCHDOG_NOWAYOUT;
33static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ 33static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */
34static unsigned long wdt_status; 34static unsigned long wdt_status;
35static spinlock_t wdt_lock; 35static DEFINE_SPINLOCK(wdt_lock);
36 36
37#define WDT_IN_USE 0 37#define WDT_IN_USE 0
38#define WDT_OK_TO_CLOSE 1 38#define WDT_OK_TO_CLOSE 1
@@ -189,7 +189,6 @@ static int __init ixp2000_wdt_init(void)
189 return -EIO; 189 return -EIO;
190 } 190 }
191 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; 191 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
192 spin_lock_init(&wdt_lock);
193 return misc_register(&ixp2000_wdt_miscdev); 192 return misc_register(&ixp2000_wdt_miscdev);
194} 193}
195 194
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c
index e02c0ecda26b..4fc2e9ac26f7 100644
--- a/drivers/watchdog/ixp4xx_wdt.c
+++ b/drivers/watchdog/ixp4xx_wdt.c
@@ -181,7 +181,6 @@ static int __init ixp4xx_wdt_init(void)
181 181
182 return -ENODEV; 182 return -ENODEV;
183 } 183 }
184 spin_lock_init(&wdt_lock);
185 boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ? 184 boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ?
186 WDIOF_CARDRESET : 0; 185 WDIOF_CARDRESET : 0;
187 ret = misc_register(&ixp4xx_wdt_miscdev); 186 ret = misc_register(&ixp4xx_wdt_miscdev);
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index 684ba01fb540..17ef300bccc5 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -295,18 +295,7 @@ static struct platform_driver jz4740_wdt_driver = {
295 }, 295 },
296}; 296};
297 297
298 298module_platform_driver(jz4740_wdt_driver);
299static int __init jz4740_wdt_init(void)
300{
301 return platform_driver_register(&jz4740_wdt_driver);
302}
303module_init(jz4740_wdt_init);
304
305static void __exit jz4740_wdt_exit(void)
306{
307 platform_driver_unregister(&jz4740_wdt_driver);
308}
309module_exit(jz4740_wdt_exit);
310 299
311MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>"); 300MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
312MODULE_DESCRIPTION("jz4740 Watchdog Driver"); 301MODULE_DESCRIPTION("jz4740 Watchdog Driver");
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index 811471903e8a..51757a520e8f 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -42,7 +42,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
42 42
43 43
44static unsigned long ks8695wdt_busy; 44static unsigned long ks8695wdt_busy;
45static spinlock_t ks8695_lock; 45static DEFINE_SPINLOCK(ks8695_lock);
46 46
47/* ......................................................................... */ 47/* ......................................................................... */
48 48
@@ -288,7 +288,6 @@ static struct platform_driver ks8695wdt_driver = {
288 288
289static int __init ks8695_wdt_init(void) 289static int __init ks8695_wdt_init(void)
290{ 290{
291 spin_lock_init(&ks8695_lock);
292 /* Check that the heartbeat value is within range; 291 /* Check that the heartbeat value is within range;
293 if not reset to the default */ 292 if not reset to the default */
294 if (ks8695_wdt_settimeout(wdt_time)) { 293 if (ks8695_wdt_settimeout(wdt_time)) {
diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c
index 102aed0efbf1..d3a63be2e28d 100644
--- a/drivers/watchdog/lantiq_wdt.c
+++ b/drivers/watchdog/lantiq_wdt.c
@@ -222,9 +222,6 @@ ltq_wdt_remove(struct platform_device *pdev)
222{ 222{
223 misc_deregister(&ltq_wdt_miscdev); 223 misc_deregister(&ltq_wdt_miscdev);
224 224
225 if (ltq_wdt_membase)
226 iounmap(ltq_wdt_membase);
227
228 return 0; 225 return 0;
229} 226}
230 227
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c
index 73ba2fd8e591..af63ecfbfa6f 100644
--- a/drivers/watchdog/max63xx_wdt.c
+++ b/drivers/watchdog/max63xx_wdt.c
@@ -364,18 +364,7 @@ static struct platform_driver max63xx_wdt_driver = {
364 }, 364 },
365}; 365};
366 366
367static int __init max63xx_wdt_init(void) 367module_platform_driver(max63xx_wdt_driver);
368{
369 return platform_driver_register(&max63xx_wdt_driver);
370}
371
372static void __exit max63xx_wdt_exit(void)
373{
374 platform_driver_unregister(&max63xx_wdt_driver);
375}
376
377module_init(max63xx_wdt_init);
378module_exit(max63xx_wdt_exit);
379 368
380MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>"); 369MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>");
381MODULE_DESCRIPTION("max63xx Watchdog Driver"); 370MODULE_DESCRIPTION("max63xx Watchdog Driver");
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
index ac37bb82392c..c29e31d99fe8 100644
--- a/drivers/watchdog/mtx-1_wdt.c
+++ b/drivers/watchdog/mtx-1_wdt.c
@@ -253,18 +253,7 @@ static struct platform_driver mtx1_wdt_driver = {
253 .driver.owner = THIS_MODULE, 253 .driver.owner = THIS_MODULE,
254}; 254};
255 255
256static int __init mtx1_wdt_init(void) 256module_platform_driver(mtx1_wdt_driver);
257{
258 return platform_driver_register(&mtx1_wdt_driver);
259}
260
261static void __exit mtx1_wdt_exit(void)
262{
263 platform_driver_unregister(&mtx1_wdt_driver);
264}
265
266module_init(mtx1_wdt_init);
267module_exit(mtx1_wdt_exit);
268 257
269MODULE_AUTHOR("Michael Stickel, Florian Fainelli"); 258MODULE_AUTHOR("Michael Stickel, Florian Fainelli");
270MODULE_DESCRIPTION("Driver for the MTX-1 watchdog"); 259MODULE_DESCRIPTION("Driver for the MTX-1 watchdog");
diff --git a/drivers/watchdog/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c
index 6cee33d4b161..50359bad9177 100644
--- a/drivers/watchdog/nuc900_wdt.c
+++ b/drivers/watchdog/nuc900_wdt.c
@@ -334,18 +334,7 @@ static struct platform_driver nuc900wdt_driver = {
334 }, 334 },
335}; 335};
336 336
337static int __init nuc900_wdt_init(void) 337module_platform_driver(nuc900wdt_driver);
338{
339 return platform_driver_register(&nuc900wdt_driver);
340}
341
342static void __exit nuc900_wdt_exit(void)
343{
344 platform_driver_unregister(&nuc900wdt_driver);
345}
346
347module_init(nuc900_wdt_init);
348module_exit(nuc900_wdt_exit);
349 338
350MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); 339MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
351MODULE_DESCRIPTION("Watchdog driver for NUC900"); 340MODULE_DESCRIPTION("Watchdog driver for NUC900");
diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c
index 4ec741ac952c..f359ab85c3bc 100644
--- a/drivers/watchdog/of_xilinx_wdt.c
+++ b/drivers/watchdog/of_xilinx_wdt.c
@@ -414,18 +414,7 @@ static struct platform_driver xwdt_driver = {
414 }, 414 },
415}; 415};
416 416
417static int __init xwdt_init(void) 417module_platform_driver(xwdt_driver);
418{
419 return platform_driver_register(&xwdt_driver);
420}
421
422static void __exit xwdt_exit(void)
423{
424 platform_driver_unregister(&xwdt_driver);
425}
426
427module_init(xwdt_init);
428module_exit(xwdt_exit);
429 418
430MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>"); 419MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>");
431MODULE_DESCRIPTION("Xilinx Watchdog driver"); 420MODULE_DESCRIPTION("Xilinx Watchdog driver");
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 2b4acb86c191..4b33e3fd726b 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -55,7 +55,7 @@ module_param(timer_margin, uint, 0);
55MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); 55MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
56 56
57static unsigned int wdt_trgr_pattern = 0x1234; 57static unsigned int wdt_trgr_pattern = 0x1234;
58static spinlock_t wdt_lock; 58static DEFINE_SPINLOCK(wdt_lock);
59 59
60struct omap_wdt_dev { 60struct omap_wdt_dev {
61 void __iomem *base; /* physical */ 61 void __iomem *base; /* physical */
@@ -232,6 +232,7 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
232 if (cpu_is_omap24xx()) 232 if (cpu_is_omap24xx())
233 return put_user(omap_prcm_get_reset_sources(), 233 return put_user(omap_prcm_get_reset_sources(),
234 (int __user *)arg); 234 (int __user *)arg);
235 return put_user(0, (int __user *)arg);
235 case WDIOC_KEEPALIVE: 236 case WDIOC_KEEPALIVE:
236 pm_runtime_get_sync(wdev->dev); 237 pm_runtime_get_sync(wdev->dev);
237 spin_lock(&wdt_lock); 238 spin_lock(&wdt_lock);
@@ -437,19 +438,7 @@ static struct platform_driver omap_wdt_driver = {
437 }, 438 },
438}; 439};
439 440
440static int __init omap_wdt_init(void) 441module_platform_driver(omap_wdt_driver);
441{
442 spin_lock_init(&wdt_lock);
443 return platform_driver_register(&omap_wdt_driver);
444}
445
446static void __exit omap_wdt_exit(void)
447{
448 platform_driver_unregister(&omap_wdt_driver);
449}
450
451module_init(omap_wdt_init);
452module_exit(omap_wdt_exit);
453 442
454MODULE_AUTHOR("George G. Davis"); 443MODULE_AUTHOR("George G. Davis");
455MODULE_LICENSE("GPL"); 444MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index 2d9fb96a9ee9..4ad78f868515 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -41,7 +41,7 @@ static int heartbeat = -1; /* module parameter (seconds) */
41static unsigned int wdt_max_duration; /* (seconds) */ 41static unsigned int wdt_max_duration; /* (seconds) */
42static unsigned int wdt_tclk; 42static unsigned int wdt_tclk;
43static unsigned long wdt_status; 43static unsigned long wdt_status;
44static spinlock_t wdt_lock; 44static DEFINE_SPINLOCK(wdt_lock);
45 45
46static void orion_wdt_ping(void) 46static void orion_wdt_ping(void)
47{ 47{
@@ -294,19 +294,7 @@ static struct platform_driver orion_wdt_driver = {
294 }, 294 },
295}; 295};
296 296
297static int __init orion_wdt_init(void) 297module_platform_driver(orion_wdt_driver);
298{
299 spin_lock_init(&wdt_lock);
300 return platform_driver_register(&orion_wdt_driver);
301}
302
303static void __exit orion_wdt_exit(void)
304{
305 platform_driver_unregister(&orion_wdt_driver);
306}
307
308module_init(orion_wdt_init);
309module_exit(orion_wdt_exit);
310 298
311MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>"); 299MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>");
312MODULE_DESCRIPTION("Orion Processor Watchdog"); 300MODULE_DESCRIPTION("Orion Processor Watchdog");
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 614933225560..bd143c9dd3e6 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -334,18 +334,7 @@ static struct platform_driver platform_wdt_driver = {
334 .remove = __devexit_p(pnx4008_wdt_remove), 334 .remove = __devexit_p(pnx4008_wdt_remove),
335}; 335};
336 336
337static int __init pnx4008_wdt_init(void) 337module_platform_driver(platform_wdt_driver);
338{
339 return platform_driver_register(&platform_wdt_driver);
340}
341
342static void __exit pnx4008_wdt_exit(void)
343{
344 platform_driver_unregister(&platform_wdt_driver);
345}
346
347module_init(pnx4008_wdt_init);
348module_exit(pnx4008_wdt_exit);
349 338
350MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); 339MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
351MODULE_DESCRIPTION("PNX4008 Watchdog Driver"); 340MODULE_DESCRIPTION("PNX4008 Watchdog Driver");
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
index d4c29b5311a4..bf7bc8aa1c01 100644
--- a/drivers/watchdog/rc32434_wdt.c
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -332,18 +332,7 @@ static struct platform_driver rc32434_wdt_driver = {
332 } 332 }
333}; 333};
334 334
335static int __init rc32434_wdt_init(void) 335module_platform_driver(rc32434_wdt_driver);
336{
337 return platform_driver_register(&rc32434_wdt_driver);
338}
339
340static void __exit rc32434_wdt_exit(void)
341{
342 platform_driver_unregister(&rc32434_wdt_driver);
343}
344
345module_init(rc32434_wdt_init);
346module_exit(rc32434_wdt_exit);
347 336
348MODULE_AUTHOR("Ondrej Zajicek <santiago@crfreenet.org>," 337MODULE_AUTHOR("Ondrej Zajicek <santiago@crfreenet.org>,"
349 "Florian Fainelli <florian@openwrt.org>"); 338 "Florian Fainelli <florian@openwrt.org>");
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 428f8a1583e8..042ccc56ae26 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -293,18 +293,7 @@ static struct platform_driver rdc321x_wdt_driver = {
293 }, 293 },
294}; 294};
295 295
296static int __init rdc321x_wdt_init(void) 296module_platform_driver(rdc321x_wdt_driver);
297{
298 return platform_driver_register(&rdc321x_wdt_driver);
299}
300
301static void __exit rdc321x_wdt_exit(void)
302{
303 platform_driver_unregister(&rdc321x_wdt_driver);
304}
305
306module_init(rdc321x_wdt_init);
307module_exit(rdc321x_wdt_exit);
308 297
309MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); 298MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
310MODULE_DESCRIPTION("RDC321x watchdog driver"); 299MODULE_DESCRIPTION("RDC321x watchdog driver");
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c
index 109b533896b7..c7e17ceafa6a 100644
--- a/drivers/watchdog/riowd.c
+++ b/drivers/watchdog/riowd.c
@@ -247,15 +247,4 @@ static struct platform_driver riowd_driver = {
247 .remove = __devexit_p(riowd_remove), 247 .remove = __devexit_p(riowd_remove),
248}; 248};
249 249
250static int __init riowd_init(void) 250module_platform_driver(riowd_driver);
251{
252 return platform_driver_register(&riowd_driver);
253}
254
255static void __exit riowd_exit(void)
256{
257 platform_driver_unregister(&riowd_driver);
258}
259
260module_init(riowd_init);
261module_exit(riowd_exit);
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index a79e3840782a..4bc3744e14e4 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -378,6 +378,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
378 "cannot start\n"); 378 "cannot start\n");
379 } 379 }
380 380
381 watchdog_set_nowayout(&s3c2410_wdd, nowayout);
382
381 ret = watchdog_register_device(&s3c2410_wdd); 383 ret = watchdog_register_device(&s3c2410_wdd);
382 if (ret) { 384 if (ret) {
383 dev_err(dev, "cannot register watchdog (%d)\n", ret); 385 dev_err(dev, "cannot register watchdog (%d)\n", ret);
diff --git a/drivers/watchdog/stmp3xxx_wdt.c b/drivers/watchdog/stmp3xxx_wdt.c
index ac2346a452e5..4c2a4e8698f9 100644
--- a/drivers/watchdog/stmp3xxx_wdt.c
+++ b/drivers/watchdog/stmp3xxx_wdt.c
@@ -272,18 +272,7 @@ static struct platform_driver platform_wdt_driver = {
272 .resume = stmp3xxx_wdt_resume, 272 .resume = stmp3xxx_wdt_resume,
273}; 273};
274 274
275static int __init stmp3xxx_wdt_init(void) 275module_platform_driver(platform_wdt_driver);
276{
277 return platform_driver_register(&platform_wdt_driver);
278}
279
280static void __exit stmp3xxx_wdt_exit(void)
281{
282 return platform_driver_unregister(&platform_wdt_driver);
283}
284
285module_init(stmp3xxx_wdt_init);
286module_exit(stmp3xxx_wdt_exit);
287 276
288MODULE_DESCRIPTION("STMP3XXX Watchdog Driver"); 277MODULE_DESCRIPTION("STMP3XXX Watchdog Driver");
289MODULE_LICENSE("GPL"); 278MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c
index 5a90a4a871dd..1490293dc7da 100644
--- a/drivers/watchdog/ts72xx_wdt.c
+++ b/drivers/watchdog/ts72xx_wdt.c
@@ -506,17 +506,7 @@ static struct platform_driver ts72xx_wdt_driver = {
506 }, 506 },
507}; 507};
508 508
509static __init int ts72xx_wdt_init(void) 509module_platform_driver(ts72xx_wdt_driver);
510{
511 return platform_driver_register(&ts72xx_wdt_driver);
512}
513module_init(ts72xx_wdt_init);
514
515static __exit void ts72xx_wdt_exit(void)
516{
517 platform_driver_unregister(&ts72xx_wdt_driver);
518}
519module_exit(ts72xx_wdt_exit);
520 510
521MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); 511MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
522MODULE_DESCRIPTION("TS-72xx SBC Watchdog"); 512MODULE_DESCRIPTION("TS-72xx SBC Watchdog");
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index b5045ca7e61c..0764c6239b98 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -256,17 +256,7 @@ static struct platform_driver twl4030_wdt_driver = {
256 }, 256 },
257}; 257};
258 258
259static int __devinit twl4030_wdt_init(void) 259module_platform_driver(twl4030_wdt_driver);
260{
261 return platform_driver_register(&twl4030_wdt_driver);
262}
263module_init(twl4030_wdt_init);
264
265static void __devexit twl4030_wdt_exit(void)
266{
267 platform_driver_unregister(&twl4030_wdt_driver);
268}
269module_exit(twl4030_wdt_exit);
270 260
271MODULE_AUTHOR("Nokia Corporation"); 261MODULE_AUTHOR("Nokia Corporation");
272MODULE_LICENSE("GPL"); 262MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
new file mode 100644
index 000000000000..026b4bbfa0aa
--- /dev/null
+++ b/drivers/watchdog/via_wdt.c
@@ -0,0 +1,267 @@
1/*
2 * VIA Chipset Watchdog Driver
3 *
4 * Copyright (C) 2011 Sigfox
5 * License terms: GNU General Public License (GPL) version 2
6 * Author: Marc Vertes <marc.vertes@sigfox.com>
7 * Based on a preliminary version from Harald Welte <HaraldWelte@viatech.com>
8 * Timer code by Wim Van Sebroeck <wim@iguana.be>
9 *
10 * Caveat: PnP must be enabled in BIOS to allow full access to watchdog
11 * control registers. If not, the watchdog must be configured in BIOS manually.
12 */
13#include <linux/device.h>
14#include <linux/io.h>
15#include <linux/jiffies.h>
16#include <linux/module.h>
17#include <linux/pci.h>
18#include <linux/timer.h>
19#include <linux/watchdog.h>
20
21/* Configuration registers relative to the pci device */
22#define VIA_WDT_MMIO_BASE 0xe8 /* MMIO region base address */
23#define VIA_WDT_CONF 0xec /* watchdog enable state */
24
25/* Relevant bits for the VIA_WDT_CONF register */
26#define VIA_WDT_CONF_ENABLE 0x01 /* 1: enable watchdog */
27#define VIA_WDT_CONF_MMIO 0x02 /* 1: enable watchdog MMIO */
28
29/*
30 * The MMIO region contains the watchog control register and the
31 * hardware timer counter.
32 */
33#define VIA_WDT_MMIO_LEN 8 /* MMIO region length in bytes */
34#define VIA_WDT_CTL 0 /* MMIO addr+0: state/control reg. */
35#define VIA_WDT_COUNT 4 /* MMIO addr+4: timer counter reg. */
36
37/* Bits for the VIA_WDT_CTL register */
38#define VIA_WDT_RUNNING 0x01 /* 0: stop, 1: running */
39#define VIA_WDT_FIRED 0x02 /* 1: restarted by expired watchdog */
40#define VIA_WDT_PWROFF 0x04 /* 0: reset, 1: poweroff */
41#define VIA_WDT_DISABLED 0x08 /* 1: timer is disabled */
42#define VIA_WDT_TRIGGER 0x80 /* 1: start a new countdown */
43
44/* Hardware heartbeat in seconds */
45#define WDT_HW_HEARTBEAT 1
46
47/* Timer heartbeat (500ms) */
48#define WDT_HEARTBEAT (HZ/2) /* should be <= ((WDT_HW_HEARTBEAT*HZ)/2) */
49
50/* User space timeout in seconds */
51#define WDT_TIMEOUT_MAX 1023 /* approx. 17 min. */
52#define WDT_TIMEOUT 60
53static int timeout = WDT_TIMEOUT;
54module_param(timeout, int, 0);
55MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, between 1 and 1023 "
56 "(default = " __MODULE_STRING(WDT_TIMEOUT) ")");
57
58static int nowayout = WATCHDOG_NOWAYOUT;
59module_param(nowayout, int, 0);
60MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
61 "(default = " __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
62
63static struct watchdog_device wdt_dev;
64static struct resource wdt_res;
65static void __iomem *wdt_mem;
66static unsigned int mmio;
67static void wdt_timer_tick(unsigned long data);
68static DEFINE_TIMER(timer, wdt_timer_tick, 0, 0);
69 /* The timer that pings the watchdog */
70static unsigned long next_heartbeat; /* the next_heartbeat for the timer */
71
72static inline void wdt_reset(void)
73{
74 unsigned int ctl = readl(wdt_mem);
75
76 writel(ctl | VIA_WDT_TRIGGER, wdt_mem);
77}
78
79/*
80 * Timer tick: the timer will make sure that the watchdog timer hardware
81 * is being reset in time. The conditions to do this are:
82 * 1) the watchog timer has been started and /dev/watchdog is open
83 * and there is still time left before userspace should send the
84 * next heartbeat/ping. (note: the internal heartbeat is much smaller
85 * then the external/userspace heartbeat).
86 * 2) the watchdog timer has been stopped by userspace.
87 */
88static void wdt_timer_tick(unsigned long data)
89{
90 if (time_before(jiffies, next_heartbeat) ||
91 (!test_bit(WDOG_ACTIVE, &wdt_dev.status))) {
92 wdt_reset();
93 mod_timer(&timer, jiffies + WDT_HEARTBEAT);
94 } else
95 pr_crit("I will reboot your machine !\n");
96}
97
98static int wdt_ping(struct watchdog_device *wdd)
99{
100 /* calculate when the next userspace timeout will be */
101 next_heartbeat = jiffies + timeout * HZ;
102 return 0;
103}
104
105static int wdt_start(struct watchdog_device *wdd)
106{
107 unsigned int ctl = readl(wdt_mem);
108
109 writel(timeout, wdt_mem + VIA_WDT_COUNT);
110 writel(ctl | VIA_WDT_RUNNING | VIA_WDT_TRIGGER, wdt_mem);
111 wdt_ping(wdd);
112 mod_timer(&timer, jiffies + WDT_HEARTBEAT);
113 return 0;
114}
115
116static int wdt_stop(struct watchdog_device *wdd)
117{
118 unsigned int ctl = readl(wdt_mem);
119
120 writel(ctl & ~VIA_WDT_RUNNING, wdt_mem);
121 return 0;
122}
123
124static int wdt_set_timeout(struct watchdog_device *wdd,
125 unsigned int new_timeout)
126{
127 if (new_timeout < 1 || new_timeout > WDT_TIMEOUT_MAX)
128 return -EINVAL;
129 writel(new_timeout, wdt_mem + VIA_WDT_COUNT);
130 timeout = new_timeout;
131 return 0;
132}
133
134static const struct watchdog_info wdt_info = {
135 .identity = "VIA watchdog",
136 .options = WDIOF_CARDRESET |
137 WDIOF_SETTIMEOUT |
138 WDIOF_MAGICCLOSE |
139 WDIOF_KEEPALIVEPING,
140};
141
142static const struct watchdog_ops wdt_ops = {
143 .owner = THIS_MODULE,
144 .start = wdt_start,
145 .stop = wdt_stop,
146 .ping = wdt_ping,
147 .set_timeout = wdt_set_timeout,
148};
149
150static struct watchdog_device wdt_dev = {
151 .info = &wdt_info,
152 .ops = &wdt_ops,
153};
154
155static int __devinit wdt_probe(struct pci_dev *pdev,
156 const struct pci_device_id *ent)
157{
158 unsigned char conf;
159 int ret = -ENODEV;
160
161 if (pci_enable_device(pdev)) {
162 dev_err(&pdev->dev, "cannot enable PCI device\n");
163 return -ENODEV;
164 }
165
166 /*
167 * Allocate a MMIO region which contains watchdog control register
168 * and counter, then configure the watchdog to use this region.
169 * This is possible only if PnP is properly enabled in BIOS.
170 * If not, the watchdog must be configured in BIOS manually.
171 */
172 if (allocate_resource(&iomem_resource, &wdt_res, VIA_WDT_MMIO_LEN,
173 0xf0000000, 0xffffff00, 0xff, NULL, NULL)) {
174 dev_err(&pdev->dev, "MMIO allocation failed\n");
175 goto err_out_disable_device;
176 }
177
178 pci_write_config_dword(pdev, VIA_WDT_MMIO_BASE, wdt_res.start);
179 pci_read_config_byte(pdev, VIA_WDT_CONF, &conf);
180 conf |= VIA_WDT_CONF_ENABLE | VIA_WDT_CONF_MMIO;
181 pci_write_config_byte(pdev, VIA_WDT_CONF, conf);
182
183 pci_read_config_dword(pdev, VIA_WDT_MMIO_BASE, &mmio);
184 if (mmio) {
185 dev_info(&pdev->dev, "VIA Chipset watchdog MMIO: %x\n", mmio);
186 } else {
187 dev_err(&pdev->dev, "MMIO setting failed. Check BIOS.\n");
188 goto err_out_resource;
189 }
190
191 if (!request_mem_region(mmio, VIA_WDT_MMIO_LEN, "via_wdt")) {
192 dev_err(&pdev->dev, "MMIO region busy\n");
193 goto err_out_resource;
194 }
195
196 wdt_mem = ioremap(mmio, VIA_WDT_MMIO_LEN);
197 if (wdt_mem == NULL) {
198 dev_err(&pdev->dev, "cannot remap VIA wdt MMIO registers\n");
199 goto err_out_release;
200 }
201
202 wdt_dev.timeout = timeout;
203 watchdog_set_nowayout(&wdt_dev, nowayout);
204 if (readl(wdt_mem) & VIA_WDT_FIRED)
205 wdt_dev.bootstatus |= WDIOF_CARDRESET;
206
207 ret = watchdog_register_device(&wdt_dev);
208 if (ret)
209 goto err_out_iounmap;
210
211 /* start triggering, in case of watchdog already enabled by BIOS */
212 mod_timer(&timer, jiffies + WDT_HEARTBEAT);
213 return 0;
214
215err_out_iounmap:
216 iounmap(wdt_mem);
217err_out_release:
218 release_mem_region(mmio, VIA_WDT_MMIO_LEN);
219err_out_resource:
220 release_resource(&wdt_res);
221err_out_disable_device:
222 pci_disable_device(pdev);
223 return ret;
224}
225
226static void __devexit wdt_remove(struct pci_dev *pdev)
227{
228 watchdog_unregister_device(&wdt_dev);
229 del_timer(&timer);
230 iounmap(wdt_mem);
231 release_mem_region(mmio, VIA_WDT_MMIO_LEN);
232 release_resource(&wdt_res);
233 pci_disable_device(pdev);
234}
235
236DEFINE_PCI_DEVICE_TABLE(wdt_pci_table) = {
237 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700) },
238 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800) },
239 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) },
240 { 0 }
241};
242
243static struct pci_driver wdt_driver = {
244 .name = "via_wdt",
245 .id_table = wdt_pci_table,
246 .probe = wdt_probe,
247 .remove = __devexit_p(wdt_remove),
248};
249
250static int __init wdt_init(void)
251{
252 if (timeout < 1 || timeout > WDT_TIMEOUT_MAX)
253 timeout = WDT_TIMEOUT;
254 return pci_register_driver(&wdt_driver);
255}
256
257static void __exit wdt_exit(void)
258{
259 pci_unregister_driver(&wdt_driver);
260}
261
262module_init(wdt_init);
263module_exit(wdt_exit);
264
265MODULE_AUTHOR("Marc Vertes");
266MODULE_DESCRIPTION("Driver for watchdog timer on VIA chipset");
267MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index e789a47db41f..263c883f0806 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -199,7 +199,8 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
199 if (reg & WM831X_WDOG_DEBUG) 199 if (reg & WM831X_WDOG_DEBUG)
200 dev_warn(wm831x->dev, "Watchdog is paused\n"); 200 dev_warn(wm831x->dev, "Watchdog is paused\n");
201 201
202 driver_data = kzalloc(sizeof(*driver_data), GFP_KERNEL); 202 driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data),
203 GFP_KERNEL);
203 if (!driver_data) { 204 if (!driver_data) {
204 dev_err(wm831x->dev, "Unable to alloacate watchdog device\n"); 205 dev_err(wm831x->dev, "Unable to alloacate watchdog device\n");
205 ret = -ENOMEM; 206 ret = -ENOMEM;
@@ -213,11 +214,9 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
213 214
214 wm831x_wdt->info = &wm831x_wdt_info; 215 wm831x_wdt->info = &wm831x_wdt_info;
215 wm831x_wdt->ops = &wm831x_wdt_ops; 216 wm831x_wdt->ops = &wm831x_wdt_ops;
217 watchdog_set_nowayout(wm831x_wdt, nowayout);
216 watchdog_set_drvdata(wm831x_wdt, driver_data); 218 watchdog_set_drvdata(wm831x_wdt, driver_data);
217 219
218 if (nowayout)
219 wm831x_wdt->status |= WDOG_NO_WAY_OUT;
220
221 reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG); 220 reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
222 reg &= WM831X_WDOG_TO_MASK; 221 reg &= WM831X_WDOG_TO_MASK;
223 for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++) 222 for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
@@ -252,7 +251,7 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
252 dev_err(wm831x->dev, 251 dev_err(wm831x->dev,
253 "Failed to request update GPIO: %d\n", 252 "Failed to request update GPIO: %d\n",
254 ret); 253 ret);
255 goto err_alloc; 254 goto err;
256 } 255 }
257 256
258 ret = gpio_direction_output(pdata->update_gpio, 0); 257 ret = gpio_direction_output(pdata->update_gpio, 0);
@@ -294,8 +293,6 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
294err_gpio: 293err_gpio:
295 if (driver_data->update_gpio) 294 if (driver_data->update_gpio)
296 gpio_free(driver_data->update_gpio); 295 gpio_free(driver_data->update_gpio);
297err_alloc:
298 kfree(driver_data);
299err: 296err:
300 return ret; 297 return ret;
301} 298}
@@ -320,17 +317,7 @@ static struct platform_driver wm831x_wdt_driver = {
320 }, 317 },
321}; 318};
322 319
323static int __init wm831x_wdt_init(void) 320module_platform_driver(wm831x_wdt_driver);
324{
325 return platform_driver_register(&wm831x_wdt_driver);
326}
327module_init(wm831x_wdt_init);
328
329static void __exit wm831x_wdt_exit(void)
330{
331 platform_driver_unregister(&wm831x_wdt_driver);
332}
333module_exit(wm831x_wdt_exit);
334 321
335MODULE_AUTHOR("Mark Brown"); 322MODULE_AUTHOR("Mark Brown");
336MODULE_DESCRIPTION("WM831x Watchdog"); 323MODULE_DESCRIPTION("WM831x Watchdog");
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
index b68d928c8f90..909c78650d3e 100644
--- a/drivers/watchdog/wm8350_wdt.c
+++ b/drivers/watchdog/wm8350_wdt.c
@@ -311,17 +311,7 @@ static struct platform_driver wm8350_wdt_driver = {
311 }, 311 },
312}; 312};
313 313
314static int __init wm8350_wdt_init(void) 314module_platform_driver(wm8350_wdt_driver);
315{
316 return platform_driver_register(&wm8350_wdt_driver);
317}
318module_init(wm8350_wdt_init);
319
320static void __exit wm8350_wdt_exit(void)
321{
322 platform_driver_unregister(&wm8350_wdt_driver);
323}
324module_exit(wm8350_wdt_exit);
325 315
326MODULE_AUTHOR("Mark Brown"); 316MODULE_AUTHOR("Mark Brown");
327MODULE_DESCRIPTION("WM8350 Watchdog"); 317MODULE_DESCRIPTION("WM8350 Watchdog");
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index 111843f88b2a..43ba5b3ce2a3 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -53,11 +53,7 @@ struct watchdog_info {
53 53
54#ifdef __KERNEL__ 54#ifdef __KERNEL__
55 55
56#ifdef CONFIG_WATCHDOG_NOWAYOUT 56#include <linux/bitops.h>
57#define WATCHDOG_NOWAYOUT 1
58#else
59#define WATCHDOG_NOWAYOUT 0
60#endif
61 57
62struct watchdog_ops; 58struct watchdog_ops;
63struct watchdog_device; 59struct watchdog_device;
@@ -122,6 +118,21 @@ struct watchdog_device {
122#define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */ 118#define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */
123}; 119};
124 120
121#ifdef CONFIG_WATCHDOG_NOWAYOUT
122#define WATCHDOG_NOWAYOUT 1
123#define WATCHDOG_NOWAYOUT_INIT_STATUS (1 << WDOG_NO_WAY_OUT)
124#else
125#define WATCHDOG_NOWAYOUT 0
126#define WATCHDOG_NOWAYOUT_INIT_STATUS 0
127#endif
128
129/* Use the following function to set the nowayout feature */
130static inline void watchdog_set_nowayout(struct watchdog_device *wdd, int nowayout)
131{
132 if (nowayout)
133 set_bit(WDOG_NO_WAY_OUT, &wdd->status);
134}
135
125/* Use the following functions to manipulate watchdog driver specific data */ 136/* Use the following functions to manipulate watchdog driver specific data */
126static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data) 137static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data)
127{ 138{