aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/watchdog/atmel-wdt.txt30
-rw-r--r--Documentation/devicetree/bindings/watchdog/davinci-wdt.txt16
-rw-r--r--Documentation/devicetree/bindings/watchdog/gpio-wdt.txt23
-rw-r--r--Documentation/devicetree/bindings/watchdog/samsung-wdt.txt21
-rw-r--r--arch/arm/boot/dts/at91sam9260.dtsi5
-rw-r--r--arch/arm/boot/dts/at91sam9263.dtsi5
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi5
-rw-r--r--arch/arm/boot/dts/at91sam9n12.dtsi5
-rw-r--r--arch/arm/boot/dts/at91sam9x5.dtsi5
-rw-r--r--arch/arm/boot/dts/kizbox.dts6
-rw-r--r--arch/arm/boot/dts/sama5d3.dtsi5
-rw-r--r--arch/arm/configs/bcm_defconfig3
-rw-r--r--drivers/watchdog/Kconfig59
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/alim1535_wdt.c2
-rw-r--r--drivers/watchdog/alim7101_wdt.c2
-rw-r--r--drivers/watchdog/at91sam9_wdt.c320
-rw-r--r--drivers/watchdog/bcm_kona_wdt.c368
-rw-r--r--drivers/watchdog/davinci_wdt.c221
-rw-r--r--drivers/watchdog/dw_wdt.c2
-rw-r--r--drivers/watchdog/gpio_wdt.c254
-rw-r--r--drivers/watchdog/hpwdt.c13
-rw-r--r--drivers/watchdog/i6300esb.c2
-rw-r--r--drivers/watchdog/imx2_wdt.c4
-rw-r--r--drivers/watchdog/moxart_wdt.c15
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c110
-rw-r--r--drivers/watchdog/nv_tco.c2
-rw-r--r--drivers/watchdog/pcwd_pci.c2
-rw-r--r--drivers/watchdog/s3c2410_wdt.c203
-rw-r--r--drivers/watchdog/sirfsoc_wdt.c2
-rw-r--r--drivers/watchdog/sp5100_tco.c2
-rw-r--r--drivers/watchdog/via_wdt.c2
-rw-r--r--drivers/watchdog/w83627hf_wdt.c234
-rw-r--r--drivers/watchdog/watchdog_core.c4
-rw-r--r--drivers/watchdog/wdt_pci.c2
35 files changed, 1598 insertions, 358 deletions
diff --git a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
index fcdd48f7dcff..f90e294d7631 100644
--- a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
@@ -9,11 +9,37 @@ Required properties:
9 9
10Optional properties: 10Optional properties:
11- timeout-sec: contains the watchdog timeout in seconds. 11- timeout-sec: contains the watchdog timeout in seconds.
12- interrupts : Should contain WDT interrupt.
13- atmel,max-heartbeat-sec : Should contain the maximum heartbeat value in
14 seconds. This value should be less or equal to 16. It is used to
15 compute the WDV field.
16- atmel,min-heartbeat-sec : Should contain the minimum heartbeat value in
17 seconds. This value must be smaller than the max-heartbeat-sec value.
18 It is used to compute the WDD field.
19- atmel,watchdog-type : Should be "hardware" or "software". Hardware watchdog
20 use the at91 watchdog reset. Software watchdog use the watchdog
21 interrupt to trigger a software reset.
22- atmel,reset-type : Should be "proc" or "all".
23 "all" : assert peripherals and processor reset signals
24 "proc" : assert the processor reset signal
25 This is valid only when using "hardware" watchdog.
26- atmel,disable : Should be present if you want to disable the watchdog.
27- atmel,idle-halt : Should be present if you want to stop the watchdog when
28 entering idle state.
29- atmel,dbg-halt : Should be present if you want to stop the watchdog when
30 entering debug state.
12 31
13Example: 32Example:
14
15 watchdog@fffffd40 { 33 watchdog@fffffd40 {
16 compatible = "atmel,at91sam9260-wdt"; 34 compatible = "atmel,at91sam9260-wdt";
17 reg = <0xfffffd40 0x10>; 35 reg = <0xfffffd40 0x10>;
18 timeout-sec = <10>; 36 interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
37 timeout-sec = <15>;
38 atmel,watchdog-type = "hardware";
39 atmel,reset-type = "all";
40 atmel,dbg-halt;
41 atmel,idle-halt;
42 atmel,max-heartbeat-sec = <16>;
43 atmel,min-heartbeat-sec = <0>;
44 status = "okay";
19 }; 45 };
diff --git a/Documentation/devicetree/bindings/watchdog/davinci-wdt.txt b/Documentation/devicetree/bindings/watchdog/davinci-wdt.txt
index 75558ccd9a05..e60b9a13bdcb 100644
--- a/Documentation/devicetree/bindings/watchdog/davinci-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/davinci-wdt.txt
@@ -1,12 +1,24 @@
1DaVinci Watchdog Timer (WDT) Controller 1Texas Instruments DaVinci/Keystone Watchdog Timer (WDT) Controller
2 2
3Required properties: 3Required properties:
4- compatible : Should be "ti,davinci-wdt" 4- compatible : Should be "ti,davinci-wdt", "ti,keystone-wdt"
5- reg : Should contain WDT registers location and length 5- reg : Should contain WDT registers location and length
6 6
7Optional properties:
8- timeout-sec : Contains the watchdog timeout in seconds
9- clocks : the clock feeding the watchdog timer.
10 Needed if platform uses clocks.
11 See clock-bindings.txt
12
13Documentation:
14Davinci DM646x - http://www.ti.com/lit/ug/spruer5b/spruer5b.pdf
15Keystone - http://www.ti.com/lit/ug/sprugv5a/sprugv5a.pdf
16
7Examples: 17Examples:
8 18
9wdt: wdt@2320000 { 19wdt: wdt@2320000 {
10 compatible = "ti,davinci-wdt"; 20 compatible = "ti,davinci-wdt";
11 reg = <0x02320000 0x80>; 21 reg = <0x02320000 0x80>;
22 timeout-sec = <30>;
23 clocks = <&clkwdtimer0>;
12}; 24};
diff --git a/Documentation/devicetree/bindings/watchdog/gpio-wdt.txt b/Documentation/devicetree/bindings/watchdog/gpio-wdt.txt
new file mode 100644
index 000000000000..37afec194949
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/gpio-wdt.txt
@@ -0,0 +1,23 @@
1* GPIO-controlled Watchdog
2
3Required Properties:
4- compatible: Should contain "linux,wdt-gpio".
5- gpios: From common gpio binding; gpio connection to WDT reset pin.
6- hw_algo: The algorithm used by the driver. Should be one of the
7 following values:
8 - toggle: Either a high-to-low or a low-to-high transition clears
9 the WDT counter. The watchdog timer is disabled when GPIO is
10 left floating or connected to a three-state buffer.
11 - level: Low or high level starts counting WDT timeout,
12 the opposite level disables the WDT. Active level is determined
13 by the GPIO flags.
14- hw_margin_ms: Maximum time to reset watchdog circuit (milliseconds).
15
16Example:
17 watchdog: watchdog {
18 /* ADM706 */
19 compatible = "linux,wdt-gpio";
20 gpios = <&gpio3 9 GPIO_ACTIVE_LOW>;
21 hw_algo = "toggle";
22 hw_margin_ms = <1600>;
23 };
diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
index 2aa486cc1ff6..cfff37511aac 100644
--- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
@@ -5,10 +5,29 @@ after a preset amount of time during which the WDT reset event has not
5occurred. 5occurred.
6 6
7Required properties: 7Required properties:
8- compatible : should be "samsung,s3c2410-wdt" 8- compatible : should be one among the following
9 (a) "samsung,s3c2410-wdt" for Exynos4 and previous SoCs
10 (b) "samsung,exynos5250-wdt" for Exynos5250
11 (c) "samsung,exynos5420-wdt" for Exynos5420
12
9- reg : base physical address of the controller and length of memory mapped 13- reg : base physical address of the controller and length of memory mapped
10 region. 14 region.
11- interrupts : interrupt number to the cpu. 15- interrupts : interrupt number to the cpu.
16- samsung,syscon-phandle : reference to syscon node (This property required only
17 in case of compatible being "samsung,exynos5250-wdt" or "samsung,exynos5420-wdt".
18 In case of Exynos5250 and 5420 this property points to syscon node holding the PMU
19 base address)
12 20
13Optional properties: 21Optional properties:
14- timeout-sec : contains the watchdog timeout in seconds. 22- timeout-sec : contains the watchdog timeout in seconds.
23
24Example:
25
26watchdog@101D0000 {
27 compatible = "samsung,exynos5250-wdt";
28 reg = <0x101D0000 0x100>;
29 interrupts = <0 42 0>;
30 clocks = <&clock 336>;
31 clock-names = "watchdog";
32 samsung,syscon-phandle = <&pmu_syscon>;
33};
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index 56ee8282a7a8..997901f7ed73 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -648,6 +648,11 @@
648 watchdog@fffffd40 { 648 watchdog@fffffd40 {
649 compatible = "atmel,at91sam9260-wdt"; 649 compatible = "atmel,at91sam9260-wdt";
650 reg = <0xfffffd40 0x10>; 650 reg = <0xfffffd40 0x10>;
651 interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
652 atmel,watchdog-type = "hardware";
653 atmel,reset-type = "all";
654 atmel,dbg-halt;
655 atmel,idle-halt;
651 status = "disabled"; 656 status = "disabled";
652 }; 657 };
653 }; 658 };
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index c8fa9b9f07e3..0042f73068b0 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -552,6 +552,11 @@
552 watchdog@fffffd40 { 552 watchdog@fffffd40 {
553 compatible = "atmel,at91sam9260-wdt"; 553 compatible = "atmel,at91sam9260-wdt";
554 reg = <0xfffffd40 0x10>; 554 reg = <0xfffffd40 0x10>;
555 interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
556 atmel,watchdog-type = "hardware";
557 atmel,reset-type = "all";
558 atmel,dbg-halt;
559 atmel,idle-halt;
555 status = "disabled"; 560 status = "disabled";
556 }; 561 };
557 562
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index ef0857cb171c..cbcc058b26b4 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -706,6 +706,11 @@
706 watchdog@fffffd40 { 706 watchdog@fffffd40 {
707 compatible = "atmel,at91sam9260-wdt"; 707 compatible = "atmel,at91sam9260-wdt";
708 reg = <0xfffffd40 0x10>; 708 reg = <0xfffffd40 0x10>;
709 interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
710 atmel,watchdog-type = "hardware";
711 atmel,reset-type = "all";
712 atmel,dbg-halt;
713 atmel,idle-halt;
709 status = "disabled"; 714 status = "disabled";
710 }; 715 };
711 716
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index 7248270a3ea6..394e6ce2afb7 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -541,6 +541,11 @@
541 watchdog@fffffe40 { 541 watchdog@fffffe40 {
542 compatible = "atmel,at91sam9260-wdt"; 542 compatible = "atmel,at91sam9260-wdt";
543 reg = <0xfffffe40 0x10>; 543 reg = <0xfffffe40 0x10>;
544 interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
545 atmel,watchdog-type = "hardware";
546 atmel,reset-type = "all";
547 atmel,dbg-halt;
548 atmel,idle-halt;
544 status = "disabled"; 549 status = "disabled";
545 }; 550 };
546 551
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 6e5e9cfc3c49..174219de92fa 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -754,6 +754,11 @@
754 watchdog@fffffe40 { 754 watchdog@fffffe40 {
755 compatible = "atmel,at91sam9260-wdt"; 755 compatible = "atmel,at91sam9260-wdt";
756 reg = <0xfffffe40 0x10>; 756 reg = <0xfffffe40 0x10>;
757 interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
758 atmel,watchdog-type = "hardware";
759 atmel,reset-type = "all";
760 atmel,dbg-halt;
761 atmel,idle-halt;
757 status = "disabled"; 762 status = "disabled";
758 }; 763 };
759 764
diff --git a/arch/arm/boot/dts/kizbox.dts b/arch/arm/boot/dts/kizbox.dts
index 02df1914a47c..928f6eef2d59 100644
--- a/arch/arm/boot/dts/kizbox.dts
+++ b/arch/arm/boot/dts/kizbox.dts
@@ -53,6 +53,12 @@
53 status = "okay"; 53 status = "okay";
54 }; 54 };
55 55
56 watchdog@fffffd40 {
57 timeout-sec = <15>;
58 atmel,max-heartbeat-sec = <16>;
59 atmel,min-heartbeat-sec = <0>;
60 status = "okay";
61 };
56 }; 62 };
57 63
58 nand0: nand@40000000 { 64 nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index 1105558d188b..52447c17537a 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -1092,6 +1092,11 @@
1092 watchdog@fffffe40 { 1092 watchdog@fffffe40 {
1093 compatible = "atmel,at91sam9260-wdt"; 1093 compatible = "atmel,at91sam9260-wdt";
1094 reg = <0xfffffe40 0x10>; 1094 reg = <0xfffffe40 0x10>;
1095 interrupts = <4 IRQ_TYPE_LEVEL_HIGH 7>;
1096 atmel,watchdog-type = "hardware";
1097 atmel,reset-type = "all";
1098 atmel,dbg-halt;
1099 atmel,idle-halt;
1095 status = "disabled"; 1100 status = "disabled";
1096 }; 1101 };
1097 1102
diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig
index 2c38fdf1951d..2519d6de0640 100644
--- a/arch/arm/configs/bcm_defconfig
+++ b/arch/arm/configs/bcm_defconfig
@@ -126,3 +126,6 @@ CONFIG_CRC7=y
126CONFIG_XZ_DEC=y 126CONFIG_XZ_DEC=y
127CONFIG_AVERAGE=y 127CONFIG_AVERAGE=y
128CONFIG_PINCTRL_CAPRI=y 128CONFIG_PINCTRL_CAPRI=y
129CONFIG_WATCHDOG=y
130CONFIG_BCM_KONA_WDT=y
131CONFIG_BCM_KONA_WDT_DEBUG=y
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 5be6e919f785..4c4c566c52a3 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -87,6 +87,14 @@ config DA9055_WATCHDOG
87 This driver can also be built as a module. If so, the module 87 This driver can also be built as a module. If so, the module
88 will be called da9055_wdt. 88 will be called da9055_wdt.
89 89
90config GPIO_WATCHDOG
91 tristate "Watchdog device controlled through GPIO-line"
92 depends on OF_GPIO
93 select WATCHDOG_CORE
94 help
95 If you say yes here you get support for watchdog device
96 controlled through GPIO-line.
97
90config WM831X_WATCHDOG 98config WM831X_WATCHDOG
91 tristate "WM831x watchdog" 99 tristate "WM831x watchdog"
92 depends on MFD_WM831X 100 depends on MFD_WM831X
@@ -109,7 +117,7 @@ config WM8350_WATCHDOG
109 117
110config ARM_SP805_WATCHDOG 118config ARM_SP805_WATCHDOG
111 tristate "ARM SP805 Watchdog" 119 tristate "ARM SP805 Watchdog"
112 depends on ARM && ARM_AMBA 120 depends on (ARM || ARM64) && ARM_AMBA
113 select WATCHDOG_CORE 121 select WATCHDOG_CORE
114 help 122 help
115 ARM Primecell SP805 Watchdog timer. This will reboot your system when 123 ARM Primecell SP805 Watchdog timer. This will reboot your system when
@@ -188,6 +196,7 @@ config S3C2410_WATCHDOG
188 tristate "S3C2410 Watchdog" 196 tristate "S3C2410 Watchdog"
189 depends on HAVE_S3C2410_WATCHDOG 197 depends on HAVE_S3C2410_WATCHDOG
190 select WATCHDOG_CORE 198 select WATCHDOG_CORE
199 select MFD_SYSCON if ARCH_EXYNOS5
191 help 200 help
192 Watchdog timer block in the Samsung SoCs. This will reboot 201 Watchdog timer block in the Samsung SoCs. This will reboot
193 the system when the timer expires with the watchdog enabled. 202 the system when the timer expires with the watchdog enabled.
@@ -214,10 +223,9 @@ config SA1100_WATCHDOG
214 223
215config DW_WATCHDOG 224config DW_WATCHDOG
216 tristate "Synopsys DesignWare watchdog" 225 tristate "Synopsys DesignWare watchdog"
217 depends on ARM && HAVE_CLK
218 help 226 help
219 Say Y here if to include support for the Synopsys DesignWare 227 Say Y here if to include support for the Synopsys DesignWare
220 watchdog timer found in many ARM chips. 228 watchdog timer found in many chips.
221 To compile this driver as a module, choose M here: the 229 To compile this driver as a module, choose M here: the
222 module will be called dw_wdt. 230 module will be called dw_wdt.
223 231
@@ -270,10 +278,11 @@ config IOP_WATCHDOG
270 278
271config DAVINCI_WATCHDOG 279config DAVINCI_WATCHDOG
272 tristate "DaVinci watchdog" 280 tristate "DaVinci watchdog"
273 depends on ARCH_DAVINCI 281 depends on ARCH_DAVINCI || ARCH_KEYSTONE
282 select WATCHDOG_CORE
274 help 283 help
275 Say Y here if to include support for the watchdog timer 284 Say Y here if to include support for the watchdog timer
276 in the DaVinci DM644x/DM646x processors. 285 in the DaVinci DM644x/DM646x or Keystone processors.
277 To compile this driver as a module, choose M here: the 286 To compile this driver as a module, choose M here: the
278 module will be called davinci_wdt. 287 module will be called davinci_wdt.
279 288
@@ -883,13 +892,22 @@ config VIA_WDT
883 Most people will say N. 892 Most people will say N.
884 893
885config W83627HF_WDT 894config W83627HF_WDT
886 tristate "W83627HF/W83627DHG Watchdog Timer" 895 tristate "Watchdog timer for W83627HF/W83627DHG and compatibles"
887 depends on X86 896 depends on X86
888 select WATCHDOG_CORE 897 select WATCHDOG_CORE
889 ---help--- 898 ---help---
890 This is the driver for the hardware watchdog on the W83627HF chipset 899 This is the driver for the hardware watchdog on the following
891 as used in Advantech PC-9578 and Tyan S2721-533 motherboards 900 Super I/O chips.
892 (and likely others). The driver also supports the W83627DHG chip. 901 W83627DHG/DHG-P/EHF/EHG/F/G/HF/S/SF/THF/UHG/UG
902 W83637HF
903 W83667HG/HG-B
904 W83687THF
905 W83697HF
906 W83697UG
907 NCT6775
908 NCT6776
909 NCT6779
910
893 This watchdog simply watches your kernel to make sure it doesn't 911 This watchdog simply watches your kernel to make sure it doesn't
894 freeze, and if it does, it reboots your computer after a certain 912 freeze, and if it does, it reboots your computer after a certain
895 amount of time. 913 amount of time.
@@ -1139,6 +1157,28 @@ config BCM2835_WDT
1139 To compile this driver as a loadable module, choose M here. 1157 To compile this driver as a loadable module, choose M here.
1140 The module will be called bcm2835_wdt. 1158 The module will be called bcm2835_wdt.
1141 1159
1160config BCM_KONA_WDT
1161 tristate "BCM Kona Watchdog"
1162 depends on ARCH_BCM
1163 select WATCHDOG_CORE
1164 help
1165 Support for the watchdog timer on the following Broadcom BCM281xx
1166 family, which includes BCM11130, BCM11140, BCM11351, BCM28145 and
1167 BCM28155 variants.
1168
1169 Say 'Y' or 'M' here to enable the driver. The module will be called
1170 bcm_kona_wdt.
1171
1172config BCM_KONA_WDT_DEBUG
1173 bool "DEBUGFS support for BCM Kona Watchdog"
1174 depends on BCM_KONA_WDT
1175 help
1176 If enabled, adds /sys/kernel/debug/bcm_kona_wdt/info which provides
1177 access to the driver's internal data structures as well as watchdog
1178 timer hardware registres.
1179
1180 If in doubt, say 'N'.
1181
1142config LANTIQ_WDT 1182config LANTIQ_WDT
1143 tristate "Lantiq SoC watchdog" 1183 tristate "Lantiq SoC watchdog"
1144 depends on LANTIQ 1184 depends on LANTIQ
@@ -1171,6 +1211,7 @@ config MPC5200_WDT
1171config 8xxx_WDT 1211config 8xxx_WDT
1172 tristate "MPC8xxx Platform Watchdog Timer" 1212 tristate "MPC8xxx Platform Watchdog Timer"
1173 depends on PPC_8xx || PPC_83xx || PPC_86xx 1213 depends on PPC_8xx || PPC_83xx || PPC_86xx
1214 select WATCHDOG_CORE
1174 help 1215 help
1175 This driver is for a SoC level watchdog that exists on some 1216 This driver is for a SoC level watchdog that exists on some
1176 Freescale PowerPC processors. So far this driver supports: 1217 Freescale PowerPC processors. So far this driver supports:
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 91bd95a64baf..985a66cda76f 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o
57obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o 57obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
58obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o 58obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o
59obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o 59obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o
60obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o
60 61
61# AVR32 Architecture 62# AVR32 Architecture
62obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o 63obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
@@ -171,6 +172,7 @@ obj-$(CONFIG_XEN_WDT) += xen_wdt.o
171# Architecture Independent 172# Architecture Independent
172obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o 173obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o
173obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o 174obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o
175obj-$(CONFIG_GPIO_WATCHDOG) += gpio_wdt.o
174obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o 176obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
175obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o 177obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
176obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o 178obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
index fbb7b94cabfd..3a17fbd39f8a 100644
--- a/drivers/watchdog/alim1535_wdt.c
+++ b/drivers/watchdog/alim1535_wdt.c
@@ -301,7 +301,7 @@ static int ali_notify_sys(struct notifier_block *this,
301 * want to register another driver on the same PCI id. 301 * want to register another driver on the same PCI id.
302 */ 302 */
303 303
304static DEFINE_PCI_DEVICE_TABLE(ali_pci_tbl) __used = { 304static const struct pci_device_id ali_pci_tbl[] __used = {
305 { PCI_VENDOR_ID_AL, 0x1533, PCI_ANY_ID, PCI_ANY_ID,}, 305 { PCI_VENDOR_ID_AL, 0x1533, PCI_ANY_ID, PCI_ANY_ID,},
306 { PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,}, 306 { PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,},
307 { 0, }, 307 { 0, },
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 12f0b762b528..996b2f7d330e 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -414,7 +414,7 @@ err_out:
414module_init(alim7101_wdt_init); 414module_init(alim7101_wdt_init);
415module_exit(alim7101_wdt_unload); 415module_exit(alim7101_wdt_unload);
416 416
417static DEFINE_PCI_DEVICE_TABLE(alim7101_pci_tbl) __used = { 417static const struct pci_device_id alim7101_pci_tbl[] __used = {
418 { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533) }, 418 { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533) },
419 { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) }, 419 { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
420 { } 420 { }
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index be37dde4f864..489729b26298 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -19,11 +19,13 @@
19 19
20#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/interrupt.h>
22#include <linux/io.h> 23#include <linux/io.h>
23#include <linux/kernel.h> 24#include <linux/kernel.h>
24#include <linux/module.h> 25#include <linux/module.h>
25#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
26#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/reboot.h>
27#include <linux/types.h> 29#include <linux/types.h>
28#include <linux/watchdog.h> 30#include <linux/watchdog.h>
29#include <linux/jiffies.h> 31#include <linux/jiffies.h>
@@ -31,22 +33,33 @@
31#include <linux/bitops.h> 33#include <linux/bitops.h>
32#include <linux/uaccess.h> 34#include <linux/uaccess.h>
33#include <linux/of.h> 35#include <linux/of.h>
36#include <linux/of_irq.h>
34 37
35#include "at91sam9_wdt.h" 38#include "at91sam9_wdt.h"
36 39
37#define DRV_NAME "AT91SAM9 Watchdog" 40#define DRV_NAME "AT91SAM9 Watchdog"
38 41
39#define wdt_read(field) \ 42#define wdt_read(wdt, field) \
40 __raw_readl(at91wdt_private.base + field) 43 __raw_readl((wdt)->base + (field))
41#define wdt_write(field, val) \ 44#define wdt_write(wtd, field, val) \
42 __raw_writel((val), at91wdt_private.base + field) 45 __raw_writel((val), (wdt)->base + (field))
43 46
44/* AT91SAM9 watchdog runs a 12bit counter @ 256Hz, 47/* AT91SAM9 watchdog runs a 12bit counter @ 256Hz,
45 * use this to convert a watchdog 48 * use this to convert a watchdog
46 * value from/to milliseconds. 49 * value from/to milliseconds.
47 */ 50 */
48#define ms_to_ticks(t) (((t << 8) / 1000) - 1) 51#define ticks_to_hz_rounddown(t) ((((t) + 1) * HZ) >> 8)
49#define ticks_to_ms(t) (((t + 1) * 1000) >> 8) 52#define ticks_to_hz_roundup(t) (((((t) + 1) * HZ) + 255) >> 8)
53#define ticks_to_secs(t) (((t) + 1) >> 8)
54#define secs_to_ticks(s) ((s) ? (((s) << 8) - 1) : 0)
55
56#define WDT_MR_RESET 0x3FFF2FFF
57
58/* Watchdog max counter value in ticks */
59#define WDT_COUNTER_MAX_TICKS 0xFFF
60
61/* Watchdog max delta/value in secs */
62#define WDT_COUNTER_MAX_SECS ticks_to_secs(WDT_COUNTER_MAX_TICKS)
50 63
51/* Hardware timeout in seconds */ 64/* Hardware timeout in seconds */
52#define WDT_HW_TIMEOUT 2 65#define WDT_HW_TIMEOUT 2
@@ -66,23 +79,40 @@ module_param(nowayout, bool, 0);
66MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " 79MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
67 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 80 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
68 81
69static struct watchdog_device at91_wdt_dev; 82#define to_wdt(wdd) container_of(wdd, struct at91wdt, wdd)
70static void at91_ping(unsigned long data); 83struct at91wdt {
71 84 struct watchdog_device wdd;
72static struct {
73 void __iomem *base; 85 void __iomem *base;
74 unsigned long next_heartbeat; /* the next_heartbeat for the timer */ 86 unsigned long next_heartbeat; /* the next_heartbeat for the timer */
75 struct timer_list timer; /* The timer that pings the watchdog */ 87 struct timer_list timer; /* The timer that pings the watchdog */
76} at91wdt_private; 88 u32 mr;
89 u32 mr_mask;
90 unsigned long heartbeat; /* WDT heartbeat in jiffies */
91 bool nowayout;
92 unsigned int irq;
93};
77 94
78/* ......................................................................... */ 95/* ......................................................................... */
79 96
97static irqreturn_t wdt_interrupt(int irq, void *dev_id)
98{
99 struct at91wdt *wdt = (struct at91wdt *)dev_id;
100
101 if (wdt_read(wdt, AT91_WDT_SR)) {
102 pr_crit("at91sam9 WDT software reset\n");
103 emergency_restart();
104 pr_crit("Reboot didn't ?????\n");
105 }
106
107 return IRQ_HANDLED;
108}
109
80/* 110/*
81 * Reload the watchdog timer. (ie, pat the watchdog) 111 * Reload the watchdog timer. (ie, pat the watchdog)
82 */ 112 */
83static inline void at91_wdt_reset(void) 113static inline void at91_wdt_reset(struct at91wdt *wdt)
84{ 114{
85 wdt_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT); 115 wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
86} 116}
87 117
88/* 118/*
@@ -90,26 +120,21 @@ static inline void at91_wdt_reset(void)
90 */ 120 */
91static void at91_ping(unsigned long data) 121static void at91_ping(unsigned long data)
92{ 122{
93 if (time_before(jiffies, at91wdt_private.next_heartbeat) || 123 struct at91wdt *wdt = (struct at91wdt *)data;
94 (!watchdog_active(&at91_wdt_dev))) { 124 if (time_before(jiffies, wdt->next_heartbeat) ||
95 at91_wdt_reset(); 125 !watchdog_active(&wdt->wdd)) {
96 mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT); 126 at91_wdt_reset(wdt);
97 } else 127 mod_timer(&wdt->timer, jiffies + wdt->heartbeat);
128 } else {
98 pr_crit("I will reset your machine !\n"); 129 pr_crit("I will reset your machine !\n");
99} 130 }
100
101static int at91_wdt_ping(struct watchdog_device *wdd)
102{
103 /* calculate when the next userspace timeout will be */
104 at91wdt_private.next_heartbeat = jiffies + wdd->timeout * HZ;
105 return 0;
106} 131}
107 132
108static int at91_wdt_start(struct watchdog_device *wdd) 133static int at91_wdt_start(struct watchdog_device *wdd)
109{ 134{
110 /* calculate the next userspace timeout and modify the timer */ 135 struct at91wdt *wdt = to_wdt(wdd);
111 at91_wdt_ping(wdd); 136 /* calculate when the next userspace timeout will be */
112 mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT); 137 wdt->next_heartbeat = jiffies + wdd->timeout * HZ;
113 return 0; 138 return 0;
114} 139}
115 140
@@ -122,39 +147,104 @@ static int at91_wdt_stop(struct watchdog_device *wdd)
122static int at91_wdt_set_timeout(struct watchdog_device *wdd, unsigned int new_timeout) 147static int at91_wdt_set_timeout(struct watchdog_device *wdd, unsigned int new_timeout)
123{ 148{
124 wdd->timeout = new_timeout; 149 wdd->timeout = new_timeout;
125 return 0; 150 return at91_wdt_start(wdd);
126} 151}
127 152
128/* 153static int at91_wdt_init(struct platform_device *pdev, struct at91wdt *wdt)
129 * Set the watchdog time interval in 1/256Hz (write-once)
130 * Counter is 12 bit.
131 */
132static int at91_wdt_settimeout(unsigned int timeout)
133{ 154{
134 unsigned int reg; 155 u32 tmp;
135 unsigned int mr; 156 u32 delta;
136 157 u32 value;
137 /* Check if disabled */ 158 int err;
138 mr = wdt_read(AT91_WDT_MR); 159 u32 mask = wdt->mr_mask;
139 if (mr & AT91_WDT_WDDIS) { 160 unsigned long min_heartbeat = 1;
140 pr_err("sorry, watchdog is disabled\n"); 161 unsigned long max_heartbeat;
141 return -EIO; 162 struct device *dev = &pdev->dev;
163
164 tmp = wdt_read(wdt, AT91_WDT_MR);
165 if ((tmp & mask) != (wdt->mr & mask)) {
166 if (tmp == WDT_MR_RESET) {
167 wdt_write(wdt, AT91_WDT_MR, wdt->mr);
168 tmp = wdt_read(wdt, AT91_WDT_MR);
169 }
170 }
171
172 if (tmp & AT91_WDT_WDDIS) {
173 if (wdt->mr & AT91_WDT_WDDIS)
174 return 0;
175 dev_err(dev, "watchdog is disabled\n");
176 return -EINVAL;
177 }
178
179 value = tmp & AT91_WDT_WDV;
180 delta = (tmp & AT91_WDT_WDD) >> 16;
181
182 if (delta < value)
183 min_heartbeat = ticks_to_hz_roundup(value - delta);
184
185 max_heartbeat = ticks_to_hz_rounddown(value);
186 if (!max_heartbeat) {
187 dev_err(dev,
188 "heartbeat is too small for the system to handle it correctly\n");
189 return -EINVAL;
142 } 190 }
143 191
144 /* 192 /*
145 * All counting occurs at SLOW_CLOCK / 128 = 256 Hz 193 * Try to reset the watchdog counter 4 or 2 times more often than
146 * 194 * actually requested, to avoid spurious watchdog reset.
147 * Since WDV is a 12-bit counter, the maximum period is 195 * If this is not possible because of the min_heartbeat value, reset
148 * 4096 / 256 = 16 seconds. 196 * it at the min_heartbeat period.
149 */ 197 */
150 reg = AT91_WDT_WDRSTEN /* causes watchdog reset */ 198 if ((max_heartbeat / 4) >= min_heartbeat)
151 /* | AT91_WDT_WDRPROC causes processor reset only */ 199 wdt->heartbeat = max_heartbeat / 4;
152 | AT91_WDT_WDDBGHLT /* disabled in debug mode */ 200 else if ((max_heartbeat / 2) >= min_heartbeat)
153 | AT91_WDT_WDD /* restart at any time */ 201 wdt->heartbeat = max_heartbeat / 2;
154 | (timeout & AT91_WDT_WDV); /* timer value */ 202 else
155 wdt_write(AT91_WDT_MR, reg); 203 wdt->heartbeat = min_heartbeat;
204
205 if (max_heartbeat < min_heartbeat + 4)
206 dev_warn(dev,
207 "min heartbeat and max heartbeat might be too close for the system to handle it correctly\n");
208
209 if ((tmp & AT91_WDT_WDFIEN) && wdt->irq) {
210 err = request_irq(wdt->irq, wdt_interrupt,
211 IRQF_SHARED | IRQF_IRQPOLL,
212 pdev->name, wdt);
213 if (err)
214 return err;
215 }
216
217 if ((tmp & wdt->mr_mask) != (wdt->mr & wdt->mr_mask))
218 dev_warn(dev,
219 "watchdog already configured differently (mr = %x expecting %x)\n",
220 tmp & wdt->mr_mask, wdt->mr & wdt->mr_mask);
221
222 setup_timer(&wdt->timer, at91_ping, (unsigned long)wdt);
223
224 /*
225 * Use min_heartbeat the first time to avoid spurious watchdog reset:
226 * we don't know for how long the watchdog counter is running, and
227 * - resetting it right now might trigger a watchdog fault reset
228 * - waiting for heartbeat time might lead to a watchdog timeout
229 * reset
230 */
231 mod_timer(&wdt->timer, jiffies + min_heartbeat);
232
233 /* Try to set timeout from device tree first */
234 if (watchdog_init_timeout(&wdt->wdd, 0, dev))
235 watchdog_init_timeout(&wdt->wdd, heartbeat, dev);
236 watchdog_set_nowayout(&wdt->wdd, wdt->nowayout);
237 err = watchdog_register_device(&wdt->wdd);
238 if (err)
239 goto out_stop_timer;
240
241 wdt->next_heartbeat = jiffies + wdt->wdd.timeout * HZ;
156 242
157 return 0; 243 return 0;
244
245out_stop_timer:
246 del_timer(&wdt->timer);
247 return err;
158} 248}
159 249
160/* ......................................................................... */ 250/* ......................................................................... */
@@ -169,61 +259,123 @@ static const struct watchdog_ops at91_wdt_ops = {
169 .owner = THIS_MODULE, 259 .owner = THIS_MODULE,
170 .start = at91_wdt_start, 260 .start = at91_wdt_start,
171 .stop = at91_wdt_stop, 261 .stop = at91_wdt_stop,
172 .ping = at91_wdt_ping,
173 .set_timeout = at91_wdt_set_timeout, 262 .set_timeout = at91_wdt_set_timeout,
174}; 263};
175 264
176static struct watchdog_device at91_wdt_dev = { 265#if defined(CONFIG_OF)
177 .info = &at91_wdt_info, 266static int of_at91wdt_init(struct device_node *np, struct at91wdt *wdt)
178 .ops = &at91_wdt_ops, 267{
179 .timeout = WDT_HEARTBEAT, 268 u32 min = 0;
180 .min_timeout = 1, 269 u32 max = WDT_COUNTER_MAX_SECS;
181 .max_timeout = 0xFFFF, 270 const char *tmp;
182}; 271
272 /* Get the interrupts property */
273 wdt->irq = irq_of_parse_and_map(np, 0);
274 if (!wdt->irq)
275 dev_warn(wdt->wdd.parent, "failed to get IRQ from DT\n");
276
277 if (!of_property_read_u32_index(np, "atmel,max-heartbeat-sec", 0,
278 &max)) {
279 if (!max || max > WDT_COUNTER_MAX_SECS)
280 max = WDT_COUNTER_MAX_SECS;
281
282 if (!of_property_read_u32_index(np, "atmel,min-heartbeat-sec",
283 0, &min)) {
284 if (min >= max)
285 min = max - 1;
286 }
287 }
288
289 min = secs_to_ticks(min);
290 max = secs_to_ticks(max);
291
292 wdt->mr_mask = 0x3FFFFFFF;
293 wdt->mr = 0;
294 if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
295 !strcmp(tmp, "software")) {
296 wdt->mr |= AT91_WDT_WDFIEN;
297 wdt->mr_mask &= ~AT91_WDT_WDRPROC;
298 } else {
299 wdt->mr |= AT91_WDT_WDRSTEN;
300 }
301
302 if (!of_property_read_string(np, "atmel,reset-type", &tmp) &&
303 !strcmp(tmp, "proc"))
304 wdt->mr |= AT91_WDT_WDRPROC;
305
306 if (of_property_read_bool(np, "atmel,disable")) {
307 wdt->mr |= AT91_WDT_WDDIS;
308 wdt->mr_mask &= AT91_WDT_WDDIS;
309 }
310
311 if (of_property_read_bool(np, "atmel,idle-halt"))
312 wdt->mr |= AT91_WDT_WDIDLEHLT;
313
314 if (of_property_read_bool(np, "atmel,dbg-halt"))
315 wdt->mr |= AT91_WDT_WDDBGHLT;
316
317 wdt->mr |= max | ((max - min) << 16);
318
319 return 0;
320}
321#else
322static inline int of_at91wdt_init(struct device_node *np, struct at91wdt *wdt)
323{
324 return 0;
325}
326#endif
183 327
184static int __init at91wdt_probe(struct platform_device *pdev) 328static int __init at91wdt_probe(struct platform_device *pdev)
185{ 329{
186 struct resource *r; 330 struct resource *r;
187 int res; 331 int err;
332 struct at91wdt *wdt;
188 333
189 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 334 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
190 if (!r) 335 if (!wdt)
191 return -ENODEV;
192 at91wdt_private.base = ioremap(r->start, resource_size(r));
193 if (!at91wdt_private.base) {
194 dev_err(&pdev->dev, "failed to map registers, aborting.\n");
195 return -ENOMEM; 336 return -ENOMEM;
196 }
197 337
198 at91_wdt_dev.parent = &pdev->dev; 338 wdt->mr = (WDT_HW_TIMEOUT * 256) | AT91_WDT_WDRSTEN | AT91_WDT_WDD |
199 watchdog_init_timeout(&at91_wdt_dev, heartbeat, &pdev->dev); 339 AT91_WDT_WDDBGHLT | AT91_WDT_WDIDLEHLT;
200 watchdog_set_nowayout(&at91_wdt_dev, nowayout); 340 wdt->mr_mask = 0x3FFFFFFF;
341 wdt->nowayout = nowayout;
342 wdt->wdd.parent = &pdev->dev;
343 wdt->wdd.info = &at91_wdt_info;
344 wdt->wdd.ops = &at91_wdt_ops;
345 wdt->wdd.timeout = WDT_HEARTBEAT;
346 wdt->wdd.min_timeout = 1;
347 wdt->wdd.max_timeout = 0xFFFF;
201 348
202 /* Set watchdog */ 349 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
203 res = at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000)); 350 wdt->base = devm_ioremap_resource(&pdev->dev, r);
204 if (res) 351 if (IS_ERR(wdt->base))
205 return res; 352 return PTR_ERR(wdt->base);
353
354 if (pdev->dev.of_node) {
355 err = of_at91wdt_init(pdev->dev.of_node, wdt);
356 if (err)
357 return err;
358 }
206 359
207 res = watchdog_register_device(&at91_wdt_dev); 360 err = at91_wdt_init(pdev, wdt);
208 if (res) 361 if (err)
209 return res; 362 return err;
210 363
211 at91wdt_private.next_heartbeat = jiffies + at91_wdt_dev.timeout * HZ; 364 platform_set_drvdata(pdev, wdt);
212 setup_timer(&at91wdt_private.timer, at91_ping, 0);
213 mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
214 365
215 pr_info("enabled (heartbeat=%d sec, nowayout=%d)\n", 366 pr_info("enabled (heartbeat=%d sec, nowayout=%d)\n",
216 at91_wdt_dev.timeout, nowayout); 367 wdt->wdd.timeout, wdt->nowayout);
217 368
218 return 0; 369 return 0;
219} 370}
220 371
221static int __exit at91wdt_remove(struct platform_device *pdev) 372static int __exit at91wdt_remove(struct platform_device *pdev)
222{ 373{
223 watchdog_unregister_device(&at91_wdt_dev); 374 struct at91wdt *wdt = platform_get_drvdata(pdev);
375 watchdog_unregister_device(&wdt->wdd);
224 376
225 pr_warn("I quit now, hardware will probably reboot!\n"); 377 pr_warn("I quit now, hardware will probably reboot!\n");
226 del_timer(&at91wdt_private.timer); 378 del_timer(&wdt->timer);
227 379
228 return 0; 380 return 0;
229} 381}
diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c
new file mode 100644
index 000000000000..9c248099f4a2
--- /dev/null
+++ b/drivers/watchdog/bcm_kona_wdt.c
@@ -0,0 +1,368 @@
1/*
2 * Copyright (C) 2013 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/debugfs.h>
15#include <linux/delay.h>
16#include <linux/err.h>
17#include <linux/io.h>
18#include <linux/module.h>
19#include <linux/of_address.h>
20#include <linux/platform_device.h>
21#include <linux/watchdog.h>
22
23#define SECWDOG_CTRL_REG 0x00000000
24#define SECWDOG_COUNT_REG 0x00000004
25
26#define SECWDOG_RESERVED_MASK 0x1dffffff
27#define SECWDOG_WD_LOAD_FLAG 0x10000000
28#define SECWDOG_EN_MASK 0x08000000
29#define SECWDOG_SRSTEN_MASK 0x04000000
30#define SECWDOG_RES_MASK 0x00f00000
31#define SECWDOG_COUNT_MASK 0x000fffff
32
33#define SECWDOG_MAX_COUNT SECWDOG_COUNT_MASK
34#define SECWDOG_CLKS_SHIFT 20
35#define SECWDOG_MAX_RES 15
36#define SECWDOG_DEFAULT_RESOLUTION 4
37#define SECWDOG_MAX_TRY 1000
38
39#define SECS_TO_TICKS(x, w) ((x) << (w)->resolution)
40#define TICKS_TO_SECS(x, w) ((x) >> (w)->resolution)
41
42#define BCM_KONA_WDT_NAME "bcm_kona_wdt"
43
44struct bcm_kona_wdt {
45 void __iomem *base;
46 /*
47 * One watchdog tick is 1/(2^resolution) seconds. Resolution can take
48 * the values 0-15, meaning one tick can be 1s to 30.52us. Our default
49 * resolution of 4 means one tick is 62.5ms.
50 *
51 * The watchdog counter is 20 bits. Depending on resolution, the maximum
52 * counter value of 0xfffff expires after about 12 days (resolution 0)
53 * down to only 32s (resolution 15). The default resolution of 4 gives
54 * us a maximum of about 18 hours and 12 minutes before the watchdog
55 * times out.
56 */
57 int resolution;
58 spinlock_t lock;
59#ifdef CONFIG_BCM_KONA_WDT_DEBUG
60 unsigned long busy_count;
61 struct dentry *debugfs;
62#endif
63};
64
65static int secure_register_read(struct bcm_kona_wdt *wdt, uint32_t offset)
66{
67 uint32_t val;
68 unsigned count = 0;
69
70 /*
71 * If the WD_LOAD_FLAG is set, the watchdog counter field is being
72 * updated in hardware. Once the WD timer is updated in hardware, it
73 * gets cleared.
74 */
75 do {
76 if (unlikely(count > 1))
77 udelay(5);
78 val = readl_relaxed(wdt->base + offset);
79 count++;
80 } while ((val & SECWDOG_WD_LOAD_FLAG) && count < SECWDOG_MAX_TRY);
81
82#ifdef CONFIG_BCM_KONA_WDT_DEBUG
83 /* Remember the maximum number iterations due to WD_LOAD_FLAG */
84 if (count > wdt->busy_count)
85 wdt->busy_count = count;
86#endif
87
88 /* This is the only place we return a negative value. */
89 if (val & SECWDOG_WD_LOAD_FLAG)
90 return -ETIMEDOUT;
91
92 /* We always mask out reserved bits. */
93 val &= SECWDOG_RESERVED_MASK;
94
95 return val;
96}
97
98#ifdef CONFIG_BCM_KONA_WDT_DEBUG
99
100static int bcm_kona_wdt_dbg_show(struct seq_file *s, void *data)
101{
102 int ctl_val, cur_val, ret;
103 unsigned long flags;
104 struct bcm_kona_wdt *wdt = s->private;
105
106 if (!wdt)
107 return seq_puts(s, "No device pointer\n");
108
109 spin_lock_irqsave(&wdt->lock, flags);
110 ctl_val = secure_register_read(wdt, SECWDOG_CTRL_REG);
111 cur_val = secure_register_read(wdt, SECWDOG_COUNT_REG);
112 spin_unlock_irqrestore(&wdt->lock, flags);
113
114 if (ctl_val < 0 || cur_val < 0) {
115 ret = seq_puts(s, "Error accessing hardware\n");
116 } else {
117 int ctl, cur, ctl_sec, cur_sec, res;
118
119 ctl = ctl_val & SECWDOG_COUNT_MASK;
120 res = (ctl_val & SECWDOG_RES_MASK) >> SECWDOG_CLKS_SHIFT;
121 cur = cur_val & SECWDOG_COUNT_MASK;
122 ctl_sec = TICKS_TO_SECS(ctl, wdt);
123 cur_sec = TICKS_TO_SECS(cur, wdt);
124 ret = seq_printf(s, "Resolution: %d / %d\n"
125 "Control: %d s / %d (%#x) ticks\n"
126 "Current: %d s / %d (%#x) ticks\n"
127 "Busy count: %lu\n", res,
128 wdt->resolution, ctl_sec, ctl, ctl, cur_sec,
129 cur, cur, wdt->busy_count);
130 }
131
132 return ret;
133}
134
135static int bcm_kona_dbg_open(struct inode *inode, struct file *file)
136{
137 return single_open(file, bcm_kona_wdt_dbg_show, inode->i_private);
138}
139
140static const struct file_operations bcm_kona_dbg_operations = {
141 .open = bcm_kona_dbg_open,
142 .read = seq_read,
143 .llseek = seq_lseek,
144 .release = single_release,
145};
146
147static void bcm_kona_wdt_debug_init(struct platform_device *pdev)
148{
149 struct dentry *dir;
150 struct bcm_kona_wdt *wdt = platform_get_drvdata(pdev);
151
152 if (!wdt)
153 return;
154
155 wdt->debugfs = NULL;
156
157 dir = debugfs_create_dir(BCM_KONA_WDT_NAME, NULL);
158 if (IS_ERR_OR_NULL(dir))
159 return;
160
161 if (debugfs_create_file("info", S_IFREG | S_IRUGO, dir, wdt,
162 &bcm_kona_dbg_operations))
163 wdt->debugfs = dir;
164 else
165 debugfs_remove_recursive(dir);
166}
167
168static void bcm_kona_wdt_debug_exit(struct platform_device *pdev)
169{
170 struct bcm_kona_wdt *wdt = platform_get_drvdata(pdev);
171
172 if (wdt && wdt->debugfs) {
173 debugfs_remove_recursive(wdt->debugfs);
174 wdt->debugfs = NULL;
175 }
176}
177
178#else
179
180static void bcm_kona_wdt_debug_init(struct platform_device *pdev) {}
181static void bcm_kona_wdt_debug_exit(struct platform_device *pdev) {}
182
183#endif /* CONFIG_BCM_KONA_WDT_DEBUG */
184
185static int bcm_kona_wdt_ctrl_reg_modify(struct bcm_kona_wdt *wdt,
186 unsigned mask, unsigned newval)
187{
188 int val;
189 unsigned long flags;
190 int ret = 0;
191
192 spin_lock_irqsave(&wdt->lock, flags);
193
194 val = secure_register_read(wdt, SECWDOG_CTRL_REG);
195 if (val < 0) {
196 ret = val;
197 } else {
198 val &= ~mask;
199 val |= newval;
200 writel_relaxed(val, wdt->base + SECWDOG_CTRL_REG);
201 }
202
203 spin_unlock_irqrestore(&wdt->lock, flags);
204
205 return ret;
206}
207
208static int bcm_kona_wdt_set_resolution_reg(struct bcm_kona_wdt *wdt)
209{
210 if (wdt->resolution > SECWDOG_MAX_RES)
211 return -EINVAL;
212
213 return bcm_kona_wdt_ctrl_reg_modify(wdt, SECWDOG_RES_MASK,
214 wdt->resolution << SECWDOG_CLKS_SHIFT);
215}
216
217static int bcm_kona_wdt_set_timeout_reg(struct watchdog_device *wdog,
218 unsigned watchdog_flags)
219{
220 struct bcm_kona_wdt *wdt = watchdog_get_drvdata(wdog);
221
222 return bcm_kona_wdt_ctrl_reg_modify(wdt, SECWDOG_COUNT_MASK,
223 SECS_TO_TICKS(wdog->timeout, wdt) |
224 watchdog_flags);
225}
226
227static int bcm_kona_wdt_set_timeout(struct watchdog_device *wdog,
228 unsigned int t)
229{
230 wdog->timeout = t;
231 return 0;
232}
233
234static unsigned int bcm_kona_wdt_get_timeleft(struct watchdog_device *wdog)
235{
236 struct bcm_kona_wdt *wdt = watchdog_get_drvdata(wdog);
237 int val;
238 unsigned long flags;
239
240 spin_lock_irqsave(&wdt->lock, flags);
241 val = secure_register_read(wdt, SECWDOG_COUNT_REG);
242 spin_unlock_irqrestore(&wdt->lock, flags);
243
244 if (val < 0)
245 return val;
246
247 return TICKS_TO_SECS(val & SECWDOG_COUNT_MASK, wdt);
248}
249
250static int bcm_kona_wdt_start(struct watchdog_device *wdog)
251{
252 return bcm_kona_wdt_set_timeout_reg(wdog,
253 SECWDOG_EN_MASK | SECWDOG_SRSTEN_MASK);
254}
255
256static int bcm_kona_wdt_stop(struct watchdog_device *wdog)
257{
258 struct bcm_kona_wdt *wdt = watchdog_get_drvdata(wdog);
259
260 return bcm_kona_wdt_ctrl_reg_modify(wdt, SECWDOG_EN_MASK |
261 SECWDOG_SRSTEN_MASK, 0);
262}
263
264static struct watchdog_ops bcm_kona_wdt_ops = {
265 .owner = THIS_MODULE,
266 .start = bcm_kona_wdt_start,
267 .stop = bcm_kona_wdt_stop,
268 .set_timeout = bcm_kona_wdt_set_timeout,
269 .get_timeleft = bcm_kona_wdt_get_timeleft,
270};
271
272static struct watchdog_info bcm_kona_wdt_info = {
273 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
274 WDIOF_KEEPALIVEPING,
275 .identity = "Broadcom Kona Watchdog Timer",
276};
277
278static struct watchdog_device bcm_kona_wdt_wdd = {
279 .info = &bcm_kona_wdt_info,
280 .ops = &bcm_kona_wdt_ops,
281 .min_timeout = 1,
282 .max_timeout = SECWDOG_MAX_COUNT >> SECWDOG_DEFAULT_RESOLUTION,
283 .timeout = SECWDOG_MAX_COUNT >> SECWDOG_DEFAULT_RESOLUTION,
284};
285
286static void bcm_kona_wdt_shutdown(struct platform_device *pdev)
287{
288 bcm_kona_wdt_stop(&bcm_kona_wdt_wdd);
289}
290
291static int bcm_kona_wdt_probe(struct platform_device *pdev)
292{
293 struct device *dev = &pdev->dev;
294 struct bcm_kona_wdt *wdt;
295 struct resource *res;
296 int ret;
297
298 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
299 if (!wdt)
300 return -ENOMEM;
301
302 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
303 wdt->base = devm_ioremap_resource(dev, res);
304 if (IS_ERR(wdt->base))
305 return -ENODEV;
306
307 wdt->resolution = SECWDOG_DEFAULT_RESOLUTION;
308 ret = bcm_kona_wdt_set_resolution_reg(wdt);
309 if (ret) {
310 dev_err(dev, "Failed to set resolution (error: %d)", ret);
311 return ret;
312 }
313
314 spin_lock_init(&wdt->lock);
315 platform_set_drvdata(pdev, wdt);
316 watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
317
318 ret = bcm_kona_wdt_set_timeout_reg(&bcm_kona_wdt_wdd, 0);
319 if (ret) {
320 dev_err(dev, "Failed set watchdog timeout");
321 return ret;
322 }
323
324 ret = watchdog_register_device(&bcm_kona_wdt_wdd);
325 if (ret) {
326 dev_err(dev, "Failed to register watchdog device");
327 return ret;
328 }
329
330 bcm_kona_wdt_debug_init(pdev);
331 dev_dbg(dev, "Broadcom Kona Watchdog Timer");
332
333 return 0;
334}
335
336static int bcm_kona_wdt_remove(struct platform_device *pdev)
337{
338 bcm_kona_wdt_debug_exit(pdev);
339 bcm_kona_wdt_shutdown(pdev);
340 watchdog_unregister_device(&bcm_kona_wdt_wdd);
341 dev_dbg(&pdev->dev, "Watchdog driver disabled");
342
343 return 0;
344}
345
346static const struct of_device_id bcm_kona_wdt_of_match[] = {
347 { .compatible = "brcm,kona-wdt", },
348 {},
349};
350MODULE_DEVICE_TABLE(of, bcm_kona_wdt_of_match);
351
352static struct platform_driver bcm_kona_wdt_driver = {
353 .driver = {
354 .name = BCM_KONA_WDT_NAME,
355 .owner = THIS_MODULE,
356 .of_match_table = bcm_kona_wdt_of_match,
357 },
358 .probe = bcm_kona_wdt_probe,
359 .remove = bcm_kona_wdt_remove,
360 .shutdown = bcm_kona_wdt_shutdown,
361};
362
363module_platform_driver(bcm_kona_wdt_driver);
364
365MODULE_ALIAS("platform:" BCM_KONA_WDT_NAME);
366MODULE_AUTHOR("Markus Mayer <mmayer@broadcom.com>");
367MODULE_DESCRIPTION("Broadcom Kona Watchdog Driver");
368MODULE_LICENSE("GPL v2");
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 12591f6596ef..b1bae03742a9 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Watchdog driver for DaVinci DM644x/DM646x processors 4 * Watchdog driver for DaVinci DM644x/DM646x processors
5 * 5 *
6 * Copyright (C) 2006 Texas Instruments. 6 * Copyright (C) 2006-2013 Texas Instruments.
7 * 7 *
8 * 2007 (c) MontaVista Software, Inc. This file is licensed under 8 * 2007 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program 9 * the terms of the GNU General Public License version 2. This program
@@ -15,18 +15,12 @@
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/fs.h>
19#include <linux/miscdevice.h>
20#include <linux/watchdog.h> 18#include <linux/watchdog.h>
21#include <linux/init.h> 19#include <linux/init.h>
22#include <linux/bitops.h>
23#include <linux/platform_device.h> 20#include <linux/platform_device.h>
24#include <linux/spinlock.h>
25#include <linux/uaccess.h>
26#include <linux/io.h> 21#include <linux/io.h>
27#include <linux/device.h> 22#include <linux/device.h>
28#include <linux/clk.h> 23#include <linux/clk.h>
29#include <linux/slab.h>
30#include <linux/err.h> 24#include <linux/err.h>
31 25
32#define MODULE_NAME "DAVINCI-WDT: " 26#define MODULE_NAME "DAVINCI-WDT: "
@@ -61,142 +55,103 @@
61#define WDKEY_SEQ0 (0xa5c6 << 16) 55#define WDKEY_SEQ0 (0xa5c6 << 16)
62#define WDKEY_SEQ1 (0xda7e << 16) 56#define WDKEY_SEQ1 (0xda7e << 16)
63 57
64static int heartbeat = DEFAULT_HEARTBEAT; 58static int heartbeat;
65 59
66static DEFINE_SPINLOCK(io_lock); 60/*
67static unsigned long wdt_status; 61 * struct to hold data for each WDT device
68#define WDT_IN_USE 0 62 * @base - base io address of WD device
69#define WDT_OK_TO_CLOSE 1 63 * @clk - source clock of WDT
70#define WDT_REGION_INITED 2 64 * @wdd - hold watchdog device as is in WDT core
71#define WDT_DEVICE_INITED 3 65 */
72 66struct davinci_wdt_device {
73static void __iomem *wdt_base; 67 void __iomem *base;
74struct clk *wdt_clk; 68 struct clk *clk;
75 69 struct watchdog_device wdd;
76static void wdt_service(void) 70};
77{
78 spin_lock(&io_lock);
79
80 /* put watchdog in service state */
81 iowrite32(WDKEY_SEQ0, wdt_base + WDTCR);
82 /* put watchdog in active state */
83 iowrite32(WDKEY_SEQ1, wdt_base + WDTCR);
84
85 spin_unlock(&io_lock);
86}
87 71
88static void wdt_enable(void) 72static int davinci_wdt_start(struct watchdog_device *wdd)
89{ 73{
90 u32 tgcr; 74 u32 tgcr;
91 u32 timer_margin; 75 u32 timer_margin;
92 unsigned long wdt_freq; 76 unsigned long wdt_freq;
77 struct davinci_wdt_device *davinci_wdt = watchdog_get_drvdata(wdd);
93 78
94 wdt_freq = clk_get_rate(wdt_clk); 79 wdt_freq = clk_get_rate(davinci_wdt->clk);
95
96 spin_lock(&io_lock);
97 80
98 /* disable, internal clock source */ 81 /* disable, internal clock source */
99 iowrite32(0, wdt_base + TCR); 82 iowrite32(0, davinci_wdt->base + TCR);
100 /* reset timer, set mode to 64-bit watchdog, and unreset */ 83 /* reset timer, set mode to 64-bit watchdog, and unreset */
101 iowrite32(0, wdt_base + TGCR); 84 iowrite32(0, davinci_wdt->base + TGCR);
102 tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET; 85 tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET;
103 iowrite32(tgcr, wdt_base + TGCR); 86 iowrite32(tgcr, davinci_wdt->base + TGCR);
104 /* clear counter regs */ 87 /* clear counter regs */
105 iowrite32(0, wdt_base + TIM12); 88 iowrite32(0, davinci_wdt->base + TIM12);
106 iowrite32(0, wdt_base + TIM34); 89 iowrite32(0, davinci_wdt->base + TIM34);
107 /* set timeout period */ 90 /* set timeout period */
108 timer_margin = (((u64)heartbeat * wdt_freq) & 0xffffffff); 91 timer_margin = (((u64)wdd->timeout * wdt_freq) & 0xffffffff);
109 iowrite32(timer_margin, wdt_base + PRD12); 92 iowrite32(timer_margin, davinci_wdt->base + PRD12);
110 timer_margin = (((u64)heartbeat * wdt_freq) >> 32); 93 timer_margin = (((u64)wdd->timeout * wdt_freq) >> 32);
111 iowrite32(timer_margin, wdt_base + PRD34); 94 iowrite32(timer_margin, davinci_wdt->base + PRD34);
112 /* enable run continuously */ 95 /* enable run continuously */
113 iowrite32(ENAMODE12_PERIODIC, wdt_base + TCR); 96 iowrite32(ENAMODE12_PERIODIC, davinci_wdt->base + TCR);
114 /* Once the WDT is in pre-active state write to 97 /* Once the WDT is in pre-active state write to
115 * TIM12, TIM34, PRD12, PRD34, TCR, TGCR, WDTCR are 98 * TIM12, TIM34, PRD12, PRD34, TCR, TGCR, WDTCR are
116 * write protected (except for the WDKEY field) 99 * write protected (except for the WDKEY field)
117 */ 100 */
118 /* put watchdog in pre-active state */ 101 /* put watchdog in pre-active state */
119 iowrite32(WDKEY_SEQ0 | WDEN, wdt_base + WDTCR); 102 iowrite32(WDKEY_SEQ0 | WDEN, davinci_wdt->base + WDTCR);
120 /* put watchdog in active state */ 103 /* put watchdog in active state */
121 iowrite32(WDKEY_SEQ1 | WDEN, wdt_base + WDTCR); 104 iowrite32(WDKEY_SEQ1 | WDEN, davinci_wdt->base + WDTCR);
122 105 return 0;
123 spin_unlock(&io_lock);
124} 106}
125 107
126static int davinci_wdt_open(struct inode *inode, struct file *file) 108static int davinci_wdt_ping(struct watchdog_device *wdd)
127{ 109{
128 if (test_and_set_bit(WDT_IN_USE, &wdt_status)) 110 struct davinci_wdt_device *davinci_wdt = watchdog_get_drvdata(wdd);
129 return -EBUSY;
130
131 wdt_enable();
132 111
133 return nonseekable_open(inode, file); 112 /* put watchdog in service state */
113 iowrite32(WDKEY_SEQ0, davinci_wdt->base + WDTCR);
114 /* put watchdog in active state */
115 iowrite32(WDKEY_SEQ1, davinci_wdt->base + WDTCR);
116 return 0;
134} 117}
135 118
136static ssize_t 119static unsigned int davinci_wdt_get_timeleft(struct watchdog_device *wdd)
137davinci_wdt_write(struct file *file, const char *data, size_t len,
138 loff_t *ppos)
139{ 120{
140 if (len) 121 u64 timer_counter;
141 wdt_service(); 122 unsigned long freq;
123 u32 val;
124 struct davinci_wdt_device *davinci_wdt = watchdog_get_drvdata(wdd);
142 125
143 return len; 126 /* if timeout has occured then return 0 */
144} 127 val = ioread32(davinci_wdt->base + WDTCR);
128 if (val & WDFLAG)
129 return 0;
145 130
146static const struct watchdog_info ident = { 131 freq = clk_get_rate(davinci_wdt->clk);
147 .options = WDIOF_KEEPALIVEPING,
148 .identity = "DaVinci Watchdog",
149};
150 132
151static long davinci_wdt_ioctl(struct file *file, 133 if (!freq)
152 unsigned int cmd, unsigned long arg) 134 return 0;
153{
154 int ret = -ENOTTY;
155
156 switch (cmd) {
157 case WDIOC_GETSUPPORT:
158 ret = copy_to_user((struct watchdog_info *)arg, &ident,
159 sizeof(ident)) ? -EFAULT : 0;
160 break;
161
162 case WDIOC_GETSTATUS:
163 case WDIOC_GETBOOTSTATUS:
164 ret = put_user(0, (int *)arg);
165 break;
166
167 case WDIOC_KEEPALIVE:
168 wdt_service();
169 ret = 0;
170 break;
171
172 case WDIOC_GETTIMEOUT:
173 ret = put_user(heartbeat, (int *)arg);
174 break;
175 }
176 return ret;
177}
178 135
179static int davinci_wdt_release(struct inode *inode, struct file *file) 136 timer_counter = ioread32(davinci_wdt->base + TIM12);
180{ 137 timer_counter |= ((u64)ioread32(davinci_wdt->base + TIM34) << 32);
181 wdt_service();
182 clear_bit(WDT_IN_USE, &wdt_status);
183 138
184 return 0; 139 do_div(timer_counter, freq);
140
141 return wdd->timeout - timer_counter;
185} 142}
186 143
187static const struct file_operations davinci_wdt_fops = { 144static const struct watchdog_info davinci_wdt_info = {
188 .owner = THIS_MODULE, 145 .options = WDIOF_KEEPALIVEPING,
189 .llseek = no_llseek, 146 .identity = "DaVinci/Keystone Watchdog",
190 .write = davinci_wdt_write,
191 .unlocked_ioctl = davinci_wdt_ioctl,
192 .open = davinci_wdt_open,
193 .release = davinci_wdt_release,
194}; 147};
195 148
196static struct miscdevice davinci_wdt_miscdev = { 149static const struct watchdog_ops davinci_wdt_ops = {
197 .minor = WATCHDOG_MINOR, 150 .owner = THIS_MODULE,
198 .name = "watchdog", 151 .start = davinci_wdt_start,
199 .fops = &davinci_wdt_fops, 152 .stop = davinci_wdt_ping,
153 .ping = davinci_wdt_ping,
154 .get_timeleft = davinci_wdt_get_timeleft,
200}; 155};
201 156
202static int davinci_wdt_probe(struct platform_device *pdev) 157static int davinci_wdt_probe(struct platform_device *pdev)
@@ -204,37 +159,53 @@ static int davinci_wdt_probe(struct platform_device *pdev)
204 int ret = 0; 159 int ret = 0;
205 struct device *dev = &pdev->dev; 160 struct device *dev = &pdev->dev;
206 struct resource *wdt_mem; 161 struct resource *wdt_mem;
162 struct watchdog_device *wdd;
163 struct davinci_wdt_device *davinci_wdt;
164
165 davinci_wdt = devm_kzalloc(dev, sizeof(*davinci_wdt), GFP_KERNEL);
166 if (!davinci_wdt)
167 return -ENOMEM;
207 168
208 wdt_clk = devm_clk_get(dev, NULL); 169 davinci_wdt->clk = devm_clk_get(dev, NULL);
209 if (WARN_ON(IS_ERR(wdt_clk))) 170 if (WARN_ON(IS_ERR(davinci_wdt->clk)))
210 return PTR_ERR(wdt_clk); 171 return PTR_ERR(davinci_wdt->clk);
211 172
212 clk_prepare_enable(wdt_clk); 173 clk_prepare_enable(davinci_wdt->clk);
213 174
214 if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) 175 platform_set_drvdata(pdev, davinci_wdt);
215 heartbeat = DEFAULT_HEARTBEAT;
216 176
217 dev_info(dev, "heartbeat %d sec\n", heartbeat); 177 wdd = &davinci_wdt->wdd;
178 wdd->info = &davinci_wdt_info;
179 wdd->ops = &davinci_wdt_ops;
180 wdd->min_timeout = 1;
181 wdd->max_timeout = MAX_HEARTBEAT;
182 wdd->timeout = DEFAULT_HEARTBEAT;
183
184 watchdog_init_timeout(wdd, heartbeat, dev);
185
186 dev_info(dev, "heartbeat %d sec\n", wdd->timeout);
187
188 watchdog_set_drvdata(wdd, davinci_wdt);
189 watchdog_set_nowayout(wdd, 1);
218 190
219 wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 191 wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
220 wdt_base = devm_ioremap_resource(dev, wdt_mem); 192 davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem);
221 if (IS_ERR(wdt_base)) 193 if (IS_ERR(davinci_wdt->base))
222 return PTR_ERR(wdt_base); 194 return PTR_ERR(davinci_wdt->base);
223 195
224 ret = misc_register(&davinci_wdt_miscdev); 196 ret = watchdog_register_device(wdd);
225 if (ret < 0) { 197 if (ret < 0)
226 dev_err(dev, "cannot register misc device\n"); 198 dev_err(dev, "cannot register watchdog device\n");
227 } else {
228 set_bit(WDT_DEVICE_INITED, &wdt_status);
229 }
230 199
231 return ret; 200 return ret;
232} 201}
233 202
234static int davinci_wdt_remove(struct platform_device *pdev) 203static int davinci_wdt_remove(struct platform_device *pdev)
235{ 204{
236 misc_deregister(&davinci_wdt_miscdev); 205 struct davinci_wdt_device *davinci_wdt = platform_get_drvdata(pdev);
237 clk_disable_unprepare(wdt_clk); 206
207 watchdog_unregister_device(&davinci_wdt->wdd);
208 clk_disable_unprepare(davinci_wdt->clk);
238 209
239 return 0; 210 return 0;
240} 211}
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index a46f5c7ee7ff..ee4f86ba83ec 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -8,7 +8,7 @@
8 * 2 of the License, or (at your option) any later version. 8 * 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This file implements a driver for the Synopsys DesignWare watchdog device 10 * This file implements a driver for the Synopsys DesignWare watchdog device
11 * in the many ARM subsystems. The watchdog has 16 different timeout periods 11 * in the many subsystems. The watchdog has 16 different timeout periods
12 * and these are a function of the input clock frequency. 12 * and these are a function of the input clock frequency.
13 * 13 *
14 * The DesignWare watchdog cannot be stopped once it has been started so we 14 * The DesignWare watchdog cannot be stopped once it has been started so we
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
new file mode 100644
index 000000000000..220a9e07cfd5
--- /dev/null
+++ b/drivers/watchdog/gpio_wdt.c
@@ -0,0 +1,254 @@
1/*
2 * Driver for watchdog device controlled through GPIO-line
3 *
4 * Author: 2013, Alexander Shiyan <shc_work@mail.ru>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/err.h>
13#include <linux/delay.h>
14#include <linux/module.h>
15#include <linux/notifier.h>
16#include <linux/of_gpio.h>
17#include <linux/platform_device.h>
18#include <linux/reboot.h>
19#include <linux/watchdog.h>
20
21#define SOFT_TIMEOUT_MIN 1
22#define SOFT_TIMEOUT_DEF 60
23#define SOFT_TIMEOUT_MAX 0xffff
24
25enum {
26 HW_ALGO_TOGGLE,
27 HW_ALGO_LEVEL,
28};
29
30struct gpio_wdt_priv {
31 int gpio;
32 bool active_low;
33 bool state;
34 unsigned int hw_algo;
35 unsigned int hw_margin;
36 unsigned long last_jiffies;
37 struct notifier_block notifier;
38 struct timer_list timer;
39 struct watchdog_device wdd;
40};
41
42static void gpio_wdt_disable(struct gpio_wdt_priv *priv)
43{
44 gpio_set_value_cansleep(priv->gpio, !priv->active_low);
45
46 /* Put GPIO back to tristate */
47 if (priv->hw_algo == HW_ALGO_TOGGLE)
48 gpio_direction_input(priv->gpio);
49}
50
51static int gpio_wdt_start(struct watchdog_device *wdd)
52{
53 struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
54
55 priv->state = priv->active_low;
56 gpio_direction_output(priv->gpio, priv->state);
57 priv->last_jiffies = jiffies;
58 mod_timer(&priv->timer, priv->last_jiffies + priv->hw_margin);
59
60 return 0;
61}
62
63static int gpio_wdt_stop(struct watchdog_device *wdd)
64{
65 struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
66
67 mod_timer(&priv->timer, 0);
68 gpio_wdt_disable(priv);
69
70 return 0;
71}
72
73static int gpio_wdt_ping(struct watchdog_device *wdd)
74{
75 struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
76
77 priv->last_jiffies = jiffies;
78
79 return 0;
80}
81
82static int gpio_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
83{
84 wdd->timeout = t;
85
86 return gpio_wdt_ping(wdd);
87}
88
89static void gpio_wdt_hwping(unsigned long data)
90{
91 struct watchdog_device *wdd = (struct watchdog_device *)data;
92 struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
93
94 if (time_after(jiffies, priv->last_jiffies +
95 msecs_to_jiffies(wdd->timeout * 1000))) {
96 dev_crit(wdd->dev, "Timer expired. System will reboot soon!\n");
97 return;
98 }
99
100 /* Restart timer */
101 mod_timer(&priv->timer, jiffies + priv->hw_margin);
102
103 switch (priv->hw_algo) {
104 case HW_ALGO_TOGGLE:
105 /* Toggle output pin */
106 priv->state = !priv->state;
107 gpio_set_value_cansleep(priv->gpio, priv->state);
108 break;
109 case HW_ALGO_LEVEL:
110 /* Pulse */
111 gpio_set_value_cansleep(priv->gpio, !priv->active_low);
112 udelay(1);
113 gpio_set_value_cansleep(priv->gpio, priv->active_low);
114 break;
115 }
116}
117
118static int gpio_wdt_notify_sys(struct notifier_block *nb, unsigned long code,
119 void *unused)
120{
121 struct gpio_wdt_priv *priv = container_of(nb, struct gpio_wdt_priv,
122 notifier);
123
124 mod_timer(&priv->timer, 0);
125
126 switch (code) {
127 case SYS_HALT:
128 case SYS_POWER_OFF:
129 gpio_wdt_disable(priv);
130 break;
131 default:
132 break;
133 }
134
135 return NOTIFY_DONE;
136}
137
138static const struct watchdog_info gpio_wdt_ident = {
139 .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING |
140 WDIOF_SETTIMEOUT,
141 .identity = "GPIO Watchdog",
142};
143
144static const struct watchdog_ops gpio_wdt_ops = {
145 .owner = THIS_MODULE,
146 .start = gpio_wdt_start,
147 .stop = gpio_wdt_stop,
148 .ping = gpio_wdt_ping,
149 .set_timeout = gpio_wdt_set_timeout,
150};
151
152static int gpio_wdt_probe(struct platform_device *pdev)
153{
154 struct gpio_wdt_priv *priv;
155 enum of_gpio_flags flags;
156 unsigned int hw_margin;
157 unsigned long f = 0;
158 const char *algo;
159 int ret;
160
161 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
162 if (!priv)
163 return -ENOMEM;
164
165 priv->gpio = of_get_gpio_flags(pdev->dev.of_node, 0, &flags);
166 if (!gpio_is_valid(priv->gpio))
167 return priv->gpio;
168
169 priv->active_low = flags & OF_GPIO_ACTIVE_LOW;
170
171 ret = of_property_read_string(pdev->dev.of_node, "hw_algo", &algo);
172 if (ret)
173 return ret;
174 if (!strncmp(algo, "toggle", 6)) {
175 priv->hw_algo = HW_ALGO_TOGGLE;
176 f = GPIOF_IN;
177 } else if (!strncmp(algo, "level", 5)) {
178 priv->hw_algo = HW_ALGO_LEVEL;
179 f = priv->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
180 } else {
181 return -EINVAL;
182 }
183
184 ret = devm_gpio_request_one(&pdev->dev, priv->gpio, f,
185 dev_name(&pdev->dev));
186 if (ret)
187 return ret;
188
189 ret = of_property_read_u32(pdev->dev.of_node,
190 "hw_margin_ms", &hw_margin);
191 if (ret)
192 return ret;
193 /* Disallow values lower than 2 and higher than 65535 ms */
194 if (hw_margin < 2 || hw_margin > 65535)
195 return -EINVAL;
196
197 /* Use safe value (1/2 of real timeout) */
198 priv->hw_margin = msecs_to_jiffies(hw_margin / 2);
199
200 watchdog_set_drvdata(&priv->wdd, priv);
201
202 priv->wdd.info = &gpio_wdt_ident;
203 priv->wdd.ops = &gpio_wdt_ops;
204 priv->wdd.min_timeout = SOFT_TIMEOUT_MIN;
205 priv->wdd.max_timeout = SOFT_TIMEOUT_MAX;
206
207 if (watchdog_init_timeout(&priv->wdd, 0, &pdev->dev) < 0)
208 priv->wdd.timeout = SOFT_TIMEOUT_DEF;
209
210 setup_timer(&priv->timer, gpio_wdt_hwping, (unsigned long)&priv->wdd);
211
212 ret = watchdog_register_device(&priv->wdd);
213 if (ret)
214 return ret;
215
216 priv->notifier.notifier_call = gpio_wdt_notify_sys;
217 ret = register_reboot_notifier(&priv->notifier);
218 if (ret)
219 watchdog_unregister_device(&priv->wdd);
220
221 return ret;
222}
223
224static int gpio_wdt_remove(struct platform_device *pdev)
225{
226 struct gpio_wdt_priv *priv = platform_get_drvdata(pdev);
227
228 del_timer_sync(&priv->timer);
229 unregister_reboot_notifier(&priv->notifier);
230 watchdog_unregister_device(&priv->wdd);
231
232 return 0;
233}
234
235static const struct of_device_id gpio_wdt_dt_ids[] = {
236 { .compatible = "linux,wdt-gpio", },
237 { }
238};
239MODULE_DEVICE_TABLE(of, gpio_wdt_dt_ids);
240
241static struct platform_driver gpio_wdt_driver = {
242 .driver = {
243 .name = "gpio-wdt",
244 .owner = THIS_MODULE,
245 .of_match_table = gpio_wdt_dt_ids,
246 },
247 .probe = gpio_wdt_probe,
248 .remove = gpio_wdt_remove,
249};
250module_platform_driver(gpio_wdt_driver);
251
252MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
253MODULE_DESCRIPTION("GPIO Watchdog");
254MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 45b979d9dd13..2b75e8b47279 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -39,7 +39,7 @@
39#endif /* CONFIG_HPWDT_NMI_DECODING */ 39#endif /* CONFIG_HPWDT_NMI_DECODING */
40#include <asm/nmi.h> 40#include <asm/nmi.h>
41 41
42#define HPWDT_VERSION "1.3.2" 42#define HPWDT_VERSION "1.3.3"
43#define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) 43#define SECS_TO_TICKS(secs) ((secs) * 1000 / 128)
44#define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) 44#define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000)
45#define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) 45#define HPWDT_MAX_TIMER TICKS_TO_SECS(65535)
@@ -55,7 +55,7 @@ static void __iomem *pci_mem_addr; /* the PCI-memory address */
55static unsigned long __iomem *hpwdt_timer_reg; 55static unsigned long __iomem *hpwdt_timer_reg;
56static unsigned long __iomem *hpwdt_timer_con; 56static unsigned long __iomem *hpwdt_timer_con;
57 57
58static DEFINE_PCI_DEVICE_TABLE(hpwdt_devices) = { 58static const struct pci_device_id hpwdt_devices[] = {
59 { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB203) }, /* iLO2 */ 59 { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB203) }, /* iLO2 */
60 { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3306) }, /* iLO3 */ 60 { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3306) }, /* iLO3 */
61 {0}, /* terminate list */ 61 {0}, /* terminate list */
@@ -501,8 +501,13 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
501 "but unable to determine source.\n"); 501 "but unable to determine source.\n");
502 } 502 }
503 } 503 }
504 panic("An NMI occurred, please see the Integrated " 504 panic("An NMI occurred. Depending on your system the reason "
505 "Management Log for details.\n"); 505 "for the NMI is logged in any one of the following "
506 "resources:\n"
507 "1. Integrated Management Log (IML)\n"
508 "2. OA Syslog\n"
509 "3. OA Forward Progress Log\n"
510 "4. iLO Event Log");
506 511
507out: 512out:
508 return NMI_DONE; 513 return NMI_DONE;
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index a72fe9361ddf..25a2bfdb4e9d 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -334,7 +334,7 @@ static struct miscdevice esb_miscdev = {
334/* 334/*
335 * Data for PCI driver interface 335 * Data for PCI driver interface
336 */ 336 */
337static DEFINE_PCI_DEVICE_TABLE(esb_pci_tbl) = { 337static const struct pci_device_id esb_pci_tbl[] = {
338 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, 338 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
339 { 0, }, /* End of list */ 339 { 0, }, /* End of list */
340}; 340};
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index b4786bccc42c..dd51d9539b33 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -2,6 +2,7 @@
2 * Watchdog driver for IMX2 and later processors 2 * Watchdog driver for IMX2 and later processors
3 * 3 *
4 * Copyright (C) 2010 Wolfram Sang, Pengutronix e.K. <w.sang@pengutronix.de> 4 * Copyright (C) 2010 Wolfram Sang, Pengutronix e.K. <w.sang@pengutronix.de>
5 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 * 6 *
6 * some parts adapted by similar drivers from Darius Augulis and Vladimir 7 * some parts adapted by similar drivers from Darius Augulis and Vladimir
7 * Zapolskiy, additional improvements by Wim Van Sebroeck. 8 * Zapolskiy, additional improvements by Wim Van Sebroeck.
@@ -40,6 +41,7 @@
40#define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */ 41#define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */
41#define IMX2_WDT_WCR_WRE (1 << 3) /* -> WDOG Reset Enable */ 42#define IMX2_WDT_WCR_WRE (1 << 3) /* -> WDOG Reset Enable */
42#define IMX2_WDT_WCR_WDE (1 << 2) /* -> Watchdog Enable */ 43#define IMX2_WDT_WCR_WDE (1 << 2) /* -> Watchdog Enable */
44#define IMX2_WDT_WCR_WDZST (1 << 0) /* -> Watchdog timer Suspend */
43 45
44#define IMX2_WDT_WSR 0x02 /* Service Register */ 46#define IMX2_WDT_WSR 0x02 /* Service Register */
45#define IMX2_WDT_SEQ1 0x5555 /* -> service sequence 1 */ 47#define IMX2_WDT_SEQ1 0x5555 /* -> service sequence 1 */
@@ -87,6 +89,8 @@ static inline void imx2_wdt_setup(void)
87{ 89{
88 u16 val = __raw_readw(imx2_wdt.base + IMX2_WDT_WCR); 90 u16 val = __raw_readw(imx2_wdt.base + IMX2_WDT_WCR);
89 91
92 /* Suspend timer in low power mode, write once-only */
93 val |= IMX2_WDT_WCR_WDZST;
90 /* Strip the old watchdog Time-Out value */ 94 /* Strip the old watchdog Time-Out value */
91 val &= ~IMX2_WDT_WCR_WT; 95 val &= ~IMX2_WDT_WCR_WT;
92 /* Generate reset if WDOG times out */ 96 /* Generate reset if WDOG times out */
diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c
index 4166e4d116a8..4aa3a8a876fe 100644
--- a/drivers/watchdog/moxart_wdt.c
+++ b/drivers/watchdog/moxart_wdt.c
@@ -19,6 +19,8 @@
19#include <linux/watchdog.h> 19#include <linux/watchdog.h>
20#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
21 21
22#include <asm/system_misc.h>
23
22#define REG_COUNT 0x4 24#define REG_COUNT 0x4
23#define REG_MODE 0x8 25#define REG_MODE 0x8
24#define REG_ENABLE 0xC 26#define REG_ENABLE 0xC
@@ -29,8 +31,17 @@ struct moxart_wdt_dev {
29 unsigned int clock_frequency; 31 unsigned int clock_frequency;
30}; 32};
31 33
34static struct moxart_wdt_dev *moxart_restart_ctx;
35
32static int heartbeat; 36static int heartbeat;
33 37
38static void moxart_wdt_restart(enum reboot_mode reboot_mode, const char *cmd)
39{
40 writel(1, moxart_restart_ctx->base + REG_COUNT);
41 writel(0x5ab9, moxart_restart_ctx->base + REG_MODE);
42 writel(0x03, moxart_restart_ctx->base + REG_ENABLE);
43}
44
34static int moxart_wdt_stop(struct watchdog_device *wdt_dev) 45static int moxart_wdt_stop(struct watchdog_device *wdt_dev)
35{ 46{
36 struct moxart_wdt_dev *moxart_wdt = watchdog_get_drvdata(wdt_dev); 47 struct moxart_wdt_dev *moxart_wdt = watchdog_get_drvdata(wdt_dev);
@@ -125,6 +136,9 @@ static int moxart_wdt_probe(struct platform_device *pdev)
125 if (err) 136 if (err)
126 return err; 137 return err;
127 138
139 moxart_restart_ctx = moxart_wdt;
140 arm_pm_restart = moxart_wdt_restart;
141
128 dev_dbg(dev, "Watchdog enabled (heartbeat=%d sec, nowayout=%d)\n", 142 dev_dbg(dev, "Watchdog enabled (heartbeat=%d sec, nowayout=%d)\n",
129 moxart_wdt->dev.timeout, nowayout); 143 moxart_wdt->dev.timeout, nowayout);
130 144
@@ -135,6 +149,7 @@ static int moxart_wdt_remove(struct platform_device *pdev)
135{ 149{
136 struct moxart_wdt_dev *moxart_wdt = platform_get_drvdata(pdev); 150 struct moxart_wdt_dev *moxart_wdt = platform_get_drvdata(pdev);
137 151
152 arm_pm_restart = NULL;
138 moxart_wdt_stop(&moxart_wdt->dev); 153 moxart_wdt_stop(&moxart_wdt->dev);
139 watchdog_unregister_device(&moxart_wdt->dev); 154 watchdog_unregister_device(&moxart_wdt->dev);
140 155
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index d82152077fd9..c1f65b4c0aa4 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -73,9 +73,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
73 * to 0 73 * to 0
74 */ 74 */
75static int prescale = 1; 75static int prescale = 1;
76static unsigned int timeout_sec;
77 76
78static unsigned long wdt_is_open;
79static DEFINE_SPINLOCK(wdt_spinlock); 77static DEFINE_SPINLOCK(wdt_spinlock);
80 78
81static void mpc8xxx_wdt_keepalive(void) 79static void mpc8xxx_wdt_keepalive(void)
@@ -87,39 +85,23 @@ static void mpc8xxx_wdt_keepalive(void)
87 spin_unlock(&wdt_spinlock); 85 spin_unlock(&wdt_spinlock);
88} 86}
89 87
88static struct watchdog_device mpc8xxx_wdt_dev;
90static void mpc8xxx_wdt_timer_ping(unsigned long arg); 89static void mpc8xxx_wdt_timer_ping(unsigned long arg);
91static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0, 0); 90static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0,
91 (unsigned long)&mpc8xxx_wdt_dev);
92 92
93static void mpc8xxx_wdt_timer_ping(unsigned long arg) 93static void mpc8xxx_wdt_timer_ping(unsigned long arg)
94{ 94{
95 struct watchdog_device *w = (struct watchdog_device *)arg;
96
95 mpc8xxx_wdt_keepalive(); 97 mpc8xxx_wdt_keepalive();
96 /* We're pinging it twice faster than needed, just to be sure. */ 98 /* We're pinging it twice faster than needed, just to be sure. */
97 mod_timer(&wdt_timer, jiffies + HZ * timeout_sec / 2); 99 mod_timer(&wdt_timer, jiffies + HZ * w->timeout / 2);
98}
99
100static void mpc8xxx_wdt_pr_warn(const char *msg)
101{
102 pr_crit("%s, expect the %s soon!\n", msg,
103 reset ? "reset" : "machine check exception");
104} 100}
105 101
106static ssize_t mpc8xxx_wdt_write(struct file *file, const char __user *buf, 102static int mpc8xxx_wdt_start(struct watchdog_device *w)
107 size_t count, loff_t *ppos)
108{
109 if (count)
110 mpc8xxx_wdt_keepalive();
111 return count;
112}
113
114static int mpc8xxx_wdt_open(struct inode *inode, struct file *file)
115{ 103{
116 u32 tmp = SWCRR_SWEN; 104 u32 tmp = SWCRR_SWEN;
117 if (test_and_set_bit(0, &wdt_is_open))
118 return -EBUSY;
119
120 /* Once we start the watchdog we can't stop it */
121 if (nowayout)
122 __module_get(THIS_MODULE);
123 105
124 /* Good, fire up the show */ 106 /* Good, fire up the show */
125 if (prescale) 107 if (prescale)
@@ -133,59 +115,37 @@ static int mpc8xxx_wdt_open(struct inode *inode, struct file *file)
133 115
134 del_timer_sync(&wdt_timer); 116 del_timer_sync(&wdt_timer);
135 117
136 return nonseekable_open(inode, file); 118 return 0;
137} 119}
138 120
139static int mpc8xxx_wdt_release(struct inode *inode, struct file *file) 121static int mpc8xxx_wdt_ping(struct watchdog_device *w)
140{ 122{
141 if (!nowayout) 123 mpc8xxx_wdt_keepalive();
142 mpc8xxx_wdt_timer_ping(0);
143 else
144 mpc8xxx_wdt_pr_warn("watchdog closed");
145 clear_bit(0, &wdt_is_open);
146 return 0; 124 return 0;
147} 125}
148 126
149static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd, 127static int mpc8xxx_wdt_stop(struct watchdog_device *w)
150 unsigned long arg)
151{ 128{
152 void __user *argp = (void __user *)arg; 129 mod_timer(&wdt_timer, jiffies);
153 int __user *p = argp; 130 return 0;
154 static const struct watchdog_info ident = {
155 .options = WDIOF_KEEPALIVEPING,
156 .firmware_version = 1,
157 .identity = "MPC8xxx",
158 };
159
160 switch (cmd) {
161 case WDIOC_GETSUPPORT:
162 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
163 case WDIOC_GETSTATUS:
164 case WDIOC_GETBOOTSTATUS:
165 return put_user(0, p);
166 case WDIOC_KEEPALIVE:
167 mpc8xxx_wdt_keepalive();
168 return 0;
169 case WDIOC_GETTIMEOUT:
170 return put_user(timeout_sec, p);
171 default:
172 return -ENOTTY;
173 }
174} 131}
175 132
176static const struct file_operations mpc8xxx_wdt_fops = { 133static struct watchdog_info mpc8xxx_wdt_info = {
177 .owner = THIS_MODULE, 134 .options = WDIOF_KEEPALIVEPING,
178 .llseek = no_llseek, 135 .firmware_version = 1,
179 .write = mpc8xxx_wdt_write, 136 .identity = "MPC8xxx",
180 .unlocked_ioctl = mpc8xxx_wdt_ioctl,
181 .open = mpc8xxx_wdt_open,
182 .release = mpc8xxx_wdt_release,
183}; 137};
184 138
185static struct miscdevice mpc8xxx_wdt_miscdev = { 139static struct watchdog_ops mpc8xxx_wdt_ops = {
186 .minor = WATCHDOG_MINOR, 140 .owner = THIS_MODULE,
187 .name = "watchdog", 141 .start = mpc8xxx_wdt_start,
188 .fops = &mpc8xxx_wdt_fops, 142 .ping = mpc8xxx_wdt_ping,
143 .stop = mpc8xxx_wdt_stop,
144};
145
146static struct watchdog_device mpc8xxx_wdt_dev = {
147 .info = &mpc8xxx_wdt_info,
148 .ops = &mpc8xxx_wdt_ops,
189}; 149};
190 150
191static const struct of_device_id mpc8xxx_wdt_match[]; 151static const struct of_device_id mpc8xxx_wdt_match[];
@@ -197,6 +157,7 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
197 const struct mpc8xxx_wdt_type *wdt_type; 157 const struct mpc8xxx_wdt_type *wdt_type;
198 u32 freq = fsl_get_sys_freq(); 158 u32 freq = fsl_get_sys_freq();
199 bool enabled; 159 bool enabled;
160 unsigned int timeout_sec;
200 161
201 match = of_match_device(mpc8xxx_wdt_match, &ofdev->dev); 162 match = of_match_device(mpc8xxx_wdt_match, &ofdev->dev);
202 if (!match) 163 if (!match)
@@ -223,6 +184,7 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
223 else 184 else
224 timeout_sec = timeout / freq; 185 timeout_sec = timeout / freq;
225 186
187 mpc8xxx_wdt_dev.timeout = timeout_sec;
226#ifdef MODULE 188#ifdef MODULE
227 ret = mpc8xxx_wdt_init_late(); 189 ret = mpc8xxx_wdt_init_late();
228 if (ret) 190 if (ret)
@@ -238,7 +200,7 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
238 * userspace handles it. 200 * userspace handles it.
239 */ 201 */
240 if (enabled) 202 if (enabled)
241 mpc8xxx_wdt_timer_ping(0); 203 mod_timer(&wdt_timer, jiffies);
242 return 0; 204 return 0;
243err_unmap: 205err_unmap:
244 iounmap(wd_base); 206 iounmap(wd_base);
@@ -248,9 +210,10 @@ err_unmap:
248 210
249static int mpc8xxx_wdt_remove(struct platform_device *ofdev) 211static int mpc8xxx_wdt_remove(struct platform_device *ofdev)
250{ 212{
251 mpc8xxx_wdt_pr_warn("watchdog removed"); 213 pr_crit("Watchdog removed, expect the %s soon!\n",
214 reset ? "reset" : "machine check exception");
252 del_timer_sync(&wdt_timer); 215 del_timer_sync(&wdt_timer);
253 misc_deregister(&mpc8xxx_wdt_miscdev); 216 watchdog_unregister_device(&mpc8xxx_wdt_dev);
254 iounmap(wd_base); 217 iounmap(wd_base);
255 218
256 return 0; 219 return 0;
@@ -302,10 +265,11 @@ static int mpc8xxx_wdt_init_late(void)
302 if (!wd_base) 265 if (!wd_base)
303 return -ENODEV; 266 return -ENODEV;
304 267
305 ret = misc_register(&mpc8xxx_wdt_miscdev); 268 watchdog_set_nowayout(&mpc8xxx_wdt_dev, nowayout);
269
270 ret = watchdog_register_device(&mpc8xxx_wdt_dev);
306 if (ret) { 271 if (ret) {
307 pr_err("cannot register miscdev on minor=%d (err=%d)\n", 272 pr_err("cannot register watchdog device (err=%d)\n", ret);
308 WATCHDOG_MINOR, ret);
309 return ret; 273 return ret;
310 } 274 }
311 return 0; 275 return 0;
diff --git a/drivers/watchdog/nv_tco.c b/drivers/watchdog/nv_tco.c
index 231e5b9d5c8e..0b9ec61e1313 100644
--- a/drivers/watchdog/nv_tco.c
+++ b/drivers/watchdog/nv_tco.c
@@ -289,7 +289,7 @@ static struct miscdevice nv_tco_miscdev = {
289 * register a pci_driver, because someone else might one day 289 * register a pci_driver, because someone else might one day
290 * want to register another driver on the same PCI id. 290 * want to register another driver on the same PCI id.
291 */ 291 */
292static DEFINE_PCI_DEVICE_TABLE(tco_pci_tbl) = { 292static const struct pci_device_id tco_pci_tbl[] = {
293 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS, 293 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS,
294 PCI_ANY_ID, PCI_ANY_ID, }, 294 PCI_ANY_ID, PCI_ANY_ID, },
295 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS, 295 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS,
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index b4864f254b48..c0d07eef2640 100644
--- a/drivers/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
@@ -801,7 +801,7 @@ static void pcipcwd_card_exit(struct pci_dev *pdev)
801 cards_found--; 801 cards_found--;
802} 802}
803 803
804static DEFINE_PCI_DEVICE_TABLE(pcipcwd_pci_tbl) = { 804static const struct pci_device_id pcipcwd_pci_tbl[] = {
805 { PCI_VENDOR_ID_QUICKLOGIC, PCI_DEVICE_ID_WATCHDOG_PCIPCWD, 805 { PCI_VENDOR_ID_QUICKLOGIC, PCI_DEVICE_ID_WATCHDOG_PCIPCWD,
806 PCI_ANY_ID, PCI_ANY_ID, }, 806 PCI_ANY_ID, PCI_ANY_ID, },
807 { 0 }, /* End of list */ 807 { 0 }, /* End of list */
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 7d8fd041ee25..aec946df6ed9 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -40,6 +40,8 @@
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/err.h> 41#include <linux/err.h>
42#include <linux/of.h> 42#include <linux/of.h>
43#include <linux/mfd/syscon.h>
44#include <linux/regmap.h>
43 45
44#define S3C2410_WTCON 0x00 46#define S3C2410_WTCON 0x00
45#define S3C2410_WTDAT 0x04 47#define S3C2410_WTDAT 0x04
@@ -60,6 +62,16 @@
60#define CONFIG_S3C2410_WATCHDOG_ATBOOT (0) 62#define CONFIG_S3C2410_WATCHDOG_ATBOOT (0)
61#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15) 63#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15)
62 64
65#define EXYNOS5_RST_STAT_REG_OFFSET 0x0404
66#define EXYNOS5_WDT_DISABLE_REG_OFFSET 0x0408
67#define EXYNOS5_WDT_MASK_RESET_REG_OFFSET 0x040c
68#define QUIRK_HAS_PMU_CONFIG (1 << 0)
69#define QUIRK_HAS_RST_STAT (1 << 1)
70
71/* These quirks require that we have a PMU register map */
72#define QUIRKS_HAVE_PMUREG (QUIRK_HAS_PMU_CONFIG | \
73 QUIRK_HAS_RST_STAT)
74
63static bool nowayout = WATCHDOG_NOWAYOUT; 75static bool nowayout = WATCHDOG_NOWAYOUT;
64static int tmr_margin; 76static int tmr_margin;
65static int tmr_atboot = CONFIG_S3C2410_WATCHDOG_ATBOOT; 77static int tmr_atboot = CONFIG_S3C2410_WATCHDOG_ATBOOT;
@@ -83,6 +95,30 @@ MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, "
83 "0 to reboot (default 0)"); 95 "0 to reboot (default 0)");
84MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug (default 0)"); 96MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug (default 0)");
85 97
98/**
99 * struct s3c2410_wdt_variant - Per-variant config data
100 *
101 * @disable_reg: Offset in pmureg for the register that disables the watchdog
102 * timer reset functionality.
103 * @mask_reset_reg: Offset in pmureg for the register that masks the watchdog
104 * timer reset functionality.
105 * @mask_bit: Bit number for the watchdog timer in the disable register and the
106 * mask reset register.
107 * @rst_stat_reg: Offset in pmureg for the register that has the reset status.
108 * @rst_stat_bit: Bit number in the rst_stat register indicating a watchdog
109 * reset.
110 * @quirks: A bitfield of quirks.
111 */
112
113struct s3c2410_wdt_variant {
114 int disable_reg;
115 int mask_reset_reg;
116 int mask_bit;
117 int rst_stat_reg;
118 int rst_stat_bit;
119 u32 quirks;
120};
121
86struct s3c2410_wdt { 122struct s3c2410_wdt {
87 struct device *dev; 123 struct device *dev;
88 struct clk *clock; 124 struct clk *clock;
@@ -93,8 +129,54 @@ struct s3c2410_wdt {
93 unsigned long wtdat_save; 129 unsigned long wtdat_save;
94 struct watchdog_device wdt_device; 130 struct watchdog_device wdt_device;
95 struct notifier_block freq_transition; 131 struct notifier_block freq_transition;
132 struct s3c2410_wdt_variant *drv_data;
133 struct regmap *pmureg;
96}; 134};
97 135
136static const struct s3c2410_wdt_variant drv_data_s3c2410 = {
137 .quirks = 0
138};
139
140#ifdef CONFIG_OF
141static const struct s3c2410_wdt_variant drv_data_exynos5250 = {
142 .disable_reg = EXYNOS5_WDT_DISABLE_REG_OFFSET,
143 .mask_reset_reg = EXYNOS5_WDT_MASK_RESET_REG_OFFSET,
144 .mask_bit = 20,
145 .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET,
146 .rst_stat_bit = 20,
147 .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT,
148};
149
150static const struct s3c2410_wdt_variant drv_data_exynos5420 = {
151 .disable_reg = EXYNOS5_WDT_DISABLE_REG_OFFSET,
152 .mask_reset_reg = EXYNOS5_WDT_MASK_RESET_REG_OFFSET,
153 .mask_bit = 0,
154 .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET,
155 .rst_stat_bit = 9,
156 .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT,
157};
158
159static const struct of_device_id s3c2410_wdt_match[] = {
160 { .compatible = "samsung,s3c2410-wdt",
161 .data = &drv_data_s3c2410 },
162 { .compatible = "samsung,exynos5250-wdt",
163 .data = &drv_data_exynos5250 },
164 { .compatible = "samsung,exynos5420-wdt",
165 .data = &drv_data_exynos5420 },
166 {},
167};
168MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
169#endif
170
171static const struct platform_device_id s3c2410_wdt_ids[] = {
172 {
173 .name = "s3c2410-wdt",
174 .driver_data = (unsigned long)&drv_data_s3c2410,
175 },
176 {}
177};
178MODULE_DEVICE_TABLE(platform, s3c2410_wdt_ids);
179
98/* watchdog control routines */ 180/* watchdog control routines */
99 181
100#define DBG(fmt, ...) \ 182#define DBG(fmt, ...) \
@@ -110,6 +192,35 @@ static inline struct s3c2410_wdt *freq_to_wdt(struct notifier_block *nb)
110 return container_of(nb, struct s3c2410_wdt, freq_transition); 192 return container_of(nb, struct s3c2410_wdt, freq_transition);
111} 193}
112 194
195static int s3c2410wdt_mask_and_disable_reset(struct s3c2410_wdt *wdt, bool mask)
196{
197 int ret;
198 u32 mask_val = 1 << wdt->drv_data->mask_bit;
199 u32 val = 0;
200
201 /* No need to do anything if no PMU CONFIG needed */
202 if (!(wdt->drv_data->quirks & QUIRK_HAS_PMU_CONFIG))
203 return 0;
204
205 if (mask)
206 val = mask_val;
207
208 ret = regmap_update_bits(wdt->pmureg,
209 wdt->drv_data->disable_reg,
210 mask_val, val);
211 if (ret < 0)
212 goto error;
213
214 ret = regmap_update_bits(wdt->pmureg,
215 wdt->drv_data->mask_reset_reg,
216 mask_val, val);
217 error:
218 if (ret < 0)
219 dev_err(wdt->dev, "failed to update reg(%d)\n", ret);
220
221 return ret;
222}
223
113static int s3c2410wdt_keepalive(struct watchdog_device *wdd) 224static int s3c2410wdt_keepalive(struct watchdog_device *wdd)
114{ 225{
115 struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); 226 struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd);
@@ -188,7 +299,7 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeou
188 if (timeout < 1) 299 if (timeout < 1)
189 return -EINVAL; 300 return -EINVAL;
190 301
191 freq /= 128; 302 freq = DIV_ROUND_UP(freq, 128);
192 count = timeout * freq; 303 count = timeout * freq;
193 304
194 DBG("%s: count=%d, timeout=%d, freq=%lu\n", 305 DBG("%s: count=%d, timeout=%d, freq=%lu\n",
@@ -200,21 +311,18 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeou
200 */ 311 */
201 312
202 if (count >= 0x10000) { 313 if (count >= 0x10000) {
203 for (divisor = 1; divisor <= 0x100; divisor++) { 314 divisor = DIV_ROUND_UP(count, 0xffff);
204 if ((count / divisor) < 0x10000)
205 break;
206 }
207 315
208 if ((count / divisor) >= 0x10000) { 316 if (divisor > 0x100) {
209 dev_err(wdt->dev, "timeout %d too big\n", timeout); 317 dev_err(wdt->dev, "timeout %d too big\n", timeout);
210 return -EINVAL; 318 return -EINVAL;
211 } 319 }
212 } 320 }
213 321
214 DBG("%s: timeout=%d, divisor=%d, count=%d (%08x)\n", 322 DBG("%s: timeout=%d, divisor=%d, count=%d (%08x)\n",
215 __func__, timeout, divisor, count, count/divisor); 323 __func__, timeout, divisor, count, DIV_ROUND_UP(count, divisor));
216 324
217 count /= divisor; 325 count = DIV_ROUND_UP(count, divisor);
218 wdt->count = count; 326 wdt->count = count;
219 327
220 /* update the pre-scaler */ 328 /* update the pre-scaler */
@@ -264,7 +372,7 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param)
264 return IRQ_HANDLED; 372 return IRQ_HANDLED;
265} 373}
266 374
267#ifdef CONFIG_CPU_FREQ 375#ifdef CONFIG_ARM_S3C24XX_CPUFREQ
268 376
269static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb, 377static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb,
270 unsigned long val, void *data) 378 unsigned long val, void *data)
@@ -331,6 +439,37 @@ static inline void s3c2410wdt_cpufreq_deregister(struct s3c2410_wdt *wdt)
331} 439}
332#endif 440#endif
333 441
442static inline unsigned int s3c2410wdt_get_bootstatus(struct s3c2410_wdt *wdt)
443{
444 unsigned int rst_stat;
445 int ret;
446
447 if (!(wdt->drv_data->quirks & QUIRK_HAS_RST_STAT))
448 return 0;
449
450 ret = regmap_read(wdt->pmureg, wdt->drv_data->rst_stat_reg, &rst_stat);
451 if (ret)
452 dev_warn(wdt->dev, "Couldn't get RST_STAT register\n");
453 else if (rst_stat & BIT(wdt->drv_data->rst_stat_bit))
454 return WDIOF_CARDRESET;
455
456 return 0;
457}
458
459/* s3c2410_get_wdt_driver_data */
460static inline struct s3c2410_wdt_variant *
461get_wdt_drv_data(struct platform_device *pdev)
462{
463 if (pdev->dev.of_node) {
464 const struct of_device_id *match;
465 match = of_match_node(s3c2410_wdt_match, pdev->dev.of_node);
466 return (struct s3c2410_wdt_variant *)match->data;
467 } else {
468 return (struct s3c2410_wdt_variant *)
469 platform_get_device_id(pdev)->driver_data;
470 }
471}
472
334static int s3c2410wdt_probe(struct platform_device *pdev) 473static int s3c2410wdt_probe(struct platform_device *pdev)
335{ 474{
336 struct device *dev; 475 struct device *dev;
@@ -353,6 +492,16 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
353 spin_lock_init(&wdt->lock); 492 spin_lock_init(&wdt->lock);
354 wdt->wdt_device = s3c2410_wdd; 493 wdt->wdt_device = s3c2410_wdd;
355 494
495 wdt->drv_data = get_wdt_drv_data(pdev);
496 if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) {
497 wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
498 "samsung,syscon-phandle");
499 if (IS_ERR(wdt->pmureg)) {
500 dev_err(dev, "syscon regmap lookup failed.\n");
501 return PTR_ERR(wdt->pmureg);
502 }
503 }
504
356 wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 505 wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
357 if (wdt_irq == NULL) { 506 if (wdt_irq == NULL) {
358 dev_err(dev, "no irq resource specified\n"); 507 dev_err(dev, "no irq resource specified\n");
@@ -415,12 +564,18 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
415 564
416 watchdog_set_nowayout(&wdt->wdt_device, nowayout); 565 watchdog_set_nowayout(&wdt->wdt_device, nowayout);
417 566
567 wdt->wdt_device.bootstatus = s3c2410wdt_get_bootstatus(wdt);
568
418 ret = watchdog_register_device(&wdt->wdt_device); 569 ret = watchdog_register_device(&wdt->wdt_device);
419 if (ret) { 570 if (ret) {
420 dev_err(dev, "cannot register watchdog (%d)\n", ret); 571 dev_err(dev, "cannot register watchdog (%d)\n", ret);
421 goto err_cpufreq; 572 goto err_cpufreq;
422 } 573 }
423 574
575 ret = s3c2410wdt_mask_and_disable_reset(wdt, false);
576 if (ret < 0)
577 goto err_unregister;
578
424 if (tmr_atboot && started == 0) { 579 if (tmr_atboot && started == 0) {
425 dev_info(dev, "starting watchdog timer\n"); 580 dev_info(dev, "starting watchdog timer\n");
426 s3c2410wdt_start(&wdt->wdt_device); 581 s3c2410wdt_start(&wdt->wdt_device);
@@ -445,6 +600,9 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
445 600
446 return 0; 601 return 0;
447 602
603 err_unregister:
604 watchdog_unregister_device(&wdt->wdt_device);
605
448 err_cpufreq: 606 err_cpufreq:
449 s3c2410wdt_cpufreq_deregister(wdt); 607 s3c2410wdt_cpufreq_deregister(wdt);
450 608
@@ -458,8 +616,13 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
458 616
459static int s3c2410wdt_remove(struct platform_device *dev) 617static int s3c2410wdt_remove(struct platform_device *dev)
460{ 618{
619 int ret;
461 struct s3c2410_wdt *wdt = platform_get_drvdata(dev); 620 struct s3c2410_wdt *wdt = platform_get_drvdata(dev);
462 621
622 ret = s3c2410wdt_mask_and_disable_reset(wdt, true);
623 if (ret < 0)
624 return ret;
625
463 watchdog_unregister_device(&wdt->wdt_device); 626 watchdog_unregister_device(&wdt->wdt_device);
464 627
465 s3c2410wdt_cpufreq_deregister(wdt); 628 s3c2410wdt_cpufreq_deregister(wdt);
@@ -474,6 +637,8 @@ static void s3c2410wdt_shutdown(struct platform_device *dev)
474{ 637{
475 struct s3c2410_wdt *wdt = platform_get_drvdata(dev); 638 struct s3c2410_wdt *wdt = platform_get_drvdata(dev);
476 639
640 s3c2410wdt_mask_and_disable_reset(wdt, true);
641
477 s3c2410wdt_stop(&wdt->wdt_device); 642 s3c2410wdt_stop(&wdt->wdt_device);
478} 643}
479 644
@@ -481,12 +646,17 @@ static void s3c2410wdt_shutdown(struct platform_device *dev)
481 646
482static int s3c2410wdt_suspend(struct device *dev) 647static int s3c2410wdt_suspend(struct device *dev)
483{ 648{
649 int ret;
484 struct s3c2410_wdt *wdt = dev_get_drvdata(dev); 650 struct s3c2410_wdt *wdt = dev_get_drvdata(dev);
485 651
486 /* Save watchdog state, and turn it off. */ 652 /* Save watchdog state, and turn it off. */
487 wdt->wtcon_save = readl(wdt->reg_base + S3C2410_WTCON); 653 wdt->wtcon_save = readl(wdt->reg_base + S3C2410_WTCON);
488 wdt->wtdat_save = readl(wdt->reg_base + S3C2410_WTDAT); 654 wdt->wtdat_save = readl(wdt->reg_base + S3C2410_WTDAT);
489 655
656 ret = s3c2410wdt_mask_and_disable_reset(wdt, true);
657 if (ret < 0)
658 return ret;
659
490 /* Note that WTCNT doesn't need to be saved. */ 660 /* Note that WTCNT doesn't need to be saved. */
491 s3c2410wdt_stop(&wdt->wdt_device); 661 s3c2410wdt_stop(&wdt->wdt_device);
492 662
@@ -495,6 +665,7 @@ static int s3c2410wdt_suspend(struct device *dev)
495 665
496static int s3c2410wdt_resume(struct device *dev) 666static int s3c2410wdt_resume(struct device *dev)
497{ 667{
668 int ret;
498 struct s3c2410_wdt *wdt = dev_get_drvdata(dev); 669 struct s3c2410_wdt *wdt = dev_get_drvdata(dev);
499 670
500 /* Restore watchdog state. */ 671 /* Restore watchdog state. */
@@ -502,6 +673,10 @@ static int s3c2410wdt_resume(struct device *dev)
502 writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTCNT);/* Reset count */ 673 writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTCNT);/* Reset count */
503 writel(wdt->wtcon_save, wdt->reg_base + S3C2410_WTCON); 674 writel(wdt->wtcon_save, wdt->reg_base + S3C2410_WTCON);
504 675
676 ret = s3c2410wdt_mask_and_disable_reset(wdt, false);
677 if (ret < 0)
678 return ret;
679
505 dev_info(dev, "watchdog %sabled\n", 680 dev_info(dev, "watchdog %sabled\n",
506 (wdt->wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis"); 681 (wdt->wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
507 682
@@ -512,18 +687,11 @@ static int s3c2410wdt_resume(struct device *dev)
512static SIMPLE_DEV_PM_OPS(s3c2410wdt_pm_ops, s3c2410wdt_suspend, 687static SIMPLE_DEV_PM_OPS(s3c2410wdt_pm_ops, s3c2410wdt_suspend,
513 s3c2410wdt_resume); 688 s3c2410wdt_resume);
514 689
515#ifdef CONFIG_OF
516static const struct of_device_id s3c2410_wdt_match[] = {
517 { .compatible = "samsung,s3c2410-wdt" },
518 {},
519};
520MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
521#endif
522
523static struct platform_driver s3c2410wdt_driver = { 690static struct platform_driver s3c2410wdt_driver = {
524 .probe = s3c2410wdt_probe, 691 .probe = s3c2410wdt_probe,
525 .remove = s3c2410wdt_remove, 692 .remove = s3c2410wdt_remove,
526 .shutdown = s3c2410wdt_shutdown, 693 .shutdown = s3c2410wdt_shutdown,
694 .id_table = s3c2410_wdt_ids,
527 .driver = { 695 .driver = {
528 .owner = THIS_MODULE, 696 .owner = THIS_MODULE,
529 .name = "s3c2410-wdt", 697 .name = "s3c2410-wdt",
@@ -538,4 +706,3 @@ MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, "
538 "Dimitry Andric <dimitry.andric@tomtom.com>"); 706 "Dimitry Andric <dimitry.andric@tomtom.com>");
539MODULE_DESCRIPTION("S3C2410 Watchdog Device Driver"); 707MODULE_DESCRIPTION("S3C2410 Watchdog Device Driver");
540MODULE_LICENSE("GPL"); 708MODULE_LICENSE("GPL");
541MODULE_ALIAS("platform:s3c2410-wdt");
diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c
index ced3edc95957..702d07870808 100644
--- a/drivers/watchdog/sirfsoc_wdt.c
+++ b/drivers/watchdog/sirfsoc_wdt.c
@@ -212,7 +212,7 @@ static struct platform_driver sirfsoc_wdt_driver = {
212 .name = "sirfsoc-wdt", 212 .name = "sirfsoc-wdt",
213 .owner = THIS_MODULE, 213 .owner = THIS_MODULE,
214 .pm = &sirfsoc_wdt_pm_ops, 214 .pm = &sirfsoc_wdt_pm_ops,
215 .of_match_table = of_match_ptr(sirfsoc_wdt_of_match), 215 .of_match_table = sirfsoc_wdt_of_match,
216 }, 216 },
217 .probe = sirfsoc_wdt_probe, 217 .probe = sirfsoc_wdt_probe,
218 .remove = sirfsoc_wdt_remove, 218 .remove = sirfsoc_wdt_remove,
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
index ce63a1bbf395..5cca9cddb87d 100644
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -303,7 +303,7 @@ static struct miscdevice sp5100_tco_miscdev = {
303 * register a pci_driver, because someone else might 303 * register a pci_driver, because someone else might
304 * want to register another driver on the same PCI id. 304 * want to register another driver on the same PCI id.
305 */ 305 */
306static DEFINE_PCI_DEVICE_TABLE(sp5100_tco_pci_tbl) = { 306static const struct pci_device_id sp5100_tco_pci_tbl[] = {
307 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, PCI_ANY_ID, 307 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, PCI_ANY_ID,
308 PCI_ANY_ID, }, 308 PCI_ANY_ID, },
309 { 0, }, /* End of list */ 309 { 0, }, /* End of list */
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
index 1a68f760cf86..d2cd9f0bcb9a 100644
--- a/drivers/watchdog/via_wdt.c
+++ b/drivers/watchdog/via_wdt.c
@@ -239,7 +239,7 @@ static void wdt_remove(struct pci_dev *pdev)
239 pci_disable_device(pdev); 239 pci_disable_device(pdev);
240} 240}
241 241
242static DEFINE_PCI_DEVICE_TABLE(wdt_pci_table) = { 242static const struct pci_device_id wdt_pci_table[] = {
243 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700) }, 243 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700) },
244 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800) }, 244 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800) },
245 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) }, 245 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) },
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index e24b21082874..b1da0c18fd1a 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -44,10 +44,13 @@
44#define WATCHDOG_NAME "w83627hf/thf/hg/dhg WDT" 44#define WATCHDOG_NAME "w83627hf/thf/hg/dhg WDT"
45#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ 45#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */
46 46
47/* You must set this - there is no sane way to probe for this board. */ 47static int wdt_io;
48static int wdt_io = 0x2E; 48static int cr_wdt_timeout; /* WDT timeout register */
49module_param(wdt_io, int, 0); 49static int cr_wdt_control; /* WDT control register */
50MODULE_PARM_DESC(wdt_io, "w83627hf/thf WDT io port (default 0x2E)"); 50
51enum chips { w83627hf, w83627s, w83697hf, w83697ug, w83637hf, w83627thf,
52 w83687thf, w83627ehf, w83627dhg, w83627uhg, w83667hg, w83627dhg_p,
53 w83667hg_b, nct6775, nct6776, nct6779 };
51 54
52static int timeout; /* in seconds */ 55static int timeout; /* in seconds */
53module_param(timeout, int, 0); 56module_param(timeout, int, 0);
@@ -72,6 +75,29 @@ MODULE_PARM_DESC(nowayout,
72 75
73#define W83627HF_LD_WDT 0x08 76#define W83627HF_LD_WDT 0x08
74 77
78#define W83627HF_ID 0x52
79#define W83627S_ID 0x59
80#define W83697HF_ID 0x60
81#define W83697UG_ID 0x68
82#define W83637HF_ID 0x70
83#define W83627THF_ID 0x82
84#define W83687THF_ID 0x85
85#define W83627EHF_ID 0x88
86#define W83627DHG_ID 0xa0
87#define W83627UHG_ID 0xa2
88#define W83667HG_ID 0xa5
89#define W83627DHG_P_ID 0xb0
90#define W83667HG_B_ID 0xb3
91#define NCT6775_ID 0xb4
92#define NCT6776_ID 0xc3
93#define NCT6779_ID 0xc5
94
95#define W83627HF_WDT_TIMEOUT 0xf6
96#define W83697HF_WDT_TIMEOUT 0xf4
97
98#define W83627HF_WDT_CONTROL 0xf5
99#define W83697HF_WDT_CONTROL 0xf3
100
75static void superio_outb(int reg, int val) 101static void superio_outb(int reg, int val)
76{ 102{
77 outb(reg, WDT_EFER); 103 outb(reg, WDT_EFER);
@@ -106,10 +132,7 @@ static void superio_exit(void)
106 release_region(wdt_io, 2); 132 release_region(wdt_io, 2);
107} 133}
108 134
109/* tyan motherboards seem to set F5 to 0x4C ? 135static int w83627hf_init(struct watchdog_device *wdog, enum chips chip)
110 * So explicitly init to appropriate value. */
111
112static int w83627hf_init(struct watchdog_device *wdog)
113{ 136{
114 int ret; 137 int ret;
115 unsigned char t; 138 unsigned char t;
@@ -119,35 +142,83 @@ static int w83627hf_init(struct watchdog_device *wdog)
119 return ret; 142 return ret;
120 143
121 superio_select(W83627HF_LD_WDT); 144 superio_select(W83627HF_LD_WDT);
122 t = superio_inb(0x20); /* check chip version */
123 if (t == 0x82) { /* W83627THF */
124 t = (superio_inb(0x2b) & 0xf7);
125 superio_outb(0x2b, t | 0x04); /* set GPIO3 to WDT0 */
126 } else if (t == 0x88 || t == 0xa0) { /* W83627EHF / W83627DHG */
127 t = superio_inb(0x2d);
128 superio_outb(0x2d, t & ~0x01); /* set GPIO5 to WDT0 */
129 }
130 145
131 /* set CR30 bit 0 to activate GPIO2 */ 146 /* set CR30 bit 0 to activate GPIO2 */
132 t = superio_inb(0x30); 147 t = superio_inb(0x30);
133 if (!(t & 0x01)) 148 if (!(t & 0x01))
134 superio_outb(0x30, t | 0x01); 149 superio_outb(0x30, t | 0x01);
135 150
136 t = superio_inb(0xF6); 151 switch (chip) {
152 case w83627hf:
153 case w83627s:
154 t = superio_inb(0x2B) & ~0x10;
155 superio_outb(0x2B, t); /* set GPIO24 to WDT0 */
156 break;
157 case w83697hf:
158 /* Set pin 119 to WDTO# mode (= CR29, WDT0) */
159 t = superio_inb(0x29) & ~0x60;
160 t |= 0x20;
161 superio_outb(0x29, t);
162 break;
163 case w83697ug:
164 /* Set pin 118 to WDTO# mode */
165 t = superio_inb(0x2b) & ~0x04;
166 superio_outb(0x2b, t);
167 break;
168 case w83627thf:
169 t = (superio_inb(0x2B) & ~0x08) | 0x04;
170 superio_outb(0x2B, t); /* set GPIO3 to WDT0 */
171 break;
172 case w83627dhg:
173 case w83627dhg_p:
174 t = superio_inb(0x2D) & ~0x01; /* PIN77 -> WDT0# */
175 superio_outb(0x2D, t); /* set GPIO5 to WDT0 */
176 t = superio_inb(cr_wdt_control);
177 t |= 0x02; /* enable the WDTO# output low pulse
178 * to the KBRST# pin */
179 superio_outb(cr_wdt_control, t);
180 break;
181 case w83637hf:
182 break;
183 case w83687thf:
184 t = superio_inb(0x2C) & ~0x80; /* PIN47 -> WDT0# */
185 superio_outb(0x2C, t);
186 break;
187 case w83627ehf:
188 case w83627uhg:
189 case w83667hg:
190 case w83667hg_b:
191 case nct6775:
192 case nct6776:
193 case nct6779:
194 /*
195 * These chips have a fixed WDTO# output pin (W83627UHG),
196 * or support more than one WDTO# output pin.
197 * Don't touch its configuration, and hope the BIOS
198 * does the right thing.
199 */
200 t = superio_inb(cr_wdt_control);
201 t |= 0x02; /* enable the WDTO# output low pulse
202 * to the KBRST# pin */
203 superio_outb(cr_wdt_control, t);
204 break;
205 default:
206 break;
207 }
208
209 t = superio_inb(cr_wdt_timeout);
137 if (t != 0) { 210 if (t != 0) {
138 pr_info("Watchdog already running. Resetting timeout to %d sec\n", 211 pr_info("Watchdog already running. Resetting timeout to %d sec\n",
139 wdog->timeout); 212 wdog->timeout);
140 superio_outb(0xF6, wdog->timeout); 213 superio_outb(cr_wdt_timeout, wdog->timeout);
141 } 214 }
142 215
143 /* set second mode & disable keyboard turning off watchdog */ 216 /* set second mode & disable keyboard turning off watchdog */
144 t = superio_inb(0xF5) & ~0x0C; 217 t = superio_inb(cr_wdt_control) & ~0x0C;
145 /* enable the WDTO# output low pulse to the KBRST# pin */ 218 superio_outb(cr_wdt_control, t);
146 t |= 0x02;
147 superio_outb(0xF5, t);
148 219
149 /* disable keyboard & mouse turning off watchdog */ 220 /* reset trigger, disable keyboard & mouse turning off watchdog */
150 t = superio_inb(0xF7) & ~0xC0; 221 t = superio_inb(0xF7) & ~0xD0;
151 superio_outb(0xF7, t); 222 superio_outb(0xF7, t);
152 223
153 superio_exit(); 224 superio_exit();
@@ -164,7 +235,7 @@ static int wdt_set_time(unsigned int timeout)
164 return ret; 235 return ret;
165 236
166 superio_select(W83627HF_LD_WDT); 237 superio_select(W83627HF_LD_WDT);
167 superio_outb(0xF6, timeout); 238 superio_outb(cr_wdt_timeout, timeout);
168 superio_exit(); 239 superio_exit();
169 240
170 return 0; 241 return 0;
@@ -197,7 +268,7 @@ static unsigned int wdt_get_time(struct watchdog_device *wdog)
197 return 0; 268 return 0;
198 269
199 superio_select(W83627HF_LD_WDT); 270 superio_select(W83627HF_LD_WDT);
200 timeleft = superio_inb(0xF6); 271 timeleft = superio_inb(cr_wdt_timeout);
201 superio_exit(); 272 superio_exit();
202 273
203 return timeleft; 274 return timeleft;
@@ -249,16 +320,123 @@ static struct notifier_block wdt_notifier = {
249 .notifier_call = wdt_notify_sys, 320 .notifier_call = wdt_notify_sys,
250}; 321};
251 322
323static int wdt_find(int addr)
324{
325 u8 val;
326 int ret;
327
328 cr_wdt_timeout = W83627HF_WDT_TIMEOUT;
329 cr_wdt_control = W83627HF_WDT_CONTROL;
330
331 ret = superio_enter();
332 if (ret)
333 return ret;
334 superio_select(W83627HF_LD_WDT);
335 val = superio_inb(0x20);
336 switch (val) {
337 case W83627HF_ID:
338 ret = w83627hf;
339 break;
340 case W83627S_ID:
341 ret = w83627s;
342 break;
343 case W83697HF_ID:
344 ret = w83697hf;
345 cr_wdt_timeout = W83697HF_WDT_TIMEOUT;
346 cr_wdt_control = W83697HF_WDT_CONTROL;
347 break;
348 case W83697UG_ID:
349 ret = w83697ug;
350 cr_wdt_timeout = W83697HF_WDT_TIMEOUT;
351 cr_wdt_control = W83697HF_WDT_CONTROL;
352 break;
353 case W83637HF_ID:
354 ret = w83637hf;
355 break;
356 case W83627THF_ID:
357 ret = w83627thf;
358 break;
359 case W83687THF_ID:
360 ret = w83687thf;
361 break;
362 case W83627EHF_ID:
363 ret = w83627ehf;
364 break;
365 case W83627DHG_ID:
366 ret = w83627dhg;
367 break;
368 case W83627DHG_P_ID:
369 ret = w83627dhg_p;
370 break;
371 case W83627UHG_ID:
372 ret = w83627uhg;
373 break;
374 case W83667HG_ID:
375 ret = w83667hg;
376 break;
377 case W83667HG_B_ID:
378 ret = w83667hg_b;
379 break;
380 case NCT6775_ID:
381 ret = nct6775;
382 break;
383 case NCT6776_ID:
384 ret = nct6776;
385 break;
386 case NCT6779_ID:
387 ret = nct6779;
388 break;
389 case 0xff:
390 ret = -ENODEV;
391 break;
392 default:
393 ret = -ENODEV;
394 pr_err("Unsupported chip ID: 0x%02x\n", val);
395 break;
396 }
397 superio_exit();
398 return ret;
399}
400
252static int __init wdt_init(void) 401static int __init wdt_init(void)
253{ 402{
254 int ret; 403 int ret;
404 int chip;
405 const char * const chip_name[] = {
406 "W83627HF",
407 "W83627S",
408 "W83697HF",
409 "W83697UG",
410 "W83637HF",
411 "W83627THF",
412 "W83687THF",
413 "W83627EHF",
414 "W83627DHG",
415 "W83627UHG",
416 "W83667HG",
417 "W83667DHG-P",
418 "W83667HG-B",
419 "NCT6775",
420 "NCT6776",
421 "NCT6779",
422 };
423
424 wdt_io = 0x2e;
425 chip = wdt_find(0x2e);
426 if (chip < 0) {
427 wdt_io = 0x4e;
428 chip = wdt_find(0x4e);
429 if (chip < 0)
430 return chip;
431 }
255 432
256 pr_info("WDT driver for the Winbond(TM) W83627HF/THF/HG/DHG Super I/O chip initialising\n"); 433 pr_info("WDT driver for %s Super I/O chip initialising\n",
434 chip_name[chip]);
257 435
258 watchdog_init_timeout(&wdt_dev, timeout, NULL); 436 watchdog_init_timeout(&wdt_dev, timeout, NULL);
259 watchdog_set_nowayout(&wdt_dev, nowayout); 437 watchdog_set_nowayout(&wdt_dev, nowayout);
260 438
261 ret = w83627hf_init(&wdt_dev); 439 ret = w83627hf_init(&wdt_dev, chip);
262 if (ret) { 440 if (ret) {
263 pr_err("failed to initialize watchdog (err=%d)\n", ret); 441 pr_err("failed to initialize watchdog (err=%d)\n", ret);
264 return ret; 442 return ret;
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
index 461336c4519f..cec9b559647d 100644
--- a/drivers/watchdog/watchdog_core.c
+++ b/drivers/watchdog/watchdog_core.c
@@ -78,7 +78,7 @@ int watchdog_init_timeout(struct watchdog_device *wdd,
78 watchdog_check_min_max_timeout(wdd); 78 watchdog_check_min_max_timeout(wdd);
79 79
80 /* try to get the timeout module parameter first */ 80 /* try to get the timeout module parameter first */
81 if (!watchdog_timeout_invalid(wdd, timeout_parm)) { 81 if (!watchdog_timeout_invalid(wdd, timeout_parm) && timeout_parm) {
82 wdd->timeout = timeout_parm; 82 wdd->timeout = timeout_parm;
83 return ret; 83 return ret;
84 } 84 }
@@ -89,7 +89,7 @@ int watchdog_init_timeout(struct watchdog_device *wdd,
89 if (dev == NULL || dev->of_node == NULL) 89 if (dev == NULL || dev->of_node == NULL)
90 return ret; 90 return ret;
91 of_property_read_u32(dev->of_node, "timeout-sec", &t); 91 of_property_read_u32(dev->of_node, "timeout-sec", &t);
92 if (!watchdog_timeout_invalid(wdd, t)) 92 if (!watchdog_timeout_invalid(wdd, t) && t)
93 wdd->timeout = t; 93 wdd->timeout = t;
94 else 94 else
95 ret = -EINVAL; 95 ret = -EINVAL;
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index ee89ba4dea63..3dc578e71211 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -720,7 +720,7 @@ static void wdtpci_remove_one(struct pci_dev *pdev)
720} 720}
721 721
722 722
723static DEFINE_PCI_DEVICE_TABLE(wdtpci_pci_tbl) = { 723static const struct pci_device_id wdtpci_pci_tbl[] = {
724 { 724 {
725 .vendor = PCI_VENDOR_ID_ACCESSIO, 725 .vendor = PCI_VENDOR_ID_ACCESSIO,
726 .device = PCI_DEVICE_ID_ACCESSIO_WDG_CSM, 726 .device = PCI_DEVICE_ID_ACCESSIO_WDG_CSM,