aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/Kconfig35
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/ar7_wdt.c33
-rw-r--r--drivers/watchdog/hpwdt.c13
-rw-r--r--drivers/watchdog/i6300esb.c14
-rw-r--r--drivers/watchdog/ie6xx_wdt.c348
-rw-r--r--drivers/watchdog/it87_wdt.c7
-rw-r--r--drivers/watchdog/ixp2000_wdt.c215
-rw-r--r--drivers/watchdog/pcwd_pci.c18
-rw-r--r--drivers/watchdog/pnx4008_wdt.c10
-rw-r--r--drivers/watchdog/s3c2410_wdt.c7
-rw-r--r--drivers/watchdog/sch311x_wdt.c39
-rw-r--r--drivers/watchdog/sp5100_tco.c2
-rw-r--r--drivers/watchdog/via_wdt.c18
-rw-r--r--drivers/watchdog/wdt_pci.c34
-rw-r--r--drivers/watchdog/wm831x_wdt.c13
16 files changed, 416 insertions, 392 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index edebaf771f50..a18bf6358eb8 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -129,17 +129,6 @@ config 977_WATCHDOG
129 129
130 Not sure? It's safe to say N. 130 Not sure? It's safe to say N.
131 131
132config IXP2000_WATCHDOG
133 tristate "IXP2000 Watchdog"
134 depends on ARCH_IXP2000
135 help
136 Say Y here if to include support for the watchdog timer
137 in the Intel IXP2000(2400, 2800, 2850) network processors.
138 This driver can be built as a module by choosing M. The module
139 will be called ixp2000_wdt.
140
141 Say N if you are unsure.
142
143config IXP4XX_WATCHDOG 132config IXP4XX_WATCHDOG
144 tristate "IXP4xx Watchdog" 133 tristate "IXP4xx Watchdog"
145 depends on ARCH_IXP4XX 134 depends on ARCH_IXP4XX
@@ -543,7 +532,7 @@ config WAFER_WDT
543 532
544config I6300ESB_WDT 533config I6300ESB_WDT
545 tristate "Intel 6300ESB Timer/Watchdog" 534 tristate "Intel 6300ESB Timer/Watchdog"
546 depends on X86 && PCI 535 depends on PCI
547 ---help--- 536 ---help---
548 Hardware driver for the watchdog timer built into the Intel 537 Hardware driver for the watchdog timer built into the Intel
549 6300ESB controller hub. 538 6300ESB controller hub.
@@ -551,6 +540,19 @@ config I6300ESB_WDT
551 To compile this driver as a module, choose M here: the 540 To compile this driver as a module, choose M here: the
552 module will be called i6300esb. 541 module will be called i6300esb.
553 542
543config IE6XX_WDT
544 tristate "Intel Atom E6xx Watchdog"
545 depends on X86 && PCI
546 select WATCHDOG_CORE
547 select MFD_CORE
548 select LPC_SCH
549 ---help---
550 Hardware driver for the watchdog timer built into the Intel
551 Atom E6XX (TunnelCreek) processor.
552
553 To compile this driver as a module, choose M here: the
554 module will be called ie6xx_wdt.
555
554config INTEL_SCU_WATCHDOG 556config INTEL_SCU_WATCHDOG
555 bool "Intel SCU Watchdog for Mobile Platforms" 557 bool "Intel SCU Watchdog for Mobile Platforms"
556 depends on X86_MRST 558 depends on X86_MRST
@@ -607,7 +609,12 @@ config IT87_WDT
607 depends on X86 && EXPERIMENTAL 609 depends on X86 && EXPERIMENTAL
608 ---help--- 610 ---help---
609 This is the driver for the hardware watchdog on the ITE IT8702, 611 This is the driver for the hardware watchdog on the ITE IT8702,
610 IT8712, IT8716, IT8718, IT8720, IT8721, IT8726 Super I/O chips. 612 IT8712, IT8716, IT8718, IT8720, IT8721, IT8726 and IT8728
613 Super I/O chips.
614
615 If the driver does not work, then make sure that the game port in
616 the BIOS is enabled.
617
611 This watchdog simply watches your kernel to make sure it doesn't 618 This watchdog simply watches your kernel to make sure it doesn't
612 freeze, and if it does, it reboots your computer after a certain 619 freeze, and if it does, it reboots your computer after a certain
613 amount of time. 620 amount of time.
@@ -780,7 +787,7 @@ config SMSC37B787_WDT
780 787
781config VIA_WDT 788config VIA_WDT
782 tristate "VIA Watchdog Timer" 789 tristate "VIA Watchdog Timer"
783 depends on X86 790 depends on X86 && PCI
784 select WATCHDOG_CORE 791 select WATCHDOG_CORE
785 ---help--- 792 ---help---
786 This is the driver for the hardware watchdog timer on VIA 793 This is the driver for the hardware watchdog timer on VIA
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index e8f479a16402..442bfbe0882a 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -36,7 +36,6 @@ obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
36obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o 36obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o
37obj-$(CONFIG_21285_WATCHDOG) += wdt285.o 37obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
38obj-$(CONFIG_977_WATCHDOG) += wdt977.o 38obj-$(CONFIG_977_WATCHDOG) += wdt977.o
39obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
40obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o 39obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
41obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o 40obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
42obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o 41obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
@@ -81,6 +80,7 @@ obj-$(CONFIG_IB700_WDT) += ib700wdt.o
81obj-$(CONFIG_IBMASR) += ibmasr.o 80obj-$(CONFIG_IBMASR) += ibmasr.o
82obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o 81obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
83obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o 82obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
83obj-$(CONFIG_IE6XX_WDT) += ie6xx_wdt.o
84obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o 84obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o
85ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y) 85ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y)
86obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o 86obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index 639ae9a23fbc..dc30dbd21cf1 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -282,29 +282,19 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev)
282 platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); 282 platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
283 if (!ar7_regs_wdt) { 283 if (!ar7_regs_wdt) {
284 pr_err("could not get registers resource\n"); 284 pr_err("could not get registers resource\n");
285 rc = -ENODEV; 285 return -ENODEV;
286 goto out;
287 }
288
289 if (!request_mem_region(ar7_regs_wdt->start,
290 resource_size(ar7_regs_wdt), LONGNAME)) {
291 pr_warn("watchdog I/O region busy\n");
292 rc = -EBUSY;
293 goto out;
294 } 286 }
295 287
296 ar7_wdt = ioremap(ar7_regs_wdt->start, resource_size(ar7_regs_wdt)); 288 ar7_wdt = devm_request_and_ioremap(&pdev->dev, ar7_regs_wdt);
297 if (!ar7_wdt) { 289 if (!ar7_wdt) {
298 pr_err("could not ioremap registers\n"); 290 pr_err("could not ioremap registers\n");
299 rc = -ENXIO; 291 return -ENXIO;
300 goto out_mem_region;
301 } 292 }
302 293
303 vbus_clk = clk_get(NULL, "vbus"); 294 vbus_clk = clk_get(NULL, "vbus");
304 if (IS_ERR(vbus_clk)) { 295 if (IS_ERR(vbus_clk)) {
305 pr_err("could not get vbus clock\n"); 296 pr_err("could not get vbus clock\n");
306 rc = PTR_ERR(vbus_clk); 297 return PTR_ERR(vbus_clk);
307 goto out_mem_region;
308 } 298 }
309 299
310 ar7_wdt_disable_wdt(); 300 ar7_wdt_disable_wdt();
@@ -314,24 +304,21 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev)
314 rc = misc_register(&ar7_wdt_miscdev); 304 rc = misc_register(&ar7_wdt_miscdev);
315 if (rc) { 305 if (rc) {
316 pr_err("unable to register misc device\n"); 306 pr_err("unable to register misc device\n");
317 goto out_alloc; 307 goto out;
318 } 308 }
319 goto out; 309 return 0;
320 310
321out_alloc:
322 iounmap(ar7_wdt);
323out_mem_region:
324 release_mem_region(ar7_regs_wdt->start, resource_size(ar7_regs_wdt));
325out: 311out:
312 clk_put(vbus_clk);
313 vbus_clk = NULL;
326 return rc; 314 return rc;
327} 315}
328 316
329static int __devexit ar7_wdt_remove(struct platform_device *pdev) 317static int __devexit ar7_wdt_remove(struct platform_device *pdev)
330{ 318{
331 misc_deregister(&ar7_wdt_miscdev); 319 misc_deregister(&ar7_wdt_miscdev);
332 iounmap(ar7_wdt); 320 clk_put(vbus_clk);
333 release_mem_region(ar7_regs_wdt->start, resource_size(ar7_regs_wdt)); 321 vbus_clk = NULL;
334
335 return 0; 322 return 0;
336} 323}
337 324
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 23885f2d56a0..2b763815aeec 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -861,16 +861,6 @@ static struct pci_driver hpwdt_driver = {
861 .remove = __devexit_p(hpwdt_exit), 861 .remove = __devexit_p(hpwdt_exit),
862}; 862};
863 863
864static void __exit hpwdt_cleanup(void)
865{
866 pci_unregister_driver(&hpwdt_driver);
867}
868
869static int __init hpwdt_init(void)
870{
871 return pci_register_driver(&hpwdt_driver);
872}
873
874MODULE_AUTHOR("Tom Mingarelli"); 864MODULE_AUTHOR("Tom Mingarelli");
875MODULE_DESCRIPTION("hp watchdog driver"); 865MODULE_DESCRIPTION("hp watchdog driver");
876MODULE_LICENSE("GPL"); 866MODULE_LICENSE("GPL");
@@ -889,5 +879,4 @@ module_param(allow_kdump, int, 0);
889MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs"); 879MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs");
890#endif /* !CONFIG_HPWDT_NMI_DECODING */ 880#endif /* !CONFIG_HPWDT_NMI_DECODING */
891 881
892module_init(hpwdt_init); 882module_pci_driver(hpwdt_driver);
893module_exit(hpwdt_cleanup);
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index 738032a36bcf..276877d5b6a3 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -492,19 +492,7 @@ static struct pci_driver esb_driver = {
492 .shutdown = esb_shutdown, 492 .shutdown = esb_shutdown,
493}; 493};
494 494
495static int __init watchdog_init(void) 495module_pci_driver(esb_driver);
496{
497 return pci_register_driver(&esb_driver);
498}
499
500static void __exit watchdog_cleanup(void)
501{
502 pci_unregister_driver(&esb_driver);
503 pr_info("Watchdog Module Unloaded\n");
504}
505
506module_init(watchdog_init);
507module_exit(watchdog_cleanup);
508 496
509MODULE_AUTHOR("Ross Biro and David Härdeman"); 497MODULE_AUTHOR("Ross Biro and David Härdeman");
510MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets"); 498MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets");
diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c
new file mode 100644
index 000000000000..5f0d776f902c
--- /dev/null
+++ b/drivers/watchdog/ie6xx_wdt.c
@@ -0,0 +1,348 @@
1/*
2 * Intel Atom E6xx Watchdog driver
3 *
4 * Copyright (C) 2011 Alexander Stein
5 * <alexander.stein@systec-electronic.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU General
9 * Public License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be
12 * useful, but WITHOUT ANY WARRANTY; without even the implied
13 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the Free
17 * Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 * The full GNU General Public License is included in this
20 * distribution in the file called COPYING.
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/platform_device.h>
27#include <linux/io.h>
28#include <linux/kernel.h>
29#include <linux/types.h>
30#include <linux/watchdog.h>
31#include <linux/miscdevice.h>
32#include <linux/seq_file.h>
33#include <linux/debugfs.h>
34#include <linux/uaccess.h>
35#include <linux/spinlock.h>
36
37#define DRIVER_NAME "ie6xx_wdt"
38
39#define PV1 0x00
40#define PV2 0x04
41
42#define RR0 0x0c
43#define RR1 0x0d
44#define WDT_RELOAD 0x01
45#define WDT_TOUT 0x02
46
47#define WDTCR 0x10
48#define WDT_PRE_SEL 0x04
49#define WDT_RESET_SEL 0x08
50#define WDT_RESET_EN 0x10
51#define WDT_TOUT_EN 0x20
52
53#define DCR 0x14
54
55#define WDTLR 0x18
56#define WDT_LOCK 0x01
57#define WDT_ENABLE 0x02
58#define WDT_TOUT_CNF 0x03
59
60#define MIN_TIME 1
61#define MAX_TIME (10 * 60) /* 10 minutes */
62#define DEFAULT_TIME 60
63
64static unsigned int timeout = DEFAULT_TIME;
65module_param(timeout, uint, 0);
66MODULE_PARM_DESC(timeout,
67 "Default Watchdog timer setting ("
68 __MODULE_STRING(DEFAULT_TIME) "s)."
69 "The range is from 1 to 600");
70
71static bool nowayout = WATCHDOG_NOWAYOUT;
72module_param(nowayout, bool, 0);
73MODULE_PARM_DESC(nowayout,
74 "Watchdog cannot be stopped once started (default="
75 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
76
77static u8 resetmode = 0x10;
78module_param(resetmode, byte, 0);
79MODULE_PARM_DESC(resetmode,
80 "Resetmode bits: 0x08 warm reset (cold reset otherwise), "
81 "0x10 reset enable, 0x20 disable toggle GPIO[4] (default=0x10)");
82
83static struct {
84 unsigned short sch_wdtba;
85 struct spinlock unlock_sequence;
86#ifdef CONFIG_DEBUG_FS
87 struct dentry *debugfs;
88#endif
89} ie6xx_wdt_data;
90
91/*
92 * This is needed to write to preload and reload registers
93 * struct ie6xx_wdt_data.unlock_sequence must be used
94 * to prevent sequence interrupts
95 */
96static void ie6xx_wdt_unlock_registers(void)
97{
98 outb(0x80, ie6xx_wdt_data.sch_wdtba + RR0);
99 outb(0x86, ie6xx_wdt_data.sch_wdtba + RR0);
100}
101
102static int ie6xx_wdt_ping(struct watchdog_device *wdd)
103{
104 spin_lock(&ie6xx_wdt_data.unlock_sequence);
105 ie6xx_wdt_unlock_registers();
106 outb(WDT_RELOAD, ie6xx_wdt_data.sch_wdtba + RR1);
107 spin_unlock(&ie6xx_wdt_data.unlock_sequence);
108 return 0;
109}
110
111static int ie6xx_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
112{
113 u32 preload;
114 u64 clock;
115 u8 wdtcr;
116
117 /* Watchdog clock is PCI Clock (33MHz) */
118 clock = 33000000;
119 /* and the preload value is loaded into [34:15] of the down counter */
120 preload = (t * clock) >> 15;
121 /*
122 * Manual states preload must be one less.
123 * Does not wrap as t is at least 1
124 */
125 preload -= 1;
126
127 spin_lock(&ie6xx_wdt_data.unlock_sequence);
128
129 /* Set ResetMode & Enable prescaler for range 10ms to 10 min */
130 wdtcr = resetmode & 0x38;
131 outb(wdtcr, ie6xx_wdt_data.sch_wdtba + WDTCR);
132
133 ie6xx_wdt_unlock_registers();
134 outl(0, ie6xx_wdt_data.sch_wdtba + PV1);
135
136 ie6xx_wdt_unlock_registers();
137 outl(preload, ie6xx_wdt_data.sch_wdtba + PV2);
138
139 ie6xx_wdt_unlock_registers();
140 outb(WDT_RELOAD | WDT_TOUT, ie6xx_wdt_data.sch_wdtba + RR1);
141
142 spin_unlock(&ie6xx_wdt_data.unlock_sequence);
143
144 wdd->timeout = t;
145 return 0;
146}
147
148static int ie6xx_wdt_start(struct watchdog_device *wdd)
149{
150 ie6xx_wdt_set_timeout(wdd, wdd->timeout);
151
152 /* Enable the watchdog timer */
153 spin_lock(&ie6xx_wdt_data.unlock_sequence);
154 outb(WDT_ENABLE, ie6xx_wdt_data.sch_wdtba + WDTLR);
155 spin_unlock(&ie6xx_wdt_data.unlock_sequence);
156
157 return 0;
158}
159
160static int ie6xx_wdt_stop(struct watchdog_device *wdd)
161{
162 if (inb(ie6xx_wdt_data.sch_wdtba + WDTLR) & WDT_LOCK)
163 return -1;
164
165 /* Disable the watchdog timer */
166 spin_lock(&ie6xx_wdt_data.unlock_sequence);
167 outb(0, ie6xx_wdt_data.sch_wdtba + WDTLR);
168 spin_unlock(&ie6xx_wdt_data.unlock_sequence);
169
170 return 0;
171}
172
173static const struct watchdog_info ie6xx_wdt_info = {
174 .identity = "Intel Atom E6xx Watchdog",
175 .options = WDIOF_SETTIMEOUT |
176 WDIOF_MAGICCLOSE |
177 WDIOF_KEEPALIVEPING,
178};
179
180static const struct watchdog_ops ie6xx_wdt_ops = {
181 .owner = THIS_MODULE,
182 .start = ie6xx_wdt_start,
183 .stop = ie6xx_wdt_stop,
184 .ping = ie6xx_wdt_ping,
185 .set_timeout = ie6xx_wdt_set_timeout,
186};
187
188static struct watchdog_device ie6xx_wdt_dev = {
189 .info = &ie6xx_wdt_info,
190 .ops = &ie6xx_wdt_ops,
191 .min_timeout = MIN_TIME,
192 .max_timeout = MAX_TIME,
193};
194
195#ifdef CONFIG_DEBUG_FS
196
197static int ie6xx_wdt_dbg_show(struct seq_file *s, void *unused)
198{
199 seq_printf(s, "PV1 = 0x%08x\n",
200 inl(ie6xx_wdt_data.sch_wdtba + PV1));
201 seq_printf(s, "PV2 = 0x%08x\n",
202 inl(ie6xx_wdt_data.sch_wdtba + PV2));
203 seq_printf(s, "RR = 0x%08x\n",
204 inw(ie6xx_wdt_data.sch_wdtba + RR0));
205 seq_printf(s, "WDTCR = 0x%08x\n",
206 inw(ie6xx_wdt_data.sch_wdtba + WDTCR));
207 seq_printf(s, "DCR = 0x%08x\n",
208 inl(ie6xx_wdt_data.sch_wdtba + DCR));
209 seq_printf(s, "WDTLR = 0x%08x\n",
210 inw(ie6xx_wdt_data.sch_wdtba + WDTLR));
211
212 seq_printf(s, "\n");
213 return 0;
214}
215
216static int ie6xx_wdt_dbg_open(struct inode *inode, struct file *file)
217{
218 return single_open(file, ie6xx_wdt_dbg_show, NULL);
219}
220
221static const struct file_operations ie6xx_wdt_dbg_operations = {
222 .open = ie6xx_wdt_dbg_open,
223 .read = seq_read,
224 .llseek = seq_lseek,
225 .release = single_release,
226};
227
228static void __devinit ie6xx_wdt_debugfs_init(void)
229{
230 /* /sys/kernel/debug/ie6xx_wdt */
231 ie6xx_wdt_data.debugfs = debugfs_create_file("ie6xx_wdt",
232 S_IFREG | S_IRUGO, NULL, NULL, &ie6xx_wdt_dbg_operations);
233}
234
235static void __devexit ie6xx_wdt_debugfs_exit(void)
236{
237 debugfs_remove(ie6xx_wdt_data.debugfs);
238}
239
240#else
241static void __devinit ie6xx_wdt_debugfs_init(void)
242{
243}
244
245static void __devexit ie6xx_wdt_debugfs_exit(void)
246{
247}
248#endif
249
250static int __devinit ie6xx_wdt_probe(struct platform_device *pdev)
251{
252 struct resource *res;
253 u8 wdtlr;
254 int ret;
255
256 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
257 if (!res)
258 return -ENODEV;
259
260 if (!request_region(res->start, resource_size(res), pdev->name)) {
261 dev_err(&pdev->dev, "Watchdog region 0x%llx already in use!\n",
262 (u64)res->start);
263 return -EBUSY;
264 }
265
266 ie6xx_wdt_data.sch_wdtba = res->start;
267 dev_dbg(&pdev->dev, "WDT = 0x%X\n", ie6xx_wdt_data.sch_wdtba);
268
269 ie6xx_wdt_dev.timeout = timeout;
270 watchdog_set_nowayout(&ie6xx_wdt_dev, nowayout);
271
272 spin_lock_init(&ie6xx_wdt_data.unlock_sequence);
273
274 wdtlr = inb(ie6xx_wdt_data.sch_wdtba + WDTLR);
275 if (wdtlr & WDT_LOCK)
276 dev_warn(&pdev->dev,
277 "Watchdog Timer is Locked (Reg=0x%x)\n", wdtlr);
278
279 ie6xx_wdt_debugfs_init();
280
281 ret = watchdog_register_device(&ie6xx_wdt_dev);
282 if (ret) {
283 dev_err(&pdev->dev,
284 "Watchdog timer: cannot register device (err =%d)\n",
285 ret);
286 goto misc_register_error;
287 }
288
289 return 0;
290
291misc_register_error:
292 ie6xx_wdt_debugfs_exit();
293 release_region(res->start, resource_size(res));
294 ie6xx_wdt_data.sch_wdtba = 0;
295 return ret;
296}
297
298static int __devexit ie6xx_wdt_remove(struct platform_device *pdev)
299{
300 struct resource *res;
301
302 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
303 ie6xx_wdt_stop(NULL);
304 watchdog_unregister_device(&ie6xx_wdt_dev);
305 ie6xx_wdt_debugfs_exit();
306 release_region(res->start, resource_size(res));
307 ie6xx_wdt_data.sch_wdtba = 0;
308
309 return 0;
310}
311
312static struct platform_driver ie6xx_wdt_driver = {
313 .probe = ie6xx_wdt_probe,
314 .remove = __devexit_p(ie6xx_wdt_remove),
315 .driver = {
316 .name = DRIVER_NAME,
317 .owner = THIS_MODULE,
318 },
319};
320
321static int __init ie6xx_wdt_init(void)
322{
323 /* Check boot parameters to verify that their initial values */
324 /* are in range. */
325 if ((timeout < MIN_TIME) ||
326 (timeout > MAX_TIME)) {
327 pr_err("Watchdog timer: value of timeout %d (dec) "
328 "is out of range from %d to %d (dec)\n",
329 timeout, MIN_TIME, MAX_TIME);
330 return -EINVAL;
331 }
332
333 return platform_driver_register(&ie6xx_wdt_driver);
334}
335
336static void __exit ie6xx_wdt_exit(void)
337{
338 platform_driver_unregister(&ie6xx_wdt_driver);
339}
340
341late_initcall(ie6xx_wdt_init);
342module_exit(ie6xx_wdt_exit);
343
344MODULE_AUTHOR("Alexander Stein <alexander.stein@systec-electronic.com>");
345MODULE_DESCRIPTION("Intel Atom E6xx Watchdog Device Driver");
346MODULE_LICENSE("GPL");
347MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
348MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c
index 8a741bcb5124..d3dcc6988b5f 100644
--- a/drivers/watchdog/it87_wdt.c
+++ b/drivers/watchdog/it87_wdt.c
@@ -12,7 +12,8 @@
12 * http://www.ite.com.tw/ 12 * http://www.ite.com.tw/
13 * 13 *
14 * Support of the watchdog timers, which are available on 14 * Support of the watchdog timers, which are available on
15 * IT8702, IT8712, IT8716, IT8718, IT8720, IT8721 and IT8726. 15 * IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726
16 * and IT8728.
16 * 17 *
17 * This program is free software; you can redistribute it and/or 18 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License 19 * modify it under the terms of the GNU General Public License
@@ -84,6 +85,7 @@
84#define IT8720_ID 0x8720 85#define IT8720_ID 0x8720
85#define IT8721_ID 0x8721 86#define IT8721_ID 0x8721
86#define IT8726_ID 0x8726 /* the data sheet suggest wrongly 0x8716 */ 87#define IT8726_ID 0x8726 /* the data sheet suggest wrongly 0x8716 */
88#define IT8728_ID 0x8728
87 89
88/* GPIO Configuration Registers LDN=0x07 */ 90/* GPIO Configuration Registers LDN=0x07 */
89#define WDTCTRL 0x71 91#define WDTCTRL 0x71
@@ -95,7 +97,7 @@
95#define WDT_CIRINT 0x80 97#define WDT_CIRINT 0x80
96#define WDT_MOUSEINT 0x40 98#define WDT_MOUSEINT 0x40
97#define WDT_KYBINT 0x20 99#define WDT_KYBINT 0x20
98#define WDT_GAMEPORT 0x10 /* not in it8718, it8720, it8721 */ 100#define WDT_GAMEPORT 0x10 /* not in it8718, it8720, it8721, it8728 */
99#define WDT_FORCE 0x02 101#define WDT_FORCE 0x02
100#define WDT_ZERO 0x01 102#define WDT_ZERO 0x01
101 103
@@ -616,6 +618,7 @@ static int __init it87_wdt_init(void)
616 case IT8718_ID: 618 case IT8718_ID:
617 case IT8720_ID: 619 case IT8720_ID:
618 case IT8721_ID: 620 case IT8721_ID:
621 case IT8728_ID:
619 max_units = 65535; 622 max_units = 65535;
620 try_gameport = 0; 623 try_gameport = 0;
621 break; 624 break;
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
deleted file mode 100644
index 3f047a58d3ae..000000000000
--- a/drivers/watchdog/ixp2000_wdt.c
+++ /dev/null
@@ -1,215 +0,0 @@
1/*
2 * drivers/char/watchdog/ixp2000_wdt.c
3 *
4 * Watchdog driver for Intel IXP2000 network processors
5 *
6 * Adapted from the IXP4xx watchdog driver by Lennert Buytenhek.
7 * The original version carries these notices:
8 *
9 * Author: Deepak Saxena <dsaxena@plexity.net>
10 *
11 * Copyright 2004 (c) MontaVista, Software, Inc.
12 * Based on sa1100 driver, Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
13 *
14 * This file is licensed under the terms of the GNU General Public
15 * License version 2. This program is licensed "as is" without any
16 * warranty of any kind, whether express or implied.
17 */
18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/types.h>
24#include <linux/timer.h>
25#include <linux/kernel.h>
26#include <linux/fs.h>
27#include <linux/miscdevice.h>
28#include <linux/watchdog.h>
29#include <linux/init.h>
30#include <linux/bitops.h>
31#include <linux/uaccess.h>
32#include <mach/hardware.h>
33
34static bool nowayout = WATCHDOG_NOWAYOUT;
35static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */
36static unsigned long wdt_status;
37static DEFINE_SPINLOCK(wdt_lock);
38
39#define WDT_IN_USE 0
40#define WDT_OK_TO_CLOSE 1
41
42static unsigned long wdt_tick_rate;
43
44static void wdt_enable(void)
45{
46 spin_lock(&wdt_lock);
47 ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE);
48 ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE);
49 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
50 ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE);
51 spin_unlock(&wdt_lock);
52}
53
54static void wdt_disable(void)
55{
56 spin_lock(&wdt_lock);
57 ixp2000_reg_write(IXP2000_T4_CTL, 0);
58 spin_unlock(&wdt_lock);
59}
60
61static void wdt_keepalive(void)
62{
63 spin_lock(&wdt_lock);
64 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
65 spin_unlock(&wdt_lock);
66}
67
68static int ixp2000_wdt_open(struct inode *inode, struct file *file)
69{
70 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
71 return -EBUSY;
72
73 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
74
75 wdt_enable();
76
77 return nonseekable_open(inode, file);
78}
79
80static ssize_t ixp2000_wdt_write(struct file *file, const char *data,
81 size_t len, loff_t *ppos)
82{
83 if (len) {
84 if (!nowayout) {
85 size_t i;
86
87 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
88
89 for (i = 0; i != len; i++) {
90 char c;
91
92 if (get_user(c, data + i))
93 return -EFAULT;
94 if (c == 'V')
95 set_bit(WDT_OK_TO_CLOSE, &wdt_status);
96 }
97 }
98 wdt_keepalive();
99 }
100
101 return len;
102}
103
104
105static const struct watchdog_info ident = {
106 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
107 WDIOF_KEEPALIVEPING,
108 .identity = "IXP2000 Watchdog",
109};
110
111static long ixp2000_wdt_ioctl(struct file *file, unsigned int cmd,
112 unsigned long arg)
113{
114 int ret = -ENOTTY;
115 int time;
116
117 switch (cmd) {
118 case WDIOC_GETSUPPORT:
119 ret = copy_to_user((struct watchdog_info *)arg, &ident,
120 sizeof(ident)) ? -EFAULT : 0;
121 break;
122
123 case WDIOC_GETSTATUS:
124 ret = put_user(0, (int *)arg);
125 break;
126
127 case WDIOC_GETBOOTSTATUS:
128 ret = put_user(0, (int *)arg);
129 break;
130
131 case WDIOC_KEEPALIVE:
132 wdt_enable();
133 ret = 0;
134 break;
135
136 case WDIOC_SETTIMEOUT:
137 ret = get_user(time, (int *)arg);
138 if (ret)
139 break;
140
141 if (time <= 0 || time > 60) {
142 ret = -EINVAL;
143 break;
144 }
145
146 heartbeat = time;
147 wdt_keepalive();
148 /* Fall through */
149
150 case WDIOC_GETTIMEOUT:
151 ret = put_user(heartbeat, (int *)arg);
152 break;
153 }
154
155 return ret;
156}
157
158static int ixp2000_wdt_release(struct inode *inode, struct file *file)
159{
160 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
161 wdt_disable();
162 else
163 pr_crit("Device closed unexpectedly - timer will not stop\n");
164 clear_bit(WDT_IN_USE, &wdt_status);
165 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
166
167 return 0;
168}
169
170
171static const struct file_operations ixp2000_wdt_fops = {
172 .owner = THIS_MODULE,
173 .llseek = no_llseek,
174 .write = ixp2000_wdt_write,
175 .unlocked_ioctl = ixp2000_wdt_ioctl,
176 .open = ixp2000_wdt_open,
177 .release = ixp2000_wdt_release,
178};
179
180static struct miscdevice ixp2000_wdt_miscdev = {
181 .minor = WATCHDOG_MINOR,
182 .name = "watchdog",
183 .fops = &ixp2000_wdt_fops,
184};
185
186static int __init ixp2000_wdt_init(void)
187{
188 if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
189 pr_info("Unable to use IXP2000 watchdog due to IXP2800 erratum #25\n");
190 return -EIO;
191 }
192 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
193 return misc_register(&ixp2000_wdt_miscdev);
194}
195
196static void __exit ixp2000_wdt_exit(void)
197{
198 misc_deregister(&ixp2000_wdt_miscdev);
199}
200
201module_init(ixp2000_wdt_init);
202module_exit(ixp2000_wdt_exit);
203
204MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
205MODULE_DESCRIPTION("IXP2000 Network Processor Watchdog");
206
207module_param(heartbeat, int, 0);
208MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 60s)");
209
210module_param(nowayout, bool, 0);
211MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
212
213MODULE_LICENSE("GPL");
214MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
215
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index c891399bed6a..ee6900da8678 100644
--- a/drivers/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
@@ -707,6 +707,7 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
707 goto err_out_disable_device; 707 goto err_out_disable_device;
708 } 708 }
709 709
710 spin_lock_init(&pcipcwd_private.io_lock);
710 pcipcwd_private.pdev = pdev; 711 pcipcwd_private.pdev = pdev;
711 pcipcwd_private.io_addr = pci_resource_start(pdev, 0); 712 pcipcwd_private.io_addr = pci_resource_start(pdev, 0);
712 713
@@ -814,22 +815,7 @@ static struct pci_driver pcipcwd_driver = {
814 .remove = __devexit_p(pcipcwd_card_exit), 815 .remove = __devexit_p(pcipcwd_card_exit),
815}; 816};
816 817
817static int __init pcipcwd_init_module(void) 818module_pci_driver(pcipcwd_driver);
818{
819 spin_lock_init(&pcipcwd_private.io_lock);
820
821 return pci_register_driver(&pcipcwd_driver);
822}
823
824static void __exit pcipcwd_cleanup_module(void)
825{
826 pci_unregister_driver(&pcipcwd_driver);
827
828 pr_info("Watchdog Module Unloaded\n");
829}
830
831module_init(pcipcwd_init_module);
832module_exit(pcipcwd_cleanup_module);
833 819
834MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>"); 820MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>");
835MODULE_DESCRIPTION("Berkshire PCI-PC Watchdog driver"); 821MODULE_DESCRIPTION("Berkshire PCI-PC Watchdog driver");
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 6b8432f61d05..87722e126058 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -32,6 +32,7 @@
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/err.h> 34#include <linux/err.h>
35#include <linux/of.h>
35#include <mach/hardware.h> 36#include <mach/hardware.h>
36 37
37/* WatchDog Timer - Chapter 23 Page 207 */ 38/* WatchDog Timer - Chapter 23 Page 207 */
@@ -201,10 +202,19 @@ static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
201 return 0; 202 return 0;
202} 203}
203 204
205#ifdef CONFIG_OF
206static const struct of_device_id pnx4008_wdt_match[] = {
207 { .compatible = "nxp,pnx4008-wdt" },
208 { }
209};
210MODULE_DEVICE_TABLE(of, pnx4008_wdt_match);
211#endif
212
204static struct platform_driver platform_wdt_driver = { 213static struct platform_driver platform_wdt_driver = {
205 .driver = { 214 .driver = {
206 .name = "pnx4008-watchdog", 215 .name = "pnx4008-watchdog",
207 .owner = THIS_MODULE, 216 .owner = THIS_MODULE,
217 .of_match_table = of_match_ptr(pnx4008_wdt_match),
208 }, 218 },
209 .probe = pnx4008_wdt_probe, 219 .probe = pnx4008_wdt_probe,
210 .remove = __devexit_p(pnx4008_wdt_remove), 220 .remove = __devexit_p(pnx4008_wdt_remove),
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 04e5a6de47d7..200ece5e2a22 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -40,6 +40,7 @@
40#include <linux/cpufreq.h> 40#include <linux/cpufreq.h>
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <linux/err.h> 42#include <linux/err.h>
43#include <linux/of.h>
43 44
44#include <mach/map.h> 45#include <mach/map.h>
45 46
@@ -201,7 +202,7 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeou
201 writel(count, wdt_base + S3C2410_WTDAT); 202 writel(count, wdt_base + S3C2410_WTDAT);
202 writel(wtcon, wdt_base + S3C2410_WTCON); 203 writel(wtcon, wdt_base + S3C2410_WTCON);
203 204
204 wdd->timeout = timeout; 205 wdd->timeout = (count * divisor) / freq;
205 206
206 return 0; 207 return 0;
207} 208}
@@ -503,8 +504,6 @@ static const struct of_device_id s3c2410_wdt_match[] = {
503 {}, 504 {},
504}; 505};
505MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); 506MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
506#else
507#define s3c2410_wdt_match NULL
508#endif 507#endif
509 508
510static struct platform_driver s3c2410wdt_driver = { 509static struct platform_driver s3c2410wdt_driver = {
@@ -516,7 +515,7 @@ static struct platform_driver s3c2410wdt_driver = {
516 .driver = { 515 .driver = {
517 .owner = THIS_MODULE, 516 .owner = THIS_MODULE,
518 .name = "s3c2410-wdt", 517 .name = "s3c2410-wdt",
519 .of_match_table = s3c2410_wdt_match, 518 .of_match_table = of_match_ptr(s3c2410_wdt_match),
520 }, 519 },
521}; 520};
522 521
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c
index bd86f32d63ab..f8477002b728 100644
--- a/drivers/watchdog/sch311x_wdt.c
+++ b/drivers/watchdog/sch311x_wdt.c
@@ -41,7 +41,6 @@
41#define DRV_NAME "sch311x_wdt" 41#define DRV_NAME "sch311x_wdt"
42 42
43/* Runtime registers */ 43/* Runtime registers */
44#define RESGEN 0x1d
45#define GP60 0x47 44#define GP60 0x47
46#define WDT_TIME_OUT 0x65 45#define WDT_TIME_OUT 0x65
47#define WDT_VAL 0x66 46#define WDT_VAL 0x66
@@ -69,10 +68,6 @@ static unsigned short force_id;
69module_param(force_id, ushort, 0); 68module_param(force_id, ushort, 0);
70MODULE_PARM_DESC(force_id, "Override the detected device ID"); 69MODULE_PARM_DESC(force_id, "Override the detected device ID");
71 70
72static unsigned short therm_trip;
73module_param(therm_trip, ushort, 0);
74MODULE_PARM_DESC(therm_trip, "Should a ThermTrip trigger the reset generator");
75
76#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ 71#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */
77static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 72static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
78module_param(timeout, int, 0); 73module_param(timeout, int, 0);
@@ -358,26 +353,16 @@ static struct miscdevice sch311x_wdt_miscdev = {
358static int __devinit sch311x_wdt_probe(struct platform_device *pdev) 353static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
359{ 354{
360 struct device *dev = &pdev->dev; 355 struct device *dev = &pdev->dev;
361 unsigned char val;
362 int err; 356 int err;
363 357
364 spin_lock_init(&sch311x_wdt_data.io_lock); 358 spin_lock_init(&sch311x_wdt_data.io_lock);
365 359
366 if (!request_region(sch311x_wdt_data.runtime_reg + RESGEN, 1,
367 DRV_NAME)) {
368 dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
369 sch311x_wdt_data.runtime_reg + RESGEN,
370 sch311x_wdt_data.runtime_reg + RESGEN);
371 err = -EBUSY;
372 goto exit;
373 }
374
375 if (!request_region(sch311x_wdt_data.runtime_reg + GP60, 1, DRV_NAME)) { 360 if (!request_region(sch311x_wdt_data.runtime_reg + GP60, 1, DRV_NAME)) {
376 dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n", 361 dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
377 sch311x_wdt_data.runtime_reg + GP60, 362 sch311x_wdt_data.runtime_reg + GP60,
378 sch311x_wdt_data.runtime_reg + GP60); 363 sch311x_wdt_data.runtime_reg + GP60);
379 err = -EBUSY; 364 err = -EBUSY;
380 goto exit_release_region; 365 goto exit;
381 } 366 }
382 367
383 if (!request_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4, 368 if (!request_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4,
@@ -386,7 +371,7 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
386 sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 371 sch311x_wdt_data.runtime_reg + WDT_TIME_OUT,
387 sch311x_wdt_data.runtime_reg + WDT_CTRL); 372 sch311x_wdt_data.runtime_reg + WDT_CTRL);
388 err = -EBUSY; 373 err = -EBUSY;
389 goto exit_release_region2; 374 goto exit_release_region;
390 } 375 }
391 376
392 /* Make sure that the watchdog is not running */ 377 /* Make sure that the watchdog is not running */
@@ -414,24 +399,13 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
414 /* Get status at boot */ 399 /* Get status at boot */
415 sch311x_wdt_get_status(&sch311x_wdt_data.boot_status); 400 sch311x_wdt_get_status(&sch311x_wdt_data.boot_status);
416 401
417 /* enable watchdog */
418 /* -- Reset Generator --
419 * Bit 0 Enable Watchdog Timer Generation: 0* = Enabled, 1 = Disabled
420 * Bit 1 Thermtrip Source Select: O* = No Source, 1 = Source
421 * Bit 2 WDT2_CTL: WDT input bit
422 * Bit 3-7 Reserved
423 */
424 outb(0, sch311x_wdt_data.runtime_reg + RESGEN);
425 val = therm_trip ? 0x06 : 0x04;
426 outb(val, sch311x_wdt_data.runtime_reg + RESGEN);
427
428 sch311x_wdt_miscdev.parent = dev; 402 sch311x_wdt_miscdev.parent = dev;
429 403
430 err = misc_register(&sch311x_wdt_miscdev); 404 err = misc_register(&sch311x_wdt_miscdev);
431 if (err != 0) { 405 if (err != 0) {
432 dev_err(dev, "cannot register miscdev on minor=%d (err=%d)\n", 406 dev_err(dev, "cannot register miscdev on minor=%d (err=%d)\n",
433 WATCHDOG_MINOR, err); 407 WATCHDOG_MINOR, err);
434 goto exit_release_region3; 408 goto exit_release_region2;
435 } 409 }
436 410
437 dev_info(dev, 411 dev_info(dev,
@@ -440,12 +414,10 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
440 414
441 return 0; 415 return 0;
442 416
443exit_release_region3:
444 release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
445exit_release_region2: 417exit_release_region2:
446 release_region(sch311x_wdt_data.runtime_reg + GP60, 1); 418 release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
447exit_release_region: 419exit_release_region:
448 release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1); 420 release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
449 sch311x_wdt_data.runtime_reg = 0; 421 sch311x_wdt_data.runtime_reg = 0;
450exit: 422exit:
451 return err; 423 return err;
@@ -461,7 +433,6 @@ static int __devexit sch311x_wdt_remove(struct platform_device *pdev)
461 misc_deregister(&sch311x_wdt_miscdev); 433 misc_deregister(&sch311x_wdt_miscdev);
462 release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4); 434 release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
463 release_region(sch311x_wdt_data.runtime_reg + GP60, 1); 435 release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
464 release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1);
465 sch311x_wdt_data.runtime_reg = 0; 436 sch311x_wdt_data.runtime_reg = 0;
466 return 0; 437 return 0;
467} 438}
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
index 59108e48ada3..ae5e82cb83fa 100644
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -313,7 +313,7 @@ static unsigned char __devinit sp5100_tco_setupdevice(void)
313 tcobase_phys = val; 313 tcobase_phys = val;
314 314
315 tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE); 315 tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE);
316 if (tcobase == 0) { 316 if (!tcobase) {
317 pr_err("failed to get tcobase address\n"); 317 pr_err("failed to get tcobase address\n");
318 goto unreg_mem_region; 318 goto unreg_mem_region;
319 } 319 }
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
index 465e08273c97..5603e31afdab 100644
--- a/drivers/watchdog/via_wdt.c
+++ b/drivers/watchdog/via_wdt.c
@@ -202,6 +202,9 @@ static int __devinit wdt_probe(struct pci_dev *pdev,
202 goto err_out_release; 202 goto err_out_release;
203 } 203 }
204 204
205 if (timeout < 1 || timeout > WDT_TIMEOUT_MAX)
206 timeout = WDT_TIMEOUT;
207
205 wdt_dev.timeout = timeout; 208 wdt_dev.timeout = timeout;
206 watchdog_set_nowayout(&wdt_dev, nowayout); 209 watchdog_set_nowayout(&wdt_dev, nowayout);
207 if (readl(wdt_mem) & VIA_WDT_FIRED) 210 if (readl(wdt_mem) & VIA_WDT_FIRED)
@@ -250,20 +253,7 @@ static struct pci_driver wdt_driver = {
250 .remove = __devexit_p(wdt_remove), 253 .remove = __devexit_p(wdt_remove),
251}; 254};
252 255
253static int __init wdt_init(void) 256module_pci_driver(wdt_driver);
254{
255 if (timeout < 1 || timeout > WDT_TIMEOUT_MAX)
256 timeout = WDT_TIMEOUT;
257 return pci_register_driver(&wdt_driver);
258}
259
260static void __exit wdt_exit(void)
261{
262 pci_unregister_driver(&wdt_driver);
263}
264
265module_init(wdt_init);
266module_exit(wdt_exit);
267 257
268MODULE_AUTHOR("Marc Vertes"); 258MODULE_AUTHOR("Marc Vertes");
269MODULE_DESCRIPTION("Driver for watchdog timer on VIA chipset"); 259MODULE_DESCRIPTION("Driver for watchdog timer on VIA chipset");
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index 1c888c7d4cce..e32654efdbb6 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -739,39 +739,7 @@ static struct pci_driver wdtpci_driver = {
739 .remove = __devexit_p(wdtpci_remove_one), 739 .remove = __devexit_p(wdtpci_remove_one),
740}; 740};
741 741
742 742module_pci_driver(wdtpci_driver);
743/**
744 * wdtpci_cleanup:
745 *
746 * Unload the watchdog. You cannot do this with any file handles open.
747 * If your watchdog is set to continue ticking on close and you unload
748 * it, well it keeps ticking. We won't get the interrupt but the board
749 * will not touch PC memory so all is fine. You just have to load a new
750 * module in xx seconds or reboot.
751 */
752
753static void __exit wdtpci_cleanup(void)
754{
755 pci_unregister_driver(&wdtpci_driver);
756}
757
758
759/**
760 * wdtpci_init:
761 *
762 * Set up the WDT watchdog board. All we have to do is grab the
763 * resources we require and bitch if anyone beat us to them.
764 * The open() function will actually kick the board off.
765 */
766
767static int __init wdtpci_init(void)
768{
769 return pci_register_driver(&wdtpci_driver);
770}
771
772
773module_init(wdtpci_init);
774module_exit(wdtpci_cleanup);
775 743
776MODULE_AUTHOR("JP Nollmann, Alan Cox"); 744MODULE_AUTHOR("JP Nollmann, Alan Cox");
777MODULE_DESCRIPTION("Driver for the ICS PCI-WDT500/501 watchdog cards"); 745MODULE_DESCRIPTION("Driver for the ICS PCI-WDT500/501 watchdog cards");
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index b1815c5ed7a7..87d66d236c3e 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -247,8 +247,9 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
247 reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT; 247 reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT;
248 248
249 if (pdata->update_gpio) { 249 if (pdata->update_gpio) {
250 ret = gpio_request(pdata->update_gpio, 250 ret = gpio_request_one(pdata->update_gpio,
251 "Watchdog update"); 251 GPIOF_DIR_OUT | GPIOF_INIT_LOW,
252 "Watchdog update");
252 if (ret < 0) { 253 if (ret < 0) {
253 dev_err(wm831x->dev, 254 dev_err(wm831x->dev,
254 "Failed to request update GPIO: %d\n", 255 "Failed to request update GPIO: %d\n",
@@ -256,14 +257,6 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
256 goto err; 257 goto err;
257 } 258 }
258 259
259 ret = gpio_direction_output(pdata->update_gpio, 0);
260 if (ret != 0) {
261 dev_err(wm831x->dev,
262 "gpio_direction_output returned: %d\n",
263 ret);
264 goto err_gpio;
265 }
266
267 driver_data->update_gpio = pdata->update_gpio; 260 driver_data->update_gpio = pdata->update_gpio;
268 261
269 /* Make sure the watchdog takes hardware updates */ 262 /* Make sure the watchdog takes hardware updates */