diff options
-rw-r--r-- | Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt | 13 | ||||
-rw-r--r-- | Documentation/watchdog/src/watchdog-test.c | 20 | ||||
-rw-r--r-- | Documentation/watchdog/watchdog-kernel-api.txt | 2 | ||||
-rw-r--r-- | drivers/watchdog/Kconfig | 35 | ||||
-rw-r--r-- | drivers/watchdog/Makefile | 2 | ||||
-rw-r--r-- | drivers/watchdog/ar7_wdt.c | 33 | ||||
-rw-r--r-- | drivers/watchdog/hpwdt.c | 13 | ||||
-rw-r--r-- | drivers/watchdog/i6300esb.c | 14 | ||||
-rw-r--r-- | drivers/watchdog/ie6xx_wdt.c | 348 | ||||
-rw-r--r-- | drivers/watchdog/it87_wdt.c | 7 | ||||
-rw-r--r-- | drivers/watchdog/ixp2000_wdt.c | 215 | ||||
-rw-r--r-- | drivers/watchdog/pcwd_pci.c | 18 | ||||
-rw-r--r-- | drivers/watchdog/pnx4008_wdt.c | 10 | ||||
-rw-r--r-- | drivers/watchdog/s3c2410_wdt.c | 7 | ||||
-rw-r--r-- | drivers/watchdog/sch311x_wdt.c | 39 | ||||
-rw-r--r-- | drivers/watchdog/sp5100_tco.c | 2 | ||||
-rw-r--r-- | drivers/watchdog/via_wdt.c | 18 | ||||
-rw-r--r-- | drivers/watchdog/wdt_pci.c | 34 | ||||
-rw-r--r-- | drivers/watchdog/wm831x_wdt.c | 13 |
19 files changed, 447 insertions, 396 deletions
diff --git a/Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt b/Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt new file mode 100644 index 000000000000..7c7f6887c796 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt | |||
@@ -0,0 +1,13 @@ | |||
1 | * NXP PNX watchdog timer | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: must be "nxp,pnx4008-wdt" | ||
5 | - reg: physical base address of the controller and length of memory mapped | ||
6 | region. | ||
7 | |||
8 | Example: | ||
9 | |||
10 | watchdog@4003C000 { | ||
11 | compatible = "nxp,pnx4008-wdt"; | ||
12 | reg = <0x4003C000 0x1000>; | ||
13 | }; | ||
diff --git a/Documentation/watchdog/src/watchdog-test.c b/Documentation/watchdog/src/watchdog-test.c index 63fdc34ceb98..73ff5cc93e05 100644 --- a/Documentation/watchdog/src/watchdog-test.c +++ b/Documentation/watchdog/src/watchdog-test.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <string.h> | 7 | #include <string.h> |
8 | #include <unistd.h> | 8 | #include <unistd.h> |
9 | #include <fcntl.h> | 9 | #include <fcntl.h> |
10 | #include <signal.h> | ||
10 | #include <sys/ioctl.h> | 11 | #include <sys/ioctl.h> |
11 | #include <linux/types.h> | 12 | #include <linux/types.h> |
12 | #include <linux/watchdog.h> | 13 | #include <linux/watchdog.h> |
@@ -29,6 +30,14 @@ static void keep_alive(void) | |||
29 | * The main program. Run the program with "-d" to disable the card, | 30 | * The main program. Run the program with "-d" to disable the card, |
30 | * or "-e" to enable the card. | 31 | * or "-e" to enable the card. |
31 | */ | 32 | */ |
33 | |||
34 | void term(int sig) | ||
35 | { | ||
36 | close(fd); | ||
37 | fprintf(stderr, "Stopping watchdog ticks...\n"); | ||
38 | exit(0); | ||
39 | } | ||
40 | |||
32 | int main(int argc, char *argv[]) | 41 | int main(int argc, char *argv[]) |
33 | { | 42 | { |
34 | int flags; | 43 | int flags; |
@@ -47,26 +56,31 @@ int main(int argc, char *argv[]) | |||
47 | ioctl(fd, WDIOC_SETOPTIONS, &flags); | 56 | ioctl(fd, WDIOC_SETOPTIONS, &flags); |
48 | fprintf(stderr, "Watchdog card disabled.\n"); | 57 | fprintf(stderr, "Watchdog card disabled.\n"); |
49 | fflush(stderr); | 58 | fflush(stderr); |
50 | exit(0); | 59 | goto end; |
51 | } else if (!strncasecmp(argv[1], "-e", 2)) { | 60 | } else if (!strncasecmp(argv[1], "-e", 2)) { |
52 | flags = WDIOS_ENABLECARD; | 61 | flags = WDIOS_ENABLECARD; |
53 | ioctl(fd, WDIOC_SETOPTIONS, &flags); | 62 | ioctl(fd, WDIOC_SETOPTIONS, &flags); |
54 | fprintf(stderr, "Watchdog card enabled.\n"); | 63 | fprintf(stderr, "Watchdog card enabled.\n"); |
55 | fflush(stderr); | 64 | fflush(stderr); |
56 | exit(0); | 65 | goto end; |
57 | } else { | 66 | } else { |
58 | fprintf(stderr, "-d to disable, -e to enable.\n"); | 67 | fprintf(stderr, "-d to disable, -e to enable.\n"); |
59 | fprintf(stderr, "run by itself to tick the card.\n"); | 68 | fprintf(stderr, "run by itself to tick the card.\n"); |
60 | fflush(stderr); | 69 | fflush(stderr); |
61 | exit(0); | 70 | goto end; |
62 | } | 71 | } |
63 | } else { | 72 | } else { |
64 | fprintf(stderr, "Watchdog Ticking Away!\n"); | 73 | fprintf(stderr, "Watchdog Ticking Away!\n"); |
65 | fflush(stderr); | 74 | fflush(stderr); |
66 | } | 75 | } |
67 | 76 | ||
77 | signal(SIGINT, term); | ||
78 | |||
68 | while(1) { | 79 | while(1) { |
69 | keep_alive(); | 80 | keep_alive(); |
70 | sleep(1); | 81 | sleep(1); |
71 | } | 82 | } |
83 | end: | ||
84 | close(fd); | ||
85 | return 0; | ||
72 | } | 86 | } |
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt index 227f6cd0e5fa..25fe4304f2fc 100644 --- a/Documentation/watchdog/watchdog-kernel-api.txt +++ b/Documentation/watchdog/watchdog-kernel-api.txt | |||
@@ -59,7 +59,7 @@ It contains following fields: | |||
59 | * bootstatus: status of the device after booting (reported with watchdog | 59 | * bootstatus: status of the device after booting (reported with watchdog |
60 | WDIOF_* status bits). | 60 | WDIOF_* status bits). |
61 | * driver_data: a pointer to the drivers private data of a watchdog device. | 61 | * driver_data: a pointer to the drivers private data of a watchdog device. |
62 | This data should only be accessed via the watchdog_set_drvadata and | 62 | This data should only be accessed via the watchdog_set_drvdata and |
63 | watchdog_get_drvdata routines. | 63 | watchdog_get_drvdata routines. |
64 | * status: this field contains a number of status bits that give extra | 64 | * status: this field contains a number of status bits that give extra |
65 | information about the status of the device (Like: is the watchdog timer | 65 | information about the status of the device (Like: is the watchdog timer |
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 | ||
132 | config 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 | |||
143 | config IXP4XX_WATCHDOG | 132 | config 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 | ||
544 | config I6300ESB_WDT | 533 | config 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 | ||
543 | config 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 | |||
554 | config INTEL_SCU_WATCHDOG | 556 | config 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 | ||
781 | config VIA_WDT | 788 | config 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 | |||
36 | obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o | 36 | obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o |
37 | obj-$(CONFIG_21285_WATCHDOG) += wdt285.o | 37 | obj-$(CONFIG_21285_WATCHDOG) += wdt285.o |
38 | obj-$(CONFIG_977_WATCHDOG) += wdt977.o | 38 | obj-$(CONFIG_977_WATCHDOG) += wdt977.o |
39 | obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o | ||
40 | obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o | 39 | obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o |
41 | obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o | 40 | obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o |
42 | obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o | 41 | obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o |
@@ -81,6 +80,7 @@ obj-$(CONFIG_IB700_WDT) += ib700wdt.o | |||
81 | obj-$(CONFIG_IBMASR) += ibmasr.o | 80 | obj-$(CONFIG_IBMASR) += ibmasr.o |
82 | obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o | 81 | obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o |
83 | obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o | 82 | obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o |
83 | obj-$(CONFIG_IE6XX_WDT) += ie6xx_wdt.o | ||
84 | obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o | 84 | obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o |
85 | ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y) | 85 | ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y) |
86 | obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o | 86 | obj-$(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 | ||
321 | out_alloc: | ||
322 | iounmap(ar7_wdt); | ||
323 | out_mem_region: | ||
324 | release_mem_region(ar7_regs_wdt->start, resource_size(ar7_regs_wdt)); | ||
325 | out: | 311 | out: |
312 | clk_put(vbus_clk); | ||
313 | vbus_clk = NULL; | ||
326 | return rc; | 314 | return rc; |
327 | } | 315 | } |
328 | 316 | ||
329 | static int __devexit ar7_wdt_remove(struct platform_device *pdev) | 317 | static 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 | ||
864 | static void __exit hpwdt_cleanup(void) | ||
865 | { | ||
866 | pci_unregister_driver(&hpwdt_driver); | ||
867 | } | ||
868 | |||
869 | static int __init hpwdt_init(void) | ||
870 | { | ||
871 | return pci_register_driver(&hpwdt_driver); | ||
872 | } | ||
873 | |||
874 | MODULE_AUTHOR("Tom Mingarelli"); | 864 | MODULE_AUTHOR("Tom Mingarelli"); |
875 | MODULE_DESCRIPTION("hp watchdog driver"); | 865 | MODULE_DESCRIPTION("hp watchdog driver"); |
876 | MODULE_LICENSE("GPL"); | 866 | MODULE_LICENSE("GPL"); |
@@ -889,5 +879,4 @@ module_param(allow_kdump, int, 0); | |||
889 | MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs"); | 879 | MODULE_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 | ||
892 | module_init(hpwdt_init); | 882 | module_pci_driver(hpwdt_driver); |
893 | module_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 | ||
495 | static int __init watchdog_init(void) | 495 | module_pci_driver(esb_driver); |
496 | { | ||
497 | return pci_register_driver(&esb_driver); | ||
498 | } | ||
499 | |||
500 | static void __exit watchdog_cleanup(void) | ||
501 | { | ||
502 | pci_unregister_driver(&esb_driver); | ||
503 | pr_info("Watchdog Module Unloaded\n"); | ||
504 | } | ||
505 | |||
506 | module_init(watchdog_init); | ||
507 | module_exit(watchdog_cleanup); | ||
508 | 496 | ||
509 | MODULE_AUTHOR("Ross Biro and David Härdeman"); | 497 | MODULE_AUTHOR("Ross Biro and David Härdeman"); |
510 | MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets"); | 498 | MODULE_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 | |||
64 | static unsigned int timeout = DEFAULT_TIME; | ||
65 | module_param(timeout, uint, 0); | ||
66 | MODULE_PARM_DESC(timeout, | ||
67 | "Default Watchdog timer setting (" | ||
68 | __MODULE_STRING(DEFAULT_TIME) "s)." | ||
69 | "The range is from 1 to 600"); | ||
70 | |||
71 | static bool nowayout = WATCHDOG_NOWAYOUT; | ||
72 | module_param(nowayout, bool, 0); | ||
73 | MODULE_PARM_DESC(nowayout, | ||
74 | "Watchdog cannot be stopped once started (default=" | ||
75 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
76 | |||
77 | static u8 resetmode = 0x10; | ||
78 | module_param(resetmode, byte, 0); | ||
79 | MODULE_PARM_DESC(resetmode, | ||
80 | "Resetmode bits: 0x08 warm reset (cold reset otherwise), " | ||
81 | "0x10 reset enable, 0x20 disable toggle GPIO[4] (default=0x10)"); | ||
82 | |||
83 | static 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 | */ | ||
96 | static 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 | |||
102 | static 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 | |||
111 | static 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 | |||
148 | static 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 | |||
160 | static 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 | |||
173 | static 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 | |||
180 | static 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 | |||
188 | static 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 | |||
197 | static 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 | |||
216 | static int ie6xx_wdt_dbg_open(struct inode *inode, struct file *file) | ||
217 | { | ||
218 | return single_open(file, ie6xx_wdt_dbg_show, NULL); | ||
219 | } | ||
220 | |||
221 | static 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 | |||
228 | static 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 | |||
235 | static void __devexit ie6xx_wdt_debugfs_exit(void) | ||
236 | { | ||
237 | debugfs_remove(ie6xx_wdt_data.debugfs); | ||
238 | } | ||
239 | |||
240 | #else | ||
241 | static void __devinit ie6xx_wdt_debugfs_init(void) | ||
242 | { | ||
243 | } | ||
244 | |||
245 | static void __devexit ie6xx_wdt_debugfs_exit(void) | ||
246 | { | ||
247 | } | ||
248 | #endif | ||
249 | |||
250 | static 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 | |||
291 | misc_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 | |||
298 | static 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 | |||
312 | static 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 | |||
321 | static 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 | |||
336 | static void __exit ie6xx_wdt_exit(void) | ||
337 | { | ||
338 | platform_driver_unregister(&ie6xx_wdt_driver); | ||
339 | } | ||
340 | |||
341 | late_initcall(ie6xx_wdt_init); | ||
342 | module_exit(ie6xx_wdt_exit); | ||
343 | |||
344 | MODULE_AUTHOR("Alexander Stein <alexander.stein@systec-electronic.com>"); | ||
345 | MODULE_DESCRIPTION("Intel Atom E6xx Watchdog Device Driver"); | ||
346 | MODULE_LICENSE("GPL"); | ||
347 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
348 | MODULE_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 | |||
34 | static bool nowayout = WATCHDOG_NOWAYOUT; | ||
35 | static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ | ||
36 | static unsigned long wdt_status; | ||
37 | static DEFINE_SPINLOCK(wdt_lock); | ||
38 | |||
39 | #define WDT_IN_USE 0 | ||
40 | #define WDT_OK_TO_CLOSE 1 | ||
41 | |||
42 | static unsigned long wdt_tick_rate; | ||
43 | |||
44 | static 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 | |||
54 | static 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 | |||
61 | static 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 | |||
68 | static 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 | |||
80 | static 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 | |||
105 | static const struct watchdog_info ident = { | ||
106 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | | ||
107 | WDIOF_KEEPALIVEPING, | ||
108 | .identity = "IXP2000 Watchdog", | ||
109 | }; | ||
110 | |||
111 | static 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 | |||
158 | static 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 | |||
171 | static 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 | |||
180 | static struct miscdevice ixp2000_wdt_miscdev = { | ||
181 | .minor = WATCHDOG_MINOR, | ||
182 | .name = "watchdog", | ||
183 | .fops = &ixp2000_wdt_fops, | ||
184 | }; | ||
185 | |||
186 | static 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 | |||
196 | static void __exit ixp2000_wdt_exit(void) | ||
197 | { | ||
198 | misc_deregister(&ixp2000_wdt_miscdev); | ||
199 | } | ||
200 | |||
201 | module_init(ixp2000_wdt_init); | ||
202 | module_exit(ixp2000_wdt_exit); | ||
203 | |||
204 | MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); | ||
205 | MODULE_DESCRIPTION("IXP2000 Network Processor Watchdog"); | ||
206 | |||
207 | module_param(heartbeat, int, 0); | ||
208 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 60s)"); | ||
209 | |||
210 | module_param(nowayout, bool, 0); | ||
211 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | ||
212 | |||
213 | MODULE_LICENSE("GPL"); | ||
214 | MODULE_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 | ||
817 | static int __init pcipcwd_init_module(void) | 818 | module_pci_driver(pcipcwd_driver); |
818 | { | ||
819 | spin_lock_init(&pcipcwd_private.io_lock); | ||
820 | |||
821 | return pci_register_driver(&pcipcwd_driver); | ||
822 | } | ||
823 | |||
824 | static void __exit pcipcwd_cleanup_module(void) | ||
825 | { | ||
826 | pci_unregister_driver(&pcipcwd_driver); | ||
827 | |||
828 | pr_info("Watchdog Module Unloaded\n"); | ||
829 | } | ||
830 | |||
831 | module_init(pcipcwd_init_module); | ||
832 | module_exit(pcipcwd_cleanup_module); | ||
833 | 819 | ||
834 | MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>"); | 820 | MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>"); |
835 | MODULE_DESCRIPTION("Berkshire PCI-PC Watchdog driver"); | 821 | MODULE_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 | ||
206 | static const struct of_device_id pnx4008_wdt_match[] = { | ||
207 | { .compatible = "nxp,pnx4008-wdt" }, | ||
208 | { } | ||
209 | }; | ||
210 | MODULE_DEVICE_TABLE(of, pnx4008_wdt_match); | ||
211 | #endif | ||
212 | |||
204 | static struct platform_driver platform_wdt_driver = { | 213 | static 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 | }; |
505 | MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); | 506 | MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); |
506 | #else | ||
507 | #define s3c2410_wdt_match NULL | ||
508 | #endif | 507 | #endif |
509 | 508 | ||
510 | static struct platform_driver s3c2410wdt_driver = { | 509 | static 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; | |||
69 | module_param(force_id, ushort, 0); | 68 | module_param(force_id, ushort, 0); |
70 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | 69 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); |
71 | 70 | ||
72 | static unsigned short therm_trip; | ||
73 | module_param(therm_trip, ushort, 0); | ||
74 | MODULE_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 */ |
77 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ | 72 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ |
78 | module_param(timeout, int, 0); | 73 | module_param(timeout, int, 0); |
@@ -358,26 +353,16 @@ static struct miscdevice sch311x_wdt_miscdev = { | |||
358 | static int __devinit sch311x_wdt_probe(struct platform_device *pdev) | 353 | static 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 | ||
443 | exit_release_region3: | ||
444 | release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4); | ||
445 | exit_release_region2: | 417 | exit_release_region2: |
446 | release_region(sch311x_wdt_data.runtime_reg + GP60, 1); | 418 | release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4); |
447 | exit_release_region: | 419 | exit_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; |
450 | exit: | 422 | exit: |
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 | ||
253 | static int __init wdt_init(void) | 256 | module_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 | |||
260 | static void __exit wdt_exit(void) | ||
261 | { | ||
262 | pci_unregister_driver(&wdt_driver); | ||
263 | } | ||
264 | |||
265 | module_init(wdt_init); | ||
266 | module_exit(wdt_exit); | ||
267 | 257 | ||
268 | MODULE_AUTHOR("Marc Vertes"); | 258 | MODULE_AUTHOR("Marc Vertes"); |
269 | MODULE_DESCRIPTION("Driver for watchdog timer on VIA chipset"); | 259 | MODULE_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 | 742 | module_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 | |||
753 | static 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 | |||
767 | static int __init wdtpci_init(void) | ||
768 | { | ||
769 | return pci_register_driver(&wdtpci_driver); | ||
770 | } | ||
771 | |||
772 | |||
773 | module_init(wdtpci_init); | ||
774 | module_exit(wdtpci_cleanup); | ||
775 | 743 | ||
776 | MODULE_AUTHOR("JP Nollmann, Alan Cox"); | 744 | MODULE_AUTHOR("JP Nollmann, Alan Cox"); |
777 | MODULE_DESCRIPTION("Driver for the ICS PCI-WDT500/501 watchdog cards"); | 745 | MODULE_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 */ |