aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/watchdog/of-xilinx-wdt.txt3
-rw-r--r--Documentation/devicetree/bindings/watchdog/st_lpc_wdt.txt3
-rw-r--r--Documentation/watchdog/watchdog-kernel-api.txt33
-rw-r--r--drivers/watchdog/Kconfig49
-rw-r--r--drivers/watchdog/Makefile8
-rw-r--r--drivers/watchdog/asm9260_wdt.c1
-rw-r--r--drivers/watchdog/bcm7038_wdt.c2
-rw-r--r--drivers/watchdog/cadence_wdt.c20
-rw-r--r--drivers/watchdog/dw_wdt.c11
-rw-r--r--drivers/watchdog/hpwdt.c8
-rw-r--r--drivers/watchdog/iTCO_wdt.c2
-rw-r--r--drivers/watchdog/imx2_wdt.c60
-rw-r--r--drivers/watchdog/kempld_wdt.c2
-rw-r--r--drivers/watchdog/mt7621_wdt.c1
-rw-r--r--drivers/watchdog/of_xilinx_wdt.c25
-rw-r--r--drivers/watchdog/pretimeout_noop.c47
-rw-r--r--drivers/watchdog/pretimeout_panic.c47
-rw-r--r--drivers/watchdog/rn5t618_wdt.c2
-rw-r--r--drivers/watchdog/rt2880_wdt.c1
-rw-r--r--drivers/watchdog/softdog.c24
-rw-r--r--drivers/watchdog/st_lpc_wdt.c33
-rw-r--r--drivers/watchdog/tegra_wdt.c2
-rw-r--r--drivers/watchdog/txx9wdt.c6
-rw-r--r--drivers/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/watchdog/watchdog_core.c2
-rw-r--r--drivers/watchdog/watchdog_dev.c101
-rw-r--r--drivers/watchdog/watchdog_pretimeout.c220
-rw-r--r--drivers/watchdog/watchdog_pretimeout.h60
-rw-r--r--drivers/watchdog/ziirave_wdt.c409
-rw-r--r--fs/compat_ioctl.c2
-rw-r--r--include/linux/watchdog.h24
31 files changed, 1131 insertions, 79 deletions
diff --git a/Documentation/devicetree/bindings/watchdog/of-xilinx-wdt.txt b/Documentation/devicetree/bindings/watchdog/of-xilinx-wdt.txt
index 6d63782a7378..c6ae9c9d5e3e 100644
--- a/Documentation/devicetree/bindings/watchdog/of-xilinx-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/of-xilinx-wdt.txt
@@ -7,6 +7,8 @@ Required properties:
7- reg : Physical base address and size 7- reg : Physical base address and size
8 8
9Optional properties: 9Optional properties:
10- clocks : Input clock specifier. Refer to common clock
11 bindings.
10- clock-frequency : Frequency of clock in Hz 12- clock-frequency : Frequency of clock in Hz
11- xlnx,wdt-enable-once : 0 - Watchdog can be restarted 13- xlnx,wdt-enable-once : 0 - Watchdog can be restarted
12 1 - Watchdog can be enabled just once 14 1 - Watchdog can be enabled just once
@@ -17,6 +19,7 @@ Example:
17axi-timebase-wdt@40100000 { 19axi-timebase-wdt@40100000 {
18 clock-frequency = <50000000>; 20 clock-frequency = <50000000>;
19 compatible = "xlnx,xps-timebase-wdt-1.00.a"; 21 compatible = "xlnx,xps-timebase-wdt-1.00.a";
22 clocks = <&clkc 15>;
20 reg = <0x40100000 0x10000>; 23 reg = <0x40100000 0x10000>;
21 xlnx,wdt-enable-once = <0x0>; 24 xlnx,wdt-enable-once = <0x0>;
22 xlnx,wdt-interval = <0x1b>; 25 xlnx,wdt-interval = <0x1b>;
diff --git a/Documentation/devicetree/bindings/watchdog/st_lpc_wdt.txt b/Documentation/devicetree/bindings/watchdog/st_lpc_wdt.txt
index 039c5ca45577..b949039bc502 100644
--- a/Documentation/devicetree/bindings/watchdog/st_lpc_wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/st_lpc_wdt.txt
@@ -9,8 +9,7 @@ functionality.
9 9
10Required properties 10Required properties
11 11
12- compatible : Must be one of: "st,stih407-lpc" "st,stih416-lpc" 12- compatible : Should be: "st,stih407-lpc"
13 "st,stih415-lpc" "st,stid127-lpc"
14- reg : LPC registers base address + size 13- reg : LPC registers base address + size
15- interrupts : LPC interrupt line number and associated flags 14- interrupts : LPC interrupt line number and associated flags
16- clocks : Clock used by LPC device (See: ../clock/clock-bindings.txt) 15- clocks : Clock used by LPC device (See: ../clock/clock-bindings.txt)
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
index 7f31125c123e..ea277478982f 100644
--- a/Documentation/watchdog/watchdog-kernel-api.txt
+++ b/Documentation/watchdog/watchdog-kernel-api.txt
@@ -48,8 +48,10 @@ struct watchdog_device {
48 const struct attribute_group **groups; 48 const struct attribute_group **groups;
49 const struct watchdog_info *info; 49 const struct watchdog_info *info;
50 const struct watchdog_ops *ops; 50 const struct watchdog_ops *ops;
51 const struct watchdog_governor *gov;
51 unsigned int bootstatus; 52 unsigned int bootstatus;
52 unsigned int timeout; 53 unsigned int timeout;
54 unsigned int pretimeout;
53 unsigned int min_timeout; 55 unsigned int min_timeout;
54 unsigned int max_timeout; 56 unsigned int max_timeout;
55 unsigned int min_hw_heartbeat_ms; 57 unsigned int min_hw_heartbeat_ms;
@@ -74,9 +76,11 @@ It contains following fields:
74* info: a pointer to a watchdog_info structure. This structure gives some 76* info: a pointer to a watchdog_info structure. This structure gives some
75 additional information about the watchdog timer itself. (Like it's unique name) 77 additional information about the watchdog timer itself. (Like it's unique name)
76* ops: a pointer to the list of watchdog operations that the watchdog supports. 78* ops: a pointer to the list of watchdog operations that the watchdog supports.
79* gov: a pointer to the assigned watchdog device pretimeout governor or NULL.
77* timeout: the watchdog timer's timeout value (in seconds). 80* timeout: the watchdog timer's timeout value (in seconds).
78 This is the time after which the system will reboot if user space does 81 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. 82 not send a heartbeat request if WDOG_ACTIVE is set.
83* pretimeout: the watchdog timer's pretimeout value (in seconds).
80* min_timeout: the watchdog timer's minimum timeout value (in seconds). 84* min_timeout: the watchdog timer's minimum timeout value (in seconds).
81 If set, the minimum configurable value for 'timeout'. 85 If set, the minimum configurable value for 'timeout'.
82* max_timeout: the watchdog timer's maximum timeout value (in seconds), 86* max_timeout: the watchdog timer's maximum timeout value (in seconds),
@@ -121,6 +125,7 @@ struct watchdog_ops {
121 int (*ping)(struct watchdog_device *); 125 int (*ping)(struct watchdog_device *);
122 unsigned int (*status)(struct watchdog_device *); 126 unsigned int (*status)(struct watchdog_device *);
123 int (*set_timeout)(struct watchdog_device *, unsigned int); 127 int (*set_timeout)(struct watchdog_device *, unsigned int);
128 int (*set_pretimeout)(struct watchdog_device *, unsigned int);
124 unsigned int (*get_timeleft)(struct watchdog_device *); 129 unsigned int (*get_timeleft)(struct watchdog_device *);
125 int (*restart)(struct watchdog_device *); 130 int (*restart)(struct watchdog_device *);
126 void (*ref)(struct watchdog_device *) __deprecated; 131 void (*ref)(struct watchdog_device *) __deprecated;
@@ -188,6 +193,23 @@ they are supported. These optional routines/operations are:
188 If set_timeout is not provided but, WDIOF_SETTIMEOUT is set, the watchdog 193 If set_timeout is not provided but, WDIOF_SETTIMEOUT is set, the watchdog
189 infrastructure updates the timeout value of the watchdog_device internally 194 infrastructure updates the timeout value of the watchdog_device internally
190 to the requested value. 195 to the requested value.
196 If the pretimeout feature is used (WDIOF_PRETIMEOUT), then set_timeout must
197 also take care of checking if pretimeout is still valid and set up the timer
198 accordingly. This can't be done in the core without races, so it is the
199 duty of the driver.
200* set_pretimeout: this routine checks and changes the pretimeout value of
201 the watchdog. It is optional because not all watchdogs support pretimeout
202 notification. The timeout value is not an absolute time, but the number of
203 seconds before the actual timeout would happen. It returns 0 on success,
204 -EINVAL for "parameter out of range" and -EIO for "could not write value to
205 the watchdog". A value of 0 disables pretimeout notification.
206 (Note: the WDIOF_PRETIMEOUT needs to be set in the options field of the
207 watchdog's info structure).
208 If the watchdog driver does not have to perform any action but setting the
209 watchdog_device.pretimeout, this callback can be omitted. That means if
210 set_pretimeout is not provided but WDIOF_PRETIMEOUT is set, the watchdog
211 infrastructure updates the pretimeout value of the watchdog_device internally
212 to the requested value.
191* get_timeleft: this routines returns the time that's left before a reset. 213* get_timeleft: this routines returns the time that's left before a reset.
192* restart: this routine restarts the machine. It returns 0 on success or a 214* restart: this routine restarts the machine. It returns 0 on success or a
193 negative errno code for failure. 215 negative errno code for failure.
@@ -268,3 +290,14 @@ User should follow the following guidelines for setting the priority:
268* 128: default restart handler, use if no other handler is expected to be 290* 128: default restart handler, use if no other handler is expected to be
269 available, and/or if restart is sufficient to restart the entire system 291 available, and/or if restart is sufficient to restart the entire system
270* 255: highest priority, will preempt all other restart handlers 292* 255: highest priority, will preempt all other restart handlers
293
294To raise a pretimeout notification, the following function should be used:
295
296void watchdog_notify_pretimeout(struct watchdog_device *wdd)
297
298The function can be called in the interrupt context. If watchdog pretimeout
299governor framework (kbuild CONFIG_WATCHDOG_PRETIMEOUT_GOV symbol) is enabled,
300an action is taken by a preconfigured pretimeout governor preassigned to
301the watchdog device. If watchdog pretimeout governor framework is not
302enabled, watchdog_notify_pretimeout() prints a notification message to
303the kernel log buffer.
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 50dbaa805658..fdd3228e0678 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1844,4 +1844,53 @@ config USBPCWATCHDOG
1844 1844
1845 Most people will say N. 1845 Most people will say N.
1846 1846
1847comment "Watchdog Pretimeout Governors"
1848
1849config WATCHDOG_PRETIMEOUT_GOV
1850 bool "Enable watchdog pretimeout governors"
1851 help
1852 The option allows to select watchdog pretimeout governors.
1853
1854if WATCHDOG_PRETIMEOUT_GOV
1855
1856choice
1857 prompt "Default Watchdog Pretimeout Governor"
1858 default WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
1859 help
1860 This option selects a default watchdog pretimeout governor.
1861 The governor takes its action, if a watchdog is capable
1862 to report a pretimeout event.
1863
1864config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP
1865 bool "noop"
1866 select WATCHDOG_PRETIMEOUT_GOV_NOOP
1867 help
1868 Use noop watchdog pretimeout governor by default. If noop
1869 governor is selected by a user, write a short message to
1870 the kernel log buffer and don't do any system changes.
1871
1872config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
1873 bool "panic"
1874 select WATCHDOG_PRETIMEOUT_GOV_PANIC
1875 help
1876 Use panic watchdog pretimeout governor by default, if
1877 a watchdog pretimeout event happens, consider that
1878 a watchdog feeder is dead and reboot is unavoidable.
1879
1880endchoice
1881
1882config WATCHDOG_PRETIMEOUT_GOV_NOOP
1883 tristate "Noop watchdog pretimeout governor"
1884 help
1885 Noop watchdog pretimeout governor, only an informational
1886 message is added to kernel log buffer.
1887
1888config WATCHDOG_PRETIMEOUT_GOV_PANIC
1889 tristate "Panic watchdog pretimeout governor"
1890 help
1891 Panic watchdog pretimeout governor, on watchdog pretimeout
1892 event put the kernel into panic.
1893
1894endif # WATCHDOG_PRETIMEOUT_GOV
1895
1847endif # WATCHDOG 1896endif # WATCHDOG
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index cba00430151b..caa9f4aa492a 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -3,9 +3,15 @@
3# 3#
4 4
5# The WatchDog Timer Driver Core. 5# The WatchDog Timer Driver Core.
6watchdog-objs += watchdog_core.o watchdog_dev.o
7obj-$(CONFIG_WATCHDOG_CORE) += watchdog.o 6obj-$(CONFIG_WATCHDOG_CORE) += watchdog.o
8 7
8watchdog-objs += watchdog_core.o watchdog_dev.o
9
10watchdog-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV) += watchdog_pretimeout.o
11
12obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP) += pretimeout_noop.o
13obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC) += pretimeout_panic.o
14
9# Only one watchdog can succeed. We probe the ISA/PCI/USB based 15# Only one watchdog can succeed. We probe the ISA/PCI/USB based
10# watchdog-cards first, then the architecture specific watchdog 16# watchdog-cards first, then the architecture specific watchdog
11# drivers and then the architecture independent "softdog" driver. 17# drivers and then the architecture independent "softdog" driver.
diff --git a/drivers/watchdog/asm9260_wdt.c b/drivers/watchdog/asm9260_wdt.c
index c9686b2fdafd..d0b59ba0f661 100644
--- a/drivers/watchdog/asm9260_wdt.c
+++ b/drivers/watchdog/asm9260_wdt.c
@@ -389,7 +389,6 @@ MODULE_DEVICE_TABLE(of, asm9260_wdt_of_match);
389static struct platform_driver asm9260_wdt_driver = { 389static struct platform_driver asm9260_wdt_driver = {
390 .driver = { 390 .driver = {
391 .name = "asm9260-wdt", 391 .name = "asm9260-wdt",
392 .owner = THIS_MODULE,
393 .of_match_table = asm9260_wdt_of_match, 392 .of_match_table = asm9260_wdt_of_match,
394 }, 393 },
395 .probe = asm9260_wdt_probe, 394 .probe = asm9260_wdt_probe,
diff --git a/drivers/watchdog/bcm7038_wdt.c b/drivers/watchdog/bcm7038_wdt.c
index 4245b65d645c..e238df4d75a2 100644
--- a/drivers/watchdog/bcm7038_wdt.c
+++ b/drivers/watchdog/bcm7038_wdt.c
@@ -107,7 +107,7 @@ static struct watchdog_info bcm7038_wdt_info = {
107 WDIOF_MAGICCLOSE 107 WDIOF_MAGICCLOSE
108}; 108};
109 109
110static struct watchdog_ops bcm7038_wdt_ops = { 110static const struct watchdog_ops bcm7038_wdt_ops = {
111 .owner = THIS_MODULE, 111 .owner = THIS_MODULE,
112 .start = bcm7038_wdt_start, 112 .start = bcm7038_wdt_start,
113 .stop = bcm7038_wdt_stop, 113 .stop = bcm7038_wdt_stop,
diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c
index 4dda9024e229..98acef72334d 100644
--- a/drivers/watchdog/cadence_wdt.c
+++ b/drivers/watchdog/cadence_wdt.c
@@ -269,7 +269,7 @@ static struct watchdog_info cdns_wdt_info = {
269}; 269};
270 270
271/* Watchdog Core Ops */ 271/* Watchdog Core Ops */
272static struct watchdog_ops cdns_wdt_ops = { 272static const struct watchdog_ops cdns_wdt_ops = {
273 .owner = THIS_MODULE, 273 .owner = THIS_MODULE,
274 .start = cdns_wdt_start, 274 .start = cdns_wdt_start,
275 .stop = cdns_wdt_stop, 275 .stop = cdns_wdt_stop,
@@ -424,8 +424,10 @@ static int __maybe_unused cdns_wdt_suspend(struct device *dev)
424 struct platform_device *pdev = to_platform_device(dev); 424 struct platform_device *pdev = to_platform_device(dev);
425 struct cdns_wdt *wdt = platform_get_drvdata(pdev); 425 struct cdns_wdt *wdt = platform_get_drvdata(pdev);
426 426
427 cdns_wdt_stop(&wdt->cdns_wdt_device); 427 if (watchdog_active(&wdt->cdns_wdt_device)) {
428 clk_disable_unprepare(wdt->clk); 428 cdns_wdt_stop(&wdt->cdns_wdt_device);
429 clk_disable_unprepare(wdt->clk);
430 }
429 431
430 return 0; 432 return 0;
431} 433}
@@ -442,12 +444,14 @@ static int __maybe_unused cdns_wdt_resume(struct device *dev)
442 struct platform_device *pdev = to_platform_device(dev); 444 struct platform_device *pdev = to_platform_device(dev);
443 struct cdns_wdt *wdt = platform_get_drvdata(pdev); 445 struct cdns_wdt *wdt = platform_get_drvdata(pdev);
444 446
445 ret = clk_prepare_enable(wdt->clk); 447 if (watchdog_active(&wdt->cdns_wdt_device)) {
446 if (ret) { 448 ret = clk_prepare_enable(wdt->clk);
447 dev_err(dev, "unable to enable clock\n"); 449 if (ret) {
448 return ret; 450 dev_err(dev, "unable to enable clock\n");
451 return ret;
452 }
453 cdns_wdt_start(&wdt->cdns_wdt_device);
449 } 454 }
450 cdns_wdt_start(&wdt->cdns_wdt_device);
451 455
452 return 0; 456 return 0;
453} 457}
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index 2acb51cf5504..3c6a3de13a1b 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -54,6 +54,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
54struct dw_wdt { 54struct dw_wdt {
55 void __iomem *regs; 55 void __iomem *regs;
56 struct clk *clk; 56 struct clk *clk;
57 unsigned long rate;
57 struct notifier_block restart_handler; 58 struct notifier_block restart_handler;
58 struct watchdog_device wdd; 59 struct watchdog_device wdd;
59}; 60};
@@ -72,7 +73,7 @@ static inline int dw_wdt_top_in_seconds(struct dw_wdt *dw_wdt, unsigned top)
72 * There are 16 possible timeout values in 0..15 where the number of 73 * There are 16 possible timeout values in 0..15 where the number of
73 * cycles is 2 ^ (16 + i) and the watchdog counts down. 74 * cycles is 2 ^ (16 + i) and the watchdog counts down.
74 */ 75 */
75 return (1U << (16 + top)) / clk_get_rate(dw_wdt->clk); 76 return (1U << (16 + top)) / dw_wdt->rate;
76} 77}
77 78
78static int dw_wdt_get_top(struct dw_wdt *dw_wdt) 79static int dw_wdt_get_top(struct dw_wdt *dw_wdt)
@@ -163,7 +164,7 @@ static unsigned int dw_wdt_get_timeleft(struct watchdog_device *wdd)
163 struct dw_wdt *dw_wdt = to_dw_wdt(wdd); 164 struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
164 165
165 return readl(dw_wdt->regs + WDOG_CURRENT_COUNT_REG_OFFSET) / 166 return readl(dw_wdt->regs + WDOG_CURRENT_COUNT_REG_OFFSET) /
166 clk_get_rate(dw_wdt->clk); 167 dw_wdt->rate;
167} 168}
168 169
169static const struct watchdog_info dw_wdt_ident = { 170static const struct watchdog_info dw_wdt_ident = {
@@ -231,6 +232,12 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
231 if (ret) 232 if (ret)
232 return ret; 233 return ret;
233 234
235 dw_wdt->rate = clk_get_rate(dw_wdt->clk);
236 if (dw_wdt->rate == 0) {
237 ret = -EINVAL;
238 goto out_disable_clk;
239 }
240
234 wdd = &dw_wdt->wdd; 241 wdd = &dw_wdt->wdd;
235 wdd->info = &dw_wdt_ident; 242 wdd->info = &dw_wdt_ident;
236 wdd->ops = &dw_wdt_ops; 243 wdd->ops = &dw_wdt_ops;
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 8f89bd8a826a..70c7194e2810 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -39,7 +39,7 @@
39#include <asm/nmi.h> 39#include <asm/nmi.h>
40#include <asm/frame.h> 40#include <asm/frame.h>
41 41
42#define HPWDT_VERSION "1.3.3" 42#define HPWDT_VERSION "1.4.0"
43#define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) 43#define SECS_TO_TICKS(secs) ((secs) * 1000 / 128)
44#define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) 44#define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000)
45#define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) 45#define HPWDT_MAX_TIMER TICKS_TO_SECS(65535)
@@ -814,7 +814,8 @@ static int hpwdt_init_one(struct pci_dev *dev,
814 * not run on a legacy ASM box. 814 * not run on a legacy ASM box.
815 * So we only support the G5 ProLiant servers and higher. 815 * So we only support the G5 ProLiant servers and higher.
816 */ 816 */
817 if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) { 817 if (dev->subsystem_vendor != PCI_VENDOR_ID_HP &&
818 dev->subsystem_vendor != PCI_VENDOR_ID_HP_3PAR) {
818 dev_warn(&dev->dev, 819 dev_warn(&dev->dev,
819 "This server does not have an iLO2+ ASIC.\n"); 820 "This server does not have an iLO2+ ASIC.\n");
820 return -ENODEV; 821 return -ENODEV;
@@ -823,7 +824,8 @@ static int hpwdt_init_one(struct pci_dev *dev,
823 /* 824 /*
824 * Ignore all auxilary iLO devices with the following PCI ID 825 * Ignore all auxilary iLO devices with the following PCI ID
825 */ 826 */
826 if (dev->subsystem_device == 0x1979) 827 if (dev->subsystem_vendor == PCI_VENDOR_ID_HP &&
828 dev->subsystem_device == 0x1979)
827 return -ENODEV; 829 return -ENODEV;
828 830
829 if (pci_enable_device(dev)) { 831 if (pci_enable_device(dev)) {
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 54cab189a763..06fcb6c8c917 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -629,7 +629,7 @@ static int iTCO_wdt_resume_noirq(struct device *dev)
629 return 0; 629 return 0;
630} 630}
631 631
632static struct dev_pm_ops iTCO_wdt_pm = { 632static const struct dev_pm_ops iTCO_wdt_pm = {
633 .suspend_noirq = iTCO_wdt_suspend_noirq, 633 .suspend_noirq = iTCO_wdt_suspend_noirq,
634 .resume_noirq = iTCO_wdt_resume_noirq, 634 .resume_noirq = iTCO_wdt_resume_noirq,
635}; 635};
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 62f346bb4348..4874b0f18650 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -24,6 +24,7 @@
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/interrupt.h>
27#include <linux/io.h> 28#include <linux/io.h>
28#include <linux/kernel.h> 29#include <linux/kernel.h>
29#include <linux/module.h> 30#include <linux/module.h>
@@ -37,18 +38,23 @@
37 38
38#define IMX2_WDT_WCR 0x00 /* Control Register */ 39#define IMX2_WDT_WCR 0x00 /* Control Register */
39#define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */ 40#define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */
40#define IMX2_WDT_WCR_WDA (1 << 5) /* -> External Reset WDOG_B */ 41#define IMX2_WDT_WCR_WDA BIT(5) /* -> External Reset WDOG_B */
41#define IMX2_WDT_WCR_SRS (1 << 4) /* -> Software Reset Signal */ 42#define IMX2_WDT_WCR_SRS BIT(4) /* -> Software Reset Signal */
42#define IMX2_WDT_WCR_WRE (1 << 3) /* -> WDOG Reset Enable */ 43#define IMX2_WDT_WCR_WRE BIT(3) /* -> WDOG Reset Enable */
43#define IMX2_WDT_WCR_WDE (1 << 2) /* -> Watchdog Enable */ 44#define IMX2_WDT_WCR_WDE BIT(2) /* -> Watchdog Enable */
44#define IMX2_WDT_WCR_WDZST (1 << 0) /* -> Watchdog timer Suspend */ 45#define IMX2_WDT_WCR_WDZST BIT(0) /* -> Watchdog timer Suspend */
45 46
46#define IMX2_WDT_WSR 0x02 /* Service Register */ 47#define IMX2_WDT_WSR 0x02 /* Service Register */
47#define IMX2_WDT_SEQ1 0x5555 /* -> service sequence 1 */ 48#define IMX2_WDT_SEQ1 0x5555 /* -> service sequence 1 */
48#define IMX2_WDT_SEQ2 0xAAAA /* -> service sequence 2 */ 49#define IMX2_WDT_SEQ2 0xAAAA /* -> service sequence 2 */
49 50
50#define IMX2_WDT_WRSR 0x04 /* Reset Status Register */ 51#define IMX2_WDT_WRSR 0x04 /* Reset Status Register */
51#define IMX2_WDT_WRSR_TOUT (1 << 1) /* -> Reset due to Timeout */ 52#define IMX2_WDT_WRSR_TOUT BIT(1) /* -> Reset due to Timeout */
53
54#define IMX2_WDT_WICR 0x06 /* Interrupt Control Register */
55#define IMX2_WDT_WICR_WIE BIT(15) /* -> Interrupt Enable */
56#define IMX2_WDT_WICR_WTIS BIT(14) /* -> Interrupt Status */
57#define IMX2_WDT_WICR_WICT 0xFF /* -> Interrupt Count Timeout */
52 58
53#define IMX2_WDT_WMCR 0x08 /* Misc Register */ 59#define IMX2_WDT_WMCR 0x08 /* Misc Register */
54 60
@@ -80,6 +86,12 @@ static const struct watchdog_info imx2_wdt_info = {
80 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 86 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
81}; 87};
82 88
89static const struct watchdog_info imx2_wdt_pretimeout_info = {
90 .identity = "imx2+ watchdog",
91 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
92 WDIOF_PRETIMEOUT,
93};
94
83static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action, 95static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action,
84 void *data) 96 void *data)
85{ 97{
@@ -169,6 +181,35 @@ static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
169 return 0; 181 return 0;
170} 182}
171 183
184static int imx2_wdt_set_pretimeout(struct watchdog_device *wdog,
185 unsigned int new_pretimeout)
186{
187 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
188
189 if (new_pretimeout >= IMX2_WDT_MAX_TIME)
190 return -EINVAL;
191
192 wdog->pretimeout = new_pretimeout;
193
194 regmap_update_bits(wdev->regmap, IMX2_WDT_WICR,
195 IMX2_WDT_WICR_WIE | IMX2_WDT_WICR_WICT,
196 IMX2_WDT_WICR_WIE | (new_pretimeout << 1));
197 return 0;
198}
199
200static irqreturn_t imx2_wdt_isr(int irq, void *wdog_arg)
201{
202 struct watchdog_device *wdog = wdog_arg;
203 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
204
205 regmap_write_bits(wdev->regmap, IMX2_WDT_WICR,
206 IMX2_WDT_WICR_WTIS, IMX2_WDT_WICR_WTIS);
207
208 watchdog_notify_pretimeout(wdog);
209
210 return IRQ_HANDLED;
211}
212
172static int imx2_wdt_start(struct watchdog_device *wdog) 213static int imx2_wdt_start(struct watchdog_device *wdog)
173{ 214{
174 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); 215 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
@@ -188,6 +229,7 @@ static const struct watchdog_ops imx2_wdt_ops = {
188 .start = imx2_wdt_start, 229 .start = imx2_wdt_start,
189 .ping = imx2_wdt_ping, 230 .ping = imx2_wdt_ping,
190 .set_timeout = imx2_wdt_set_timeout, 231 .set_timeout = imx2_wdt_set_timeout,
232 .set_pretimeout = imx2_wdt_set_pretimeout,
191 .restart = imx2_wdt_restart, 233 .restart = imx2_wdt_restart,
192}; 234};
193 235
@@ -236,6 +278,12 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
236 wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000; 278 wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000;
237 wdog->parent = &pdev->dev; 279 wdog->parent = &pdev->dev;
238 280
281 ret = platform_get_irq(pdev, 0);
282 if (ret > 0)
283 if (!devm_request_irq(&pdev->dev, ret, imx2_wdt_isr, 0,
284 dev_name(&pdev->dev), wdog))
285 wdog->info = &imx2_wdt_pretimeout_info;
286
239 ret = clk_prepare_enable(wdev->clk); 287 ret = clk_prepare_enable(wdev->clk);
240 if (ret) 288 if (ret)
241 return ret; 289 return ret;
diff --git a/drivers/watchdog/kempld_wdt.c b/drivers/watchdog/kempld_wdt.c
index 5bf931ce1353..8e302d0e346c 100644
--- a/drivers/watchdog/kempld_wdt.c
+++ b/drivers/watchdog/kempld_wdt.c
@@ -430,7 +430,7 @@ static struct watchdog_info kempld_wdt_info = {
430 WDIOF_PRETIMEOUT 430 WDIOF_PRETIMEOUT
431}; 431};
432 432
433static struct watchdog_ops kempld_wdt_ops = { 433static const struct watchdog_ops kempld_wdt_ops = {
434 .owner = THIS_MODULE, 434 .owner = THIS_MODULE,
435 .start = kempld_wdt_start, 435 .start = kempld_wdt_start,
436 .stop = kempld_wdt_stop, 436 .stop = kempld_wdt_stop,
diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c
index 4a2290f900a8..d5735c12067d 100644
--- a/drivers/watchdog/mt7621_wdt.c
+++ b/drivers/watchdog/mt7621_wdt.c
@@ -139,7 +139,6 @@ static int mt7621_wdt_probe(struct platform_device *pdev)
139 if (!IS_ERR(mt7621_wdt_reset)) 139 if (!IS_ERR(mt7621_wdt_reset))
140 reset_control_deassert(mt7621_wdt_reset); 140 reset_control_deassert(mt7621_wdt_reset);
141 141
142 mt7621_wdt_dev.dev = &pdev->dev;
143 mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause(); 142 mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause();
144 143
145 watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout, 144 watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout,
diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c
index b2e1b4cbbdc1..fae7fe929ea3 100644
--- a/drivers/watchdog/of_xilinx_wdt.c
+++ b/drivers/watchdog/of_xilinx_wdt.c
@@ -10,6 +10,7 @@
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 */ 11 */
12 12
13#include <linux/clk.h>
13#include <linux/err.h> 14#include <linux/err.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/types.h> 16#include <linux/types.h>
@@ -45,6 +46,7 @@ struct xwdt_device {
45 u32 wdt_interval; 46 u32 wdt_interval;
46 spinlock_t spinlock; 47 spinlock_t spinlock;
47 struct watchdog_device xilinx_wdt_wdd; 48 struct watchdog_device xilinx_wdt_wdd;
49 struct clk *clk;
48}; 50};
49 51
50static int xilinx_wdt_start(struct watchdog_device *wdd) 52static int xilinx_wdt_start(struct watchdog_device *wdd)
@@ -195,16 +197,30 @@ static int xwdt_probe(struct platform_device *pdev)
195 spin_lock_init(&xdev->spinlock); 197 spin_lock_init(&xdev->spinlock);
196 watchdog_set_drvdata(xilinx_wdt_wdd, xdev); 198 watchdog_set_drvdata(xilinx_wdt_wdd, xdev);
197 199
200 xdev->clk = devm_clk_get(&pdev->dev, NULL);
201 if (IS_ERR(xdev->clk)) {
202 if (PTR_ERR(xdev->clk) == -ENOENT)
203 xdev->clk = NULL;
204 else
205 return PTR_ERR(xdev->clk);
206 }
207
208 rc = clk_prepare_enable(xdev->clk);
209 if (rc) {
210 dev_err(&pdev->dev, "unable to enable clock\n");
211 return rc;
212 }
213
198 rc = xwdt_selftest(xdev); 214 rc = xwdt_selftest(xdev);
199 if (rc == XWT_TIMER_FAILED) { 215 if (rc == XWT_TIMER_FAILED) {
200 dev_err(&pdev->dev, "SelfTest routine error\n"); 216 dev_err(&pdev->dev, "SelfTest routine error\n");
201 return rc; 217 goto err_clk_disable;
202 } 218 }
203 219
204 rc = watchdog_register_device(xilinx_wdt_wdd); 220 rc = watchdog_register_device(xilinx_wdt_wdd);
205 if (rc) { 221 if (rc) {
206 dev_err(&pdev->dev, "Cannot register watchdog (err=%d)\n", rc); 222 dev_err(&pdev->dev, "Cannot register watchdog (err=%d)\n", rc);
207 return rc; 223 goto err_clk_disable;
208 } 224 }
209 225
210 dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds\n", 226 dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds\n",
@@ -213,6 +229,10 @@ static int xwdt_probe(struct platform_device *pdev)
213 platform_set_drvdata(pdev, xdev); 229 platform_set_drvdata(pdev, xdev);
214 230
215 return 0; 231 return 0;
232err_clk_disable:
233 clk_disable_unprepare(xdev->clk);
234
235 return rc;
216} 236}
217 237
218static int xwdt_remove(struct platform_device *pdev) 238static int xwdt_remove(struct platform_device *pdev)
@@ -220,6 +240,7 @@ static int xwdt_remove(struct platform_device *pdev)
220 struct xwdt_device *xdev = platform_get_drvdata(pdev); 240 struct xwdt_device *xdev = platform_get_drvdata(pdev);
221 241
222 watchdog_unregister_device(&xdev->xilinx_wdt_wdd); 242 watchdog_unregister_device(&xdev->xilinx_wdt_wdd);
243 clk_disable_unprepare(xdev->clk);
223 244
224 return 0; 245 return 0;
225} 246}
diff --git a/drivers/watchdog/pretimeout_noop.c b/drivers/watchdog/pretimeout_noop.c
new file mode 100644
index 000000000000..85f5299d197c
--- /dev/null
+++ b/drivers/watchdog/pretimeout_noop.c
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2015-2016 Mentor Graphics
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 */
10
11#include <linux/module.h>
12#include <linux/printk.h>
13#include <linux/watchdog.h>
14
15#include "watchdog_pretimeout.h"
16
17/**
18 * pretimeout_noop - No operation on watchdog pretimeout event
19 * @wdd - watchdog_device
20 *
21 * This function prints a message about pretimeout to kernel log.
22 */
23static void pretimeout_noop(struct watchdog_device *wdd)
24{
25 pr_alert("watchdog%d: pretimeout event\n", wdd->id);
26}
27
28static struct watchdog_governor watchdog_gov_noop = {
29 .name = "noop",
30 .pretimeout = pretimeout_noop,
31};
32
33static int __init watchdog_gov_noop_register(void)
34{
35 return watchdog_register_governor(&watchdog_gov_noop);
36}
37
38static void __exit watchdog_gov_noop_unregister(void)
39{
40 watchdog_unregister_governor(&watchdog_gov_noop);
41}
42module_init(watchdog_gov_noop_register);
43module_exit(watchdog_gov_noop_unregister);
44
45MODULE_AUTHOR("Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>");
46MODULE_DESCRIPTION("Panic watchdog pretimeout governor");
47MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/pretimeout_panic.c b/drivers/watchdog/pretimeout_panic.c
new file mode 100644
index 000000000000..0c197a1c97f4
--- /dev/null
+++ b/drivers/watchdog/pretimeout_panic.c
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2015-2016 Mentor Graphics
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 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/watchdog.h>
14
15#include "watchdog_pretimeout.h"
16
17/**
18 * pretimeout_panic - Panic on watchdog pretimeout event
19 * @wdd - watchdog_device
20 *
21 * Panic, watchdog has not been fed till pretimeout event.
22 */
23static void pretimeout_panic(struct watchdog_device *wdd)
24{
25 panic("watchdog pretimeout event\n");
26}
27
28static struct watchdog_governor watchdog_gov_panic = {
29 .name = "panic",
30 .pretimeout = pretimeout_panic,
31};
32
33static int __init watchdog_gov_panic_register(void)
34{
35 return watchdog_register_governor(&watchdog_gov_panic);
36}
37
38static void __exit watchdog_gov_panic_unregister(void)
39{
40 watchdog_unregister_governor(&watchdog_gov_panic);
41}
42module_init(watchdog_gov_panic_register);
43module_exit(watchdog_gov_panic_unregister);
44
45MODULE_AUTHOR("Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>");
46MODULE_DESCRIPTION("Panic watchdog pretimeout governor");
47MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/rn5t618_wdt.c b/drivers/watchdog/rn5t618_wdt.c
index d1c12278cb6a..0805ee2acd7a 100644
--- a/drivers/watchdog/rn5t618_wdt.c
+++ b/drivers/watchdog/rn5t618_wdt.c
@@ -136,7 +136,7 @@ static struct watchdog_info rn5t618_wdt_info = {
136 .identity = DRIVER_NAME, 136 .identity = DRIVER_NAME,
137}; 137};
138 138
139static struct watchdog_ops rn5t618_wdt_ops = { 139static const struct watchdog_ops rn5t618_wdt_ops = {
140 .owner = THIS_MODULE, 140 .owner = THIS_MODULE,
141 .start = rn5t618_wdt_start, 141 .start = rn5t618_wdt_start,
142 .stop = rn5t618_wdt_stop, 142 .stop = rn5t618_wdt_stop,
diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c
index 1967919ae743..14b4fd428fff 100644
--- a/drivers/watchdog/rt2880_wdt.c
+++ b/drivers/watchdog/rt2880_wdt.c
@@ -158,7 +158,6 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
158 158
159 rt288x_wdt_freq = clk_get_rate(rt288x_wdt_clk) / RALINK_WDT_PRESCALE; 159 rt288x_wdt_freq = clk_get_rate(rt288x_wdt_clk) / RALINK_WDT_PRESCALE;
160 160
161 rt288x_wdt_dev.dev = &pdev->dev;
162 rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause(); 161 rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause();
163 rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq); 162 rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq);
164 rt288x_wdt_dev.parent = &pdev->dev; 163 rt288x_wdt_dev.parent = &pdev->dev;
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c
index b067edf246df..c7bdc986dca1 100644
--- a/drivers/watchdog/softdog.c
+++ b/drivers/watchdog/softdog.c
@@ -72,10 +72,27 @@ static void softdog_fire(unsigned long data)
72static struct timer_list softdog_ticktock = 72static struct timer_list softdog_ticktock =
73 TIMER_INITIALIZER(softdog_fire, 0, 0); 73 TIMER_INITIALIZER(softdog_fire, 0, 0);
74 74
75static struct watchdog_device softdog_dev;
76
77static void softdog_pretimeout(unsigned long data)
78{
79 watchdog_notify_pretimeout(&softdog_dev);
80}
81
82static struct timer_list softdog_preticktock =
83 TIMER_INITIALIZER(softdog_pretimeout, 0, 0);
84
75static int softdog_ping(struct watchdog_device *w) 85static int softdog_ping(struct watchdog_device *w)
76{ 86{
77 if (!mod_timer(&softdog_ticktock, jiffies + (w->timeout * HZ))) 87 if (!mod_timer(&softdog_ticktock, jiffies + (w->timeout * HZ)))
78 __module_get(THIS_MODULE); 88 __module_get(THIS_MODULE);
89
90 if (w->pretimeout)
91 mod_timer(&softdog_preticktock, jiffies +
92 (w->timeout - w->pretimeout) * HZ);
93 else
94 del_timer(&softdog_preticktock);
95
79 return 0; 96 return 0;
80} 97}
81 98
@@ -84,15 +101,18 @@ static int softdog_stop(struct watchdog_device *w)
84 if (del_timer(&softdog_ticktock)) 101 if (del_timer(&softdog_ticktock))
85 module_put(THIS_MODULE); 102 module_put(THIS_MODULE);
86 103
104 del_timer(&softdog_preticktock);
105
87 return 0; 106 return 0;
88} 107}
89 108
90static struct watchdog_info softdog_info = { 109static struct watchdog_info softdog_info = {
91 .identity = "Software Watchdog", 110 .identity = "Software Watchdog",
92 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 111 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE |
112 WDIOF_PRETIMEOUT,
93}; 113};
94 114
95static struct watchdog_ops softdog_ops = { 115static const struct watchdog_ops softdog_ops = {
96 .owner = THIS_MODULE, 116 .owner = THIS_MODULE,
97 .start = softdog_ping, 117 .start = softdog_ping,
98 .stop = softdog_stop, 118 .stop = softdog_stop,
diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c
index 14e9badf2bfa..e6100e447dd8 100644
--- a/drivers/watchdog/st_lpc_wdt.c
+++ b/drivers/watchdog/st_lpc_wdt.c
@@ -52,27 +52,6 @@ struct st_wdog {
52 bool warm_reset; 52 bool warm_reset;
53}; 53};
54 54
55static struct st_wdog_syscfg stid127_syscfg = {
56 .reset_type_reg = 0x004,
57 .reset_type_mask = BIT(2),
58 .enable_reg = 0x000,
59 .enable_mask = BIT(2),
60};
61
62static struct st_wdog_syscfg stih415_syscfg = {
63 .reset_type_reg = 0x0B8,
64 .reset_type_mask = BIT(6),
65 .enable_reg = 0x0B4,
66 .enable_mask = BIT(7),
67};
68
69static struct st_wdog_syscfg stih416_syscfg = {
70 .reset_type_reg = 0x88C,
71 .reset_type_mask = BIT(6),
72 .enable_reg = 0x888,
73 .enable_mask = BIT(7),
74};
75
76static struct st_wdog_syscfg stih407_syscfg = { 55static struct st_wdog_syscfg stih407_syscfg = {
77 .enable_reg = 0x204, 56 .enable_reg = 0x204,
78 .enable_mask = BIT(19), 57 .enable_mask = BIT(19),
@@ -83,18 +62,6 @@ static const struct of_device_id st_wdog_match[] = {
83 .compatible = "st,stih407-lpc", 62 .compatible = "st,stih407-lpc",
84 .data = &stih407_syscfg, 63 .data = &stih407_syscfg,
85 }, 64 },
86 {
87 .compatible = "st,stih416-lpc",
88 .data = &stih416_syscfg,
89 },
90 {
91 .compatible = "st,stih415-lpc",
92 .data = &stih415_syscfg,
93 },
94 {
95 .compatible = "st,stid127-lpc",
96 .data = &stid127_syscfg,
97 },
98 {}, 65 {},
99}; 66};
100MODULE_DEVICE_TABLE(of, st_wdog_match); 67MODULE_DEVICE_TABLE(of, st_wdog_match);
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c
index 9ec57608da82..2d53c3f9394f 100644
--- a/drivers/watchdog/tegra_wdt.c
+++ b/drivers/watchdog/tegra_wdt.c
@@ -178,7 +178,7 @@ static const struct watchdog_info tegra_wdt_info = {
178 .identity = "Tegra Watchdog", 178 .identity = "Tegra Watchdog",
179}; 179};
180 180
181static struct watchdog_ops tegra_wdt_ops = { 181static const struct watchdog_ops tegra_wdt_ops = {
182 .owner = THIS_MODULE, 182 .owner = THIS_MODULE,
183 .start = tegra_wdt_start, 183 .start = tegra_wdt_start,
184 .stop = tegra_wdt_stop, 184 .stop = tegra_wdt_stop,
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index c2da880292bc..6f7a9deb27d0 100644
--- a/drivers/watchdog/txx9wdt.c
+++ b/drivers/watchdog/txx9wdt.c
@@ -112,7 +112,7 @@ static int __init txx9wdt_probe(struct platform_device *dev)
112 txx9_imclk = NULL; 112 txx9_imclk = NULL;
113 goto exit; 113 goto exit;
114 } 114 }
115 ret = clk_enable(txx9_imclk); 115 ret = clk_prepare_enable(txx9_imclk);
116 if (ret) { 116 if (ret) {
117 clk_put(txx9_imclk); 117 clk_put(txx9_imclk);
118 txx9_imclk = NULL; 118 txx9_imclk = NULL;
@@ -144,7 +144,7 @@ static int __init txx9wdt_probe(struct platform_device *dev)
144 return 0; 144 return 0;
145exit: 145exit:
146 if (txx9_imclk) { 146 if (txx9_imclk) {
147 clk_disable(txx9_imclk); 147 clk_disable_unprepare(txx9_imclk);
148 clk_put(txx9_imclk); 148 clk_put(txx9_imclk);
149 } 149 }
150 return ret; 150 return ret;
@@ -153,7 +153,7 @@ exit:
153static int __exit txx9wdt_remove(struct platform_device *dev) 153static int __exit txx9wdt_remove(struct platform_device *dev)
154{ 154{
155 watchdog_unregister_device(&txx9wdt); 155 watchdog_unregister_device(&txx9wdt);
156 clk_disable(txx9_imclk); 156 clk_disable_unprepare(txx9_imclk);
157 clk_put(txx9_imclk); 157 clk_put(txx9_imclk);
158 return 0; 158 return 0;
159} 159}
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index 09e8003039dc..ef2ecaf53a14 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -302,7 +302,7 @@ static struct watchdog_info wdt_info = {
302 .identity = "W83627HF Watchdog", 302 .identity = "W83627HF Watchdog",
303}; 303};
304 304
305static struct watchdog_ops wdt_ops = { 305static const struct watchdog_ops wdt_ops = {
306 .owner = THIS_MODULE, 306 .owner = THIS_MODULE,
307 .start = wdt_start, 307 .start = wdt_start,
308 .stop = wdt_stop, 308 .stop = wdt_stop,
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
index 6abb83cd7681..74265b2f806c 100644
--- a/drivers/watchdog/watchdog_core.c
+++ b/drivers/watchdog/watchdog_core.c
@@ -349,7 +349,7 @@ int devm_watchdog_register_device(struct device *dev,
349 struct watchdog_device **rcwdd; 349 struct watchdog_device **rcwdd;
350 int ret; 350 int ret;
351 351
352 rcwdd = devres_alloc(devm_watchdog_unregister_device, sizeof(*wdd), 352 rcwdd = devres_alloc(devm_watchdog_unregister_device, sizeof(*rcwdd),
353 GFP_KERNEL); 353 GFP_KERNEL);
354 if (!rcwdd) 354 if (!rcwdd)
355 return -ENOMEM; 355 return -ENOMEM;
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index 040bf8382f46..32930a073a12 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -49,6 +49,7 @@
49#include <linux/uaccess.h> /* For copy_to_user/put_user/... */ 49#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
50 50
51#include "watchdog_core.h" 51#include "watchdog_core.h"
52#include "watchdog_pretimeout.h"
52 53
53/* 54/*
54 * struct watchdog_core_data - watchdog core internal data 55 * struct watchdog_core_data - watchdog core internal data
@@ -335,10 +336,14 @@ static int watchdog_set_timeout(struct watchdog_device *wdd,
335 if (watchdog_timeout_invalid(wdd, timeout)) 336 if (watchdog_timeout_invalid(wdd, timeout))
336 return -EINVAL; 337 return -EINVAL;
337 338
338 if (wdd->ops->set_timeout) 339 if (wdd->ops->set_timeout) {
339 err = wdd->ops->set_timeout(wdd, timeout); 340 err = wdd->ops->set_timeout(wdd, timeout);
340 else 341 } else {
341 wdd->timeout = timeout; 342 wdd->timeout = timeout;
343 /* Disable pretimeout if it doesn't fit the new timeout */
344 if (wdd->pretimeout >= wdd->timeout)
345 wdd->pretimeout = 0;
346 }
342 347
343 watchdog_update_worker(wdd); 348 watchdog_update_worker(wdd);
344 349
@@ -346,6 +351,31 @@ static int watchdog_set_timeout(struct watchdog_device *wdd,
346} 351}
347 352
348/* 353/*
354 * watchdog_set_pretimeout: set the watchdog timer pretimeout
355 * @wdd: the watchdog device to set the timeout for
356 * @timeout: pretimeout to set in seconds
357 */
358
359static int watchdog_set_pretimeout(struct watchdog_device *wdd,
360 unsigned int timeout)
361{
362 int err = 0;
363
364 if (!(wdd->info->options & WDIOF_PRETIMEOUT))
365 return -EOPNOTSUPP;
366
367 if (watchdog_pretimeout_invalid(wdd, timeout))
368 return -EINVAL;
369
370 if (wdd->ops->set_pretimeout)
371 err = wdd->ops->set_pretimeout(wdd, timeout);
372 else
373 wdd->pretimeout = timeout;
374
375 return err;
376}
377
378/*
349 * watchdog_get_timeleft: wrapper to get the time left before a reboot 379 * watchdog_get_timeleft: wrapper to get the time left before a reboot
350 * @wdd: the watchdog device to get the remaining time from 380 * @wdd: the watchdog device to get the remaining time from
351 * @timeleft: the time that's left 381 * @timeleft: the time that's left
@@ -429,6 +459,15 @@ static ssize_t timeout_show(struct device *dev, struct device_attribute *attr,
429} 459}
430static DEVICE_ATTR_RO(timeout); 460static DEVICE_ATTR_RO(timeout);
431 461
462static ssize_t pretimeout_show(struct device *dev,
463 struct device_attribute *attr, char *buf)
464{
465 struct watchdog_device *wdd = dev_get_drvdata(dev);
466
467 return sprintf(buf, "%u\n", wdd->pretimeout);
468}
469static DEVICE_ATTR_RO(pretimeout);
470
432static ssize_t identity_show(struct device *dev, struct device_attribute *attr, 471static ssize_t identity_show(struct device *dev, struct device_attribute *attr,
433 char *buf) 472 char *buf)
434{ 473{
@@ -450,6 +489,36 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr,
450} 489}
451static DEVICE_ATTR_RO(state); 490static DEVICE_ATTR_RO(state);
452 491
492static ssize_t pretimeout_available_governors_show(struct device *dev,
493 struct device_attribute *attr, char *buf)
494{
495 return watchdog_pretimeout_available_governors_get(buf);
496}
497static DEVICE_ATTR_RO(pretimeout_available_governors);
498
499static ssize_t pretimeout_governor_show(struct device *dev,
500 struct device_attribute *attr,
501 char *buf)
502{
503 struct watchdog_device *wdd = dev_get_drvdata(dev);
504
505 return watchdog_pretimeout_governor_get(wdd, buf);
506}
507
508static ssize_t pretimeout_governor_store(struct device *dev,
509 struct device_attribute *attr,
510 const char *buf, size_t count)
511{
512 struct watchdog_device *wdd = dev_get_drvdata(dev);
513 int ret = watchdog_pretimeout_governor_set(wdd, buf);
514
515 if (!ret)
516 ret = count;
517
518 return ret;
519}
520static DEVICE_ATTR_RW(pretimeout_governor);
521
453static umode_t wdt_is_visible(struct kobject *kobj, struct attribute *attr, 522static umode_t wdt_is_visible(struct kobject *kobj, struct attribute *attr,
454 int n) 523 int n)
455{ 524{
@@ -459,6 +528,14 @@ static umode_t wdt_is_visible(struct kobject *kobj, struct attribute *attr,
459 528
460 if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft) 529 if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft)
461 mode = 0; 530 mode = 0;
531 else if (attr == &dev_attr_pretimeout.attr &&
532 !(wdd->info->options & WDIOF_PRETIMEOUT))
533 mode = 0;
534 else if ((attr == &dev_attr_pretimeout_governor.attr ||
535 attr == &dev_attr_pretimeout_available_governors.attr) &&
536 (!(wdd->info->options & WDIOF_PRETIMEOUT) ||
537 !IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_GOV)))
538 mode = 0;
462 539
463 return mode; 540 return mode;
464} 541}
@@ -466,10 +543,13 @@ static struct attribute *wdt_attrs[] = {
466 &dev_attr_state.attr, 543 &dev_attr_state.attr,
467 &dev_attr_identity.attr, 544 &dev_attr_identity.attr,
468 &dev_attr_timeout.attr, 545 &dev_attr_timeout.attr,
546 &dev_attr_pretimeout.attr,
469 &dev_attr_timeleft.attr, 547 &dev_attr_timeleft.attr,
470 &dev_attr_bootstatus.attr, 548 &dev_attr_bootstatus.attr,
471 &dev_attr_status.attr, 549 &dev_attr_status.attr,
472 &dev_attr_nowayout.attr, 550 &dev_attr_nowayout.attr,
551 &dev_attr_pretimeout_governor.attr,
552 &dev_attr_pretimeout_available_governors.attr,
473 NULL, 553 NULL,
474}; 554};
475 555
@@ -646,6 +726,16 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
646 break; 726 break;
647 err = put_user(val, p); 727 err = put_user(val, p);
648 break; 728 break;
729 case WDIOC_SETPRETIMEOUT:
730 if (get_user(val, p)) {
731 err = -EFAULT;
732 break;
733 }
734 err = watchdog_set_pretimeout(wdd, val);
735 break;
736 case WDIOC_GETPRETIMEOUT:
737 err = put_user(wdd->pretimeout, p);
738 break;
649 default: 739 default:
650 err = -ENOTTY; 740 err = -ENOTTY;
651 break; 741 break;
@@ -937,6 +1027,12 @@ int watchdog_dev_register(struct watchdog_device *wdd)
937 return PTR_ERR(dev); 1027 return PTR_ERR(dev);
938 } 1028 }
939 1029
1030 ret = watchdog_register_pretimeout(wdd);
1031 if (ret) {
1032 device_destroy(&watchdog_class, devno);
1033 watchdog_cdev_unregister(wdd);
1034 }
1035
940 return ret; 1036 return ret;
941} 1037}
942 1038
@@ -950,6 +1046,7 @@ int watchdog_dev_register(struct watchdog_device *wdd)
950 1046
951void watchdog_dev_unregister(struct watchdog_device *wdd) 1047void watchdog_dev_unregister(struct watchdog_device *wdd)
952{ 1048{
1049 watchdog_unregister_pretimeout(wdd);
953 device_destroy(&watchdog_class, wdd->wd_data->cdev.dev); 1050 device_destroy(&watchdog_class, wdd->wd_data->cdev.dev);
954 watchdog_cdev_unregister(wdd); 1051 watchdog_cdev_unregister(wdd);
955} 1052}
diff --git a/drivers/watchdog/watchdog_pretimeout.c b/drivers/watchdog/watchdog_pretimeout.c
new file mode 100644
index 000000000000..9db07bfb4334
--- /dev/null
+++ b/drivers/watchdog/watchdog_pretimeout.c
@@ -0,0 +1,220 @@
1/*
2 * Copyright (C) 2015-2016 Mentor Graphics
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 */
10
11#include <linux/list.h>
12#include <linux/slab.h>
13#include <linux/spinlock.h>
14#include <linux/string.h>
15#include <linux/watchdog.h>
16
17#include "watchdog_pretimeout.h"
18
19/* Default watchdog pretimeout governor */
20static struct watchdog_governor *default_gov;
21
22/* The spinlock protects default_gov, wdd->gov and pretimeout_list */
23static DEFINE_SPINLOCK(pretimeout_lock);
24
25/* List of watchdog devices, which can generate a pretimeout event */
26static LIST_HEAD(pretimeout_list);
27
28struct watchdog_pretimeout {
29 struct watchdog_device *wdd;
30 struct list_head entry;
31};
32
33/* The mutex protects governor list and serializes external interfaces */
34static DEFINE_MUTEX(governor_lock);
35
36/* List of the registered watchdog pretimeout governors */
37static LIST_HEAD(governor_list);
38
39struct governor_priv {
40 struct watchdog_governor *gov;
41 struct list_head entry;
42};
43
44static struct governor_priv *find_governor_by_name(const char *gov_name)
45{
46 struct governor_priv *priv;
47
48 list_for_each_entry(priv, &governor_list, entry)
49 if (sysfs_streq(gov_name, priv->gov->name))
50 return priv;
51
52 return NULL;
53}
54
55int watchdog_pretimeout_available_governors_get(char *buf)
56{
57 struct governor_priv *priv;
58 int count = 0;
59
60 mutex_lock(&governor_lock);
61
62 list_for_each_entry(priv, &governor_list, entry)
63 count += sprintf(buf + count, "%s\n", priv->gov->name);
64
65 mutex_unlock(&governor_lock);
66
67 return count;
68}
69
70int watchdog_pretimeout_governor_get(struct watchdog_device *wdd, char *buf)
71{
72 int count = 0;
73
74 spin_lock_irq(&pretimeout_lock);
75 if (wdd->gov)
76 count = sprintf(buf, "%s\n", wdd->gov->name);
77 spin_unlock_irq(&pretimeout_lock);
78
79 return count;
80}
81
82int watchdog_pretimeout_governor_set(struct watchdog_device *wdd,
83 const char *buf)
84{
85 struct governor_priv *priv;
86
87 mutex_lock(&governor_lock);
88
89 priv = find_governor_by_name(buf);
90 if (!priv) {
91 mutex_unlock(&governor_lock);
92 return -EINVAL;
93 }
94
95 spin_lock_irq(&pretimeout_lock);
96 wdd->gov = priv->gov;
97 spin_unlock_irq(&pretimeout_lock);
98
99 mutex_unlock(&governor_lock);
100
101 return 0;
102}
103
104void watchdog_notify_pretimeout(struct watchdog_device *wdd)
105{
106 unsigned long flags;
107
108 spin_lock_irqsave(&pretimeout_lock, flags);
109 if (!wdd->gov) {
110 spin_unlock_irqrestore(&pretimeout_lock, flags);
111 return;
112 }
113
114 wdd->gov->pretimeout(wdd);
115 spin_unlock_irqrestore(&pretimeout_lock, flags);
116}
117EXPORT_SYMBOL_GPL(watchdog_notify_pretimeout);
118
119int watchdog_register_governor(struct watchdog_governor *gov)
120{
121 struct watchdog_pretimeout *p;
122 struct governor_priv *priv;
123
124 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
125 if (!priv)
126 return -ENOMEM;
127
128 mutex_lock(&governor_lock);
129
130 if (find_governor_by_name(gov->name)) {
131 mutex_unlock(&governor_lock);
132 kfree(priv);
133 return -EBUSY;
134 }
135
136 priv->gov = gov;
137 list_add(&priv->entry, &governor_list);
138
139 if (!strncmp(gov->name, WATCHDOG_PRETIMEOUT_DEFAULT_GOV,
140 WATCHDOG_GOV_NAME_MAXLEN)) {
141 spin_lock_irq(&pretimeout_lock);
142 default_gov = gov;
143
144 list_for_each_entry(p, &pretimeout_list, entry)
145 if (!p->wdd->gov)
146 p->wdd->gov = default_gov;
147 spin_unlock_irq(&pretimeout_lock);
148 }
149
150 mutex_unlock(&governor_lock);
151
152 return 0;
153}
154EXPORT_SYMBOL(watchdog_register_governor);
155
156void watchdog_unregister_governor(struct watchdog_governor *gov)
157{
158 struct watchdog_pretimeout *p;
159 struct governor_priv *priv, *t;
160
161 mutex_lock(&governor_lock);
162
163 list_for_each_entry_safe(priv, t, &governor_list, entry) {
164 if (priv->gov == gov) {
165 list_del(&priv->entry);
166 kfree(priv);
167 break;
168 }
169 }
170
171 spin_lock_irq(&pretimeout_lock);
172 list_for_each_entry(p, &pretimeout_list, entry)
173 if (p->wdd->gov == gov)
174 p->wdd->gov = default_gov;
175 spin_unlock_irq(&pretimeout_lock);
176
177 mutex_unlock(&governor_lock);
178}
179EXPORT_SYMBOL(watchdog_unregister_governor);
180
181int watchdog_register_pretimeout(struct watchdog_device *wdd)
182{
183 struct watchdog_pretimeout *p;
184
185 if (!(wdd->info->options & WDIOF_PRETIMEOUT))
186 return 0;
187
188 p = kzalloc(sizeof(*p), GFP_KERNEL);
189 if (!p)
190 return -ENOMEM;
191
192 spin_lock_irq(&pretimeout_lock);
193 list_add(&p->entry, &pretimeout_list);
194 p->wdd = wdd;
195 wdd->gov = default_gov;
196 spin_unlock_irq(&pretimeout_lock);
197
198 return 0;
199}
200
201void watchdog_unregister_pretimeout(struct watchdog_device *wdd)
202{
203 struct watchdog_pretimeout *p, *t;
204
205 if (!(wdd->info->options & WDIOF_PRETIMEOUT))
206 return;
207
208 spin_lock_irq(&pretimeout_lock);
209 wdd->gov = NULL;
210
211 list_for_each_entry_safe(p, t, &pretimeout_list, entry) {
212 if (p->wdd == wdd) {
213 list_del(&p->entry);
214 break;
215 }
216 }
217 spin_unlock_irq(&pretimeout_lock);
218
219 kfree(p);
220}
diff --git a/drivers/watchdog/watchdog_pretimeout.h b/drivers/watchdog/watchdog_pretimeout.h
new file mode 100644
index 000000000000..a5a32b39c56d
--- /dev/null
+++ b/drivers/watchdog/watchdog_pretimeout.h
@@ -0,0 +1,60 @@
1#ifndef __WATCHDOG_PRETIMEOUT_H
2#define __WATCHDOG_PRETIMEOUT_H
3
4#define WATCHDOG_GOV_NAME_MAXLEN 20
5
6struct watchdog_device;
7
8struct watchdog_governor {
9 const char name[WATCHDOG_GOV_NAME_MAXLEN];
10 void (*pretimeout)(struct watchdog_device *wdd);
11};
12
13#if IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_GOV)
14/* Interfaces to watchdog pretimeout governors */
15int watchdog_register_governor(struct watchdog_governor *gov);
16void watchdog_unregister_governor(struct watchdog_governor *gov);
17
18/* Interfaces to watchdog_dev.c */
19int watchdog_register_pretimeout(struct watchdog_device *wdd);
20void watchdog_unregister_pretimeout(struct watchdog_device *wdd);
21int watchdog_pretimeout_available_governors_get(char *buf);
22int watchdog_pretimeout_governor_get(struct watchdog_device *wdd, char *buf);
23int watchdog_pretimeout_governor_set(struct watchdog_device *wdd,
24 const char *buf);
25
26#if IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP)
27#define WATCHDOG_PRETIMEOUT_DEFAULT_GOV "noop"
28#elif IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC)
29#define WATCHDOG_PRETIMEOUT_DEFAULT_GOV "panic"
30#endif
31
32#else
33static inline int watchdog_register_pretimeout(struct watchdog_device *wdd)
34{
35 return 0;
36}
37
38static inline void watchdog_unregister_pretimeout(struct watchdog_device *wdd)
39{
40}
41
42static inline int watchdog_pretimeout_available_governors_get(char *buf)
43{
44 return -EINVAL;
45}
46
47static inline int watchdog_pretimeout_governor_get(struct watchdog_device *wdd,
48 char *buf)
49{
50 return -EINVAL;
51}
52
53static inline int watchdog_pretimeout_governor_set(struct watchdog_device *wdd,
54 const char *buf)
55{
56 return -EINVAL;
57}
58#endif
59
60#endif
diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c
index fa1efef3c96e..b4e0cea5a64e 100644
--- a/drivers/watchdog/ziirave_wdt.c
+++ b/drivers/watchdog/ziirave_wdt.c
@@ -18,7 +18,10 @@
18 * GNU General Public License for more details. 18 * GNU General Public License for more details.
19 */ 19 */
20 20
21#include <linux/delay.h>
21#include <linux/i2c.h> 22#include <linux/i2c.h>
23#include <linux/ihex.h>
24#include <linux/firmware.h>
22#include <linux/kernel.h> 25#include <linux/kernel.h>
23#include <linux/module.h> 26#include <linux/module.h>
24#include <linux/slab.h> 27#include <linux/slab.h>
@@ -36,6 +39,8 @@
36#define ZIIRAVE_STATE_OFF 0x1 39#define ZIIRAVE_STATE_OFF 0x1
37#define ZIIRAVE_STATE_ON 0x2 40#define ZIIRAVE_STATE_ON 0x2
38 41
42#define ZIIRAVE_FW_NAME "ziirave_wdt.fw"
43
39static char *ziirave_reasons[] = {"power cycle", "hw watchdog", NULL, NULL, 44static char *ziirave_reasons[] = {"power cycle", "hw watchdog", NULL, NULL,
40 "host request", NULL, "illegal configuration", 45 "host request", NULL, "illegal configuration",
41 "illegal instruction", "illegal trap", 46 "illegal instruction", "illegal trap",
@@ -50,12 +55,35 @@ static char *ziirave_reasons[] = {"power cycle", "hw watchdog", NULL, NULL,
50#define ZIIRAVE_WDT_PING 0x9 55#define ZIIRAVE_WDT_PING 0x9
51#define ZIIRAVE_WDT_RESET_DURATION 0xa 56#define ZIIRAVE_WDT_RESET_DURATION 0xa
52 57
58#define ZIIRAVE_FIRM_PKT_TOTAL_SIZE 20
59#define ZIIRAVE_FIRM_PKT_DATA_SIZE 16
60#define ZIIRAVE_FIRM_FLASH_MEMORY_START 0x1600
61#define ZIIRAVE_FIRM_FLASH_MEMORY_END 0x2bbf
62
63/* Received and ready for next Download packet. */
64#define ZIIRAVE_FIRM_DOWNLOAD_ACK 1
65/* Currently writing to flash. Retry Download status in a moment! */
66#define ZIIRAVE_FIRM_DOWNLOAD_BUSY 2
67
68/* Wait for ACK timeout in ms */
69#define ZIIRAVE_FIRM_WAIT_FOR_ACK_TIMEOUT 50
70
71/* Firmware commands */
72#define ZIIRAVE_CMD_DOWNLOAD_START 0x10
73#define ZIIRAVE_CMD_DOWNLOAD_END 0x11
74#define ZIIRAVE_CMD_DOWNLOAD_SET_READ_ADDR 0x12
75#define ZIIRAVE_CMD_DOWNLOAD_READ_BYTE 0x13
76#define ZIIRAVE_CMD_RESET_PROCESSOR 0x0b
77#define ZIIRAVE_CMD_JUMP_TO_BOOTLOADER 0x0c
78#define ZIIRAVE_CMD_DOWNLOAD_PACKET 0x0e
79
53struct ziirave_wdt_rev { 80struct ziirave_wdt_rev {
54 unsigned char major; 81 unsigned char major;
55 unsigned char minor; 82 unsigned char minor;
56}; 83};
57 84
58struct ziirave_wdt_data { 85struct ziirave_wdt_data {
86 struct mutex sysfs_mutex;
59 struct watchdog_device wdd; 87 struct watchdog_device wdd;
60 struct ziirave_wdt_rev bootloader_rev; 88 struct ziirave_wdt_rev bootloader_rev;
61 struct ziirave_wdt_rev firmware_rev; 89 struct ziirave_wdt_rev firmware_rev;
@@ -146,6 +174,293 @@ static unsigned int ziirave_wdt_get_timeleft(struct watchdog_device *wdd)
146 return ret; 174 return ret;
147} 175}
148 176
177static int ziirave_firm_wait_for_ack(struct watchdog_device *wdd)
178{
179 struct i2c_client *client = to_i2c_client(wdd->parent);
180 int ret;
181 unsigned long timeout;
182
183 timeout = jiffies + msecs_to_jiffies(ZIIRAVE_FIRM_WAIT_FOR_ACK_TIMEOUT);
184 do {
185 if (time_after(jiffies, timeout))
186 return -ETIMEDOUT;
187
188 usleep_range(5000, 10000);
189
190 ret = i2c_smbus_read_byte(client);
191 if (ret < 0) {
192 dev_err(&client->dev, "Failed to read byte\n");
193 return ret;
194 }
195 } while (ret == ZIIRAVE_FIRM_DOWNLOAD_BUSY);
196
197 return ret == ZIIRAVE_FIRM_DOWNLOAD_ACK ? 0 : -EIO;
198}
199
200static int ziirave_firm_set_read_addr(struct watchdog_device *wdd, u16 addr)
201{
202 struct i2c_client *client = to_i2c_client(wdd->parent);
203 u8 address[2];
204
205 address[0] = addr & 0xff;
206 address[1] = (addr >> 8) & 0xff;
207
208 return i2c_smbus_write_block_data(client,
209 ZIIRAVE_CMD_DOWNLOAD_SET_READ_ADDR,
210 ARRAY_SIZE(address), address);
211}
212
213static int ziirave_firm_write_block_data(struct watchdog_device *wdd,
214 u8 command, u8 length, const u8 *data,
215 bool wait_for_ack)
216{
217 struct i2c_client *client = to_i2c_client(wdd->parent);
218 int ret;
219
220 ret = i2c_smbus_write_block_data(client, command, length, data);
221 if (ret) {
222 dev_err(&client->dev,
223 "Failed to send command 0x%02x: %d\n", command, ret);
224 return ret;
225 }
226
227 if (wait_for_ack)
228 ret = ziirave_firm_wait_for_ack(wdd);
229
230 return ret;
231}
232
233static int ziirave_firm_write_byte(struct watchdog_device *wdd, u8 command,
234 u8 byte, bool wait_for_ack)
235{
236 return ziirave_firm_write_block_data(wdd, command, 1, &byte,
237 wait_for_ack);
238}
239
240/*
241 * ziirave_firm_write_pkt() - Build and write a firmware packet
242 *
243 * A packet to send to the firmware is composed by following bytes:
244 * Length | Addr0 | Addr1 | Data0 .. Data15 | Checksum |
245 * Where,
246 * Length: A data byte containing the length of the data.
247 * Addr0: Low byte of the address.
248 * Addr1: High byte of the address.
249 * Data0 .. Data15: Array of 16 bytes of data.
250 * Checksum: Checksum byte to verify data integrity.
251 */
252static int ziirave_firm_write_pkt(struct watchdog_device *wdd,
253 const struct ihex_binrec *rec)
254{
255 struct i2c_client *client = to_i2c_client(wdd->parent);
256 u8 i, checksum = 0, packet[ZIIRAVE_FIRM_PKT_TOTAL_SIZE];
257 int ret;
258 u16 addr;
259
260 memset(packet, 0, ARRAY_SIZE(packet));
261
262 /* Packet length */
263 packet[0] = (u8)be16_to_cpu(rec->len);
264 /* Packet address */
265 addr = (be32_to_cpu(rec->addr) & 0xffff) >> 1;
266 packet[1] = addr & 0xff;
267 packet[2] = (addr & 0xff00) >> 8;
268
269 /* Packet data */
270 if (be16_to_cpu(rec->len) > ZIIRAVE_FIRM_PKT_DATA_SIZE)
271 return -EMSGSIZE;
272 memcpy(packet + 3, rec->data, be16_to_cpu(rec->len));
273
274 /* Packet checksum */
275 for (i = 0; i < ZIIRAVE_FIRM_PKT_TOTAL_SIZE - 1; i++)
276 checksum += packet[i];
277 packet[ZIIRAVE_FIRM_PKT_TOTAL_SIZE - 1] = checksum;
278
279 ret = ziirave_firm_write_block_data(wdd, ZIIRAVE_CMD_DOWNLOAD_PACKET,
280 ARRAY_SIZE(packet), packet, true);
281 if (ret)
282 dev_err(&client->dev,
283 "Failed to write firmware packet at address 0x%04x: %d\n",
284 addr, ret);
285
286 return ret;
287}
288
289static int ziirave_firm_verify(struct watchdog_device *wdd,
290 const struct firmware *fw)
291{
292 struct i2c_client *client = to_i2c_client(wdd->parent);
293 const struct ihex_binrec *rec;
294 int i, ret;
295 u8 data[ZIIRAVE_FIRM_PKT_DATA_SIZE];
296 u16 addr;
297
298 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
299 /* Zero length marks end of records */
300 if (!be16_to_cpu(rec->len))
301 break;
302
303 addr = (be32_to_cpu(rec->addr) & 0xffff) >> 1;
304 if (addr < ZIIRAVE_FIRM_FLASH_MEMORY_START ||
305 addr > ZIIRAVE_FIRM_FLASH_MEMORY_END)
306 continue;
307
308 ret = ziirave_firm_set_read_addr(wdd, addr);
309 if (ret) {
310 dev_err(&client->dev,
311 "Failed to send SET_READ_ADDR command: %d\n",
312 ret);
313 return ret;
314 }
315
316 for (i = 0; i < ARRAY_SIZE(data); i++) {
317 ret = i2c_smbus_read_byte_data(client,
318 ZIIRAVE_CMD_DOWNLOAD_READ_BYTE);
319 if (ret < 0) {
320 dev_err(&client->dev,
321 "Failed to READ DATA: %d\n", ret);
322 return ret;
323 }
324 data[i] = ret;
325 }
326
327 if (memcmp(data, rec->data, be16_to_cpu(rec->len))) {
328 dev_err(&client->dev,
329 "Firmware mismatch at address 0x%04x\n", addr);
330 return -EINVAL;
331 }
332 }
333
334 return 0;
335}
336
337static int ziirave_firm_upload(struct watchdog_device *wdd,
338 const struct firmware *fw)
339{
340 struct i2c_client *client = to_i2c_client(wdd->parent);
341 int ret, words_till_page_break;
342 const struct ihex_binrec *rec;
343 struct ihex_binrec *rec_new;
344
345 ret = ziirave_firm_write_byte(wdd, ZIIRAVE_CMD_JUMP_TO_BOOTLOADER, 1,
346 false);
347 if (ret)
348 return ret;
349
350 msleep(500);
351
352 ret = ziirave_firm_write_byte(wdd, ZIIRAVE_CMD_DOWNLOAD_START, 1, true);
353 if (ret)
354 return ret;
355
356 msleep(500);
357
358 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
359 /* Zero length marks end of records */
360 if (!be16_to_cpu(rec->len))
361 break;
362
363 /* Check max data size */
364 if (be16_to_cpu(rec->len) > ZIIRAVE_FIRM_PKT_DATA_SIZE) {
365 dev_err(&client->dev, "Firmware packet too long (%d)\n",
366 be16_to_cpu(rec->len));
367 return -EMSGSIZE;
368 }
369
370 /* Calculate words till page break */
371 words_till_page_break = (64 - ((be32_to_cpu(rec->addr) >> 1) &
372 0x3f));
373 if ((be16_to_cpu(rec->len) >> 1) > words_till_page_break) {
374 /*
375 * Data in passes page boundary, so we need to split in
376 * two blocks of data. Create a packet with the first
377 * block of data.
378 */
379 rec_new = kzalloc(sizeof(struct ihex_binrec) +
380 (words_till_page_break << 1),
381 GFP_KERNEL);
382 if (!rec_new)
383 return -ENOMEM;
384
385 rec_new->len = cpu_to_be16(words_till_page_break << 1);
386 rec_new->addr = rec->addr;
387 memcpy(rec_new->data, rec->data,
388 be16_to_cpu(rec_new->len));
389
390 ret = ziirave_firm_write_pkt(wdd, rec_new);
391 kfree(rec_new);
392 if (ret)
393 return ret;
394
395 /* Create a packet with the second block of data */
396 rec_new = kzalloc(sizeof(struct ihex_binrec) +
397 be16_to_cpu(rec->len) -
398 (words_till_page_break << 1),
399 GFP_KERNEL);
400 if (!rec_new)
401 return -ENOMEM;
402
403 /* Remaining bytes */
404 rec_new->len = rec->len -
405 cpu_to_be16(words_till_page_break << 1);
406
407 rec_new->addr = cpu_to_be32(be32_to_cpu(rec->addr) +
408 (words_till_page_break << 1));
409
410 memcpy(rec_new->data,
411 rec->data + (words_till_page_break << 1),
412 be16_to_cpu(rec_new->len));
413
414 ret = ziirave_firm_write_pkt(wdd, rec_new);
415 kfree(rec_new);
416 if (ret)
417 return ret;
418 } else {
419 ret = ziirave_firm_write_pkt(wdd, rec);
420 if (ret)
421 return ret;
422 }
423 }
424
425 /* For end of download, the length field will be set to 0 */
426 rec_new = kzalloc(sizeof(struct ihex_binrec) + 1, GFP_KERNEL);
427 if (!rec_new)
428 return -ENOMEM;
429
430 ret = ziirave_firm_write_pkt(wdd, rec_new);
431 kfree(rec_new);
432 if (ret) {
433 dev_err(&client->dev, "Failed to send EMPTY packet: %d\n", ret);
434 return ret;
435 }
436
437 /* This sleep seems to be required */
438 msleep(20);
439
440 /* Start firmware verification */
441 ret = ziirave_firm_verify(wdd, fw);
442 if (ret) {
443 dev_err(&client->dev,
444 "Failed to verify firmware: %d\n", ret);
445 return ret;
446 }
447
448 /* End download operation */
449 ret = ziirave_firm_write_byte(wdd, ZIIRAVE_CMD_DOWNLOAD_END, 1, false);
450 if (ret)
451 return ret;
452
453 /* Reset the processor */
454 ret = ziirave_firm_write_byte(wdd, ZIIRAVE_CMD_RESET_PROCESSOR, 1,
455 false);
456 if (ret)
457 return ret;
458
459 msleep(500);
460
461 return 0;
462}
463
149static const struct watchdog_info ziirave_wdt_info = { 464static const struct watchdog_info ziirave_wdt_info = {
150 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 465 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
151 .identity = "Zodiac RAVE Watchdog", 466 .identity = "Zodiac RAVE Watchdog",
@@ -166,9 +481,18 @@ static ssize_t ziirave_wdt_sysfs_show_firm(struct device *dev,
166{ 481{
167 struct i2c_client *client = to_i2c_client(dev->parent); 482 struct i2c_client *client = to_i2c_client(dev->parent);
168 struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client); 483 struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
484 int ret;
485
486 ret = mutex_lock_interruptible(&w_priv->sysfs_mutex);
487 if (ret)
488 return ret;
489
490 ret = sprintf(buf, "02.%02u.%02u", w_priv->firmware_rev.major,
491 w_priv->firmware_rev.minor);
169 492
170 return sprintf(buf, "02.%02u.%02u", w_priv->firmware_rev.major, 493 mutex_unlock(&w_priv->sysfs_mutex);
171 w_priv->firmware_rev.minor); 494
495 return ret;
172} 496}
173 497
174static DEVICE_ATTR(firmware_version, S_IRUGO, ziirave_wdt_sysfs_show_firm, 498static DEVICE_ATTR(firmware_version, S_IRUGO, ziirave_wdt_sysfs_show_firm,
@@ -180,9 +504,18 @@ static ssize_t ziirave_wdt_sysfs_show_boot(struct device *dev,
180{ 504{
181 struct i2c_client *client = to_i2c_client(dev->parent); 505 struct i2c_client *client = to_i2c_client(dev->parent);
182 struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client); 506 struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
507 int ret;
183 508
184 return sprintf(buf, "01.%02u.%02u", w_priv->bootloader_rev.major, 509 ret = mutex_lock_interruptible(&w_priv->sysfs_mutex);
185 w_priv->bootloader_rev.minor); 510 if (ret)
511 return ret;
512
513 ret = sprintf(buf, "01.%02u.%02u", w_priv->bootloader_rev.major,
514 w_priv->bootloader_rev.minor);
515
516 mutex_unlock(&w_priv->sysfs_mutex);
517
518 return ret;
186} 519}
187 520
188static DEVICE_ATTR(bootloader_version, S_IRUGO, ziirave_wdt_sysfs_show_boot, 521static DEVICE_ATTR(bootloader_version, S_IRUGO, ziirave_wdt_sysfs_show_boot,
@@ -194,17 +527,81 @@ static ssize_t ziirave_wdt_sysfs_show_reason(struct device *dev,
194{ 527{
195 struct i2c_client *client = to_i2c_client(dev->parent); 528 struct i2c_client *client = to_i2c_client(dev->parent);
196 struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client); 529 struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
530 int ret;
531
532 ret = mutex_lock_interruptible(&w_priv->sysfs_mutex);
533 if (ret)
534 return ret;
535
536 ret = sprintf(buf, "%s", ziirave_reasons[w_priv->reset_reason]);
197 537
198 return sprintf(buf, "%s", ziirave_reasons[w_priv->reset_reason]); 538 mutex_unlock(&w_priv->sysfs_mutex);
539
540 return ret;
199} 541}
200 542
201static DEVICE_ATTR(reset_reason, S_IRUGO, ziirave_wdt_sysfs_show_reason, 543static DEVICE_ATTR(reset_reason, S_IRUGO, ziirave_wdt_sysfs_show_reason,
202 NULL); 544 NULL);
203 545
546static ssize_t ziirave_wdt_sysfs_store_firm(struct device *dev,
547 struct device_attribute *attr,
548 const char *buf, size_t count)
549{
550 struct i2c_client *client = to_i2c_client(dev->parent);
551 struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
552 const struct firmware *fw;
553 int err;
554
555 err = request_ihex_firmware(&fw, ZIIRAVE_FW_NAME, dev);
556 if (err) {
557 dev_err(&client->dev, "Failed to request ihex firmware\n");
558 return err;
559 }
560
561 err = mutex_lock_interruptible(&w_priv->sysfs_mutex);
562 if (err)
563 goto release_firmware;
564
565 err = ziirave_firm_upload(&w_priv->wdd, fw);
566 if (err) {
567 dev_err(&client->dev, "The firmware update failed: %d\n", err);
568 goto unlock_mutex;
569 }
570
571 /* Update firmware version */
572 err = ziirave_wdt_revision(client, &w_priv->firmware_rev,
573 ZIIRAVE_WDT_FIRM_VER_MAJOR);
574 if (err) {
575 dev_err(&client->dev, "Failed to read firmware version: %d\n",
576 err);
577 goto unlock_mutex;
578 }
579
580 dev_info(&client->dev, "Firmware updated to version 02.%02u.%02u\n",
581 w_priv->firmware_rev.major, w_priv->firmware_rev.minor);
582
583 /* Restore the watchdog timeout */
584 err = ziirave_wdt_set_timeout(&w_priv->wdd, w_priv->wdd.timeout);
585 if (err)
586 dev_err(&client->dev, "Failed to set timeout: %d\n", err);
587
588unlock_mutex:
589 mutex_unlock(&w_priv->sysfs_mutex);
590
591release_firmware:
592 release_firmware(fw);
593
594 return err ? err : count;
595}
596
597static DEVICE_ATTR(update_firmware, S_IWUSR, NULL,
598 ziirave_wdt_sysfs_store_firm);
599
204static struct attribute *ziirave_wdt_attrs[] = { 600static struct attribute *ziirave_wdt_attrs[] = {
205 &dev_attr_firmware_version.attr, 601 &dev_attr_firmware_version.attr,
206 &dev_attr_bootloader_version.attr, 602 &dev_attr_bootloader_version.attr,
207 &dev_attr_reset_reason.attr, 603 &dev_attr_reset_reason.attr,
604 &dev_attr_update_firmware.attr,
208 NULL 605 NULL
209}; 606};
210ATTRIBUTE_GROUPS(ziirave_wdt); 607ATTRIBUTE_GROUPS(ziirave_wdt);
@@ -252,6 +649,8 @@ static int ziirave_wdt_probe(struct i2c_client *client,
252 if (!w_priv) 649 if (!w_priv)
253 return -ENOMEM; 650 return -ENOMEM;
254 651
652 mutex_init(&w_priv->sysfs_mutex);
653
255 w_priv->wdd.info = &ziirave_wdt_info; 654 w_priv->wdd.info = &ziirave_wdt_info;
256 w_priv->wdd.ops = &ziirave_wdt_ops; 655 w_priv->wdd.ops = &ziirave_wdt_ops;
257 w_priv->wdd.min_timeout = ZIIRAVE_TIMEOUT_MIN; 656 w_priv->wdd.min_timeout = ZIIRAVE_TIMEOUT_MIN;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index c1e9f29c924c..f2d7402abe02 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -1209,6 +1209,8 @@ COMPATIBLE_IOCTL(WDIOC_SETOPTIONS)
1209COMPATIBLE_IOCTL(WDIOC_KEEPALIVE) 1209COMPATIBLE_IOCTL(WDIOC_KEEPALIVE)
1210COMPATIBLE_IOCTL(WDIOC_SETTIMEOUT) 1210COMPATIBLE_IOCTL(WDIOC_SETTIMEOUT)
1211COMPATIBLE_IOCTL(WDIOC_GETTIMEOUT) 1211COMPATIBLE_IOCTL(WDIOC_GETTIMEOUT)
1212COMPATIBLE_IOCTL(WDIOC_SETPRETIMEOUT)
1213COMPATIBLE_IOCTL(WDIOC_GETPRETIMEOUT)
1212/* Big R */ 1214/* Big R */
1213COMPATIBLE_IOCTL(RNDGETENTCNT) 1215COMPATIBLE_IOCTL(RNDGETENTCNT)
1214COMPATIBLE_IOCTL(RNDADDTOENTCNT) 1216COMPATIBLE_IOCTL(RNDADDTOENTCNT)
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index 7047bc7f8106..35a4d8185b51 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -19,6 +19,7 @@
19struct watchdog_ops; 19struct watchdog_ops;
20struct watchdog_device; 20struct watchdog_device;
21struct watchdog_core_data; 21struct watchdog_core_data;
22struct watchdog_governor;
22 23
23/** struct watchdog_ops - The watchdog-devices operations 24/** struct watchdog_ops - The watchdog-devices operations
24 * 25 *
@@ -28,6 +29,7 @@ struct watchdog_core_data;
28 * @ping: The routine that sends a keepalive ping to the watchdog device. 29 * @ping: The routine that sends a keepalive ping to the watchdog device.
29 * @status: The routine that shows the status of the watchdog device. 30 * @status: The routine that shows the status of the watchdog device.
30 * @set_timeout:The routine for setting the watchdog devices timeout value (in seconds). 31 * @set_timeout:The routine for setting the watchdog devices timeout value (in seconds).
32 * @set_pretimeout:The routine for setting the watchdog devices pretimeout.
31 * @get_timeleft:The routine that gets the time left before a reset (in seconds). 33 * @get_timeleft:The routine that gets the time left before a reset (in seconds).
32 * @restart: The routine for restarting the machine. 34 * @restart: The routine for restarting the machine.
33 * @ioctl: The routines that handles extra ioctl calls. 35 * @ioctl: The routines that handles extra ioctl calls.
@@ -46,6 +48,7 @@ struct watchdog_ops {
46 int (*ping)(struct watchdog_device *); 48 int (*ping)(struct watchdog_device *);
47 unsigned int (*status)(struct watchdog_device *); 49 unsigned int (*status)(struct watchdog_device *);
48 int (*set_timeout)(struct watchdog_device *, unsigned int); 50 int (*set_timeout)(struct watchdog_device *, unsigned int);
51 int (*set_pretimeout)(struct watchdog_device *, unsigned int);
49 unsigned int (*get_timeleft)(struct watchdog_device *); 52 unsigned int (*get_timeleft)(struct watchdog_device *);
50 int (*restart)(struct watchdog_device *, unsigned long, void *); 53 int (*restart)(struct watchdog_device *, unsigned long, void *);
51 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long); 54 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
@@ -59,8 +62,10 @@ struct watchdog_ops {
59 * watchdog device. 62 * watchdog device.
60 * @info: Pointer to a watchdog_info structure. 63 * @info: Pointer to a watchdog_info structure.
61 * @ops: Pointer to the list of watchdog operations. 64 * @ops: Pointer to the list of watchdog operations.
65 * @gov: Pointer to watchdog pretimeout governor.
62 * @bootstatus: Status of the watchdog device at boot. 66 * @bootstatus: Status of the watchdog device at boot.
63 * @timeout: The watchdog devices timeout value (in seconds). 67 * @timeout: The watchdog devices timeout value (in seconds).
68 * @pretimeout: The watchdog devices pre_timeout value.
64 * @min_timeout:The watchdog devices minimum timeout value (in seconds). 69 * @min_timeout:The watchdog devices minimum timeout value (in seconds).
65 * @max_timeout:The watchdog devices maximum timeout value (in seconds) 70 * @max_timeout:The watchdog devices maximum timeout value (in seconds)
66 * as configurable from user space. Only relevant if 71 * as configurable from user space. Only relevant if
@@ -94,8 +99,10 @@ struct watchdog_device {
94 const struct attribute_group **groups; 99 const struct attribute_group **groups;
95 const struct watchdog_info *info; 100 const struct watchdog_info *info;
96 const struct watchdog_ops *ops; 101 const struct watchdog_ops *ops;
102 const struct watchdog_governor *gov;
97 unsigned int bootstatus; 103 unsigned int bootstatus;
98 unsigned int timeout; 104 unsigned int timeout;
105 unsigned int pretimeout;
99 unsigned int min_timeout; 106 unsigned int min_timeout;
100 unsigned int max_timeout; 107 unsigned int max_timeout;
101 unsigned int min_hw_heartbeat_ms; 108 unsigned int min_hw_heartbeat_ms;
@@ -163,6 +170,13 @@ static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne
163 t > wdd->max_timeout); 170 t > wdd->max_timeout);
164} 171}
165 172
173/* Use the following function to check if a pretimeout value is invalid */
174static inline bool watchdog_pretimeout_invalid(struct watchdog_device *wdd,
175 unsigned int t)
176{
177 return t && wdd->timeout && t >= wdd->timeout;
178}
179
166/* Use the following functions to manipulate watchdog driver specific data */ 180/* Use the following functions to manipulate watchdog driver specific data */
167static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data) 181static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data)
168{ 182{
@@ -174,6 +188,16 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd)
174 return wdd->driver_data; 188 return wdd->driver_data;
175} 189}
176 190
191/* Use the following functions to report watchdog pretimeout event */
192#if IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_GOV)
193void watchdog_notify_pretimeout(struct watchdog_device *wdd);
194#else
195static inline void watchdog_notify_pretimeout(struct watchdog_device *wdd)
196{
197 pr_alert("watchdog%d: pretimeout event\n", wdd->id);
198}
199#endif
200
177/* drivers/watchdog/watchdog_core.c */ 201/* drivers/watchdog/watchdog_core.c */
178void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority); 202void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority);
179extern int watchdog_init_timeout(struct watchdog_device *wdd, 203extern int watchdog_init_timeout(struct watchdog_device *wdd,