aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-19 22:35:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-19 22:35:51 -0400
commit1e75a9f34a5ed5902707fb74b468356c55142b71 (patch)
tree810ff2a5e9d393242e663b321c8a80a17cebe11d
parent1c3d770043583d99118d52cad309f586ef8e7d4a (diff)
parentd1ed3ba4e3d76b4ebec239c64f990c26d7935700 (diff)
Merge git://www.linux-watchdog.org/linux-watchdog
Pull watchdog updates from Wim Van Sebroeck: - new drivers for: NI 903x/913x watchdog driver, WinSystems EBC-C384 watchdog timer and ARM SBSA watchdog driver - Support for NCT6102D devices - Improvements of the generic watchdog framework (improve restart handler, make set_timeout optional, introduce infrastructure triggered keepalives, ... - improvements on the pnx4008 watchdog driver - several smaller fixes and improvements * git://www.linux-watchdog.org/linux-watchdog: (28 commits) watchdog: Ensure that wdd is not dereferenced if NULL watchdog: imx2: Convert to use infrastructure triggered keepalives watchdog: dw_wdt: Convert to use watchdog infrastructure watchdog: Add support for minimum time between heartbeats watchdog: Make stop function optional watchdog: Introduce WDOG_HW_RUNNING flag watchdog: Introduce hardware maximum heartbeat in watchdog core watchdog: Make set_timeout function optional arm: lpc32xx: remove restart handler arm: lpc32xx: phy3250 remove restart hook watchdog: pnx4008: restart: support "cmd" from userspace watchdog: pnx4008: add support for soft reset watchdog: pnx4008: add restart handler watchdog: pnx4008: update logging during power-on watchdog: tangox_wdt: test clock rate to avoid division by 0 watchdog: atlas7_wdt: test clock rate to avoid division by 0 watchdog: s3c2410_wdt: Add max and min timeout values Watchdog: introduce ARM SBSA watchdog driver Documentation: add sbsa-gwdt driver documentation watchdog: Add watchdog timer support for the WinSystems EBC-C384 ...
-rw-r--r--Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt31
-rw-r--r--Documentation/watchdog/watchdog-kernel-api.txt59
-rw-r--r--Documentation/watchdog/watchdog-parameters.txt12
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arm/mach-lpc32xx/common.c15
-rw-r--r--arch/arm/mach-lpc32xx/common.h1
-rw-r--r--arch/arm/mach-lpc32xx/phy3250.c1
-rw-r--r--drivers/watchdog/Kconfig52
-rw-r--r--drivers/watchdog/Makefile3
-rw-r--r--drivers/watchdog/atlas7_wdt.c5
-rw-r--r--drivers/watchdog/bcm47xx_wdt.c3
-rw-r--r--drivers/watchdog/da9063_wdt.c3
-rw-r--r--drivers/watchdog/digicolor_wdt.c3
-rw-r--r--drivers/watchdog/dw_wdt.c323
-rw-r--r--drivers/watchdog/ebc-c384_wdt.c188
-rw-r--r--drivers/watchdog/imgpdc_wdt.c3
-rw-r--r--drivers/watchdog/imx2_wdt.c77
-rw-r--r--drivers/watchdog/lpc18xx_wdt.c3
-rw-r--r--drivers/watchdog/meson_wdt.c3
-rw-r--r--drivers/watchdog/moxart_wdt.c3
-rw-r--r--drivers/watchdog/mtk_wdt.c3
-rw-r--r--drivers/watchdog/ni903x_wdt.c270
-rw-r--r--drivers/watchdog/pnx4008_wdt.c42
-rw-r--r--drivers/watchdog/qcom-wdt.c3
-rw-r--r--drivers/watchdog/rc32434_wdt.c2
-rw-r--r--drivers/watchdog/s3c2410_wdt.c19
-rw-r--r--drivers/watchdog/sbsa_gwdt.c408
-rw-r--r--drivers/watchdog/sunxi_wdt.c3
-rw-r--r--drivers/watchdog/tangox_wdt.c14
-rw-r--r--drivers/watchdog/w83627hf_wdt.c22
-rw-r--r--drivers/watchdog/watchdog_core.c4
-rw-r--r--drivers/watchdog/watchdog_dev.c207
-rw-r--r--drivers/watchdog/ziirave_wdt.c2
-rw-r--r--include/linux/watchdog.h43
34 files changed, 1482 insertions, 354 deletions
diff --git a/Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt b/Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt
new file mode 100644
index 000000000000..6f2d5f91964d
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt
@@ -0,0 +1,31 @@
1* SBSA (Server Base System Architecture) Generic Watchdog
2
3The SBSA Generic Watchdog Timer is used to force a reset of the system
4after two stages of timeout have elapsed. A detailed definition of the
5watchdog timer can be found in the ARM document: ARM-DEN-0029 - Server
6Base System Architecture (SBSA)
7
8Required properties:
9- compatible: Should at least contain "arm,sbsa-gwdt".
10
11- reg: Each entry specifies the base physical address of a register frame
12 and the length of that frame; currently, two frames must be defined,
13 in this order:
14 1: Watchdog control frame;
15 2: Refresh frame.
16
17- interrupts: Should contain the Watchdog Signal 0 (WS0) SPI (Shared
18 Peripheral Interrupt) number of SBSA Generic Watchdog.
19
20Optional properties
21- timeout-sec: Watchdog timeout values (in seconds).
22
23Example for FVP Foundation Model v8:
24
25watchdog@2a440000 {
26 compatible = "arm,sbsa-gwdt";
27 reg = <0x0 0x2a440000 0 0x1000>,
28 <0x0 0x2a450000 0 0x1000>;
29 interrupts = <0 27 4>;
30 timeout-sec = <30>;
31};
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
index 55120a055a14..917eeeabfa5e 100644
--- a/Documentation/watchdog/watchdog-kernel-api.txt
+++ b/Documentation/watchdog/watchdog-kernel-api.txt
@@ -52,6 +52,8 @@ struct watchdog_device {
52 unsigned int timeout; 52 unsigned int timeout;
53 unsigned int min_timeout; 53 unsigned int min_timeout;
54 unsigned int max_timeout; 54 unsigned int max_timeout;
55 unsigned int min_hw_heartbeat_ms;
56 unsigned int max_hw_heartbeat_ms;
55 struct notifier_block reboot_nb; 57 struct notifier_block reboot_nb;
56 struct notifier_block restart_nb; 58 struct notifier_block restart_nb;
57 void *driver_data; 59 void *driver_data;
@@ -73,8 +75,21 @@ It contains following fields:
73 additional information about the watchdog timer itself. (Like it's unique name) 75 additional information about the watchdog timer itself. (Like it's unique name)
74* ops: a pointer to the list of watchdog operations that the watchdog supports. 76* ops: a pointer to the list of watchdog operations that the watchdog supports.
75* timeout: the watchdog timer's timeout value (in seconds). 77* timeout: the watchdog timer's timeout value (in seconds).
78 This is the time after which the system will reboot if user space does
79 not send a heartbeat request if WDOG_ACTIVE is set.
76* min_timeout: the watchdog timer's minimum timeout value (in seconds). 80* min_timeout: the watchdog timer's minimum timeout value (in seconds).
77* max_timeout: the watchdog timer's maximum timeout value (in seconds). 81 If set, the minimum configurable value for 'timeout'.
82* max_timeout: the watchdog timer's maximum timeout value (in seconds),
83 as seen from userspace. If set, the maximum configurable value for
84 'timeout'. Not used if max_hw_heartbeat_ms is non-zero.
85* min_hw_heartbeat_ms: Minimum time between heartbeats sent to the chip,
86 in milli-seconds.
87* max_hw_heartbeat_ms: Maximum hardware heartbeat, in milli-seconds.
88 If set, the infrastructure will send heartbeats to the watchdog driver
89 if 'timeout' is larger than max_hw_heartbeat_ms, unless WDOG_ACTIVE
90 is set and userspace failed to send a heartbeat for at least 'timeout'
91 seconds. max_hw_heartbeat_ms must be set if a driver does not implement
92 the stop function.
78* reboot_nb: notifier block that is registered for reboot notifications, for 93* reboot_nb: notifier block that is registered for reboot notifications, for
79 internal use only. If the driver calls watchdog_stop_on_reboot, watchdog core 94 internal use only. If the driver calls watchdog_stop_on_reboot, watchdog core
80 will stop the watchdog on such notifications. 95 will stop the watchdog on such notifications.
@@ -123,17 +138,20 @@ are:
123 device. 138 device.
124 The routine needs a pointer to the watchdog timer device structure as a 139 The routine needs a pointer to the watchdog timer device structure as a
125 parameter. It returns zero on success or a negative errno code for failure. 140 parameter. It returns zero on success or a negative errno code for failure.
126* stop: with this routine the watchdog timer device is being stopped.
127 The routine needs a pointer to the watchdog timer device structure as a
128 parameter. It returns zero on success or a negative errno code for failure.
129 Some watchdog timer hardware can only be started and not be stopped. The
130 driver supporting this hardware needs to make sure that a start and stop
131 routine is being provided. This can be done by using a timer in the driver
132 that regularly sends a keepalive ping to the watchdog timer hardware.
133 141
134Not all watchdog timer hardware supports the same functionality. That's why 142Not all watchdog timer hardware supports the same functionality. That's why
135all other routines/operations are optional. They only need to be provided if 143all other routines/operations are optional. They only need to be provided if
136they are supported. These optional routines/operations are: 144they are supported. These optional routines/operations are:
145* stop: with this routine the watchdog timer device is being stopped.
146 The routine needs a pointer to the watchdog timer device structure as a
147 parameter. It returns zero on success or a negative errno code for failure.
148 Some watchdog timer hardware can only be started and not be stopped. A
149 driver supporting such hardware does not have to implement the stop routine.
150 If a driver has no stop function, the watchdog core will set WDOG_HW_RUNNING
151 and start calling the driver's keepalive pings function after the watchdog
152 device is closed.
153 If a watchdog driver does not implement the stop function, it must set
154 max_hw_heartbeat_ms.
137* ping: this is the routine that sends a keepalive ping to the watchdog timer 155* ping: this is the routine that sends a keepalive ping to the watchdog timer
138 hardware. 156 hardware.
139 The routine needs a pointer to the watchdog timer device structure as a 157 The routine needs a pointer to the watchdog timer device structure as a
@@ -153,9 +171,18 @@ they are supported. These optional routines/operations are:
153 and -EIO for "could not write value to the watchdog". On success this 171 and -EIO for "could not write value to the watchdog". On success this
154 routine should set the timeout value of the watchdog_device to the 172 routine should set the timeout value of the watchdog_device to the
155 achieved timeout value (which may be different from the requested one 173 achieved timeout value (which may be different from the requested one
156 because the watchdog does not necessarily has a 1 second resolution). 174 because the watchdog does not necessarily have a 1 second resolution).
175 Drivers implementing max_hw_heartbeat_ms set the hardware watchdog heartbeat
176 to the minimum of timeout and max_hw_heartbeat_ms. Those drivers set the
177 timeout value of the watchdog_device either to the requested timeout value
178 (if it is larger than max_hw_heartbeat_ms), or to the achieved timeout value.
157 (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the 179 (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the
158 watchdog's info structure). 180 watchdog's info structure).
181 If the watchdog driver does not have to perform any action but setting the
182 watchdog_device.timeout, this callback can be omitted.
183 If set_timeout is not provided but, WDIOF_SETTIMEOUT is set, the watchdog
184 infrastructure updates the timeout value of the watchdog_device internally
185 to the requested value.
159* get_timeleft: this routines returns the time that's left before a reset. 186* get_timeleft: this routines returns the time that's left before a reset.
160* restart: this routine restarts the machine. It returns 0 on success or a 187* restart: this routine restarts the machine. It returns 0 on success or a
161 negative errno code for failure. 188 negative errno code for failure.
@@ -169,11 +196,19 @@ The 'ref' and 'unref' operations are no longer used and deprecated.
169The status bits should (preferably) be set with the set_bit and clear_bit alike 196The status bits should (preferably) be set with the set_bit and clear_bit alike
170bit-operations. The status bits that are defined are: 197bit-operations. The status bits that are defined are:
171* WDOG_ACTIVE: this status bit indicates whether or not a watchdog timer device 198* WDOG_ACTIVE: this status bit indicates whether or not a watchdog timer device
172 is active or not. When the watchdog is active after booting, then you should 199 is active or not from user perspective. User space is expected to send
173 set this status bit (Note: when you register the watchdog timer device with 200 heartbeat requests to the driver while this flag is set.
174 this bit set, then opening /dev/watchdog will skip the start operation)
175* WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog. 201* WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog.
176 If this bit is set then the watchdog timer will not be able to stop. 202 If this bit is set then the watchdog timer will not be able to stop.
203* WDOG_HW_RUNNING: Set by the watchdog driver if the hardware watchdog is
204 running. The bit must be set if the watchdog timer hardware can not be
205 stopped. The bit may also be set if the watchdog timer is running after
206 booting, before the watchdog device is opened. If set, the watchdog
207 infrastructure will send keepalives to the watchdog hardware while
208 WDOG_ACTIVE is not set.
209 Note: when you register the watchdog timer device with this bit set,
210 then opening /dev/watchdog will skip the start operation but send a keepalive
211 request instead.
177 212
178 To set the WDOG_NO_WAY_OUT status bit (before registering your watchdog 213 To set the WDOG_NO_WAY_OUT status bit (before registering your watchdog
179 timer device) you can either: 214 timer device) you can either:
diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt
index 4e4b6f10d841..c161399a6b5c 100644
--- a/Documentation/watchdog/watchdog-parameters.txt
+++ b/Documentation/watchdog/watchdog-parameters.txt
@@ -200,6 +200,11 @@ mv64x60_wdt:
200nowayout: Watchdog cannot be stopped once started 200nowayout: Watchdog cannot be stopped once started
201 (default=kernel config parameter) 201 (default=kernel config parameter)
202------------------------------------------------- 202-------------------------------------------------
203ni903x_wdt:
204timeout: Initial watchdog timeout in seconds (0<timeout<516, default=60)
205nowayout: Watchdog cannot be stopped once started
206 (default=kernel config parameter)
207-------------------------------------------------
203nuc900_wdt: 208nuc900_wdt:
204heartbeat: Watchdog heartbeats in seconds. 209heartbeat: Watchdog heartbeats in seconds.
205 (default = 15) 210 (default = 15)
@@ -284,6 +289,13 @@ sbc_fitpc2_wdt:
284margin: Watchdog margin in seconds (default 60s) 289margin: Watchdog margin in seconds (default 60s)
285nowayout: Watchdog cannot be stopped once started 290nowayout: Watchdog cannot be stopped once started
286------------------------------------------------- 291-------------------------------------------------
292sbsa_gwdt:
293timeout: Watchdog timeout in seconds. (default 10s)
294action: Watchdog action at the first stage timeout,
295 set to 0 to ignore, 1 to panic. (default=0)
296nowayout: Watchdog cannot be stopped once started
297 (default=kernel config parameter)
298-------------------------------------------------
287sc1200wdt: 299sc1200wdt:
288isapnp: When set to 0 driver ISA PnP support will be disabled (default=1) 300isapnp: When set to 0 driver ISA PnP support will be disabled (default=1)
289io: io port 301io: io port
diff --git a/MAINTAINERS b/MAINTAINERS
index 0cbfc69a2303..606528bb16af 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11965,6 +11965,12 @@ M: David Härdeman <david@hardeman.nu>
11965S: Maintained 11965S: Maintained
11966F: drivers/media/rc/winbond-cir.c 11966F: drivers/media/rc/winbond-cir.c
11967 11967
11968WINSYSTEMS EBC-C384 WATCHDOG DRIVER
11969M: William Breathitt Gray <vilhelm.gray@gmail.com>
11970L: linux-watchdog@vger.kernel.org
11971S: Maintained
11972F: drivers/watchdog/ebc-c384_wdt.c
11973
11968WINSYSTEMS WS16C48 GPIO DRIVER 11974WINSYSTEMS WS16C48 GPIO DRIVER
11969M: William Breathitt Gray <vilhelm.gray@gmail.com> 11975M: William Breathitt Gray <vilhelm.gray@gmail.com>
11970L: linux-gpio@vger.kernel.org 11976L: linux-gpio@vger.kernel.org
diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c
index 716e83eb1db8..5b7a1e78c3a5 100644
--- a/arch/arm/mach-lpc32xx/common.c
+++ b/arch/arm/mach-lpc32xx/common.c
@@ -194,21 +194,6 @@ void __init lpc32xx_map_io(void)
194 iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc)); 194 iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc));
195} 195}
196 196
197void lpc23xx_restart(enum reboot_mode mode, const char *cmd)
198{
199 /* Make sure WDT clocks are enabled */
200 __raw_writel(LPC32XX_CLKPWR_PWMCLK_WDOG_EN,
201 LPC32XX_CLKPWR_TIMER_CLK_CTRL);
202
203 /* Instant assert of RESETOUT_N with pulse length 1mS */
204 __raw_writel(13000, io_p2v(LPC32XX_WDTIM_BASE + 0x18));
205 __raw_writel(0x70, io_p2v(LPC32XX_WDTIM_BASE + 0xC));
206
207 /* Wait for watchdog to reset system */
208 while (1)
209 ;
210}
211
212static int __init lpc32xx_check_uid(void) 197static int __init lpc32xx_check_uid(void)
213{ 198{
214 u32 uid[4]; 199 u32 uid[4];
diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h
index 1cd8853b2f9b..2d90801ed1e1 100644
--- a/arch/arm/mach-lpc32xx/common.h
+++ b/arch/arm/mach-lpc32xx/common.h
@@ -30,7 +30,6 @@ extern void lpc32xx_timer_init(void);
30extern void __init lpc32xx_init_irq(void); 30extern void __init lpc32xx_init_irq(void);
31extern void __init lpc32xx_map_io(void); 31extern void __init lpc32xx_map_io(void);
32extern void __init lpc32xx_serial_init(void); 32extern void __init lpc32xx_serial_init(void);
33extern void lpc23xx_restart(enum reboot_mode, const char *);
34 33
35 34
36/* 35/*
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index ee06fabdf60e..e6f03783ad73 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -262,5 +262,4 @@ DT_MACHINE_START(LPC32XX_DT, "LPC32XX SoC (Flattened Device Tree)")
262 .init_time = lpc32xx_timer_init, 262 .init_time = lpc32xx_timer_init,
263 .init_machine = lpc3250_machine_init, 263 .init_machine = lpc3250_machine_init,
264 .dt_compat = lpc32xx_dt_compat, 264 .dt_compat = lpc32xx_dt_compat,
265 .restart = lpc23xx_restart,
266MACHINE_END 265MACHINE_END
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 9289da313d98..fb947655badd 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -202,6 +202,26 @@ config ARM_SP805_WATCHDOG
202 ARM Primecell SP805 Watchdog timer. This will reboot your system when 202 ARM Primecell SP805 Watchdog timer. This will reboot your system when
203 the timeout is reached. 203 the timeout is reached.
204 204
205config ARM_SBSA_WATCHDOG
206 tristate "ARM SBSA Generic Watchdog"
207 depends on ARM64
208 depends on ARM_ARCH_TIMER
209 select WATCHDOG_CORE
210 help
211 ARM SBSA Generic Watchdog has two stage timeouts:
212 the first signal (WS0) is for alerting the system by interrupt,
213 the second one (WS1) is a real hardware reset.
214 More details: ARM DEN0029B - Server Base System Architecture (SBSA)
215
216 This driver can operate ARM SBSA Generic Watchdog as a single stage
217 or a two stages watchdog, it depends on the module parameter "action".
218
219 Note: the maximum timeout in the two stages mode is half of that in
220 the single stage mode.
221
222 To compile this driver as module, choose M here: The module
223 will be called sbsa_gwdt.
224
205config ASM9260_WATCHDOG 225config ASM9260_WATCHDOG
206 tristate "Alphascale ASM9260 watchdog" 226 tristate "Alphascale ASM9260 watchdog"
207 depends on MACH_ASM9260 227 depends on MACH_ASM9260
@@ -330,6 +350,7 @@ config SA1100_WATCHDOG
330config DW_WATCHDOG 350config DW_WATCHDOG
331 tristate "Synopsys DesignWare watchdog" 351 tristate "Synopsys DesignWare watchdog"
332 depends on HAS_IOMEM 352 depends on HAS_IOMEM
353 select WATCHDOG_CORE
333 help 354 help
334 Say Y here if to include support for the Synopsys DesignWare 355 Say Y here if to include support for the Synopsys DesignWare
335 watchdog timer found in many chips. 356 watchdog timer found in many chips.
@@ -399,6 +420,7 @@ config DAVINCI_WATCHDOG
399config ORION_WATCHDOG 420config ORION_WATCHDOG
400 tristate "Orion watchdog" 421 tristate "Orion watchdog"
401 depends on ARCH_ORION5X || ARCH_DOVE || MACH_DOVE || ARCH_MVEBU 422 depends on ARCH_ORION5X || ARCH_DOVE || MACH_DOVE || ARCH_MVEBU
423 depends on ARM
402 select WATCHDOG_CORE 424 select WATCHDOG_CORE
403 help 425 help
404 Say Y here if to include support for the watchdog timer 426 Say Y here if to include support for the watchdog timer
@@ -468,6 +490,7 @@ config NUC900_WATCHDOG
468config TS4800_WATCHDOG 490config TS4800_WATCHDOG
469 tristate "TS-4800 Watchdog" 491 tristate "TS-4800 Watchdog"
470 depends on HAS_IOMEM && OF 492 depends on HAS_IOMEM && OF
493 depends on SOC_IMX51 || COMPILE_TEST
471 select WATCHDOG_CORE 494 select WATCHDOG_CORE
472 select MFD_SYSCON 495 select MFD_SYSCON
473 help 496 help
@@ -713,6 +736,15 @@ config ALIM7101_WDT
713 736
714 Most people will say N. 737 Most people will say N.
715 738
739config EBC_C384_WDT
740 tristate "WinSystems EBC-C384 Watchdog Timer"
741 depends on X86
742 select WATCHDOG_CORE
743 help
744 Enables watchdog timer support for the watchdog timer on the
745 WinSystems EBC-C384 motherboard. The timeout may be configured via
746 the timeout module parameter.
747
716config F71808E_WDT 748config F71808E_WDT
717 tristate "Fintek F71808E, F71862FG, F71869, F71882FG and F71889FG Watchdog" 749 tristate "Fintek F71808E, F71862FG, F71869, F71882FG and F71889FG Watchdog"
718 depends on X86 750 depends on X86
@@ -1142,6 +1174,7 @@ config W83627HF_WDT
1142 NCT6779 1174 NCT6779
1143 NCT6791 1175 NCT6791
1144 NCT6792 1176 NCT6792
1177 NCT6102D/04D/06D
1145 1178
1146 This watchdog simply watches your kernel to make sure it doesn't 1179 This watchdog simply watches your kernel to make sure it doesn't
1147 freeze, and if it does, it reboots your computer after a certain 1180 freeze, and if it does, it reboots your computer after a certain
@@ -1229,6 +1262,17 @@ config INTEL_MEI_WDT
1229 To compile this driver as a module, choose M here: 1262 To compile this driver as a module, choose M here:
1230 the module will be called mei_wdt. 1263 the module will be called mei_wdt.
1231 1264
1265config NI903X_WDT
1266 tristate "NI 903x/913x Watchdog"
1267 depends on X86 && ACPI
1268 select WATCHDOG_CORE
1269 ---help---
1270 This is the driver for the watchdog timer on the National Instruments
1271 903x/913x real-time controllers.
1272
1273 To compile this driver as a module, choose M here: the module will be
1274 called ni903x_wdt.
1275
1232# M32R Architecture 1276# M32R Architecture
1233 1277
1234# M68K Architecture 1278# M68K Architecture
@@ -1392,10 +1436,12 @@ config BCM7038_WDT
1392 tristate "BCM7038 Watchdog" 1436 tristate "BCM7038 Watchdog"
1393 select WATCHDOG_CORE 1437 select WATCHDOG_CORE
1394 depends on HAS_IOMEM 1438 depends on HAS_IOMEM
1439 depends on ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST
1395 help 1440 help
1396 Watchdog driver for the built-in hardware in Broadcom 7038 SoCs. 1441 Watchdog driver for the built-in hardware in Broadcom 7038 and
1397 1442 later SoCs used in set-top boxes. BCM7038 was made public
1398 Say 'Y or 'M' here to enable the driver. 1443 during the 2004 CES, and since then, many Broadcom chips use this
1444 watchdog block, including some cable modem chips.
1399 1445
1400config IMGPDC_WDT 1446config IMGPDC_WDT
1401 tristate "Imagination Technologies PDC Watchdog Timer" 1447 tristate "Imagination Technologies PDC Watchdog Timer"
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 14bd772d3e66..feb6270fdbde 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
30 30
31# ARM Architecture 31# ARM Architecture
32obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o 32obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
33obj-$(CONFIG_ARM_SBSA_WATCHDOG) += sbsa_gwdt.o
33obj-$(CONFIG_ASM9260_WATCHDOG) += asm9260_wdt.o 34obj-$(CONFIG_ASM9260_WATCHDOG) += asm9260_wdt.o
34obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o 35obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
35obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o 36obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
@@ -88,6 +89,7 @@ obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
88obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o 89obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
89obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o 90obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
90obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o 91obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
92obj-$(CONFIG_EBC_C384_WDT) += ebc-c384_wdt.o
91obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o 93obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
92obj-$(CONFIG_SP5100_TCO) += sp5100_tco.o 94obj-$(CONFIG_SP5100_TCO) += sp5100_tco.o
93obj-$(CONFIG_GEODE_WDT) += geodewdt.o 95obj-$(CONFIG_GEODE_WDT) += geodewdt.o
@@ -127,6 +129,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
127obj-$(CONFIG_INTEL_SCU_WATCHDOG) += intel_scu_watchdog.o 129obj-$(CONFIG_INTEL_SCU_WATCHDOG) += intel_scu_watchdog.o
128obj-$(CONFIG_INTEL_MID_WATCHDOG) += intel-mid_wdt.o 130obj-$(CONFIG_INTEL_MID_WATCHDOG) += intel-mid_wdt.o
129obj-$(CONFIG_INTEL_MEI_WDT) += mei_wdt.o 131obj-$(CONFIG_INTEL_MEI_WDT) += mei_wdt.o
132obj-$(CONFIG_NI903X_WDT) += ni903x_wdt.o
130 133
131# M32R Architecture 134# M32R Architecture
132 135
diff --git a/drivers/watchdog/atlas7_wdt.c b/drivers/watchdog/atlas7_wdt.c
index df6d9242a319..ed80734befae 100644
--- a/drivers/watchdog/atlas7_wdt.c
+++ b/drivers/watchdog/atlas7_wdt.c
@@ -154,6 +154,11 @@ static int atlas7_wdt_probe(struct platform_device *pdev)
154 writel(0, wdt->base + ATLAS7_WDT_CNT_CTRL); 154 writel(0, wdt->base + ATLAS7_WDT_CNT_CTRL);
155 155
156 wdt->tick_rate = clk_get_rate(clk); 156 wdt->tick_rate = clk_get_rate(clk);
157 if (!wdt->tick_rate) {
158 ret = -EINVAL;
159 goto err1;
160 }
161
157 wdt->clk = clk; 162 wdt->clk = clk;
158 atlas7_wdd.min_timeout = 1; 163 atlas7_wdd.min_timeout = 1;
159 atlas7_wdd.max_timeout = UINT_MAX / wdt->tick_rate; 164 atlas7_wdd.max_timeout = UINT_MAX / wdt->tick_rate;
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index df1c2a4b0165..a1900b9ab6c4 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -87,7 +87,8 @@ static int bcm47xx_wdt_hard_set_timeout(struct watchdog_device *wdd,
87 return 0; 87 return 0;
88} 88}
89 89
90static int bcm47xx_wdt_restart(struct watchdog_device *wdd) 90static int bcm47xx_wdt_restart(struct watchdog_device *wdd,
91 unsigned long action, void *data)
91{ 92{
92 struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd); 93 struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
93 94
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c
index 11e887572649..a100f648880d 100644
--- a/drivers/watchdog/da9063_wdt.c
+++ b/drivers/watchdog/da9063_wdt.c
@@ -119,7 +119,8 @@ static int da9063_wdt_set_timeout(struct watchdog_device *wdd,
119 return ret; 119 return ret;
120} 120}
121 121
122static int da9063_wdt_restart(struct watchdog_device *wdd) 122static int da9063_wdt_restart(struct watchdog_device *wdd, unsigned long action,
123 void *data)
123{ 124{
124 struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd); 125 struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd);
125 int ret; 126 int ret;
diff --git a/drivers/watchdog/digicolor_wdt.c b/drivers/watchdog/digicolor_wdt.c
index 1ccb0b239348..77df772406b0 100644
--- a/drivers/watchdog/digicolor_wdt.c
+++ b/drivers/watchdog/digicolor_wdt.c
@@ -48,7 +48,8 @@ static void dc_wdt_set(struct dc_wdt *wdt, u32 ticks)
48 spin_unlock_irqrestore(&wdt->lock, flags); 48 spin_unlock_irqrestore(&wdt->lock, flags);
49} 49}
50 50
51static int dc_wdt_restart(struct watchdog_device *wdog) 51static int dc_wdt_restart(struct watchdog_device *wdog, unsigned long action,
52 void *data)
52{ 53{
53 struct dc_wdt *wdt = watchdog_get_drvdata(wdog); 54 struct dc_wdt *wdt = watchdog_get_drvdata(wdog);
54 55
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index 8fefa4ad46d4..2acb51cf5504 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -12,9 +12,8 @@
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
15 * use a software timer to implement a ping that will keep the watchdog alive. 15 * do not implement a stop function. The watchdog core will continue to send
16 * If we receive an expected close for the watchdog then we keep the timer 16 * heartbeat requests after the watchdog device has been closed.
17 * running, otherwise the timer is stopped and the watchdog will expire.
18 */ 17 */
19 18
20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -22,12 +21,9 @@
22#include <linux/bitops.h> 21#include <linux/bitops.h>
23#include <linux/clk.h> 22#include <linux/clk.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <linux/device.h>
26#include <linux/err.h> 24#include <linux/err.h>
27#include <linux/fs.h>
28#include <linux/io.h> 25#include <linux/io.h>
29#include <linux/kernel.h> 26#include <linux/kernel.h>
30#include <linux/miscdevice.h>
31#include <linux/module.h> 27#include <linux/module.h>
32#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
33#include <linux/notifier.h> 29#include <linux/notifier.h>
@@ -35,8 +31,6 @@
35#include <linux/pm.h> 31#include <linux/pm.h>
36#include <linux/platform_device.h> 32#include <linux/platform_device.h>
37#include <linux/reboot.h> 33#include <linux/reboot.h>
38#include <linux/timer.h>
39#include <linux/uaccess.h>
40#include <linux/watchdog.h> 34#include <linux/watchdog.h>
41 35
42#define WDOG_CONTROL_REG_OFFSET 0x00 36#define WDOG_CONTROL_REG_OFFSET 0x00
@@ -57,53 +51,50 @@ module_param(nowayout, bool, 0);
57MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " 51MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
58 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 52 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
59 53
60#define WDT_TIMEOUT (HZ / 2) 54struct dw_wdt {
61
62static struct {
63 void __iomem *regs; 55 void __iomem *regs;
64 struct clk *clk; 56 struct clk *clk;
65 unsigned long in_use;
66 unsigned long next_heartbeat;
67 struct timer_list timer;
68 int expect_close;
69 struct notifier_block restart_handler; 57 struct notifier_block restart_handler;
70} dw_wdt; 58 struct watchdog_device wdd;
59};
60
61#define to_dw_wdt(wdd) container_of(wdd, struct dw_wdt, wdd)
71 62
72static inline int dw_wdt_is_enabled(void) 63static inline int dw_wdt_is_enabled(struct dw_wdt *dw_wdt)
73{ 64{
74 return readl(dw_wdt.regs + WDOG_CONTROL_REG_OFFSET) & 65 return readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET) &
75 WDOG_CONTROL_REG_WDT_EN_MASK; 66 WDOG_CONTROL_REG_WDT_EN_MASK;
76} 67}
77 68
78static inline int dw_wdt_top_in_seconds(unsigned top) 69static inline int dw_wdt_top_in_seconds(struct dw_wdt *dw_wdt, unsigned top)
79{ 70{
80 /* 71 /*
81 * There are 16 possible timeout values in 0..15 where the number of 72 * There are 16 possible timeout values in 0..15 where the number of
82 * cycles is 2 ^ (16 + i) and the watchdog counts down. 73 * cycles is 2 ^ (16 + i) and the watchdog counts down.
83 */ 74 */
84 return (1U << (16 + top)) / clk_get_rate(dw_wdt.clk); 75 return (1U << (16 + top)) / clk_get_rate(dw_wdt->clk);
85} 76}
86 77
87static int dw_wdt_get_top(void) 78static int dw_wdt_get_top(struct dw_wdt *dw_wdt)
88{ 79{
89 int top = readl(dw_wdt.regs + WDOG_TIMEOUT_RANGE_REG_OFFSET) & 0xF; 80 int top = readl(dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET) & 0xF;
90 81
91 return dw_wdt_top_in_seconds(top); 82 return dw_wdt_top_in_seconds(dw_wdt, top);
92} 83}
93 84
94static inline void dw_wdt_set_next_heartbeat(void) 85static int dw_wdt_ping(struct watchdog_device *wdd)
95{ 86{
96 dw_wdt.next_heartbeat = jiffies + dw_wdt_get_top() * HZ; 87 struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
97}
98 88
99static void dw_wdt_keepalive(void) 89 writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt->regs +
100{
101 writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt.regs +
102 WDOG_COUNTER_RESTART_REG_OFFSET); 90 WDOG_COUNTER_RESTART_REG_OFFSET);
91
92 return 0;
103} 93}
104 94
105static int dw_wdt_set_top(unsigned top_s) 95static int dw_wdt_set_timeout(struct watchdog_device *wdd, unsigned int top_s)
106{ 96{
97 struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
107 int i, top_val = DW_WDT_MAX_TOP; 98 int i, top_val = DW_WDT_MAX_TOP;
108 99
109 /* 100 /*
@@ -111,7 +102,7 @@ static int dw_wdt_set_top(unsigned top_s)
111 * always look for >=. 102 * always look for >=.
112 */ 103 */
113 for (i = 0; i <= DW_WDT_MAX_TOP; ++i) 104 for (i = 0; i <= DW_WDT_MAX_TOP; ++i)
114 if (dw_wdt_top_in_seconds(i) >= top_s) { 105 if (dw_wdt_top_in_seconds(dw_wdt, i) >= top_s) {
115 top_val = i; 106 top_val = i;
116 break; 107 break;
117 } 108 }
@@ -123,33 +114,43 @@ static int dw_wdt_set_top(unsigned top_s)
123 * effectively get a pat of the watchdog right here. 114 * effectively get a pat of the watchdog right here.
124 */ 115 */
125 writel(top_val | top_val << WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT, 116 writel(top_val | top_val << WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT,
126 dw_wdt.regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); 117 dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
127 118
128 /* 119 wdd->timeout = dw_wdt_top_in_seconds(dw_wdt, top_val);
129 * Add an explicit pat to handle versions of the watchdog that
130 * don't have TOPINIT. This won't hurt on versions that have
131 * it.
132 */
133 dw_wdt_keepalive();
134 120
135 dw_wdt_set_next_heartbeat(); 121 return 0;
122}
123
124static int dw_wdt_start(struct watchdog_device *wdd)
125{
126 struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
127
128 dw_wdt_set_timeout(wdd, wdd->timeout);
136 129
137 return dw_wdt_top_in_seconds(top_val); 130 set_bit(WDOG_HW_RUNNING, &wdd->status);
131
132 writel(WDOG_CONTROL_REG_WDT_EN_MASK,
133 dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
134
135 return 0;
138} 136}
139 137
140static int dw_wdt_restart_handle(struct notifier_block *this, 138static int dw_wdt_restart_handle(struct notifier_block *this,
141 unsigned long mode, void *cmd) 139 unsigned long mode, void *cmd)
142{ 140{
141 struct dw_wdt *dw_wdt;
143 u32 val; 142 u32 val;
144 143
145 writel(0, dw_wdt.regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); 144 dw_wdt = container_of(this, struct dw_wdt, restart_handler);
146 val = readl(dw_wdt.regs + WDOG_CONTROL_REG_OFFSET); 145
146 writel(0, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
147 val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
147 if (val & WDOG_CONTROL_REG_WDT_EN_MASK) 148 if (val & WDOG_CONTROL_REG_WDT_EN_MASK)
148 writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt.regs + 149 writel(WDOG_COUNTER_RESTART_KICK_VALUE,
149 WDOG_COUNTER_RESTART_REG_OFFSET); 150 dw_wdt->regs + WDOG_COUNTER_RESTART_REG_OFFSET);
150 else 151 else
151 writel(WDOG_CONTROL_REG_WDT_EN_MASK, 152 writel(WDOG_CONTROL_REG_WDT_EN_MASK,
152 dw_wdt.regs + WDOG_CONTROL_REG_OFFSET); 153 dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
153 154
154 /* wait for reset to assert... */ 155 /* wait for reset to assert... */
155 mdelay(500); 156 mdelay(500);
@@ -157,74 +158,12 @@ static int dw_wdt_restart_handle(struct notifier_block *this,
157 return NOTIFY_DONE; 158 return NOTIFY_DONE;
158} 159}
159 160
160static void dw_wdt_ping(unsigned long data) 161static unsigned int dw_wdt_get_timeleft(struct watchdog_device *wdd)
161{ 162{
162 if (time_before(jiffies, dw_wdt.next_heartbeat) || 163 struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
163 (!nowayout && !dw_wdt.in_use)) {
164 dw_wdt_keepalive();
165 mod_timer(&dw_wdt.timer, jiffies + WDT_TIMEOUT);
166 } else
167 pr_crit("keepalive missed, machine will reset\n");
168}
169
170static int dw_wdt_open(struct inode *inode, struct file *filp)
171{
172 if (test_and_set_bit(0, &dw_wdt.in_use))
173 return -EBUSY;
174
175 /* Make sure we don't get unloaded. */
176 __module_get(THIS_MODULE);
177
178 if (!dw_wdt_is_enabled()) {
179 /*
180 * The watchdog is not currently enabled. Set the timeout to
181 * something reasonable and then start it.
182 */
183 dw_wdt_set_top(DW_WDT_DEFAULT_SECONDS);
184 writel(WDOG_CONTROL_REG_WDT_EN_MASK,
185 dw_wdt.regs + WDOG_CONTROL_REG_OFFSET);
186 }
187
188 dw_wdt_set_next_heartbeat();
189
190 return nonseekable_open(inode, filp);
191}
192
193static ssize_t dw_wdt_write(struct file *filp, const char __user *buf,
194 size_t len, loff_t *offset)
195{
196 if (!len)
197 return 0;
198
199 if (!nowayout) {
200 size_t i;
201
202 dw_wdt.expect_close = 0;
203
204 for (i = 0; i < len; ++i) {
205 char c;
206
207 if (get_user(c, buf + i))
208 return -EFAULT;
209
210 if (c == 'V') {
211 dw_wdt.expect_close = 1;
212 break;
213 }
214 }
215 }
216 164
217 dw_wdt_set_next_heartbeat(); 165 return readl(dw_wdt->regs + WDOG_CURRENT_COUNT_REG_OFFSET) /
218 dw_wdt_keepalive(); 166 clk_get_rate(dw_wdt->clk);
219 mod_timer(&dw_wdt.timer, jiffies + WDT_TIMEOUT);
220
221 return len;
222}
223
224static u32 dw_wdt_time_left(void)
225{
226 return readl(dw_wdt.regs + WDOG_CURRENT_COUNT_REG_OFFSET) /
227 clk_get_rate(dw_wdt.clk);
228} 167}
229 168
230static const struct watchdog_info dw_wdt_ident = { 169static const struct watchdog_info dw_wdt_ident = {
@@ -233,78 +172,33 @@ static const struct watchdog_info dw_wdt_ident = {
233 .identity = "Synopsys DesignWare Watchdog", 172 .identity = "Synopsys DesignWare Watchdog",
234}; 173};
235 174
236static long dw_wdt_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 175static const struct watchdog_ops dw_wdt_ops = {
237{ 176 .owner = THIS_MODULE,
238 unsigned long val; 177 .start = dw_wdt_start,
239 int timeout; 178 .ping = dw_wdt_ping,
240 179 .set_timeout = dw_wdt_set_timeout,
241 switch (cmd) { 180 .get_timeleft = dw_wdt_get_timeleft,
242 case WDIOC_GETSUPPORT: 181};
243 return copy_to_user((void __user *)arg, &dw_wdt_ident,
244 sizeof(dw_wdt_ident)) ? -EFAULT : 0;
245
246 case WDIOC_GETSTATUS:
247 case WDIOC_GETBOOTSTATUS:
248 return put_user(0, (int __user *)arg);
249
250 case WDIOC_KEEPALIVE:
251 dw_wdt_set_next_heartbeat();
252 return 0;
253
254 case WDIOC_SETTIMEOUT:
255 if (get_user(val, (int __user *)arg))
256 return -EFAULT;
257 timeout = dw_wdt_set_top(val);
258 return put_user(timeout , (int __user *)arg);
259
260 case WDIOC_GETTIMEOUT:
261 return put_user(dw_wdt_get_top(), (int __user *)arg);
262
263 case WDIOC_GETTIMELEFT:
264 /* Get the time left until expiry. */
265 if (get_user(val, (int __user *)arg))
266 return -EFAULT;
267 return put_user(dw_wdt_time_left(), (int __user *)arg);
268
269 default:
270 return -ENOTTY;
271 }
272}
273
274static int dw_wdt_release(struct inode *inode, struct file *filp)
275{
276 clear_bit(0, &dw_wdt.in_use);
277
278 if (!dw_wdt.expect_close) {
279 del_timer(&dw_wdt.timer);
280
281 if (!nowayout)
282 pr_crit("unexpected close, system will reboot soon\n");
283 else
284 pr_crit("watchdog cannot be disabled, system will reboot soon\n");
285 }
286
287 dw_wdt.expect_close = 0;
288
289 return 0;
290}
291 182
292#ifdef CONFIG_PM_SLEEP 183#ifdef CONFIG_PM_SLEEP
293static int dw_wdt_suspend(struct device *dev) 184static int dw_wdt_suspend(struct device *dev)
294{ 185{
295 clk_disable_unprepare(dw_wdt.clk); 186 struct dw_wdt *dw_wdt = dev_get_drvdata(dev);
187
188 clk_disable_unprepare(dw_wdt->clk);
296 189
297 return 0; 190 return 0;
298} 191}
299 192
300static int dw_wdt_resume(struct device *dev) 193static int dw_wdt_resume(struct device *dev)
301{ 194{
302 int err = clk_prepare_enable(dw_wdt.clk); 195 struct dw_wdt *dw_wdt = dev_get_drvdata(dev);
196 int err = clk_prepare_enable(dw_wdt->clk);
303 197
304 if (err) 198 if (err)
305 return err; 199 return err;
306 200
307 dw_wdt_keepalive(); 201 dw_wdt_ping(&dw_wdt->wdd);
308 202
309 return 0; 203 return 0;
310} 204}
@@ -312,67 +206,82 @@ static int dw_wdt_resume(struct device *dev)
312 206
313static SIMPLE_DEV_PM_OPS(dw_wdt_pm_ops, dw_wdt_suspend, dw_wdt_resume); 207static SIMPLE_DEV_PM_OPS(dw_wdt_pm_ops, dw_wdt_suspend, dw_wdt_resume);
314 208
315static const struct file_operations wdt_fops = {
316 .owner = THIS_MODULE,
317 .llseek = no_llseek,
318 .open = dw_wdt_open,
319 .write = dw_wdt_write,
320 .unlocked_ioctl = dw_wdt_ioctl,
321 .release = dw_wdt_release
322};
323
324static struct miscdevice dw_wdt_miscdev = {
325 .fops = &wdt_fops,
326 .name = "watchdog",
327 .minor = WATCHDOG_MINOR,
328};
329
330static int dw_wdt_drv_probe(struct platform_device *pdev) 209static int dw_wdt_drv_probe(struct platform_device *pdev)
331{ 210{
211 struct device *dev = &pdev->dev;
212 struct watchdog_device *wdd;
213 struct dw_wdt *dw_wdt;
214 struct resource *mem;
332 int ret; 215 int ret;
333 struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
334 216
335 dw_wdt.regs = devm_ioremap_resource(&pdev->dev, mem); 217 dw_wdt = devm_kzalloc(dev, sizeof(*dw_wdt), GFP_KERNEL);
336 if (IS_ERR(dw_wdt.regs)) 218 if (!dw_wdt)
337 return PTR_ERR(dw_wdt.regs); 219 return -ENOMEM;
220
221 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
222 dw_wdt->regs = devm_ioremap_resource(dev, mem);
223 if (IS_ERR(dw_wdt->regs))
224 return PTR_ERR(dw_wdt->regs);
338 225
339 dw_wdt.clk = devm_clk_get(&pdev->dev, NULL); 226 dw_wdt->clk = devm_clk_get(dev, NULL);
340 if (IS_ERR(dw_wdt.clk)) 227 if (IS_ERR(dw_wdt->clk))
341 return PTR_ERR(dw_wdt.clk); 228 return PTR_ERR(dw_wdt->clk);
342 229
343 ret = clk_prepare_enable(dw_wdt.clk); 230 ret = clk_prepare_enable(dw_wdt->clk);
344 if (ret) 231 if (ret)
345 return ret; 232 return ret;
346 233
347 ret = misc_register(&dw_wdt_miscdev); 234 wdd = &dw_wdt->wdd;
235 wdd->info = &dw_wdt_ident;
236 wdd->ops = &dw_wdt_ops;
237 wdd->min_timeout = 1;
238 wdd->max_hw_heartbeat_ms =
239 dw_wdt_top_in_seconds(dw_wdt, DW_WDT_MAX_TOP) * 1000;
240 wdd->parent = dev;
241
242 watchdog_set_drvdata(wdd, dw_wdt);
243 watchdog_set_nowayout(wdd, nowayout);
244 watchdog_init_timeout(wdd, 0, dev);
245
246 /*
247 * If the watchdog is already running, use its already configured
248 * timeout. Otherwise use the default or the value provided through
249 * devicetree.
250 */
251 if (dw_wdt_is_enabled(dw_wdt)) {
252 wdd->timeout = dw_wdt_get_top(dw_wdt);
253 set_bit(WDOG_HW_RUNNING, &wdd->status);
254 } else {
255 wdd->timeout = DW_WDT_DEFAULT_SECONDS;
256 watchdog_init_timeout(wdd, 0, dev);
257 }
258
259 platform_set_drvdata(pdev, dw_wdt);
260
261 ret = watchdog_register_device(wdd);
348 if (ret) 262 if (ret)
349 goto out_disable_clk; 263 goto out_disable_clk;
350 264
351 dw_wdt.restart_handler.notifier_call = dw_wdt_restart_handle; 265 dw_wdt->restart_handler.notifier_call = dw_wdt_restart_handle;
352 dw_wdt.restart_handler.priority = 128; 266 dw_wdt->restart_handler.priority = 128;
353 ret = register_restart_handler(&dw_wdt.restart_handler); 267 ret = register_restart_handler(&dw_wdt->restart_handler);
354 if (ret) 268 if (ret)
355 pr_warn("cannot register restart handler\n"); 269 pr_warn("cannot register restart handler\n");
356 270
357 dw_wdt_set_next_heartbeat();
358 setup_timer(&dw_wdt.timer, dw_wdt_ping, 0);
359 mod_timer(&dw_wdt.timer, jiffies + WDT_TIMEOUT);
360
361 return 0; 271 return 0;
362 272
363out_disable_clk: 273out_disable_clk:
364 clk_disable_unprepare(dw_wdt.clk); 274 clk_disable_unprepare(dw_wdt->clk);
365
366 return ret; 275 return ret;
367} 276}
368 277
369static int dw_wdt_drv_remove(struct platform_device *pdev) 278static int dw_wdt_drv_remove(struct platform_device *pdev)
370{ 279{
371 unregister_restart_handler(&dw_wdt.restart_handler); 280 struct dw_wdt *dw_wdt = platform_get_drvdata(pdev);
372
373 misc_deregister(&dw_wdt_miscdev);
374 281
375 clk_disable_unprepare(dw_wdt.clk); 282 unregister_restart_handler(&dw_wdt->restart_handler);
283 watchdog_unregister_device(&dw_wdt->wdd);
284 clk_disable_unprepare(dw_wdt->clk);
376 285
377 return 0; 286 return 0;
378} 287}
diff --git a/drivers/watchdog/ebc-c384_wdt.c b/drivers/watchdog/ebc-c384_wdt.c
new file mode 100644
index 000000000000..77fda0b4b90e
--- /dev/null
+++ b/drivers/watchdog/ebc-c384_wdt.c
@@ -0,0 +1,188 @@
1/*
2 * Watchdog timer driver for the WinSystems EBC-C384
3 * Copyright (C) 2016 William Breathitt Gray
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2, as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 */
14#include <linux/device.h>
15#include <linux/dmi.h>
16#include <linux/errno.h>
17#include <linux/io.h>
18#include <linux/ioport.h>
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/moduleparam.h>
22#include <linux/platform_device.h>
23#include <linux/types.h>
24#include <linux/watchdog.h>
25
26#define MODULE_NAME "ebc-c384_wdt"
27#define WATCHDOG_TIMEOUT 60
28/*
29 * The timeout value in minutes must fit in a single byte when sent to the
30 * watchdog timer; the maximum timeout possible is 15300 (255 * 60) seconds.
31 */
32#define WATCHDOG_MAX_TIMEOUT 15300
33#define BASE_ADDR 0x564
34#define ADDR_EXTENT 5
35#define CFG_ADDR (BASE_ADDR + 1)
36#define PET_ADDR (BASE_ADDR + 2)
37
38static bool nowayout = WATCHDOG_NOWAYOUT;
39module_param(nowayout, bool, 0);
40MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
41 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
42
43static unsigned timeout;
44module_param(timeout, uint, 0);
45MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default="
46 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
47
48static int ebc_c384_wdt_start(struct watchdog_device *wdev)
49{
50 unsigned t = wdev->timeout;
51
52 /* resolution is in minutes for timeouts greater than 255 seconds */
53 if (t > 255)
54 t = DIV_ROUND_UP(t, 60);
55
56 outb(t, PET_ADDR);
57
58 return 0;
59}
60
61static int ebc_c384_wdt_stop(struct watchdog_device *wdev)
62{
63 outb(0x00, PET_ADDR);
64
65 return 0;
66}
67
68static int ebc_c384_wdt_set_timeout(struct watchdog_device *wdev, unsigned t)
69{
70 /* resolution is in minutes for timeouts greater than 255 seconds */
71 if (t > 255) {
72 /* round second resolution up to minute granularity */
73 wdev->timeout = roundup(t, 60);
74
75 /* set watchdog timer for minutes */
76 outb(0x00, CFG_ADDR);
77 } else {
78 wdev->timeout = t;
79
80 /* set watchdog timer for seconds */
81 outb(0x80, CFG_ADDR);
82 }
83
84 return 0;
85}
86
87static const struct watchdog_ops ebc_c384_wdt_ops = {
88 .start = ebc_c384_wdt_start,
89 .stop = ebc_c384_wdt_stop,
90 .set_timeout = ebc_c384_wdt_set_timeout
91};
92
93static const struct watchdog_info ebc_c384_wdt_info = {
94 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT,
95 .identity = MODULE_NAME
96};
97
98static int __init ebc_c384_wdt_probe(struct platform_device *pdev)
99{
100 struct device *dev = &pdev->dev;
101 struct watchdog_device *wdd;
102
103 if (!devm_request_region(dev, BASE_ADDR, ADDR_EXTENT, dev_name(dev))) {
104 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
105 BASE_ADDR, BASE_ADDR + ADDR_EXTENT);
106 return -EBUSY;
107 }
108
109 wdd = devm_kzalloc(dev, sizeof(*wdd), GFP_KERNEL);
110 if (!wdd)
111 return -ENOMEM;
112
113 wdd->info = &ebc_c384_wdt_info;
114 wdd->ops = &ebc_c384_wdt_ops;
115 wdd->timeout = WATCHDOG_TIMEOUT;
116 wdd->min_timeout = 1;
117 wdd->max_timeout = WATCHDOG_MAX_TIMEOUT;
118
119 watchdog_set_nowayout(wdd, nowayout);
120
121 if (watchdog_init_timeout(wdd, timeout, dev))
122 dev_warn(dev, "Invalid timeout (%u seconds), using default (%u seconds)\n",
123 timeout, WATCHDOG_TIMEOUT);
124
125 platform_set_drvdata(pdev, wdd);
126
127 return watchdog_register_device(wdd);
128}
129
130static int ebc_c384_wdt_remove(struct platform_device *pdev)
131{
132 struct watchdog_device *wdd = platform_get_drvdata(pdev);
133
134 watchdog_unregister_device(wdd);
135
136 return 0;
137}
138
139static struct platform_driver ebc_c384_wdt_driver = {
140 .driver = {
141 .name = MODULE_NAME
142 },
143 .remove = ebc_c384_wdt_remove
144};
145
146static struct platform_device *ebc_c384_wdt_device;
147
148static int __init ebc_c384_wdt_init(void)
149{
150 int err;
151
152 if (!dmi_match(DMI_BOARD_NAME, "EBC-C384 SBC"))
153 return -ENODEV;
154
155 ebc_c384_wdt_device = platform_device_alloc(MODULE_NAME, -1);
156 if (!ebc_c384_wdt_device)
157 return -ENOMEM;
158
159 err = platform_device_add(ebc_c384_wdt_device);
160 if (err)
161 goto err_platform_device;
162
163 err = platform_driver_probe(&ebc_c384_wdt_driver, ebc_c384_wdt_probe);
164 if (err)
165 goto err_platform_driver;
166
167 return 0;
168
169err_platform_driver:
170 platform_device_del(ebc_c384_wdt_device);
171err_platform_device:
172 platform_device_put(ebc_c384_wdt_device);
173 return err;
174}
175
176static void __exit ebc_c384_wdt_exit(void)
177{
178 platform_device_unregister(ebc_c384_wdt_device);
179 platform_driver_unregister(&ebc_c384_wdt_driver);
180}
181
182module_init(ebc_c384_wdt_init);
183module_exit(ebc_c384_wdt_exit);
184
185MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
186MODULE_DESCRIPTION("WinSystems EBC-C384 watchdog timer driver");
187MODULE_LICENSE("GPL v2");
188MODULE_ALIAS("platform:" MODULE_NAME);
diff --git a/drivers/watchdog/imgpdc_wdt.c b/drivers/watchdog/imgpdc_wdt.c
index 3679f2e1922f..516fbef00856 100644
--- a/drivers/watchdog/imgpdc_wdt.c
+++ b/drivers/watchdog/imgpdc_wdt.c
@@ -150,7 +150,8 @@ static int pdc_wdt_start(struct watchdog_device *wdt_dev)
150 return 0; 150 return 0;
151} 151}
152 152
153static int pdc_wdt_restart(struct watchdog_device *wdt_dev) 153static int pdc_wdt_restart(struct watchdog_device *wdt_dev,
154 unsigned long action, void *data)
154{ 155{
155 struct pdc_wdt_dev *wdt = watchdog_get_drvdata(wdt_dev); 156 struct pdc_wdt_dev *wdt = watchdog_get_drvdata(wdt_dev);
156 157
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index e47966aa2db0..331aed831dac 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -25,14 +25,12 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/jiffies.h>
29#include <linux/kernel.h> 28#include <linux/kernel.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
32#include <linux/of_address.h> 31#include <linux/of_address.h>
33#include <linux/platform_device.h> 32#include <linux/platform_device.h>
34#include <linux/regmap.h> 33#include <linux/regmap.h>
35#include <linux/timer.h>
36#include <linux/watchdog.h> 34#include <linux/watchdog.h>
37 35
38#define DRIVER_NAME "imx2-wdt" 36#define DRIVER_NAME "imx2-wdt"
@@ -60,7 +58,6 @@
60struct imx2_wdt_device { 58struct imx2_wdt_device {
61 struct clk *clk; 59 struct clk *clk;
62 struct regmap *regmap; 60 struct regmap *regmap;
63 struct timer_list timer; /* Pings the watchdog when closed */
64 struct watchdog_device wdog; 61 struct watchdog_device wdog;
65}; 62};
66 63
@@ -80,7 +77,8 @@ static const struct watchdog_info imx2_wdt_info = {
80 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 77 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
81}; 78};
82 79
83static int imx2_wdt_restart(struct watchdog_device *wdog) 80static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action,
81 void *data)
84{ 82{
85 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); 83 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
86 unsigned int wcr_enable = IMX2_WDT_WCR_WDE; 84 unsigned int wcr_enable = IMX2_WDT_WCR_WDE;
@@ -146,16 +144,6 @@ static int imx2_wdt_ping(struct watchdog_device *wdog)
146 return 0; 144 return 0;
147} 145}
148 146
149static void imx2_wdt_timer_ping(unsigned long arg)
150{
151 struct watchdog_device *wdog = (struct watchdog_device *)arg;
152 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
153
154 /* ping it every wdog->timeout / 2 seconds to prevent reboot */
155 imx2_wdt_ping(wdog);
156 mod_timer(&wdev->timer, jiffies + wdog->timeout * HZ / 2);
157}
158
159static int imx2_wdt_set_timeout(struct watchdog_device *wdog, 147static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
160 unsigned int new_timeout) 148 unsigned int new_timeout)
161{ 149{
@@ -172,40 +160,19 @@ static int imx2_wdt_start(struct watchdog_device *wdog)
172{ 160{
173 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); 161 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
174 162
175 if (imx2_wdt_is_running(wdev)) { 163 if (imx2_wdt_is_running(wdev))
176 /* delete the timer that pings the watchdog after close */
177 del_timer_sync(&wdev->timer);
178 imx2_wdt_set_timeout(wdog, wdog->timeout); 164 imx2_wdt_set_timeout(wdog, wdog->timeout);
179 } else 165 else
180 imx2_wdt_setup(wdog); 166 imx2_wdt_setup(wdog);
181 167
182 return imx2_wdt_ping(wdog); 168 set_bit(WDOG_HW_RUNNING, &wdog->status);
183}
184
185static int imx2_wdt_stop(struct watchdog_device *wdog)
186{
187 /*
188 * We don't need a clk_disable, it cannot be disabled once started.
189 * We use a timer to ping the watchdog while /dev/watchdog is closed
190 */
191 imx2_wdt_timer_ping((unsigned long)wdog);
192 return 0;
193}
194
195static inline void imx2_wdt_ping_if_active(struct watchdog_device *wdog)
196{
197 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
198 169
199 if (imx2_wdt_is_running(wdev)) { 170 return imx2_wdt_ping(wdog);
200 imx2_wdt_set_timeout(wdog, wdog->timeout);
201 imx2_wdt_timer_ping((unsigned long)wdog);
202 }
203} 171}
204 172
205static const struct watchdog_ops imx2_wdt_ops = { 173static const struct watchdog_ops imx2_wdt_ops = {
206 .owner = THIS_MODULE, 174 .owner = THIS_MODULE,
207 .start = imx2_wdt_start, 175 .start = imx2_wdt_start,
208 .stop = imx2_wdt_stop,
209 .ping = imx2_wdt_ping, 176 .ping = imx2_wdt_ping,
210 .set_timeout = imx2_wdt_set_timeout, 177 .set_timeout = imx2_wdt_set_timeout,
211 .restart = imx2_wdt_restart, 178 .restart = imx2_wdt_restart,
@@ -253,7 +220,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
253 wdog->info = &imx2_wdt_info; 220 wdog->info = &imx2_wdt_info;
254 wdog->ops = &imx2_wdt_ops; 221 wdog->ops = &imx2_wdt_ops;
255 wdog->min_timeout = 1; 222 wdog->min_timeout = 1;
256 wdog->max_timeout = IMX2_WDT_MAX_TIME; 223 wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000;
257 wdog->parent = &pdev->dev; 224 wdog->parent = &pdev->dev;
258 225
259 ret = clk_prepare_enable(wdev->clk); 226 ret = clk_prepare_enable(wdev->clk);
@@ -274,9 +241,10 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
274 watchdog_set_restart_priority(wdog, 128); 241 watchdog_set_restart_priority(wdog, 128);
275 watchdog_init_timeout(wdog, timeout, &pdev->dev); 242 watchdog_init_timeout(wdog, timeout, &pdev->dev);
276 243
277 setup_timer(&wdev->timer, imx2_wdt_timer_ping, (unsigned long)wdog); 244 if (imx2_wdt_is_running(wdev)) {
278 245 imx2_wdt_set_timeout(wdog, wdog->timeout);
279 imx2_wdt_ping_if_active(wdog); 246 set_bit(WDOG_HW_RUNNING, &wdog->status);
247 }
280 248
281 /* 249 /*
282 * Disable the watchdog power down counter at boot. Otherwise the power 250 * Disable the watchdog power down counter at boot. Otherwise the power
@@ -309,7 +277,6 @@ static int __exit imx2_wdt_remove(struct platform_device *pdev)
309 watchdog_unregister_device(wdog); 277 watchdog_unregister_device(wdog);
310 278
311 if (imx2_wdt_is_running(wdev)) { 279 if (imx2_wdt_is_running(wdev)) {
312 del_timer_sync(&wdev->timer);
313 imx2_wdt_ping(wdog); 280 imx2_wdt_ping(wdog);
314 dev_crit(&pdev->dev, "Device removed: Expect reboot!\n"); 281 dev_crit(&pdev->dev, "Device removed: Expect reboot!\n");
315 } 282 }
@@ -323,10 +290,9 @@ static void imx2_wdt_shutdown(struct platform_device *pdev)
323 290
324 if (imx2_wdt_is_running(wdev)) { 291 if (imx2_wdt_is_running(wdev)) {
325 /* 292 /*
326 * We are running, we need to delete the timer but will 293 * We are running, configure max timeout before reboot
327 * give max timeout before reboot will take place 294 * will take place.
328 */ 295 */
329 del_timer_sync(&wdev->timer);
330 imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); 296 imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME);
331 imx2_wdt_ping(wdog); 297 imx2_wdt_ping(wdog);
332 dev_crit(&pdev->dev, "Device shutdown: Expect reboot!\n"); 298 dev_crit(&pdev->dev, "Device shutdown: Expect reboot!\n");
@@ -344,10 +310,6 @@ static int imx2_wdt_suspend(struct device *dev)
344 if (imx2_wdt_is_running(wdev)) { 310 if (imx2_wdt_is_running(wdev)) {
345 imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); 311 imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME);
346 imx2_wdt_ping(wdog); 312 imx2_wdt_ping(wdog);
347
348 /* The watchdog is not active */
349 if (!watchdog_active(wdog))
350 del_timer_sync(&wdev->timer);
351 } 313 }
352 314
353 clk_disable_unprepare(wdev->clk); 315 clk_disable_unprepare(wdev->clk);
@@ -373,19 +335,10 @@ static int imx2_wdt_resume(struct device *dev)
373 * watchdog again. 335 * watchdog again.
374 */ 336 */
375 imx2_wdt_setup(wdog); 337 imx2_wdt_setup(wdog);
338 }
339 if (imx2_wdt_is_running(wdev)) {
376 imx2_wdt_set_timeout(wdog, wdog->timeout); 340 imx2_wdt_set_timeout(wdog, wdog->timeout);
377 imx2_wdt_ping(wdog); 341 imx2_wdt_ping(wdog);
378 } else if (imx2_wdt_is_running(wdev)) {
379 /* Resuming from non-deep sleep state. */
380 imx2_wdt_set_timeout(wdog, wdog->timeout);
381 imx2_wdt_ping(wdog);
382 /*
383 * But the watchdog is not active, then start
384 * the timer again.
385 */
386 if (!watchdog_active(wdog))
387 mod_timer(&wdev->timer,
388 jiffies + wdog->timeout * HZ / 2);
389 } 342 }
390 343
391 return 0; 344 return 0;
diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c
index 6914c83aa6d9..fd171e6caa16 100644
--- a/drivers/watchdog/lpc18xx_wdt.c
+++ b/drivers/watchdog/lpc18xx_wdt.c
@@ -153,7 +153,8 @@ static int lpc18xx_wdt_start(struct watchdog_device *wdt_dev)
153 return 0; 153 return 0;
154} 154}
155 155
156static int lpc18xx_wdt_restart(struct watchdog_device *wdt_dev) 156static int lpc18xx_wdt_restart(struct watchdog_device *wdt_dev,
157 unsigned long action, void *data)
157{ 158{
158 struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev); 159 struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
159 unsigned long flags; 160 unsigned long flags;
diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c
index aea5d2f44ad7..56ea1caf71c3 100644
--- a/drivers/watchdog/meson_wdt.c
+++ b/drivers/watchdog/meson_wdt.c
@@ -62,7 +62,8 @@ struct meson_wdt_dev {
62 const struct meson_wdt_data *data; 62 const struct meson_wdt_data *data;
63}; 63};
64 64
65static int meson_wdt_restart(struct watchdog_device *wdt_dev) 65static int meson_wdt_restart(struct watchdog_device *wdt_dev,
66 unsigned long action, void *data)
66{ 67{
67 struct meson_wdt_dev *meson_wdt = watchdog_get_drvdata(wdt_dev); 68 struct meson_wdt_dev *meson_wdt = watchdog_get_drvdata(wdt_dev);
68 u32 tc_reboot = MESON_WDT_DC_RESET; 69 u32 tc_reboot = MESON_WDT_DC_RESET;
diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c
index 885c81bc4210..2c4a73d1e214 100644
--- a/drivers/watchdog/moxart_wdt.c
+++ b/drivers/watchdog/moxart_wdt.c
@@ -31,7 +31,8 @@ struct moxart_wdt_dev {
31 31
32static int heartbeat; 32static int heartbeat;
33 33
34static int moxart_wdt_restart(struct watchdog_device *wdt_dev) 34static int moxart_wdt_restart(struct watchdog_device *wdt_dev,
35 unsigned long action, void *data)
35{ 36{
36 struct moxart_wdt_dev *moxart_wdt = watchdog_get_drvdata(wdt_dev); 37 struct moxart_wdt_dev *moxart_wdt = watchdog_get_drvdata(wdt_dev);
37 38
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index b78776c05554..7ed417a765c7 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -64,7 +64,8 @@ struct mtk_wdt_dev {
64 void __iomem *wdt_base; 64 void __iomem *wdt_base;
65}; 65};
66 66
67static int mtk_wdt_restart(struct watchdog_device *wdt_dev) 67static int mtk_wdt_restart(struct watchdog_device *wdt_dev,
68 unsigned long action, void *data)
68{ 69{
69 struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); 70 struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
70 void __iomem *wdt_base; 71 void __iomem *wdt_base;
diff --git a/drivers/watchdog/ni903x_wdt.c b/drivers/watchdog/ni903x_wdt.c
new file mode 100644
index 000000000000..dc67742e9018
--- /dev/null
+++ b/drivers/watchdog/ni903x_wdt.c
@@ -0,0 +1,270 @@
1/*
2 * Copyright (C) 2016 National Instruments Corp.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/acpi.h>
16#include <linux/device.h>
17#include <linux/interrupt.h>
18#include <linux/io.h>
19#include <linux/module.h>
20#include <linux/watchdog.h>
21
22#define NIWD_CONTROL 0x01
23#define NIWD_COUNTER2 0x02
24#define NIWD_COUNTER1 0x03
25#define NIWD_COUNTER0 0x04
26#define NIWD_SEED2 0x05
27#define NIWD_SEED1 0x06
28#define NIWD_SEED0 0x07
29
30#define NIWD_IO_SIZE 0x08
31
32#define NIWD_CONTROL_MODE 0x80
33#define NIWD_CONTROL_PROC_RESET 0x20
34#define NIWD_CONTROL_PET 0x10
35#define NIWD_CONTROL_RUNNING 0x08
36#define NIWD_CONTROL_CAPTURECOUNTER 0x04
37#define NIWD_CONTROL_RESET 0x02
38#define NIWD_CONTROL_ALARM 0x01
39
40#define NIWD_PERIOD_NS 30720
41#define NIWD_MIN_TIMEOUT 1
42#define NIWD_MAX_TIMEOUT 515
43#define NIWD_DEFAULT_TIMEOUT 60
44
45#define NIWD_NAME "ni903x_wdt"
46
47struct ni903x_wdt {
48 struct device *dev;
49 u16 io_base;
50 struct watchdog_device wdd;
51};
52
53static unsigned int timeout;
54module_param(timeout, uint, 0);
55MODULE_PARM_DESC(timeout,
56 "Watchdog timeout in seconds. (default="
57 __MODULE_STRING(NIWD_DEFAULT_TIMEOUT) ")");
58
59static int nowayout = WATCHDOG_NOWAYOUT;
60module_param(nowayout, int, S_IRUGO);
61MODULE_PARM_DESC(nowayout,
62 "Watchdog cannot be stopped once started (default="
63 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
64
65static void ni903x_start(struct ni903x_wdt *wdt)
66{
67 u8 control = inb(wdt->io_base + NIWD_CONTROL);
68
69 outb(control | NIWD_CONTROL_RESET, wdt->io_base + NIWD_CONTROL);
70 outb(control | NIWD_CONTROL_PET, wdt->io_base + NIWD_CONTROL);
71}
72
73static int ni903x_wdd_set_timeout(struct watchdog_device *wdd,
74 unsigned int timeout)
75{
76 struct ni903x_wdt *wdt = watchdog_get_drvdata(wdd);
77 u32 counter = timeout * (1000000000 / NIWD_PERIOD_NS);
78
79 outb(((0x00FF0000 & counter) >> 16), wdt->io_base + NIWD_SEED2);
80 outb(((0x0000FF00 & counter) >> 8), wdt->io_base + NIWD_SEED1);
81 outb((0x000000FF & counter), wdt->io_base + NIWD_SEED0);
82
83 wdd->timeout = timeout;
84
85 return 0;
86}
87
88static unsigned int ni903x_wdd_get_timeleft(struct watchdog_device *wdd)
89{
90 struct ni903x_wdt *wdt = watchdog_get_drvdata(wdd);
91 u8 control, counter0, counter1, counter2;
92 u32 counter;
93
94 control = inb(wdt->io_base + NIWD_CONTROL);
95 control |= NIWD_CONTROL_CAPTURECOUNTER;
96 outb(control, wdt->io_base + NIWD_CONTROL);
97
98 counter2 = inb(wdt->io_base + NIWD_COUNTER2);
99 counter1 = inb(wdt->io_base + NIWD_COUNTER1);
100 counter0 = inb(wdt->io_base + NIWD_COUNTER0);
101
102 counter = (counter2 << 16) | (counter1 << 8) | counter0;
103
104 return counter / (1000000000 / NIWD_PERIOD_NS);
105}
106
107static int ni903x_wdd_ping(struct watchdog_device *wdd)
108{
109 struct ni903x_wdt *wdt = watchdog_get_drvdata(wdd);
110 u8 control;
111
112 control = inb(wdt->io_base + NIWD_CONTROL);
113 outb(control | NIWD_CONTROL_PET, wdt->io_base + NIWD_CONTROL);
114
115 return 0;
116}
117
118static int ni903x_wdd_start(struct watchdog_device *wdd)
119{
120 struct ni903x_wdt *wdt = watchdog_get_drvdata(wdd);
121
122 outb(NIWD_CONTROL_RESET | NIWD_CONTROL_PROC_RESET,
123 wdt->io_base + NIWD_CONTROL);
124
125 ni903x_wdd_set_timeout(wdd, wdd->timeout);
126 ni903x_start(wdt);
127
128 return 0;
129}
130
131static int ni903x_wdd_stop(struct watchdog_device *wdd)
132{
133 struct ni903x_wdt *wdt = watchdog_get_drvdata(wdd);
134
135 outb(NIWD_CONTROL_RESET, wdt->io_base + NIWD_CONTROL);
136
137 return 0;
138}
139
140static acpi_status ni903x_resources(struct acpi_resource *res, void *data)
141{
142 struct ni903x_wdt *wdt = data;
143 u16 io_size;
144
145 switch (res->type) {
146 case ACPI_RESOURCE_TYPE_IO:
147 if (wdt->io_base != 0) {
148 dev_err(wdt->dev, "too many IO resources\n");
149 return AE_ERROR;
150 }
151
152 wdt->io_base = res->data.io.minimum;
153 io_size = res->data.io.address_length;
154
155 if (io_size < NIWD_IO_SIZE) {
156 dev_err(wdt->dev, "memory region too small\n");
157 return AE_ERROR;
158 }
159
160 if (!devm_request_region(wdt->dev, wdt->io_base, io_size,
161 NIWD_NAME)) {
162 dev_err(wdt->dev, "failed to get memory region\n");
163 return AE_ERROR;
164 }
165
166 return AE_OK;
167
168 case ACPI_RESOURCE_TYPE_END_TAG:
169 default:
170 /* Ignore unsupported resources, e.g. IRQ */
171 return AE_OK;
172 }
173}
174
175static const struct watchdog_info ni903x_wdd_info = {
176 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
177 .identity = "NI Watchdog",
178};
179
180static const struct watchdog_ops ni903x_wdd_ops = {
181 .owner = THIS_MODULE,
182 .start = ni903x_wdd_start,
183 .stop = ni903x_wdd_stop,
184 .ping = ni903x_wdd_ping,
185 .set_timeout = ni903x_wdd_set_timeout,
186 .get_timeleft = ni903x_wdd_get_timeleft,
187};
188
189static int ni903x_acpi_add(struct acpi_device *device)
190{
191 struct device *dev = &device->dev;
192 struct watchdog_device *wdd;
193 struct ni903x_wdt *wdt;
194 acpi_status status;
195 int ret;
196
197 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
198 if (!wdt)
199 return -ENOMEM;
200
201 device->driver_data = wdt;
202 wdt->dev = dev;
203
204 status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
205 ni903x_resources, wdt);
206 if (ACPI_FAILURE(status) || wdt->io_base == 0) {
207 dev_err(dev, "failed to get resources\n");
208 return -ENODEV;
209 }
210
211 wdd = &wdt->wdd;
212 wdd->info = &ni903x_wdd_info;
213 wdd->ops = &ni903x_wdd_ops;
214 wdd->min_timeout = NIWD_MIN_TIMEOUT;
215 wdd->max_timeout = NIWD_MAX_TIMEOUT;
216 wdd->timeout = NIWD_DEFAULT_TIMEOUT;
217 wdd->parent = dev;
218 watchdog_set_drvdata(wdd, wdt);
219 watchdog_set_nowayout(wdd, nowayout);
220 ret = watchdog_init_timeout(wdd, timeout, dev);
221 if (ret)
222 dev_err(dev, "unable to set timeout value, using default\n");
223
224 ret = watchdog_register_device(wdd);
225 if (ret) {
226 dev_err(dev, "failed to register watchdog\n");
227 return ret;
228 }
229
230 /* Switch from boot mode to user mode */
231 outb(NIWD_CONTROL_RESET | NIWD_CONTROL_MODE,
232 wdt->io_base + NIWD_CONTROL);
233
234 dev_dbg(dev, "io_base=0x%04X, timeout=%d, nowayout=%d\n",
235 wdt->io_base, timeout, nowayout);
236
237 return 0;
238}
239
240static int ni903x_acpi_remove(struct acpi_device *device)
241{
242 struct ni903x_wdt *wdt = acpi_driver_data(device);
243
244 ni903x_wdd_stop(&wdt->wdd);
245 watchdog_unregister_device(&wdt->wdd);
246
247 return 0;
248}
249
250static const struct acpi_device_id ni903x_device_ids[] = {
251 {"NIC775C", 0},
252 {"", 0},
253};
254MODULE_DEVICE_TABLE(acpi, ni903x_device_ids);
255
256static struct acpi_driver ni903x_acpi_driver = {
257 .name = NIWD_NAME,
258 .ids = ni903x_device_ids,
259 .ops = {
260 .add = ni903x_acpi_add,
261 .remove = ni903x_acpi_remove,
262 },
263};
264
265module_acpi_driver(ni903x_acpi_driver);
266
267MODULE_DESCRIPTION("NI 903x Watchdog");
268MODULE_AUTHOR("Jeff Westfahl <jeff.westfahl@ni.com>");
269MODULE_AUTHOR("Kyle Roeschley <kyle.roeschley@ni.com>");
270MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 313cd1c6fda0..0529aed158a4 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -31,6 +31,8 @@
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/err.h> 32#include <linux/err.h>
33#include <linux/of.h> 33#include <linux/of.h>
34#include <linux/delay.h>
35#include <linux/reboot.h>
34#include <mach/hardware.h> 36#include <mach/hardware.h>
35 37
36/* WatchDog Timer - Chapter 23 Page 207 */ 38/* WatchDog Timer - Chapter 23 Page 207 */
@@ -124,6 +126,41 @@ static int pnx4008_wdt_set_timeout(struct watchdog_device *wdd,
124 return 0; 126 return 0;
125} 127}
126 128
129static int pnx4008_restart_handler(struct watchdog_device *wdd,
130 unsigned long mode, void *cmd)
131{
132 const char *boot_cmd = cmd;
133
134 /*
135 * Verify if a "cmd" passed from the userspace program rebooting
136 * the system; if available, handle it.
137 * - For details, see the 'reboot' syscall in kernel/reboot.c
138 * - If the received "cmd" is not supported, use the default mode.
139 */
140 if (boot_cmd) {
141 if (boot_cmd[0] == 'h')
142 mode = REBOOT_HARD;
143 else if (boot_cmd[0] == 's')
144 mode = REBOOT_SOFT;
145 }
146
147 if (mode == REBOOT_SOFT) {
148 /* Force match output active */
149 writel(EXT_MATCH0, WDTIM_EMR(wdt_base));
150 /* Internal reset on match output (RESOUT_N not asserted) */
151 writel(M_RES1, WDTIM_MCTRL(wdt_base));
152 } else {
153 /* Instant assert of RESETOUT_N with pulse length 1mS */
154 writel(13000, WDTIM_PULSE(wdt_base));
155 writel(M_RES2 | RESFRC1 | RESFRC2, WDTIM_MCTRL(wdt_base));
156 }
157
158 /* Wait for watchdog to reset system */
159 mdelay(1000);
160
161 return NOTIFY_DONE;
162}
163
127static const struct watchdog_info pnx4008_wdt_ident = { 164static const struct watchdog_info pnx4008_wdt_ident = {
128 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | 165 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
129 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 166 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
@@ -135,6 +172,7 @@ static const struct watchdog_ops pnx4008_wdt_ops = {
135 .start = pnx4008_wdt_start, 172 .start = pnx4008_wdt_start,
136 .stop = pnx4008_wdt_stop, 173 .stop = pnx4008_wdt_stop,
137 .set_timeout = pnx4008_wdt_set_timeout, 174 .set_timeout = pnx4008_wdt_set_timeout,
175 .restart = pnx4008_restart_handler,
138}; 176};
139 177
140static struct watchdog_device pnx4008_wdd = { 178static struct watchdog_device pnx4008_wdd = {
@@ -169,6 +207,7 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
169 WDIOF_CARDRESET : 0; 207 WDIOF_CARDRESET : 0;
170 pnx4008_wdd.parent = &pdev->dev; 208 pnx4008_wdd.parent = &pdev->dev;
171 watchdog_set_nowayout(&pnx4008_wdd, nowayout); 209 watchdog_set_nowayout(&pnx4008_wdd, nowayout);
210 watchdog_set_restart_priority(&pnx4008_wdd, 128);
172 211
173 pnx4008_wdt_stop(&pnx4008_wdd); /* disable for now */ 212 pnx4008_wdt_stop(&pnx4008_wdd); /* disable for now */
174 213
@@ -178,8 +217,7 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
178 goto disable_clk; 217 goto disable_clk;
179 } 218 }
180 219
181 dev_info(&pdev->dev, "PNX4008 Watchdog Timer: heartbeat %d sec\n", 220 dev_info(&pdev->dev, "heartbeat %d sec\n", pnx4008_wdd.timeout);
182 pnx4008_wdd.timeout);
183 221
184 return 0; 222 return 0;
185 223
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index 424f9a952fee..20563ccb7be0 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -70,7 +70,8 @@ static int qcom_wdt_set_timeout(struct watchdog_device *wdd,
70 return qcom_wdt_start(wdd); 70 return qcom_wdt_start(wdd);
71} 71}
72 72
73static int qcom_wdt_restart(struct watchdog_device *wdd) 73static int qcom_wdt_restart(struct watchdog_device *wdd, unsigned long action,
74 void *data)
74{ 75{
75 struct qcom_wdt *wdt = to_qcom_wdt(wdd); 76 struct qcom_wdt *wdt = to_qcom_wdt(wdd);
76 u32 timeout; 77 u32 timeout;
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
index 71e78ef4b736..3a75f3b53452 100644
--- a/drivers/watchdog/rc32434_wdt.c
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -237,7 +237,7 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd,
237 return -EINVAL; 237 return -EINVAL;
238 /* Fall through */ 238 /* Fall through */
239 case WDIOC_GETTIMEOUT: 239 case WDIOC_GETTIMEOUT:
240 return copy_to_user(argp, &timeout, sizeof(int)); 240 return copy_to_user(argp, &timeout, sizeof(int)) ? -EFAULT : 0;
241 default: 241 default:
242 return -ENOTTY; 242 return -ENOTTY;
243 } 243 }
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 0093450441fe..59e95762a6de 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -47,6 +47,8 @@
47#define S3C2410_WTDAT 0x04 47#define S3C2410_WTDAT 0x04
48#define S3C2410_WTCNT 0x08 48#define S3C2410_WTCNT 0x08
49 49
50#define S3C2410_WTCNT_MAXCNT 0xffff
51
50#define S3C2410_WTCON_RSTEN (1 << 0) 52#define S3C2410_WTCON_RSTEN (1 << 0)
51#define S3C2410_WTCON_INTEN (1 << 2) 53#define S3C2410_WTCON_INTEN (1 << 2)
52#define S3C2410_WTCON_ENABLE (1 << 5) 54#define S3C2410_WTCON_ENABLE (1 << 5)
@@ -56,8 +58,11 @@
56#define S3C2410_WTCON_DIV64 (2 << 3) 58#define S3C2410_WTCON_DIV64 (2 << 3)
57#define S3C2410_WTCON_DIV128 (3 << 3) 59#define S3C2410_WTCON_DIV128 (3 << 3)
58 60
61#define S3C2410_WTCON_MAXDIV 0x80
62
59#define S3C2410_WTCON_PRESCALE(x) ((x) << 8) 63#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
60#define S3C2410_WTCON_PRESCALE_MASK (0xff << 8) 64#define S3C2410_WTCON_PRESCALE_MASK (0xff << 8)
65#define S3C2410_WTCON_PRESCALE_MAX 0xff
61 66
62#define CONFIG_S3C2410_WATCHDOG_ATBOOT (0) 67#define CONFIG_S3C2410_WATCHDOG_ATBOOT (0)
63#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15) 68#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15)
@@ -198,6 +203,14 @@ do { \
198 203
199/* functions */ 204/* functions */
200 205
206static inline unsigned int s3c2410wdt_max_timeout(struct clk *clock)
207{
208 unsigned long freq = clk_get_rate(clock);
209
210 return S3C2410_WTCNT_MAXCNT / (freq / (S3C2410_WTCON_PRESCALE_MAX + 1)
211 / S3C2410_WTCON_MAXDIV);
212}
213
201static inline struct s3c2410_wdt *freq_to_wdt(struct notifier_block *nb) 214static inline struct s3c2410_wdt *freq_to_wdt(struct notifier_block *nb)
202{ 215{
203 return container_of(nb, struct s3c2410_wdt, freq_transition); 216 return container_of(nb, struct s3c2410_wdt, freq_transition);
@@ -349,7 +362,8 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeou
349 return 0; 362 return 0;
350} 363}
351 364
352static int s3c2410wdt_restart(struct watchdog_device *wdd) 365static int s3c2410wdt_restart(struct watchdog_device *wdd, unsigned long action,
366 void *data)
353{ 367{
354 struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); 368 struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd);
355 void __iomem *wdt_base = wdt->reg_base; 369 void __iomem *wdt_base = wdt->reg_base;
@@ -567,6 +581,9 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
567 return ret; 581 return ret;
568 } 582 }
569 583
584 wdt->wdt_device.min_timeout = 1;
585 wdt->wdt_device.max_timeout = s3c2410wdt_max_timeout(wdt->clock);
586
570 ret = s3c2410wdt_cpufreq_register(wdt); 587 ret = s3c2410wdt_cpufreq_register(wdt);
571 if (ret < 0) { 588 if (ret < 0) {
572 dev_err(dev, "failed to register cpufreq\n"); 589 dev_err(dev, "failed to register cpufreq\n");
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
new file mode 100644
index 000000000000..ad383f6f15fc
--- /dev/null
+++ b/drivers/watchdog/sbsa_gwdt.c
@@ -0,0 +1,408 @@
1/*
2 * SBSA(Server Base System Architecture) Generic Watchdog driver
3 *
4 * Copyright (c) 2015, Linaro Ltd.
5 * Author: Fu Wei <fu.wei@linaro.org>
6 * Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
7 * Al Stone <al.stone@linaro.org>
8 * Timur Tabi <timur@codeaurora.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License 2 as published
12 * by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * ARM SBSA Generic Watchdog has two stage timeouts:
20 * the first signal (WS0) is for alerting the system by interrupt,
21 * the second one (WS1) is a real hardware reset.
22 * More details about the hardware specification of this device:
23 * ARM DEN0029B - Server Base System Architecture (SBSA)
24 *
25 * This driver can operate ARM SBSA Generic Watchdog as a single stage watchdog
26 * or a two stages watchdog, it's set up by the module parameter "action".
27 * In the single stage mode, when the timeout is reached, your system
28 * will be reset by WS1. The first signal (WS0) is ignored.
29 * In the two stages mode, when the timeout is reached, the first signal (WS0)
30 * will trigger panic. If the system is getting into trouble and cannot be reset
31 * by panic or restart properly by the kdump kernel(if supported), then the
32 * second stage (as long as the first stage) will be reached, system will be
33 * reset by WS1. This function can help administrator to backup the system
34 * context info by panic console output or kdump.
35 *
36 * SBSA GWDT:
37 * if action is 1 (the two stages mode):
38 * |--------WOR-------WS0--------WOR-------WS1
39 * |----timeout-----(panic)----timeout-----reset
40 *
41 * if action is 0 (the single stage mode):
42 * |------WOR-----WS0(ignored)-----WOR------WS1
43 * |--------------timeout-------------------reset
44 *
45 * Note: Since this watchdog timer has two stages, and each stage is determined
46 * by WOR, in the single stage mode, the timeout is (WOR * 2); in the two
47 * stages mode, the timeout is WOR. The maximum timeout in the two stages mode
48 * is half of that in the single stage mode.
49 *
50 */
51
52#include <linux/io.h>
53#include <linux/interrupt.h>
54#include <linux/module.h>
55#include <linux/moduleparam.h>
56#include <linux/of.h>
57#include <linux/of_device.h>
58#include <linux/platform_device.h>
59#include <linux/uaccess.h>
60#include <linux/watchdog.h>
61#include <asm/arch_timer.h>
62
63#define DRV_NAME "sbsa-gwdt"
64#define WATCHDOG_NAME "SBSA Generic Watchdog"
65
66/* SBSA Generic Watchdog register definitions */
67/* refresh frame */
68#define SBSA_GWDT_WRR 0x000
69
70/* control frame */
71#define SBSA_GWDT_WCS 0x000
72#define SBSA_GWDT_WOR 0x008
73#define SBSA_GWDT_WCV 0x010
74
75/* refresh/control frame */
76#define SBSA_GWDT_W_IIDR 0xfcc
77#define SBSA_GWDT_IDR 0xfd0
78
79/* Watchdog Control and Status Register */
80#define SBSA_GWDT_WCS_EN BIT(0)
81#define SBSA_GWDT_WCS_WS0 BIT(1)
82#define SBSA_GWDT_WCS_WS1 BIT(2)
83
84/**
85 * struct sbsa_gwdt - Internal representation of the SBSA GWDT
86 * @wdd: kernel watchdog_device structure
87 * @clk: store the System Counter clock frequency, in Hz.
88 * @refresh_base: Virtual address of the watchdog refresh frame
89 * @control_base: Virtual address of the watchdog control frame
90 */
91struct sbsa_gwdt {
92 struct watchdog_device wdd;
93 u32 clk;
94 void __iomem *refresh_base;
95 void __iomem *control_base;
96};
97
98#define DEFAULT_TIMEOUT 10 /* seconds */
99
100static unsigned int timeout;
101module_param(timeout, uint, 0);
102MODULE_PARM_DESC(timeout,
103 "Watchdog timeout in seconds. (>=0, default="
104 __MODULE_STRING(DEFAULT_TIMEOUT) ")");
105
106/*
107 * action refers to action taken when watchdog gets WS0
108 * 0 = skip
109 * 1 = panic
110 * defaults to skip (0)
111 */
112static int action;
113module_param(action, int, 0);
114MODULE_PARM_DESC(action, "after watchdog gets WS0 interrupt, do: "
115 "0 = skip(*) 1 = panic");
116
117static bool nowayout = WATCHDOG_NOWAYOUT;
118module_param(nowayout, bool, S_IRUGO);
119MODULE_PARM_DESC(nowayout,
120 "Watchdog cannot be stopped once started (default="
121 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
122
123/*
124 * watchdog operation functions
125 */
126static int sbsa_gwdt_set_timeout(struct watchdog_device *wdd,
127 unsigned int timeout)
128{
129 struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
130
131 wdd->timeout = timeout;
132
133 if (action)
134 writel(gwdt->clk * timeout,
135 gwdt->control_base + SBSA_GWDT_WOR);
136 else
137 /*
138 * In the single stage mode, The first signal (WS0) is ignored,
139 * the timeout is (WOR * 2), so the WOR should be configured
140 * to half value of timeout.
141 */
142 writel(gwdt->clk / 2 * timeout,
143 gwdt->control_base + SBSA_GWDT_WOR);
144
145 return 0;
146}
147
148static unsigned int sbsa_gwdt_get_timeleft(struct watchdog_device *wdd)
149{
150 struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
151 u64 timeleft = 0;
152
153 /*
154 * In the single stage mode, if WS0 is deasserted
155 * (watchdog is in the first stage),
156 * timeleft = WOR + (WCV - system counter)
157 */
158 if (!action &&
159 !(readl(gwdt->control_base + SBSA_GWDT_WCS) & SBSA_GWDT_WCS_WS0))
160 timeleft += readl(gwdt->control_base + SBSA_GWDT_WOR);
161
162 timeleft += readq(gwdt->control_base + SBSA_GWDT_WCV) -
163 arch_counter_get_cntvct();
164
165 do_div(timeleft, gwdt->clk);
166
167 return timeleft;
168}
169
170static int sbsa_gwdt_keepalive(struct watchdog_device *wdd)
171{
172 struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
173
174 /*
175 * Writing WRR for an explicit watchdog refresh.
176 * You can write anyting (like 0).
177 */
178 writel(0, gwdt->refresh_base + SBSA_GWDT_WRR);
179
180 return 0;
181}
182
183static unsigned int sbsa_gwdt_status(struct watchdog_device *wdd)
184{
185 struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
186 u32 status = readl(gwdt->control_base + SBSA_GWDT_WCS);
187
188 /* is the watchdog timer running? */
189 return (status & SBSA_GWDT_WCS_EN) << WDOG_ACTIVE;
190}
191
192static int sbsa_gwdt_start(struct watchdog_device *wdd)
193{
194 struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
195
196 /* writing WCS will cause an explicit watchdog refresh */
197 writel(SBSA_GWDT_WCS_EN, gwdt->control_base + SBSA_GWDT_WCS);
198
199 return 0;
200}
201
202static int sbsa_gwdt_stop(struct watchdog_device *wdd)
203{
204 struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
205
206 /* Simply write 0 to WCS to clean WCS_EN bit */
207 writel(0, gwdt->control_base + SBSA_GWDT_WCS);
208
209 return 0;
210}
211
212static irqreturn_t sbsa_gwdt_interrupt(int irq, void *dev_id)
213{
214 panic(WATCHDOG_NAME " timeout");
215
216 return IRQ_HANDLED;
217}
218
219static struct watchdog_info sbsa_gwdt_info = {
220 .identity = WATCHDOG_NAME,
221 .options = WDIOF_SETTIMEOUT |
222 WDIOF_KEEPALIVEPING |
223 WDIOF_MAGICCLOSE |
224 WDIOF_CARDRESET,
225};
226
227static struct watchdog_ops sbsa_gwdt_ops = {
228 .owner = THIS_MODULE,
229 .start = sbsa_gwdt_start,
230 .stop = sbsa_gwdt_stop,
231 .status = sbsa_gwdt_status,
232 .ping = sbsa_gwdt_keepalive,
233 .set_timeout = sbsa_gwdt_set_timeout,
234 .get_timeleft = sbsa_gwdt_get_timeleft,
235};
236
237static int sbsa_gwdt_probe(struct platform_device *pdev)
238{
239 void __iomem *rf_base, *cf_base;
240 struct device *dev = &pdev->dev;
241 struct watchdog_device *wdd;
242 struct sbsa_gwdt *gwdt;
243 struct resource *res;
244 int ret, irq;
245 u32 status;
246
247 gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
248 if (!gwdt)
249 return -ENOMEM;
250 platform_set_drvdata(pdev, gwdt);
251
252 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
253 cf_base = devm_ioremap_resource(dev, res);
254 if (IS_ERR(cf_base))
255 return PTR_ERR(cf_base);
256
257 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
258 rf_base = devm_ioremap_resource(dev, res);
259 if (IS_ERR(rf_base))
260 return PTR_ERR(rf_base);
261
262 /*
263 * Get the frequency of system counter from the cp15 interface of ARM
264 * Generic timer. We don't need to check it, because if it returns "0",
265 * system would panic in very early stage.
266 */
267 gwdt->clk = arch_timer_get_cntfrq();
268 gwdt->refresh_base = rf_base;
269 gwdt->control_base = cf_base;
270
271 wdd = &gwdt->wdd;
272 wdd->parent = dev;
273 wdd->info = &sbsa_gwdt_info;
274 wdd->ops = &sbsa_gwdt_ops;
275 wdd->min_timeout = 1;
276 wdd->max_timeout = U32_MAX / gwdt->clk;
277 wdd->timeout = DEFAULT_TIMEOUT;
278 watchdog_set_drvdata(wdd, gwdt);
279 watchdog_set_nowayout(wdd, nowayout);
280
281 status = readl(cf_base + SBSA_GWDT_WCS);
282 if (status & SBSA_GWDT_WCS_WS1) {
283 dev_warn(dev, "System reset by WDT.\n");
284 wdd->bootstatus |= WDIOF_CARDRESET;
285 }
286
287 if (action) {
288 irq = platform_get_irq(pdev, 0);
289 if (irq < 0) {
290 action = 0;
291 dev_warn(dev, "unable to get ws0 interrupt.\n");
292 } else {
293 /*
294 * In case there is a pending ws0 interrupt, just ping
295 * the watchdog before registering the interrupt routine
296 */
297 writel(0, rf_base + SBSA_GWDT_WRR);
298 if (devm_request_irq(dev, irq, sbsa_gwdt_interrupt, 0,
299 pdev->name, gwdt)) {
300 action = 0;
301 dev_warn(dev, "unable to request IRQ %d.\n",
302 irq);
303 }
304 }
305 if (!action)
306 dev_warn(dev, "falling back to single stage mode.\n");
307 }
308 /*
309 * In the single stage mode, The first signal (WS0) is ignored,
310 * the timeout is (WOR * 2), so the maximum timeout should be doubled.
311 */
312 if (!action)
313 wdd->max_timeout *= 2;
314
315 watchdog_init_timeout(wdd, timeout, dev);
316 /*
317 * Update timeout to WOR.
318 * Because of the explicit watchdog refresh mechanism,
319 * it's also a ping, if watchdog is enabled.
320 */
321 sbsa_gwdt_set_timeout(wdd, wdd->timeout);
322
323 ret = watchdog_register_device(wdd);
324 if (ret)
325 return ret;
326
327 dev_info(dev, "Initialized with %ds timeout @ %u Hz, action=%d.%s\n",
328 wdd->timeout, gwdt->clk, action,
329 status & SBSA_GWDT_WCS_EN ? " [enabled]" : "");
330
331 return 0;
332}
333
334static void sbsa_gwdt_shutdown(struct platform_device *pdev)
335{
336 struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
337
338 sbsa_gwdt_stop(&gwdt->wdd);
339}
340
341static int sbsa_gwdt_remove(struct platform_device *pdev)
342{
343 struct sbsa_gwdt *gwdt = platform_get_drvdata(pdev);
344
345 watchdog_unregister_device(&gwdt->wdd);
346
347 return 0;
348}
349
350/* Disable watchdog if it is active during suspend */
351static int __maybe_unused sbsa_gwdt_suspend(struct device *dev)
352{
353 struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
354
355 if (watchdog_active(&gwdt->wdd))
356 sbsa_gwdt_stop(&gwdt->wdd);
357
358 return 0;
359}
360
361/* Enable watchdog if necessary */
362static int __maybe_unused sbsa_gwdt_resume(struct device *dev)
363{
364 struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
365
366 if (watchdog_active(&gwdt->wdd))
367 sbsa_gwdt_start(&gwdt->wdd);
368
369 return 0;
370}
371
372static const struct dev_pm_ops sbsa_gwdt_pm_ops = {
373 SET_SYSTEM_SLEEP_PM_OPS(sbsa_gwdt_suspend, sbsa_gwdt_resume)
374};
375
376static const struct of_device_id sbsa_gwdt_of_match[] = {
377 { .compatible = "arm,sbsa-gwdt", },
378 {},
379};
380MODULE_DEVICE_TABLE(of, sbsa_gwdt_of_match);
381
382static const struct platform_device_id sbsa_gwdt_pdev_match[] = {
383 { .name = DRV_NAME, },
384 {},
385};
386MODULE_DEVICE_TABLE(platform, sbsa_gwdt_pdev_match);
387
388static struct platform_driver sbsa_gwdt_driver = {
389 .driver = {
390 .name = DRV_NAME,
391 .pm = &sbsa_gwdt_pm_ops,
392 .of_match_table = sbsa_gwdt_of_match,
393 },
394 .probe = sbsa_gwdt_probe,
395 .remove = sbsa_gwdt_remove,
396 .shutdown = sbsa_gwdt_shutdown,
397 .id_table = sbsa_gwdt_pdev_match,
398};
399
400module_platform_driver(sbsa_gwdt_driver);
401
402MODULE_DESCRIPTION("SBSA Generic Watchdog Driver");
403MODULE_AUTHOR("Fu Wei <fu.wei@linaro.org>");
404MODULE_AUTHOR("Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>");
405MODULE_AUTHOR("Al Stone <al.stone@linaro.org>");
406MODULE_AUTHOR("Timur Tabi <timur@codeaurora.org>");
407MODULE_LICENSE("GPL v2");
408MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c
index e027deb54740..953bb7b7446f 100644
--- a/drivers/watchdog/sunxi_wdt.c
+++ b/drivers/watchdog/sunxi_wdt.c
@@ -83,7 +83,8 @@ static const int wdt_timeout_map[] = {
83}; 83};
84 84
85 85
86static int sunxi_wdt_restart(struct watchdog_device *wdt_dev) 86static int sunxi_wdt_restart(struct watchdog_device *wdt_dev,
87 unsigned long action, void *data)
87{ 88{
88 struct sunxi_wdt_dev *sunxi_wdt = watchdog_get_drvdata(wdt_dev); 89 struct sunxi_wdt_dev *sunxi_wdt = watchdog_get_drvdata(wdt_dev);
89 void __iomem *wdt_base = sunxi_wdt->wdt_base; 90 void __iomem *wdt_base = sunxi_wdt->wdt_base;
diff --git a/drivers/watchdog/tangox_wdt.c b/drivers/watchdog/tangox_wdt.c
index 709c1ed6fd79..cfbed7e051b6 100644
--- a/drivers/watchdog/tangox_wdt.c
+++ b/drivers/watchdog/tangox_wdt.c
@@ -139,6 +139,10 @@ static int tangox_wdt_probe(struct platform_device *pdev)
139 return err; 139 return err;
140 140
141 dev->clk_rate = clk_get_rate(dev->clk); 141 dev->clk_rate = clk_get_rate(dev->clk);
142 if (!dev->clk_rate) {
143 err = -EINVAL;
144 goto err;
145 }
142 146
143 dev->wdt.parent = &pdev->dev; 147 dev->wdt.parent = &pdev->dev;
144 dev->wdt.info = &tangox_wdt_info; 148 dev->wdt.info = &tangox_wdt_info;
@@ -171,10 +175,8 @@ static int tangox_wdt_probe(struct platform_device *pdev)
171 } 175 }
172 176
173 err = watchdog_register_device(&dev->wdt); 177 err = watchdog_register_device(&dev->wdt);
174 if (err) { 178 if (err)
175 clk_disable_unprepare(dev->clk); 179 goto err;
176 return err;
177 }
178 180
179 platform_set_drvdata(pdev, dev); 181 platform_set_drvdata(pdev, dev);
180 182
@@ -187,6 +189,10 @@ static int tangox_wdt_probe(struct platform_device *pdev)
187 dev_info(&pdev->dev, "SMP86xx/SMP87xx watchdog registered\n"); 189 dev_info(&pdev->dev, "SMP86xx/SMP87xx watchdog registered\n");
188 190
189 return 0; 191 return 0;
192
193 err:
194 clk_disable_unprepare(dev->clk);
195 return err;
190} 196}
191 197
192static int tangox_wdt_remove(struct platform_device *pdev) 198static int tangox_wdt_remove(struct platform_device *pdev)
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index cab14bc9106c..09e8003039dc 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -45,10 +45,11 @@
45static int wdt_io; 45static int wdt_io;
46static int cr_wdt_timeout; /* WDT timeout register */ 46static int cr_wdt_timeout; /* WDT timeout register */
47static int cr_wdt_control; /* WDT control register */ 47static int cr_wdt_control; /* WDT control register */
48static int cr_wdt_csr; /* WDT control & status register */
48 49
49enum chips { w83627hf, w83627s, w83697hf, w83697ug, w83637hf, w83627thf, 50enum chips { w83627hf, w83627s, w83697hf, w83697ug, w83637hf, w83627thf,
50 w83687thf, w83627ehf, w83627dhg, w83627uhg, w83667hg, w83627dhg_p, 51 w83687thf, w83627ehf, w83627dhg, w83627uhg, w83667hg, w83627dhg_p,
51 w83667hg_b, nct6775, nct6776, nct6779, nct6791, nct6792 }; 52 w83667hg_b, nct6775, nct6776, nct6779, nct6791, nct6792, nct6102 };
52 53
53static int timeout; /* in seconds */ 54static int timeout; /* in seconds */
54module_param(timeout, int, 0); 55module_param(timeout, int, 0);
@@ -92,15 +93,21 @@ MODULE_PARM_DESC(early_disable, "Disable watchdog at boot time (default=0)");
92#define W83667HG_B_ID 0xb3 93#define W83667HG_B_ID 0xb3
93#define NCT6775_ID 0xb4 94#define NCT6775_ID 0xb4
94#define NCT6776_ID 0xc3 95#define NCT6776_ID 0xc3
96#define NCT6102_ID 0xc4
95#define NCT6779_ID 0xc5 97#define NCT6779_ID 0xc5
96#define NCT6791_ID 0xc8 98#define NCT6791_ID 0xc8
97#define NCT6792_ID 0xc9 99#define NCT6792_ID 0xc9
98 100
99#define W83627HF_WDT_TIMEOUT 0xf6 101#define W83627HF_WDT_TIMEOUT 0xf6
100#define W83697HF_WDT_TIMEOUT 0xf4 102#define W83697HF_WDT_TIMEOUT 0xf4
103#define NCT6102D_WDT_TIMEOUT 0xf1
101 104
102#define W83627HF_WDT_CONTROL 0xf5 105#define W83627HF_WDT_CONTROL 0xf5
103#define W83697HF_WDT_CONTROL 0xf3 106#define W83697HF_WDT_CONTROL 0xf3
107#define NCT6102D_WDT_CONTROL 0xf0
108
109#define W836X7HF_WDT_CSR 0xf7
110#define NCT6102D_WDT_CSR 0xf2
104 111
105static void superio_outb(int reg, int val) 112static void superio_outb(int reg, int val)
106{ 113{
@@ -197,6 +204,7 @@ static int w83627hf_init(struct watchdog_device *wdog, enum chips chip)
197 case nct6779: 204 case nct6779:
198 case nct6791: 205 case nct6791:
199 case nct6792: 206 case nct6792:
207 case nct6102:
200 /* 208 /*
201 * These chips have a fixed WDTO# output pin (W83627UHG), 209 * These chips have a fixed WDTO# output pin (W83627UHG),
202 * or support more than one WDTO# output pin. 210 * or support more than one WDTO# output pin.
@@ -229,8 +237,8 @@ static int w83627hf_init(struct watchdog_device *wdog, enum chips chip)
229 superio_outb(cr_wdt_control, t); 237 superio_outb(cr_wdt_control, t);
230 238
231 /* reset trigger, disable keyboard & mouse turning off watchdog */ 239 /* reset trigger, disable keyboard & mouse turning off watchdog */
232 t = superio_inb(0xF7) & ~0xD0; 240 t = superio_inb(cr_wdt_csr) & ~0xD0;
233 superio_outb(0xF7, t); 241 superio_outb(cr_wdt_csr, t);
234 242
235 superio_exit(); 243 superio_exit();
236 244
@@ -322,6 +330,7 @@ static int wdt_find(int addr)
322 330
323 cr_wdt_timeout = W83627HF_WDT_TIMEOUT; 331 cr_wdt_timeout = W83627HF_WDT_TIMEOUT;
324 cr_wdt_control = W83627HF_WDT_CONTROL; 332 cr_wdt_control = W83627HF_WDT_CONTROL;
333 cr_wdt_csr = W836X7HF_WDT_CSR;
325 334
326 ret = superio_enter(); 335 ret = superio_enter();
327 if (ret) 336 if (ret)
@@ -387,6 +396,12 @@ static int wdt_find(int addr)
387 case NCT6792_ID: 396 case NCT6792_ID:
388 ret = nct6792; 397 ret = nct6792;
389 break; 398 break;
399 case NCT6102_ID:
400 ret = nct6102;
401 cr_wdt_timeout = NCT6102D_WDT_TIMEOUT;
402 cr_wdt_control = NCT6102D_WDT_CONTROL;
403 cr_wdt_csr = NCT6102D_WDT_CSR;
404 break;
390 case 0xff: 405 case 0xff:
391 ret = -ENODEV; 406 ret = -ENODEV;
392 break; 407 break;
@@ -422,6 +437,7 @@ static int __init wdt_init(void)
422 "NCT6779", 437 "NCT6779",
423 "NCT6791", 438 "NCT6791",
424 "NCT6792", 439 "NCT6792",
440 "NCT6102",
425 }; 441 };
426 442
427 wdt_io = 0x2e; 443 wdt_io = 0x2e;
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
index e600fd93b7de..c1658fe73d58 100644
--- a/drivers/watchdog/watchdog_core.c
+++ b/drivers/watchdog/watchdog_core.c
@@ -164,7 +164,7 @@ static int watchdog_restart_notifier(struct notifier_block *nb,
164 164
165 int ret; 165 int ret;
166 166
167 ret = wdd->ops->restart(wdd); 167 ret = wdd->ops->restart(wdd, action, data);
168 if (ret) 168 if (ret)
169 return NOTIFY_BAD; 169 return NOTIFY_BAD;
170 170
@@ -199,7 +199,7 @@ static int __watchdog_register_device(struct watchdog_device *wdd)
199 return -EINVAL; 199 return -EINVAL;
200 200
201 /* Mandatory operations need to be supported */ 201 /* Mandatory operations need to be supported */
202 if (wdd->ops->start == NULL || wdd->ops->stop == NULL) 202 if (!wdd->ops->start || (!wdd->ops->stop && !wdd->max_hw_heartbeat_ms))
203 return -EINVAL; 203 return -EINVAL;
204 204
205 watchdog_check_min_max_timeout(wdd); 205 watchdog_check_min_max_timeout(wdd);
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index ba2ecce4aae6..e2c5abbb45ff 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -36,6 +36,7 @@
36#include <linux/errno.h> /* For the -ENODEV/... values */ 36#include <linux/errno.h> /* For the -ENODEV/... values */
37#include <linux/fs.h> /* For file operations */ 37#include <linux/fs.h> /* For file operations */
38#include <linux/init.h> /* For __init/__exit/... */ 38#include <linux/init.h> /* For __init/__exit/... */
39#include <linux/jiffies.h> /* For timeout functions */
39#include <linux/kernel.h> /* For printk/panic/... */ 40#include <linux/kernel.h> /* For printk/panic/... */
40#include <linux/kref.h> /* For data references */ 41#include <linux/kref.h> /* For data references */
41#include <linux/miscdevice.h> /* For handling misc devices */ 42#include <linux/miscdevice.h> /* For handling misc devices */
@@ -44,6 +45,7 @@
44#include <linux/slab.h> /* For memory functions */ 45#include <linux/slab.h> /* For memory functions */
45#include <linux/types.h> /* For standard types (like size_t) */ 46#include <linux/types.h> /* For standard types (like size_t) */
46#include <linux/watchdog.h> /* For watchdog specific items */ 47#include <linux/watchdog.h> /* For watchdog specific items */
48#include <linux/workqueue.h> /* For workqueue */
47#include <linux/uaccess.h> /* For copy_to_user/put_user/... */ 49#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
48 50
49#include "watchdog_core.h" 51#include "watchdog_core.h"
@@ -61,6 +63,9 @@ struct watchdog_core_data {
61 struct cdev cdev; 63 struct cdev cdev;
62 struct watchdog_device *wdd; 64 struct watchdog_device *wdd;
63 struct mutex lock; 65 struct mutex lock;
66 unsigned long last_keepalive;
67 unsigned long last_hw_keepalive;
68 struct delayed_work work;
64 unsigned long status; /* Internal status bits */ 69 unsigned long status; /* Internal status bits */
65#define _WDOG_DEV_OPEN 0 /* Opened ? */ 70#define _WDOG_DEV_OPEN 0 /* Opened ? */
66#define _WDOG_ALLOW_RELEASE 1 /* Did we receive the magic char ? */ 71#define _WDOG_ALLOW_RELEASE 1 /* Did we receive the magic char ? */
@@ -71,6 +76,91 @@ static dev_t watchdog_devt;
71/* Reference to watchdog device behind /dev/watchdog */ 76/* Reference to watchdog device behind /dev/watchdog */
72static struct watchdog_core_data *old_wd_data; 77static struct watchdog_core_data *old_wd_data;
73 78
79static struct workqueue_struct *watchdog_wq;
80
81static inline bool watchdog_need_worker(struct watchdog_device *wdd)
82{
83 /* All variables in milli-seconds */
84 unsigned int hm = wdd->max_hw_heartbeat_ms;
85 unsigned int t = wdd->timeout * 1000;
86
87 /*
88 * A worker to generate heartbeat requests is needed if all of the
89 * following conditions are true.
90 * - Userspace activated the watchdog.
91 * - The driver provided a value for the maximum hardware timeout, and
92 * thus is aware that the framework supports generating heartbeat
93 * requests.
94 * - Userspace requests a longer timeout than the hardware can handle.
95 */
96 return hm && ((watchdog_active(wdd) && t > hm) ||
97 (t && !watchdog_active(wdd) && watchdog_hw_running(wdd)));
98}
99
100static long watchdog_next_keepalive(struct watchdog_device *wdd)
101{
102 struct watchdog_core_data *wd_data = wdd->wd_data;
103 unsigned int timeout_ms = wdd->timeout * 1000;
104 unsigned long keepalive_interval;
105 unsigned long last_heartbeat;
106 unsigned long virt_timeout;
107 unsigned int hw_heartbeat_ms;
108
109 virt_timeout = wd_data->last_keepalive + msecs_to_jiffies(timeout_ms);
110 hw_heartbeat_ms = min(timeout_ms, wdd->max_hw_heartbeat_ms);
111 keepalive_interval = msecs_to_jiffies(hw_heartbeat_ms / 2);
112
113 if (!watchdog_active(wdd))
114 return keepalive_interval;
115
116 /*
117 * To ensure that the watchdog times out wdd->timeout seconds
118 * after the most recent ping from userspace, the last
119 * worker ping has to come in hw_heartbeat_ms before this timeout.
120 */
121 last_heartbeat = virt_timeout - msecs_to_jiffies(hw_heartbeat_ms);
122 return min_t(long, last_heartbeat - jiffies, keepalive_interval);
123}
124
125static inline void watchdog_update_worker(struct watchdog_device *wdd)
126{
127 struct watchdog_core_data *wd_data = wdd->wd_data;
128
129 if (watchdog_need_worker(wdd)) {
130 long t = watchdog_next_keepalive(wdd);
131
132 if (t > 0)
133 mod_delayed_work(watchdog_wq, &wd_data->work, t);
134 } else {
135 cancel_delayed_work(&wd_data->work);
136 }
137}
138
139static int __watchdog_ping(struct watchdog_device *wdd)
140{
141 struct watchdog_core_data *wd_data = wdd->wd_data;
142 unsigned long earliest_keepalive = wd_data->last_hw_keepalive +
143 msecs_to_jiffies(wdd->min_hw_heartbeat_ms);
144 int err;
145
146 if (time_is_after_jiffies(earliest_keepalive)) {
147 mod_delayed_work(watchdog_wq, &wd_data->work,
148 earliest_keepalive - jiffies);
149 return 0;
150 }
151
152 wd_data->last_hw_keepalive = jiffies;
153
154 if (wdd->ops->ping)
155 err = wdd->ops->ping(wdd); /* ping the watchdog */
156 else
157 err = wdd->ops->start(wdd); /* restart watchdog */
158
159 watchdog_update_worker(wdd);
160
161 return err;
162}
163
74/* 164/*
75 * watchdog_ping: ping the watchdog. 165 * watchdog_ping: ping the watchdog.
76 * @wdd: the watchdog device to ping 166 * @wdd: the watchdog device to ping
@@ -85,17 +175,28 @@ static struct watchdog_core_data *old_wd_data;
85 175
86static int watchdog_ping(struct watchdog_device *wdd) 176static int watchdog_ping(struct watchdog_device *wdd)
87{ 177{
88 int err; 178 struct watchdog_core_data *wd_data = wdd->wd_data;
89 179
90 if (!watchdog_active(wdd)) 180 if (!watchdog_active(wdd) && !watchdog_hw_running(wdd))
91 return 0; 181 return 0;
92 182
93 if (wdd->ops->ping) 183 wd_data->last_keepalive = jiffies;
94 err = wdd->ops->ping(wdd); /* ping the watchdog */ 184 return __watchdog_ping(wdd);
95 else 185}
96 err = wdd->ops->start(wdd); /* restart watchdog */
97 186
98 return err; 187static void watchdog_ping_work(struct work_struct *work)
188{
189 struct watchdog_core_data *wd_data;
190 struct watchdog_device *wdd;
191
192 wd_data = container_of(to_delayed_work(work), struct watchdog_core_data,
193 work);
194
195 mutex_lock(&wd_data->lock);
196 wdd = wd_data->wdd;
197 if (wdd && (watchdog_active(wdd) || watchdog_hw_running(wdd)))
198 __watchdog_ping(wdd);
199 mutex_unlock(&wd_data->lock);
99} 200}
100 201
101/* 202/*
@@ -111,14 +212,23 @@ static int watchdog_ping(struct watchdog_device *wdd)
111 212
112static int watchdog_start(struct watchdog_device *wdd) 213static int watchdog_start(struct watchdog_device *wdd)
113{ 214{
215 struct watchdog_core_data *wd_data = wdd->wd_data;
216 unsigned long started_at;
114 int err; 217 int err;
115 218
116 if (watchdog_active(wdd)) 219 if (watchdog_active(wdd))
117 return 0; 220 return 0;
118 221
119 err = wdd->ops->start(wdd); 222 started_at = jiffies;
120 if (err == 0) 223 if (watchdog_hw_running(wdd) && wdd->ops->ping)
224 err = wdd->ops->ping(wdd);
225 else
226 err = wdd->ops->start(wdd);
227 if (err == 0) {
121 set_bit(WDOG_ACTIVE, &wdd->status); 228 set_bit(WDOG_ACTIVE, &wdd->status);
229 wd_data->last_keepalive = started_at;
230 watchdog_update_worker(wdd);
231 }
122 232
123 return err; 233 return err;
124} 234}
@@ -137,7 +247,7 @@ static int watchdog_start(struct watchdog_device *wdd)
137 247
138static int watchdog_stop(struct watchdog_device *wdd) 248static int watchdog_stop(struct watchdog_device *wdd)
139{ 249{
140 int err; 250 int err = 0;
141 251
142 if (!watchdog_active(wdd)) 252 if (!watchdog_active(wdd))
143 return 0; 253 return 0;
@@ -148,9 +258,15 @@ static int watchdog_stop(struct watchdog_device *wdd)
148 return -EBUSY; 258 return -EBUSY;
149 } 259 }
150 260
151 err = wdd->ops->stop(wdd); 261 if (wdd->ops->stop)
152 if (err == 0) 262 err = wdd->ops->stop(wdd);
263 else
264 set_bit(WDOG_HW_RUNNING, &wdd->status);
265
266 if (err == 0) {
153 clear_bit(WDOG_ACTIVE, &wdd->status); 267 clear_bit(WDOG_ACTIVE, &wdd->status);
268 watchdog_update_worker(wdd);
269 }
154 270
155 return err; 271 return err;
156} 272}
@@ -183,13 +299,22 @@ static unsigned int watchdog_get_status(struct watchdog_device *wdd)
183static int watchdog_set_timeout(struct watchdog_device *wdd, 299static int watchdog_set_timeout(struct watchdog_device *wdd,
184 unsigned int timeout) 300 unsigned int timeout)
185{ 301{
186 if (!wdd->ops->set_timeout || !(wdd->info->options & WDIOF_SETTIMEOUT)) 302 int err = 0;
303
304 if (!(wdd->info->options & WDIOF_SETTIMEOUT))
187 return -EOPNOTSUPP; 305 return -EOPNOTSUPP;
188 306
189 if (watchdog_timeout_invalid(wdd, timeout)) 307 if (watchdog_timeout_invalid(wdd, timeout))
190 return -EINVAL; 308 return -EINVAL;
191 309
192 return wdd->ops->set_timeout(wdd, timeout); 310 if (wdd->ops->set_timeout)
311 err = wdd->ops->set_timeout(wdd, timeout);
312 else
313 wdd->timeout = timeout;
314
315 watchdog_update_worker(wdd);
316
317 return err;
193} 318}
194 319
195/* 320/*
@@ -538,7 +663,7 @@ static int watchdog_open(struct inode *inode, struct file *file)
538 * If the /dev/watchdog device is open, we don't want the module 663 * If the /dev/watchdog device is open, we don't want the module
539 * to be unloaded. 664 * to be unloaded.
540 */ 665 */
541 if (!try_module_get(wdd->ops->owner)) { 666 if (!watchdog_hw_running(wdd) && !try_module_get(wdd->ops->owner)) {
542 err = -EBUSY; 667 err = -EBUSY;
543 goto out_clear; 668 goto out_clear;
544 } 669 }
@@ -549,7 +674,8 @@ static int watchdog_open(struct inode *inode, struct file *file)
549 674
550 file->private_data = wd_data; 675 file->private_data = wd_data;
551 676
552 kref_get(&wd_data->kref); 677 if (!watchdog_hw_running(wdd))
678 kref_get(&wd_data->kref);
553 679
554 /* dev/watchdog is a virtual (and thus non-seekable) filesystem */ 680 /* dev/watchdog is a virtual (and thus non-seekable) filesystem */
555 return nonseekable_open(inode, file); 681 return nonseekable_open(inode, file);
@@ -585,6 +711,7 @@ static int watchdog_release(struct inode *inode, struct file *file)
585 struct watchdog_core_data *wd_data = file->private_data; 711 struct watchdog_core_data *wd_data = file->private_data;
586 struct watchdog_device *wdd; 712 struct watchdog_device *wdd;
587 int err = -EBUSY; 713 int err = -EBUSY;
714 bool running;
588 715
589 mutex_lock(&wd_data->lock); 716 mutex_lock(&wd_data->lock);
590 717
@@ -609,14 +736,24 @@ static int watchdog_release(struct inode *inode, struct file *file)
609 watchdog_ping(wdd); 736 watchdog_ping(wdd);
610 } 737 }
611 738
739 cancel_delayed_work_sync(&wd_data->work);
740 watchdog_update_worker(wdd);
741
612 /* make sure that /dev/watchdog can be re-opened */ 742 /* make sure that /dev/watchdog can be re-opened */
613 clear_bit(_WDOG_DEV_OPEN, &wd_data->status); 743 clear_bit(_WDOG_DEV_OPEN, &wd_data->status);
614 744
615done: 745done:
746 running = wdd && watchdog_hw_running(wdd);
616 mutex_unlock(&wd_data->lock); 747 mutex_unlock(&wd_data->lock);
617 /* Allow the owner module to be unloaded again */ 748 /*
618 module_put(wd_data->cdev.owner); 749 * Allow the owner module to be unloaded again unless the watchdog
619 kref_put(&wd_data->kref, watchdog_core_data_release); 750 * is still running. If the watchdog is still running, it can not
751 * be stopped, and its driver must not be unloaded.
752 */
753 if (!running) {
754 module_put(wd_data->cdev.owner);
755 kref_put(&wd_data->kref, watchdog_core_data_release);
756 }
620 return 0; 757 return 0;
621} 758}
622 759
@@ -658,6 +795,11 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
658 wd_data->wdd = wdd; 795 wd_data->wdd = wdd;
659 wdd->wd_data = wd_data; 796 wdd->wd_data = wd_data;
660 797
798 if (!watchdog_wq)
799 return -ENODEV;
800
801 INIT_DELAYED_WORK(&wd_data->work, watchdog_ping_work);
802
661 if (wdd->id == 0) { 803 if (wdd->id == 0) {
662 old_wd_data = wd_data; 804 old_wd_data = wd_data;
663 watchdog_miscdev.parent = wdd->parent; 805 watchdog_miscdev.parent = wdd->parent;
@@ -688,8 +830,23 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
688 old_wd_data = NULL; 830 old_wd_data = NULL;
689 kref_put(&wd_data->kref, watchdog_core_data_release); 831 kref_put(&wd_data->kref, watchdog_core_data_release);
690 } 832 }
833 return err;
691 } 834 }
692 return err; 835
836 /* Record time of most recent heartbeat as 'just before now'. */
837 wd_data->last_hw_keepalive = jiffies - 1;
838
839 /*
840 * If the watchdog is running, prevent its driver from being unloaded,
841 * and schedule an immediate ping.
842 */
843 if (watchdog_hw_running(wdd)) {
844 __module_get(wdd->ops->owner);
845 kref_get(&wd_data->kref);
846 queue_delayed_work(watchdog_wq, &wd_data->work, 0);
847 }
848
849 return 0;
693} 850}
694 851
695/* 852/*
@@ -715,6 +872,8 @@ static void watchdog_cdev_unregister(struct watchdog_device *wdd)
715 wdd->wd_data = NULL; 872 wdd->wd_data = NULL;
716 mutex_unlock(&wd_data->lock); 873 mutex_unlock(&wd_data->lock);
717 874
875 cancel_delayed_work_sync(&wd_data->work);
876
718 kref_put(&wd_data->kref, watchdog_core_data_release); 877 kref_put(&wd_data->kref, watchdog_core_data_release);
719} 878}
720 879
@@ -780,6 +939,13 @@ int __init watchdog_dev_init(void)
780{ 939{
781 int err; 940 int err;
782 941
942 watchdog_wq = alloc_workqueue("watchdogd",
943 WQ_HIGHPRI | WQ_MEM_RECLAIM, 0);
944 if (!watchdog_wq) {
945 pr_err("Failed to create watchdog workqueue\n");
946 return -ENOMEM;
947 }
948
783 err = class_register(&watchdog_class); 949 err = class_register(&watchdog_class);
784 if (err < 0) { 950 if (err < 0) {
785 pr_err("couldn't register class\n"); 951 pr_err("couldn't register class\n");
@@ -806,4 +972,5 @@ void __exit watchdog_dev_exit(void)
806{ 972{
807 unregister_chrdev_region(watchdog_devt, MAX_DOGS); 973 unregister_chrdev_region(watchdog_devt, MAX_DOGS);
808 class_unregister(&watchdog_class); 974 class_unregister(&watchdog_class);
975 destroy_workqueue(watchdog_wq);
809} 976}
diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c
index 0c7cb7302cf0..cbe373de3659 100644
--- a/drivers/watchdog/ziirave_wdt.c
+++ b/drivers/watchdog/ziirave_wdt.c
@@ -36,7 +36,7 @@
36#define ZIIRAVE_STATE_OFF 0x1 36#define ZIIRAVE_STATE_OFF 0x1
37#define ZIIRAVE_STATE_ON 0x2 37#define ZIIRAVE_STATE_ON 0x2
38 38
39static char *ziirave_reasons[] = {"power cycle", "triggered", NULL, NULL, 39static char *ziirave_reasons[] = {"power cycle", "hw watchdog", NULL, NULL,
40 "host request", NULL, "illegal configuration", 40 "host request", NULL, "illegal configuration",
41 "illegal instruction", "illegal trap", 41 "illegal instruction", "illegal trap",
42 "unknown"}; 42 "unknown"};
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index b585fa2507ee..51732d6c9555 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -10,8 +10,9 @@
10 10
11 11
12#include <linux/bitops.h> 12#include <linux/bitops.h>
13#include <linux/device.h>
14#include <linux/cdev.h> 13#include <linux/cdev.h>
14#include <linux/device.h>
15#include <linux/kernel.h>
15#include <linux/notifier.h> 16#include <linux/notifier.h>
16#include <uapi/linux/watchdog.h> 17#include <uapi/linux/watchdog.h>
17 18
@@ -46,7 +47,7 @@ struct watchdog_ops {
46 unsigned int (*status)(struct watchdog_device *); 47 unsigned int (*status)(struct watchdog_device *);
47 int (*set_timeout)(struct watchdog_device *, unsigned int); 48 int (*set_timeout)(struct watchdog_device *, unsigned int);
48 unsigned int (*get_timeleft)(struct watchdog_device *); 49 unsigned int (*get_timeleft)(struct watchdog_device *);
49 int (*restart)(struct watchdog_device *); 50 int (*restart)(struct watchdog_device *, unsigned long, void *);
50 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long); 51 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
51}; 52};
52 53
@@ -61,14 +62,21 @@ struct watchdog_ops {
61 * @bootstatus: Status of the watchdog device at boot. 62 * @bootstatus: Status of the watchdog device at boot.
62 * @timeout: The watchdog devices timeout value (in seconds). 63 * @timeout: The watchdog devices timeout value (in seconds).
63 * @min_timeout:The watchdog devices minimum timeout value (in seconds). 64 * @min_timeout:The watchdog devices minimum timeout value (in seconds).
64 * @max_timeout:The watchdog devices maximum timeout value (in seconds). 65 * @max_timeout:The watchdog devices maximum timeout value (in seconds)
66 * as configurable from user space. Only relevant if
67 * max_hw_heartbeat_ms is not provided.
68 * @min_hw_heartbeat_ms:
69 * Minimum time between heartbeats, in milli-seconds.
70 * @max_hw_heartbeat_ms:
71 * Hardware limit for maximum timeout, in milli-seconds.
72 * Replaces max_timeout if specified.
65 * @reboot_nb: The notifier block to stop watchdog on reboot. 73 * @reboot_nb: The notifier block to stop watchdog on reboot.
66 * @restart_nb: The notifier block to register a restart function. 74 * @restart_nb: The notifier block to register a restart function.
67 * @driver_data:Pointer to the drivers private data. 75 * @driver_data:Pointer to the drivers private data.
68 * @wd_data: Pointer to watchdog core internal data. 76 * @wd_data: Pointer to watchdog core internal data.
69 * @status: Field that contains the devices internal status bits. 77 * @status: Field that contains the devices internal status bits.
70 * @deferred: entry in wtd_deferred_reg_list which is used to 78 * @deferred: Entry in wtd_deferred_reg_list which is used to
71 * register early initialized watchdogs. 79 * register early initialized watchdogs.
72 * 80 *
73 * The watchdog_device structure contains all information about a 81 * The watchdog_device structure contains all information about a
74 * watchdog timer device. 82 * watchdog timer device.
@@ -89,6 +97,8 @@ struct watchdog_device {
89 unsigned int timeout; 97 unsigned int timeout;
90 unsigned int min_timeout; 98 unsigned int min_timeout;
91 unsigned int max_timeout; 99 unsigned int max_timeout;
100 unsigned int min_hw_heartbeat_ms;
101 unsigned int max_hw_heartbeat_ms;
92 struct notifier_block reboot_nb; 102 struct notifier_block reboot_nb;
93 struct notifier_block restart_nb; 103 struct notifier_block restart_nb;
94 void *driver_data; 104 void *driver_data;
@@ -98,6 +108,7 @@ struct watchdog_device {
98#define WDOG_ACTIVE 0 /* Is the watchdog running/active */ 108#define WDOG_ACTIVE 0 /* Is the watchdog running/active */
99#define WDOG_NO_WAY_OUT 1 /* Is 'nowayout' feature set ? */ 109#define WDOG_NO_WAY_OUT 1 /* Is 'nowayout' feature set ? */
100#define WDOG_STOP_ON_REBOOT 2 /* Should be stopped on reboot */ 110#define WDOG_STOP_ON_REBOOT 2 /* Should be stopped on reboot */
111#define WDOG_HW_RUNNING 3 /* True if HW watchdog running */
101 struct list_head deferred; 112 struct list_head deferred;
102}; 113};
103 114
@@ -110,6 +121,15 @@ static inline bool watchdog_active(struct watchdog_device *wdd)
110 return test_bit(WDOG_ACTIVE, &wdd->status); 121 return test_bit(WDOG_ACTIVE, &wdd->status);
111} 122}
112 123
124/*
125 * Use the following function to check whether or not the hardware watchdog
126 * is running
127 */
128static inline bool watchdog_hw_running(struct watchdog_device *wdd)
129{
130 return test_bit(WDOG_HW_RUNNING, &wdd->status);
131}
132
113/* Use the following function to set the nowayout feature */ 133/* Use the following function to set the nowayout feature */
114static inline void watchdog_set_nowayout(struct watchdog_device *wdd, bool nowayout) 134static inline void watchdog_set_nowayout(struct watchdog_device *wdd, bool nowayout)
115{ 135{
@@ -128,13 +148,18 @@ static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne
128{ 148{
129 /* 149 /*
130 * The timeout is invalid if 150 * The timeout is invalid if
151 * - the requested value is larger than UINT_MAX / 1000
152 * (since internal calculations are done in milli-seconds),
153 * or
131 * - the requested value is smaller than the configured minimum timeout, 154 * - the requested value is smaller than the configured minimum timeout,
132 * or 155 * or
133 * - a maximum timeout is configured, and the requested value is larger 156 * - a maximum hardware timeout is not configured, a maximum timeout
134 * than the maximum timeout. 157 * is configured, and the requested value is larger than the
158 * configured maximum timeout.
135 */ 159 */
136 return t < wdd->min_timeout || 160 return t > UINT_MAX / 1000 || t < wdd->min_timeout ||
137 (wdd->max_timeout && t > wdd->max_timeout); 161 (!wdd->max_hw_heartbeat_ms && wdd->max_timeout &&
162 t > wdd->max_timeout);
138} 163}
139 164
140/* Use the following functions to manipulate watchdog driver specific data */ 165/* Use the following functions to manipulate watchdog driver specific data */