aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-17 15:15:38 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-17 15:15:38 -0500
commit6606b342febfd470b4a33acb73e360eeaca1d9bb (patch)
tree2414cc2ca582aa34be6e6ed5c830658fbf21db41
parenta016af2e70bfca23f2f5de7d8708157b86ea374d (diff)
parentac36856fe4321454b6789c019c96c3ec854094ed (diff)
Merge git://www.linux-watchdog.org/linux-watchdog
Pull watchdog updates from Wim Van Sebroeck: "This adds following items: - watchdog restart handler support - watchdog reboot notifier support - watchdog sysfs attributes - support for the following new devices: AMD Mullins platform, AMD Carrizo platform, meson8b SoC, CSRatlas7, TS-4800, Alphascale asm9260-wdt, Zodiac, Sigma Designs SMP86xx/SMP87xx - Changes in refcounting for the watchdog core - watchdog core improvements - and small fixes" * git://www.linux-watchdog.org/linux-watchdog: (60 commits) watchdog: asm9260: remove __init and __exit annotations watchdog: Drop pointer to watchdog device from struct watchdog_device watchdog: ziirave: Use watchdog infrastructure to create sysfs attributes watchdog: Add support for creating driver specific sysfs attributes watchdog: kill unref/ref ops watchdog: stmp3xxx: Remove unused variables watchdog: add MT7621 watchdog support hwmon: (sch56xx) Drop watchdog driver data reference count callbacks watchdog: da9055_wdt: Drop reference counting watchdog: da9052_wdt: Drop reference counting watchdog: Separate and maintain variables based on variable lifetime watchdog: diag288: Stop re-using watchdog core internal flags watchdog: Create watchdog device in watchdog_dev.c watchdog: qcom-wdt: Do not set 'dev' in struct watchdog_device watchdog: mena21: Do not use device pointer from struct watchdog_device watchdog: gpio: Do not use device pointer from struct watchdog_device watchdog: tangox: Print info message using pointer to platform device watchdog: bcm2835_wdt: Drop log message if watchdog is stopped devicetree: watchdog: add binding for Sigma Designs SMP8642 watchdog watchdog: add support for Sigma Designs SMP86xx/SMP87xx ...
-rw-r--r--Documentation/ABI/testing/sysfs-class-watchdog51
-rw-r--r--Documentation/devicetree/bindings/watchdog/alphascale-asm9260.txt35
-rw-r--r--Documentation/devicetree/bindings/watchdog/mt7621-wdt.txt12
-rw-r--r--Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt18
-rw-r--r--Documentation/devicetree/bindings/watchdog/ts4800-wdt.txt25
-rw-r--r--Documentation/devicetree/bindings/watchdog/ziirave-wdt.txt19
-rw-r--r--Documentation/watchdog/watchdog-kernel-api.txt77
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/hwmon/sch56xx-common.c31
-rw-r--r--drivers/watchdog/Kconfig65
-rw-r--r--drivers/watchdog/Makefile6
-rw-r--r--drivers/watchdog/asm9260_wdt.c403
-rw-r--r--drivers/watchdog/atlas7_wdt.c242
-rw-r--r--drivers/watchdog/bcm2835_wdt.c1
-rw-r--r--drivers/watchdog/bcm47xx_wdt.c55
-rw-r--r--drivers/watchdog/cadence_wdt.c42
-rw-r--r--drivers/watchdog/da9052_wdt.c24
-rw-r--r--drivers/watchdog/da9055_wdt.c24
-rw-r--r--drivers/watchdog/da9063_wdt.c23
-rw-r--r--drivers/watchdog/diag288_wdt.c26
-rw-r--r--drivers/watchdog/digicolor_wdt.c18
-rw-r--r--drivers/watchdog/dw_wdt.c2
-rw-r--r--drivers/watchdog/gpio_wdt.c38
-rw-r--r--drivers/watchdog/hpwdt.c12
-rw-r--r--drivers/watchdog/imgpdc_wdt.c34
-rw-r--r--drivers/watchdog/imx2_wdt.c23
-rw-r--r--drivers/watchdog/lpc18xx_wdt.c52
-rw-r--r--drivers/watchdog/mena21_wdt.c4
-rw-r--r--drivers/watchdog/meson_wdt.c88
-rw-r--r--drivers/watchdog/moxart_wdt.c23
-rw-r--r--drivers/watchdog/mt7621_wdt.c186
-rw-r--r--drivers/watchdog/mtk_wdt.c22
-rw-r--r--drivers/watchdog/omap_wdt.c7
-rw-r--r--drivers/watchdog/qcom-wdt.c50
-rw-r--r--drivers/watchdog/s3c2410_wdt.c60
-rw-r--r--drivers/watchdog/softdog.c38
-rw-r--r--drivers/watchdog/sp5100_tco.c32
-rw-r--r--drivers/watchdog/stmp3xxx_rtc_wdt.c25
-rw-r--r--drivers/watchdog/sunxi_wdt.c23
-rw-r--r--drivers/watchdog/tangox_wdt.c225
-rw-r--r--drivers/watchdog/ts4800_wdt.c215
-rw-r--r--drivers/watchdog/w83627hf_wdt.c32
-rw-r--r--drivers/watchdog/watchdog_core.c115
-rw-r--r--drivers/watchdog/watchdog_core.h2
-rw-r--r--drivers/watchdog/watchdog_dev.c572
-rw-r--r--drivers/watchdog/ziirave_wdt.c367
-rw-r--r--include/linux/bcm47xx_wdt.h3
-rw-r--r--include/linux/watchdog.h38
48 files changed, 2671 insertions, 815 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-watchdog b/Documentation/ABI/testing/sysfs-class-watchdog
new file mode 100644
index 000000000000..736046b33040
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-watchdog
@@ -0,0 +1,51 @@
1What: /sys/class/watchdog/watchdogn/bootstatus
2Date: August 2015
3Contact: Wim Van Sebroeck <wim@iguana.be>
4Description:
5 It is a read only file. It contains status of the watchdog
6 device at boot. It is equivalent to WDIOC_GETBOOTSTATUS of
7 ioctl interface.
8
9What: /sys/class/watchdog/watchdogn/identity
10Date: August 2015
11Contact: Wim Van Sebroeck <wim@iguana.be>
12Description:
13 It is a read only file. It contains identity string of
14 watchdog device.
15
16What: /sys/class/watchdog/watchdogn/nowayout
17Date: August 2015
18Contact: Wim Van Sebroeck <wim@iguana.be>
19Description:
20 It is a read only file. While reading, it gives '1' if that
21 device supports nowayout feature else, it gives '0'.
22
23What: /sys/class/watchdog/watchdogn/state
24Date: August 2015
25Contact: Wim Van Sebroeck <wim@iguana.be>
26Description:
27 It is a read only file. It gives active/inactive status of
28 watchdog device.
29
30What: /sys/class/watchdog/watchdogn/status
31Date: August 2015
32Contact: Wim Van Sebroeck <wim@iguana.be>
33Description:
34 It is a read only file. It contains watchdog device's
35 internal status bits. It is equivalent to WDIOC_GETSTATUS
36 of ioctl interface.
37
38What: /sys/class/watchdog/watchdogn/timeleft
39Date: August 2015
40Contact: Wim Van Sebroeck <wim@iguana.be>
41Description:
42 It is a read only file. It contains value of time left for
43 reset generation. It is equivalent to WDIOC_GETTIMELEFT of
44 ioctl interface.
45
46What: /sys/class/watchdog/watchdogn/timeout
47Date: August 2015
48Contact: Wim Van Sebroeck <wim@iguana.be>
49Description:
50 It is a read only file. It is read to know about current
51 value of timeout programmed.
diff --git a/Documentation/devicetree/bindings/watchdog/alphascale-asm9260.txt b/Documentation/devicetree/bindings/watchdog/alphascale-asm9260.txt
new file mode 100644
index 000000000000..75b265a04047
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/alphascale-asm9260.txt
@@ -0,0 +1,35 @@
1Alphascale asm9260 Watchdog timer
2
3Required properties:
4
5- compatible : should be "alphascale,asm9260-wdt".
6- reg : Specifies base physical address and size of the registers.
7- clocks : the clocks feeding the watchdog timer. See clock-bindings.txt
8- clock-names : should be set to
9 "mod" - source for tick counter.
10 "ahb" - ahb gate.
11- resets : phandle pointing to the system reset controller with
12 line index for the watchdog.
13- reset-names : should be set to "wdt_rst".
14
15Optional properties:
16- timeout-sec : shall contain the default watchdog timeout in seconds,
17 if unset, the default timeout is 30 seconds.
18- alphascale,mode : three modes are supported
19 "hw" - hw reset (default).
20 "sw" - sw reset.
21 "debug" - no action is taken.
22
23Example:
24
25watchdog0: watchdog@80048000 {
26 compatible = "alphascale,asm9260-wdt";
27 reg = <0x80048000 0x10>;
28 clocks = <&acc CLKID_SYS_WDT>, <&acc CLKID_AHB_WDT>;
29 clock-names = "mod", "ahb";
30 interrupts = <55>;
31 resets = <&rst WDT_RESET>;
32 reset-names = "wdt_rst";
33 timeout-sec = <30>;
34 alphascale,mode = "hw";
35};
diff --git a/Documentation/devicetree/bindings/watchdog/mt7621-wdt.txt b/Documentation/devicetree/bindings/watchdog/mt7621-wdt.txt
new file mode 100644
index 000000000000..c15ef0ef609f
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/mt7621-wdt.txt
@@ -0,0 +1,12 @@
1Ralink Watchdog Timers
2
3Required properties:
4- compatible: must be "mediatek,mt7621-wdt"
5- reg: physical base address of the controller and length of the register range
6
7Example:
8
9 watchdog@100 {
10 compatible = "mediatek,mt7621-wdt";
11 reg = <0x100 0x10>;
12 };
diff --git a/Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt b/Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt
new file mode 100644
index 000000000000..5b7ec2c707d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/sigma,smp8642-wdt.txt
@@ -0,0 +1,18 @@
1Sigma Designs SMP86xx/SMP87xx watchdog
2
3Required properties:
4- compatible: Should be "sigma,smp8642-wdt"
5- reg: Specifies the physical address region
6- clocks: Should be a phandle to the clock
7
8Optional properties:
9- timeout-sec: watchdog timeout in seconds
10
11Example:
12
13watchdog@1fd00 {
14 compatible = "sigma,smp8642-wdt";
15 reg = <0x1fd00 8>;
16 clocks = <&xtal_in_clk>;
17 timeout-sec = <30>;
18};
diff --git a/Documentation/devicetree/bindings/watchdog/ts4800-wdt.txt b/Documentation/devicetree/bindings/watchdog/ts4800-wdt.txt
new file mode 100644
index 000000000000..8f6caad4258d
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/ts4800-wdt.txt
@@ -0,0 +1,25 @@
1Technologic Systems Watchdog
2
3Required properties:
4- compatible: must be "technologic,ts4800-wdt"
5- syscon: phandle / integer array that points to the syscon node which
6 describes the FPGA's syscon registers.
7 - phandle to FPGA's syscon
8 - offset to the watchdog register
9
10Optional property:
11- timeout-sec: contains the watchdog timeout in seconds.
12
13Example:
14
15syscon: syscon@b0010000 {
16 compatible = "syscon", "simple-mfd";
17 reg = <0xb0010000 0x3d>;
18 reg-io-width = <2>;
19
20 wdt@e {
21 compatible = "technologic,ts4800-wdt";
22 syscon = <&syscon 0xe>;
23 timeout-sec = <10>;
24 };
25}
diff --git a/Documentation/devicetree/bindings/watchdog/ziirave-wdt.txt b/Documentation/devicetree/bindings/watchdog/ziirave-wdt.txt
new file mode 100644
index 000000000000..3d878184ec3f
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/ziirave-wdt.txt
@@ -0,0 +1,19 @@
1Zodiac RAVE Watchdog Timer
2
3Required properties:
4- compatible: must be "zii,rave-wdt"
5- reg: i2c slave address of device, usually 0x38
6
7Optional Properties:
8- timeout-sec: Watchdog timeout value in seconds.
9- reset-duration-ms: Duration of the pulse generated when the watchdog times
10 out. Value in milliseconds.
11
12Example:
13
14 watchdog@38 {
15 compatible = "zii,rave-wdt";
16 reg = <0x38>;
17 timeout-sec = <30>;
18 reset-duration-ms = <30>;
19 };
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
index d8b0d3367706..55120a055a14 100644
--- a/Documentation/watchdog/watchdog-kernel-api.txt
+++ b/Documentation/watchdog/watchdog-kernel-api.txt
@@ -44,17 +44,18 @@ The watchdog device structure looks like this:
44 44
45struct watchdog_device { 45struct watchdog_device {
46 int id; 46 int id;
47 struct cdev cdev;
48 struct device *dev;
49 struct device *parent; 47 struct device *parent;
48 const struct attribute_group **groups;
50 const struct watchdog_info *info; 49 const struct watchdog_info *info;
51 const struct watchdog_ops *ops; 50 const struct watchdog_ops *ops;
52 unsigned int bootstatus; 51 unsigned int bootstatus;
53 unsigned int timeout; 52 unsigned int timeout;
54 unsigned int min_timeout; 53 unsigned int min_timeout;
55 unsigned int max_timeout; 54 unsigned int max_timeout;
55 struct notifier_block reboot_nb;
56 struct notifier_block restart_nb;
56 void *driver_data; 57 void *driver_data;
57 struct mutex lock; 58 struct watchdog_core_data *wd_data;
58 unsigned long status; 59 unsigned long status;
59 struct list_head deferred; 60 struct list_head deferred;
60}; 61};
@@ -64,27 +65,32 @@ It contains following fields:
64 /dev/watchdog0 cdev (dynamic major, minor 0) as well as the old 65 /dev/watchdog0 cdev (dynamic major, minor 0) as well as the old
65 /dev/watchdog miscdev. The id is set automatically when calling 66 /dev/watchdog miscdev. The id is set automatically when calling
66 watchdog_register_device. 67 watchdog_register_device.
67* cdev: cdev for the dynamic /dev/watchdog<id> device nodes. This
68 field is also populated by watchdog_register_device.
69* dev: device under the watchdog class (created by watchdog_register_device).
70* parent: set this to the parent device (or NULL) before calling 68* parent: set this to the parent device (or NULL) before calling
71 watchdog_register_device. 69 watchdog_register_device.
70* groups: List of sysfs attribute groups to create when creating the watchdog
71 device.
72* info: a pointer to a watchdog_info structure. This structure gives some 72* info: a pointer to a watchdog_info structure. This structure gives some
73 additional information about the watchdog timer itself. (Like it's unique name) 73 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. 74* ops: a pointer to the list of watchdog operations that the watchdog supports.
75* timeout: the watchdog timer's timeout value (in seconds). 75* timeout: the watchdog timer's timeout value (in seconds).
76* min_timeout: the watchdog timer's minimum timeout value (in seconds). 76* min_timeout: the watchdog timer's minimum timeout value (in seconds).
77* max_timeout: the watchdog timer's maximum timeout value (in seconds). 77* max_timeout: the watchdog timer's maximum timeout value (in seconds).
78* 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
80 will stop the watchdog on such notifications.
81* restart_nb: notifier block that is registered for machine restart, for
82 internal use only. If a watchdog is capable of restarting the machine, it
83 should define ops->restart. Priority can be changed through
84 watchdog_set_restart_priority.
78* bootstatus: status of the device after booting (reported with watchdog 85* bootstatus: status of the device after booting (reported with watchdog
79 WDIOF_* status bits). 86 WDIOF_* status bits).
80* driver_data: a pointer to the drivers private data of a watchdog device. 87* driver_data: a pointer to the drivers private data of a watchdog device.
81 This data should only be accessed via the watchdog_set_drvdata and 88 This data should only be accessed via the watchdog_set_drvdata and
82 watchdog_get_drvdata routines. 89 watchdog_get_drvdata routines.
83* lock: Mutex for WatchDog Timer Driver Core internal use only. 90* wd_data: a pointer to watchdog core internal data.
84* status: this field contains a number of status bits that give extra 91* status: this field contains a number of status bits that give extra
85 information about the status of the device (Like: is the watchdog timer 92 information about the status of the device (Like: is the watchdog timer
86 running/active, is the nowayout bit set, is the device opened via 93 running/active, or is the nowayout bit set).
87 the /dev/watchdog interface or not, ...).
88* deferred: entry in wtd_deferred_reg_list which is used to 94* deferred: entry in wtd_deferred_reg_list which is used to
89 register early initialized watchdogs. 95 register early initialized watchdogs.
90 96
@@ -100,8 +106,9 @@ struct watchdog_ops {
100 unsigned int (*status)(struct watchdog_device *); 106 unsigned int (*status)(struct watchdog_device *);
101 int (*set_timeout)(struct watchdog_device *, unsigned int); 107 int (*set_timeout)(struct watchdog_device *, unsigned int);
102 unsigned int (*get_timeleft)(struct watchdog_device *); 108 unsigned int (*get_timeleft)(struct watchdog_device *);
103 void (*ref)(struct watchdog_device *); 109 int (*restart)(struct watchdog_device *);
104 void (*unref)(struct watchdog_device *); 110 void (*ref)(struct watchdog_device *) __deprecated;
111 void (*unref)(struct watchdog_device *) __deprecated;
105 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long); 112 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
106}; 113};
107 114
@@ -110,20 +117,6 @@ driver's operations. This module owner will be used to lock the module when
110the watchdog is active. (This to avoid a system crash when you unload the 117the watchdog is active. (This to avoid a system crash when you unload the
111module and /dev/watchdog is still open). 118module and /dev/watchdog is still open).
112 119
113If the watchdog_device struct is dynamically allocated, just locking the module
114is not enough and a driver also needs to define the ref and unref operations to
115ensure the structure holding the watchdog_device does not go away.
116
117The simplest (and usually sufficient) implementation of this is to:
1181) Add a kref struct to the same structure which is holding the watchdog_device
1192) Define a release callback for the kref which frees the struct holding both
1203) Call kref_init on this kref *before* calling watchdog_register_device()
1214) Define a ref operation calling kref_get on this kref
1225) Define a unref operation calling kref_put on this kref
1236) When it is time to cleanup:
124 * Do not kfree() the struct holding both, the last kref_put will do this!
125 * *After* calling watchdog_unregister_device() call kref_put on the kref
126
127Some operations are mandatory and some are optional. The mandatory operations 120Some operations are mandatory and some are optional. The mandatory operations
128are: 121are:
129* start: this is a pointer to the routine that starts the watchdog timer 122* start: this is a pointer to the routine that starts the watchdog timer
@@ -164,34 +157,23 @@ they are supported. These optional routines/operations are:
164 (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the 157 (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the
165 watchdog's info structure). 158 watchdog's info structure).
166* get_timeleft: this routines returns the time that's left before a reset. 159* get_timeleft: this routines returns the time that's left before a reset.
167* ref: the operation that calls kref_get on the kref of a dynamically 160* restart: this routine restarts the machine. It returns 0 on success or a
168 allocated watchdog_device struct. 161 negative errno code for failure.
169* unref: the operation that calls kref_put on the kref of a dynamically
170 allocated watchdog_device struct.
171* ioctl: if this routine is present then it will be called first before we do 162* ioctl: if this routine is present then it will be called first before we do
172 our own internal ioctl call handling. This routine should return -ENOIOCTLCMD 163 our own internal ioctl call handling. This routine should return -ENOIOCTLCMD
173 if a command is not supported. The parameters that are passed to the ioctl 164 if a command is not supported. The parameters that are passed to the ioctl
174 call are: watchdog_device, cmd and arg. 165 call are: watchdog_device, cmd and arg.
175 166
167The 'ref' and 'unref' operations are no longer used and deprecated.
168
176The status bits should (preferably) be set with the set_bit and clear_bit alike 169The status bits should (preferably) be set with the set_bit and clear_bit alike
177bit-operations. The status bits that are defined are: 170bit-operations. The status bits that are defined are:
178* WDOG_ACTIVE: this status bit indicates whether or not a watchdog timer device 171* WDOG_ACTIVE: this status bit indicates whether or not a watchdog timer device
179 is active or not. When the watchdog is active after booting, then you should 172 is active or not. When the watchdog is active after booting, then you should
180 set this status bit (Note: when you register the watchdog timer device with 173 set this status bit (Note: when you register the watchdog timer device with
181 this bit set, then opening /dev/watchdog will skip the start operation) 174 this bit set, then opening /dev/watchdog will skip the start operation)
182* WDOG_DEV_OPEN: this status bit shows whether or not the watchdog device
183 was opened via /dev/watchdog.
184 (This bit should only be used by the WatchDog Timer Driver Core).
185* WDOG_ALLOW_RELEASE: this bit stores whether or not the magic close character
186 has been sent (so that we can support the magic close feature).
187 (This bit should only be used by the WatchDog Timer Driver Core).
188* WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog. 175* WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog.
189 If this bit is set then the watchdog timer will not be able to stop. 176 If this bit is set then the watchdog timer will not be able to stop.
190* WDOG_UNREGISTERED: this bit gets set by the WatchDog Timer Driver Core
191 after calling watchdog_unregister_device, and then checked before calling
192 any watchdog_ops, so that you can be sure that no operations (other then
193 unref) will get called after unregister, even if userspace still holds a
194 reference to /dev/watchdog
195 177
196 To set the WDOG_NO_WAY_OUT status bit (before registering your watchdog 178 To set the WDOG_NO_WAY_OUT status bit (before registering your watchdog
197 timer device) you can either: 179 timer device) you can either:
@@ -231,3 +213,18 @@ the device tree (if the module timeout parameter is invalid). Best practice is
231to set the default timeout value as timeout value in the watchdog_device and 213to set the default timeout value as timeout value in the watchdog_device and
232then use this function to set the user "preferred" timeout value. 214then use this function to set the user "preferred" timeout value.
233This routine returns zero on success and a negative errno code for failure. 215This routine returns zero on success and a negative errno code for failure.
216
217To disable the watchdog on reboot, the user must call the following helper:
218
219static inline void watchdog_stop_on_reboot(struct watchdog_device *wdd);
220
221To change the priority of the restart handler the following helper should be
222used:
223
224void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority);
225
226User should follow the following guidelines for setting the priority:
227* 0: should be called in last resort, has limited restart capabilities
228* 128: default restart handler, use if no other handler is expected to be
229 available, and/or if restart is sufficient to restart the entire system
230* 255: highest priority, will preempt all other restart handlers
diff --git a/MAINTAINERS b/MAINTAINERS
index 04d62b1e8b17..11073db4c0a0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11676,6 +11676,7 @@ F: drivers/input/tablet/wacom_serial4.c
11676 11676
11677WATCHDOG DEVICE DRIVERS 11677WATCHDOG DEVICE DRIVERS
11678M: Wim Van Sebroeck <wim@iguana.be> 11678M: Wim Van Sebroeck <wim@iguana.be>
11679R: Guenter Roeck <linux@roeck-us.net>
11679L: linux-watchdog@vger.kernel.org 11680L: linux-watchdog@vger.kernel.org
11680W: http://www.linux-watchdog.org/ 11681W: http://www.linux-watchdog.org/
11681T: git git://www.linux-watchdog.org/linux-watchdog.git 11682T: git git://www.linux-watchdog.org/linux-watchdog.git
diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c
index 738681983284..68c350c704fb 100644
--- a/drivers/hwmon/sch56xx-common.c
+++ b/drivers/hwmon/sch56xx-common.c
@@ -30,7 +30,6 @@
30#include <linux/watchdog.h> 30#include <linux/watchdog.h>
31#include <linux/miscdevice.h> 31#include <linux/miscdevice.h>
32#include <linux/uaccess.h> 32#include <linux/uaccess.h>
33#include <linux/kref.h>
34#include <linux/slab.h> 33#include <linux/slab.h>
35#include "sch56xx-common.h" 34#include "sch56xx-common.h"
36 35
@@ -67,7 +66,6 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
67struct sch56xx_watchdog_data { 66struct sch56xx_watchdog_data {
68 u16 addr; 67 u16 addr;
69 struct mutex *io_lock; 68 struct mutex *io_lock;
70 struct kref kref;
71 struct watchdog_info wdinfo; 69 struct watchdog_info wdinfo;
72 struct watchdog_device wddev; 70 struct watchdog_device wddev;
73 u8 watchdog_preset; 71 u8 watchdog_preset;
@@ -258,15 +256,6 @@ EXPORT_SYMBOL(sch56xx_read_virtual_reg12);
258 * Watchdog routines 256 * Watchdog routines
259 */ 257 */
260 258
261/* Release our data struct when we're unregistered *and*
262 all references to our watchdog device are released */
263static void watchdog_release_resources(struct kref *r)
264{
265 struct sch56xx_watchdog_data *data =
266 container_of(r, struct sch56xx_watchdog_data, kref);
267 kfree(data);
268}
269
270static int watchdog_set_timeout(struct watchdog_device *wddev, 259static int watchdog_set_timeout(struct watchdog_device *wddev,
271 unsigned int timeout) 260 unsigned int timeout)
272{ 261{
@@ -395,28 +384,12 @@ static int watchdog_stop(struct watchdog_device *wddev)
395 return 0; 384 return 0;
396} 385}
397 386
398static void watchdog_ref(struct watchdog_device *wddev)
399{
400 struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev);
401
402 kref_get(&data->kref);
403}
404
405static void watchdog_unref(struct watchdog_device *wddev)
406{
407 struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev);
408
409 kref_put(&data->kref, watchdog_release_resources);
410}
411
412static const struct watchdog_ops watchdog_ops = { 387static const struct watchdog_ops watchdog_ops = {
413 .owner = THIS_MODULE, 388 .owner = THIS_MODULE,
414 .start = watchdog_start, 389 .start = watchdog_start,
415 .stop = watchdog_stop, 390 .stop = watchdog_stop,
416 .ping = watchdog_trigger, 391 .ping = watchdog_trigger,
417 .set_timeout = watchdog_set_timeout, 392 .set_timeout = watchdog_set_timeout,
418 .ref = watchdog_ref,
419 .unref = watchdog_unref,
420}; 393};
421 394
422struct sch56xx_watchdog_data *sch56xx_watchdog_register(struct device *parent, 395struct sch56xx_watchdog_data *sch56xx_watchdog_register(struct device *parent,
@@ -448,7 +421,6 @@ struct sch56xx_watchdog_data *sch56xx_watchdog_register(struct device *parent,
448 421
449 data->addr = addr; 422 data->addr = addr;
450 data->io_lock = io_lock; 423 data->io_lock = io_lock;
451 kref_init(&data->kref);
452 424
453 strlcpy(data->wdinfo.identity, "sch56xx watchdog", 425 strlcpy(data->wdinfo.identity, "sch56xx watchdog",
454 sizeof(data->wdinfo.identity)); 426 sizeof(data->wdinfo.identity));
@@ -494,8 +466,7 @@ EXPORT_SYMBOL(sch56xx_watchdog_register);
494void sch56xx_watchdog_unregister(struct sch56xx_watchdog_data *data) 466void sch56xx_watchdog_unregister(struct sch56xx_watchdog_data *data)
495{ 467{
496 watchdog_unregister_device(&data->wddev); 468 watchdog_unregister_device(&data->wddev);
497 kref_put(&data->kref, watchdog_release_resources); 469 kfree(data);
498 /* Don't touch data after this it may have been free-ed! */
499} 470}
500EXPORT_SYMBOL(sch56xx_watchdog_unregister); 471EXPORT_SYMBOL(sch56xx_watchdog_unregister);
501 472
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 1c427beffadd..4f0e7be0da34 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -46,6 +46,13 @@ config WATCHDOG_NOWAYOUT
46 get killed. If you say Y here, the watchdog cannot be stopped once 46 get killed. If you say Y here, the watchdog cannot be stopped once
47 it has been started. 47 it has been started.
48 48
49config WATCHDOG_SYSFS
50 bool "Read different watchdog information through sysfs"
51 default n
52 help
53 Say Y here if you want to enable watchdog device status read through
54 sysfs attributes.
55
49# 56#
50# General Watchdog drivers 57# General Watchdog drivers
51# 58#
@@ -135,6 +142,16 @@ config MENF21BMC_WATCHDOG
135 This driver can also be built as a module. If so the module 142 This driver can also be built as a module. If so the module
136 will be called menf21bmc_wdt. 143 will be called menf21bmc_wdt.
137 144
145config TANGOX_WATCHDOG
146 tristate "Sigma Designs SMP86xx/SMP87xx watchdog"
147 select WATCHDOG_CORE
148 depends on ARCH_TANGOX || COMPILE_TEST
149 help
150 Support for the watchdog in Sigma Designs SMP86xx (tango3)
151 and SMP87xx (tango4) family chips.
152
153 This driver can be built as a module. The module name is tangox_wdt.
154
138config WM831X_WATCHDOG 155config WM831X_WATCHDOG
139 tristate "WM831x watchdog" 156 tristate "WM831x watchdog"
140 depends on MFD_WM831X 157 depends on MFD_WM831X
@@ -161,6 +178,17 @@ config XILINX_WATCHDOG
161 To compile this driver as a module, choose M here: the 178 To compile this driver as a module, choose M here: the
162 module will be called of_xilinx_wdt. 179 module will be called of_xilinx_wdt.
163 180
181config ZIIRAVE_WATCHDOG
182 tristate "Zodiac RAVE Watchdog Timer"
183 depends on I2C
184 select WATCHDOG_CORE
185 help
186 Watchdog driver for the Zodiac Aerospace RAVE Switch Watchdog
187 Processor.
188
189 To compile this driver as a module, choose M here: the
190 module will be called ziirave_wdt.
191
164# ALPHA Architecture 192# ALPHA Architecture
165 193
166# ARM Architecture 194# ARM Architecture
@@ -173,6 +201,16 @@ config ARM_SP805_WATCHDOG
173 ARM Primecell SP805 Watchdog timer. This will reboot your system when 201 ARM Primecell SP805 Watchdog timer. This will reboot your system when
174 the timeout is reached. 202 the timeout is reached.
175 203
204config ASM9260_WATCHDOG
205 tristate "Alphascale ASM9260 watchdog"
206 depends on MACH_ASM9260
207 depends on OF
208 select WATCHDOG_CORE
209 select RESET_CONTROLLER
210 help
211 Watchdog timer embedded into Alphascale asm9260 chips. This will reboot your
212 system when the timeout is reached.
213
176config AT91RM9200_WATCHDOG 214config AT91RM9200_WATCHDOG
177 tristate "AT91RM9200 watchdog" 215 tristate "AT91RM9200 watchdog"
178 depends on SOC_AT91RM9200 && MFD_SYSCON 216 depends on SOC_AT91RM9200 && MFD_SYSCON
@@ -426,6 +464,16 @@ config NUC900_WATCHDOG
426 To compile this driver as a module, choose M here: the 464 To compile this driver as a module, choose M here: the
427 module will be called nuc900_wdt. 465 module will be called nuc900_wdt.
428 466
467config TS4800_WATCHDOG
468 tristate "TS-4800 Watchdog"
469 depends on HAS_IOMEM && OF
470 select WATCHDOG_CORE
471 select MFD_SYSCON
472 help
473 Technologic Systems TS-4800 has watchdog timer implemented in
474 an external FPGA. Say Y here if you want to support for the
475 watchdog timer on TS-4800 board.
476
429config TS72XX_WATCHDOG 477config TS72XX_WATCHDOG
430 tristate "TS-72XX SBC Watchdog" 478 tristate "TS-72XX SBC Watchdog"
431 depends on MACH_TS72XX 479 depends on MACH_TS72XX
@@ -578,6 +626,16 @@ config LPC18XX_WATCHDOG
578 To compile this driver as a module, choose M here: the 626 To compile this driver as a module, choose M here: the
579 module will be called lpc18xx_wdt. 627 module will be called lpc18xx_wdt.
580 628
629config ATLAS7_WATCHDOG
630 tristate "CSRatlas7 watchdog"
631 depends on ARCH_ATLAS7
632 help
633 Say Y here to include Watchdog timer support for the watchdog
634 existing on the CSRatlas7 series platforms.
635
636 To compile this driver as a module, choose M here: the
637 module will be called atlas7_wdt.
638
581# AVR32 Architecture 639# AVR32 Architecture
582 640
583config AT32AP700X_WDT 641config AT32AP700X_WDT
@@ -1345,6 +1403,13 @@ config RALINK_WDT
1345 help 1403 help
1346 Hardware driver for the Ralink SoC Watchdog Timer. 1404 Hardware driver for the Ralink SoC Watchdog Timer.
1347 1405
1406config MT7621_WDT
1407 tristate "Mediatek SoC watchdog"
1408 select WATCHDOG_CORE
1409 depends on SOC_MT7620 || SOC_MT7621
1410 help
1411 Hardware driver for the Mediatek/Ralink MT7621/8 SoC Watchdog Timer.
1412
1348# PARISC Architecture 1413# PARISC Architecture
1349 1414
1350# POWERPC Architecture 1415# POWERPC Architecture
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 53d4827ddfe1..f566753256ab 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_ASM9260_WATCHDOG) += asm9260_wdt.o
33obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o 34obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
34obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o 35obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
35obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.o 36obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.o
@@ -53,6 +54,7 @@ obj-$(CONFIG_RN5T618_WATCHDOG) += rn5t618_wdt.o
53obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o 54obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
54obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o 55obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o
55obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o 56obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
57obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o
56obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o 58obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
57obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o 59obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
58obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o 60obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o
@@ -69,6 +71,7 @@ obj-$(CONFIG_MEDIATEK_WATCHDOG) += mtk_wdt.o
69obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o 71obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o
70obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o 72obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o
71obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o 73obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o
74obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o
72 75
73# AVR32 Architecture 76# AVR32 Architecture
74obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o 77obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
@@ -149,6 +152,7 @@ octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
149obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o 152obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o
150obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o 153obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o
151obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o 154obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o
155obj-$(CONFIG_MT7621_WDT) += mt7621_wdt.o
152 156
153# PARISC Architecture 157# PARISC Architecture
154 158
@@ -187,8 +191,10 @@ obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o
187obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o 191obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o
188obj-$(CONFIG_DA9063_WATCHDOG) += da9063_wdt.o 192obj-$(CONFIG_DA9063_WATCHDOG) += da9063_wdt.o
189obj-$(CONFIG_GPIO_WATCHDOG) += gpio_wdt.o 193obj-$(CONFIG_GPIO_WATCHDOG) += gpio_wdt.o
194obj-$(CONFIG_TANGOX_WATCHDOG) += tangox_wdt.o
190obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o 195obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
191obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o 196obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
192obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o 197obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
198obj-$(CONFIG_ZIIRAVE_WATCHDOG) += ziirave_wdt.o
193obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o 199obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
194obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o 200obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o
diff --git a/drivers/watchdog/asm9260_wdt.c b/drivers/watchdog/asm9260_wdt.c
new file mode 100644
index 000000000000..c9686b2fdafd
--- /dev/null
+++ b/drivers/watchdog/asm9260_wdt.c
@@ -0,0 +1,403 @@
1/*
2 * Watchdog driver for Alphascale ASM9260.
3 *
4 * Copyright (c) 2014 Oleksij Rempel <linux@rempel-privat.de>
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/bitops.h>
10#include <linux/clk.h>
11#include <linux/delay.h>
12#include <linux/interrupt.h>
13#include <linux/io.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/platform_device.h>
17#include <linux/reboot.h>
18#include <linux/reset.h>
19#include <linux/watchdog.h>
20
21#define CLOCK_FREQ 1000000
22
23/* Watchdog Mode register */
24#define HW_WDMOD 0x00
25/* Wake interrupt. Set by HW, can't be cleared. */
26#define BM_MOD_WDINT BIT(3)
27/* This bit set if timeout reached. Cleared by SW. */
28#define BM_MOD_WDTOF BIT(2)
29/* HW Reset on timeout */
30#define BM_MOD_WDRESET BIT(1)
31/* WD enable */
32#define BM_MOD_WDEN BIT(0)
33
34/*
35 * Watchdog Timer Constant register
36 * Minimal value is 0xff, the meaning of this value
37 * depends on used clock: T = WDCLK * (0xff + 1) * 4
38 */
39#define HW_WDTC 0x04
40#define BM_WDTC_MAX(freq) (0x7fffffff / (freq))
41
42/* Watchdog Feed register */
43#define HW_WDFEED 0x08
44
45/* Watchdog Timer Value register */
46#define HW_WDTV 0x0c
47
48#define ASM9260_WDT_DEFAULT_TIMEOUT 30
49
50enum asm9260_wdt_mode {
51 HW_RESET,
52 SW_RESET,
53 DEBUG,
54};
55
56struct asm9260_wdt_priv {
57 struct device *dev;
58 struct watchdog_device wdd;
59 struct clk *clk;
60 struct clk *clk_ahb;
61 struct reset_control *rst;
62 struct notifier_block restart_handler;
63
64 void __iomem *iobase;
65 int irq;
66 unsigned long wdt_freq;
67 enum asm9260_wdt_mode mode;
68};
69
70static int asm9260_wdt_feed(struct watchdog_device *wdd)
71{
72 struct asm9260_wdt_priv *priv = watchdog_get_drvdata(wdd);
73
74 iowrite32(0xaa, priv->iobase + HW_WDFEED);
75 iowrite32(0x55, priv->iobase + HW_WDFEED);
76
77 return 0;
78}
79
80static unsigned int asm9260_wdt_gettimeleft(struct watchdog_device *wdd)
81{
82 struct asm9260_wdt_priv *priv = watchdog_get_drvdata(wdd);
83 u32 counter;
84
85 counter = ioread32(priv->iobase + HW_WDTV);
86
87 return DIV_ROUND_CLOSEST(counter, priv->wdt_freq);
88}
89
90static int asm9260_wdt_updatetimeout(struct watchdog_device *wdd)
91{
92 struct asm9260_wdt_priv *priv = watchdog_get_drvdata(wdd);
93 u32 counter;
94
95 counter = wdd->timeout * priv->wdt_freq;
96
97 iowrite32(counter, priv->iobase + HW_WDTC);
98
99 return 0;
100}
101
102static int asm9260_wdt_enable(struct watchdog_device *wdd)
103{
104 struct asm9260_wdt_priv *priv = watchdog_get_drvdata(wdd);
105 u32 mode = 0;
106
107 if (priv->mode == HW_RESET)
108 mode = BM_MOD_WDRESET;
109
110 iowrite32(BM_MOD_WDEN | mode, priv->iobase + HW_WDMOD);
111
112 asm9260_wdt_updatetimeout(wdd);
113
114 asm9260_wdt_feed(wdd);
115
116 return 0;
117}
118
119static int asm9260_wdt_disable(struct watchdog_device *wdd)
120{
121 struct asm9260_wdt_priv *priv = watchdog_get_drvdata(wdd);
122
123 /* The only way to disable WD is to reset it. */
124 reset_control_assert(priv->rst);
125 reset_control_deassert(priv->rst);
126
127 return 0;
128}
129
130static int asm9260_wdt_settimeout(struct watchdog_device *wdd, unsigned int to)
131{
132 wdd->timeout = to;
133 asm9260_wdt_updatetimeout(wdd);
134
135 return 0;
136}
137
138static void asm9260_wdt_sys_reset(struct asm9260_wdt_priv *priv)
139{
140 /* init WD if it was not started */
141
142 iowrite32(BM_MOD_WDEN | BM_MOD_WDRESET, priv->iobase + HW_WDMOD);
143
144 iowrite32(0xff, priv->iobase + HW_WDTC);
145 /* first pass correct sequence */
146 asm9260_wdt_feed(&priv->wdd);
147 /*
148 * Then write wrong pattern to the feed to trigger reset
149 * ASAP.
150 */
151 iowrite32(0xff, priv->iobase + HW_WDFEED);
152
153 mdelay(1000);
154}
155
156static irqreturn_t asm9260_wdt_irq(int irq, void *devid)
157{
158 struct asm9260_wdt_priv *priv = devid;
159 u32 stat;
160
161 stat = ioread32(priv->iobase + HW_WDMOD);
162 if (!(stat & BM_MOD_WDINT))
163 return IRQ_NONE;
164
165 if (priv->mode == DEBUG) {
166 dev_info(priv->dev, "Watchdog Timeout. Do nothing.\n");
167 } else {
168 dev_info(priv->dev, "Watchdog Timeout. Doing SW Reset.\n");
169 asm9260_wdt_sys_reset(priv);
170 }
171
172 return IRQ_HANDLED;
173}
174
175static int asm9260_restart_handler(struct notifier_block *this,
176 unsigned long mode, void *cmd)
177{
178 struct asm9260_wdt_priv *priv =
179 container_of(this, struct asm9260_wdt_priv, restart_handler);
180
181 asm9260_wdt_sys_reset(priv);
182
183 return NOTIFY_DONE;
184}
185
186static const struct watchdog_info asm9260_wdt_ident = {
187 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING
188 | WDIOF_MAGICCLOSE,
189 .identity = "Alphascale asm9260 Watchdog",
190};
191
192static struct watchdog_ops asm9260_wdt_ops = {
193 .owner = THIS_MODULE,
194 .start = asm9260_wdt_enable,
195 .stop = asm9260_wdt_disable,
196 .get_timeleft = asm9260_wdt_gettimeleft,
197 .ping = asm9260_wdt_feed,
198 .set_timeout = asm9260_wdt_settimeout,
199};
200
201static int asm9260_wdt_get_dt_clks(struct asm9260_wdt_priv *priv)
202{
203 int err;
204 unsigned long clk;
205
206 priv->clk = devm_clk_get(priv->dev, "mod");
207 if (IS_ERR(priv->clk)) {
208 dev_err(priv->dev, "Failed to get \"mod\" clk\n");
209 return PTR_ERR(priv->clk);
210 }
211
212 /* configure AHB clock */
213 priv->clk_ahb = devm_clk_get(priv->dev, "ahb");
214 if (IS_ERR(priv->clk_ahb)) {
215 dev_err(priv->dev, "Failed to get \"ahb\" clk\n");
216 return PTR_ERR(priv->clk_ahb);
217 }
218
219 err = clk_prepare_enable(priv->clk_ahb);
220 if (err) {
221 dev_err(priv->dev, "Failed to enable ahb_clk!\n");
222 return err;
223 }
224
225 err = clk_set_rate(priv->clk, CLOCK_FREQ);
226 if (err) {
227 clk_disable_unprepare(priv->clk_ahb);
228 dev_err(priv->dev, "Failed to set rate!\n");
229 return err;
230 }
231
232 err = clk_prepare_enable(priv->clk);
233 if (err) {
234 clk_disable_unprepare(priv->clk_ahb);
235 dev_err(priv->dev, "Failed to enable clk!\n");
236 return err;
237 }
238
239 /* wdt has internal divider */
240 clk = clk_get_rate(priv->clk);
241 if (!clk) {
242 clk_disable_unprepare(priv->clk);
243 clk_disable_unprepare(priv->clk_ahb);
244 dev_err(priv->dev, "Failed, clk is 0!\n");
245 return -EINVAL;
246 }
247
248 priv->wdt_freq = clk / 2;
249
250 return 0;
251}
252
253static void asm9260_wdt_get_dt_mode(struct asm9260_wdt_priv *priv)
254{
255 const char *tmp;
256 int ret;
257
258 /* default mode */
259 priv->mode = HW_RESET;
260
261 ret = of_property_read_string(priv->dev->of_node,
262 "alphascale,mode", &tmp);
263 if (ret < 0)
264 return;
265
266 if (!strcmp(tmp, "hw"))
267 priv->mode = HW_RESET;
268 else if (!strcmp(tmp, "sw"))
269 priv->mode = SW_RESET;
270 else if (!strcmp(tmp, "debug"))
271 priv->mode = DEBUG;
272 else
273 dev_warn(priv->dev, "unknown reset-type: %s. Using default \"hw\" mode.",
274 tmp);
275}
276
277static int asm9260_wdt_probe(struct platform_device *pdev)
278{
279 struct asm9260_wdt_priv *priv;
280 struct watchdog_device *wdd;
281 struct resource *res;
282 int ret;
283 const char * const mode_name[] = { "hw", "sw", "debug", };
284
285 priv = devm_kzalloc(&pdev->dev, sizeof(struct asm9260_wdt_priv),
286 GFP_KERNEL);
287 if (!priv)
288 return -ENOMEM;
289
290 priv->dev = &pdev->dev;
291
292 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
293 priv->iobase = devm_ioremap_resource(&pdev->dev, res);
294 if (IS_ERR(priv->iobase))
295 return PTR_ERR(priv->iobase);
296
297 ret = asm9260_wdt_get_dt_clks(priv);
298 if (ret)
299 return ret;
300
301 priv->rst = devm_reset_control_get(&pdev->dev, "wdt_rst");
302 if (IS_ERR(priv->rst))
303 return PTR_ERR(priv->rst);
304
305 wdd = &priv->wdd;
306 wdd->info = &asm9260_wdt_ident;
307 wdd->ops = &asm9260_wdt_ops;
308 wdd->min_timeout = 1;
309 wdd->max_timeout = BM_WDTC_MAX(priv->wdt_freq);
310 wdd->parent = &pdev->dev;
311
312 watchdog_set_drvdata(wdd, priv);
313
314 /*
315 * If 'timeout-sec' unspecified in devicetree, assume a 30 second
316 * default, unless the max timeout is less than 30 seconds, then use
317 * the max instead.
318 */
319 wdd->timeout = ASM9260_WDT_DEFAULT_TIMEOUT;
320 watchdog_init_timeout(wdd, 0, &pdev->dev);
321
322 asm9260_wdt_get_dt_mode(priv);
323
324 if (priv->mode != HW_RESET)
325 priv->irq = platform_get_irq(pdev, 0);
326
327 if (priv->irq > 0) {
328 /*
329 * Not all supported platforms specify an interrupt for the
330 * watchdog, so let's make it optional.
331 */
332 ret = devm_request_irq(&pdev->dev, priv->irq,
333 asm9260_wdt_irq, 0, pdev->name, priv);
334 if (ret < 0)
335 dev_warn(&pdev->dev, "failed to request IRQ\n");
336 }
337
338 ret = watchdog_register_device(wdd);
339 if (ret)
340 goto clk_off;
341
342 platform_set_drvdata(pdev, priv);
343
344 priv->restart_handler.notifier_call = asm9260_restart_handler;
345 priv->restart_handler.priority = 128;
346 ret = register_restart_handler(&priv->restart_handler);
347 if (ret)
348 dev_warn(&pdev->dev, "cannot register restart handler\n");
349
350 dev_info(&pdev->dev, "Watchdog enabled (timeout: %d sec, mode: %s)\n",
351 wdd->timeout, mode_name[priv->mode]);
352 return 0;
353
354clk_off:
355 clk_disable_unprepare(priv->clk);
356 clk_disable_unprepare(priv->clk_ahb);
357 return ret;
358}
359
360static void asm9260_wdt_shutdown(struct platform_device *pdev)
361{
362 struct asm9260_wdt_priv *priv = platform_get_drvdata(pdev);
363
364 asm9260_wdt_disable(&priv->wdd);
365}
366
367static int asm9260_wdt_remove(struct platform_device *pdev)
368{
369 struct asm9260_wdt_priv *priv = platform_get_drvdata(pdev);
370
371 asm9260_wdt_disable(&priv->wdd);
372
373 unregister_restart_handler(&priv->restart_handler);
374
375 watchdog_unregister_device(&priv->wdd);
376
377 clk_disable_unprepare(priv->clk);
378 clk_disable_unprepare(priv->clk_ahb);
379
380 return 0;
381}
382
383static const struct of_device_id asm9260_wdt_of_match[] = {
384 { .compatible = "alphascale,asm9260-wdt"},
385 {},
386};
387MODULE_DEVICE_TABLE(of, asm9260_wdt_of_match);
388
389static struct platform_driver asm9260_wdt_driver = {
390 .driver = {
391 .name = "asm9260-wdt",
392 .owner = THIS_MODULE,
393 .of_match_table = asm9260_wdt_of_match,
394 },
395 .probe = asm9260_wdt_probe,
396 .remove = asm9260_wdt_remove,
397 .shutdown = asm9260_wdt_shutdown,
398};
399module_platform_driver(asm9260_wdt_driver);
400
401MODULE_DESCRIPTION("asm9260 WatchDog Timer Driver");
402MODULE_AUTHOR("Oleksij Rempel <linux@rempel-privat.de>");
403MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/atlas7_wdt.c b/drivers/watchdog/atlas7_wdt.c
new file mode 100644
index 000000000000..df6d9242a319
--- /dev/null
+++ b/drivers/watchdog/atlas7_wdt.c
@@ -0,0 +1,242 @@
1/*
2 * Watchdog driver for CSR Atlas7
3 *
4 * Copyright (c) 2015 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2.
7 */
8
9#include <linux/clk.h>
10#include <linux/io.h>
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/of.h>
14#include <linux/platform_device.h>
15#include <linux/watchdog.h>
16
17#define ATLAS7_TIMER_WDT_INDEX 5
18#define ATLAS7_WDT_DEFAULT_TIMEOUT 20
19
20#define ATLAS7_WDT_CNT_CTRL (0 + 4 * ATLAS7_TIMER_WDT_INDEX)
21#define ATLAS7_WDT_CNT_MATCH (0x18 + 4 * ATLAS7_TIMER_WDT_INDEX)
22#define ATLAS7_WDT_CNT (0x48 + 4 * ATLAS7_TIMER_WDT_INDEX)
23#define ATLAS7_WDT_CNT_EN (BIT(0) | BIT(1))
24#define ATLAS7_WDT_EN 0x64
25
26static unsigned int timeout = ATLAS7_WDT_DEFAULT_TIMEOUT;
27static bool nowayout = WATCHDOG_NOWAYOUT;
28
29module_param(timeout, uint, 0);
30module_param(nowayout, bool, 0);
31
32MODULE_PARM_DESC(timeout, "Default watchdog timeout (in seconds)");
33MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
34 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
35
36struct atlas7_wdog {
37 struct device *dev;
38 void __iomem *base;
39 unsigned long tick_rate;
40 struct clk *clk;
41};
42
43static unsigned int atlas7_wdt_gettimeleft(struct watchdog_device *wdd)
44{
45 struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd);
46 u32 counter, match, delta;
47
48 counter = readl(wdt->base + ATLAS7_WDT_CNT);
49 match = readl(wdt->base + ATLAS7_WDT_CNT_MATCH);
50 delta = match - counter;
51
52 return delta / wdt->tick_rate;
53}
54
55static int atlas7_wdt_ping(struct watchdog_device *wdd)
56{
57 struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd);
58 u32 counter, match, delta;
59
60 counter = readl(wdt->base + ATLAS7_WDT_CNT);
61 delta = wdd->timeout * wdt->tick_rate;
62 match = counter + delta;
63
64 writel(match, wdt->base + ATLAS7_WDT_CNT_MATCH);
65
66 return 0;
67}
68
69static int atlas7_wdt_enable(struct watchdog_device *wdd)
70{
71 struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd);
72
73 atlas7_wdt_ping(wdd);
74
75 writel(readl(wdt->base + ATLAS7_WDT_CNT_CTRL) | ATLAS7_WDT_CNT_EN,
76 wdt->base + ATLAS7_WDT_CNT_CTRL);
77 writel(1, wdt->base + ATLAS7_WDT_EN);
78
79 return 0;
80}
81
82static int atlas7_wdt_disable(struct watchdog_device *wdd)
83{
84 struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd);
85
86 writel(0, wdt->base + ATLAS7_WDT_EN);
87 writel(readl(wdt->base + ATLAS7_WDT_CNT_CTRL) & ~ATLAS7_WDT_CNT_EN,
88 wdt->base + ATLAS7_WDT_CNT_CTRL);
89
90 return 0;
91}
92
93static int atlas7_wdt_settimeout(struct watchdog_device *wdd, unsigned int to)
94{
95 wdd->timeout = to;
96
97 return 0;
98}
99
100#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
101
102static const struct watchdog_info atlas7_wdt_ident = {
103 .options = OPTIONS,
104 .firmware_version = 0,
105 .identity = "atlas7 Watchdog",
106};
107
108static struct watchdog_ops atlas7_wdt_ops = {
109 .owner = THIS_MODULE,
110 .start = atlas7_wdt_enable,
111 .stop = atlas7_wdt_disable,
112 .get_timeleft = atlas7_wdt_gettimeleft,
113 .ping = atlas7_wdt_ping,
114 .set_timeout = atlas7_wdt_settimeout,
115};
116
117static struct watchdog_device atlas7_wdd = {
118 .info = &atlas7_wdt_ident,
119 .ops = &atlas7_wdt_ops,
120 .timeout = ATLAS7_WDT_DEFAULT_TIMEOUT,
121};
122
123static const struct of_device_id atlas7_wdt_ids[] = {
124 { .compatible = "sirf,atlas7-tick"},
125 {}
126};
127
128static int atlas7_wdt_probe(struct platform_device *pdev)
129{
130 struct device_node *np = pdev->dev.of_node;
131 struct atlas7_wdog *wdt;
132 struct resource *res;
133 struct clk *clk;
134 int ret;
135
136 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
137 if (!wdt)
138 return -ENOMEM;
139 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
140 wdt->base = devm_ioremap_resource(&pdev->dev, res);
141 if (IS_ERR(wdt->base))
142 return PTR_ERR(wdt->base);
143
144 clk = of_clk_get(np, 0);
145 if (IS_ERR(clk))
146 return PTR_ERR(clk);
147 ret = clk_prepare_enable(clk);
148 if (ret) {
149 dev_err(&pdev->dev, "clk enable failed\n");
150 goto err;
151 }
152
153 /* disable watchdog hardware */
154 writel(0, wdt->base + ATLAS7_WDT_CNT_CTRL);
155
156 wdt->tick_rate = clk_get_rate(clk);
157 wdt->clk = clk;
158 atlas7_wdd.min_timeout = 1;
159 atlas7_wdd.max_timeout = UINT_MAX / wdt->tick_rate;
160
161 watchdog_init_timeout(&atlas7_wdd, 0, &pdev->dev);
162 watchdog_set_nowayout(&atlas7_wdd, nowayout);
163
164 watchdog_set_drvdata(&atlas7_wdd, wdt);
165 platform_set_drvdata(pdev, &atlas7_wdd);
166
167 ret = watchdog_register_device(&atlas7_wdd);
168 if (ret)
169 goto err1;
170
171 return 0;
172
173err1:
174 clk_disable_unprepare(clk);
175err:
176 clk_put(clk);
177 return ret;
178}
179
180static void atlas7_wdt_shutdown(struct platform_device *pdev)
181{
182 struct watchdog_device *wdd = platform_get_drvdata(pdev);
183 struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd);
184
185 atlas7_wdt_disable(wdd);
186 clk_disable_unprepare(wdt->clk);
187}
188
189static int atlas7_wdt_remove(struct platform_device *pdev)
190{
191 struct watchdog_device *wdd = platform_get_drvdata(pdev);
192 struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd);
193
194 atlas7_wdt_shutdown(pdev);
195 clk_put(wdt->clk);
196 return 0;
197}
198
199static int __maybe_unused atlas7_wdt_suspend(struct device *dev)
200{
201 /*
202 * NOTE:timer controller registers settings are saved
203 * and restored back by the timer-atlas7.c
204 */
205 return 0;
206}
207
208static int __maybe_unused atlas7_wdt_resume(struct device *dev)
209{
210 struct watchdog_device *wdd = dev_get_drvdata(dev);
211
212 /*
213 * NOTE: Since timer controller registers settings are saved
214 * and restored back by the timer-atlas7.c, so we need not
215 * update WD settings except refreshing timeout.
216 */
217 atlas7_wdt_ping(wdd);
218
219 return 0;
220}
221
222static SIMPLE_DEV_PM_OPS(atlas7_wdt_pm_ops,
223 atlas7_wdt_suspend, atlas7_wdt_resume);
224
225MODULE_DEVICE_TABLE(of, atlas7_wdt_ids);
226
227static struct platform_driver atlas7_wdt_driver = {
228 .driver = {
229 .name = "atlas7-wdt",
230 .pm = &atlas7_wdt_pm_ops,
231 .of_match_table = atlas7_wdt_ids,
232 },
233 .probe = atlas7_wdt_probe,
234 .remove = atlas7_wdt_remove,
235 .shutdown = atlas7_wdt_shutdown,
236};
237module_platform_driver(atlas7_wdt_driver);
238
239MODULE_DESCRIPTION("CSRatlas7 watchdog driver");
240MODULE_AUTHOR("Guo Zeng <Guo.Zeng@csr.com>");
241MODULE_LICENSE("GPL v2");
242MODULE_ALIAS("platform:atlas7-wdt");
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
index 8a5ce5b5a0b6..2e6164c4abc0 100644
--- a/drivers/watchdog/bcm2835_wdt.c
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -79,7 +79,6 @@ static int bcm2835_wdt_stop(struct watchdog_device *wdog)
79 struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog); 79 struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
80 80
81 writel_relaxed(PM_PASSWORD | PM_RSTC_RESET, wdt->base + PM_RSTC); 81 writel_relaxed(PM_PASSWORD | PM_RSTC_RESET, wdt->base + PM_RSTC);
82 dev_info(wdog->dev, "Watchdog timer stopped");
83 return 0; 82 return 0;
84} 83}
85 84
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index 4064a43f1360..df1c2a4b0165 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -20,7 +20,6 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/moduleparam.h> 21#include <linux/moduleparam.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/reboot.h>
24#include <linux/types.h> 23#include <linux/types.h>
25#include <linux/watchdog.h> 24#include <linux/watchdog.h>
26#include <linux/timer.h> 25#include <linux/timer.h>
@@ -88,12 +87,22 @@ static int bcm47xx_wdt_hard_set_timeout(struct watchdog_device *wdd,
88 return 0; 87 return 0;
89} 88}
90 89
90static int bcm47xx_wdt_restart(struct watchdog_device *wdd)
91{
92 struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
93
94 wdt->timer_set(wdt, 1);
95
96 return 0;
97}
98
91static struct watchdog_ops bcm47xx_wdt_hard_ops = { 99static struct watchdog_ops bcm47xx_wdt_hard_ops = {
92 .owner = THIS_MODULE, 100 .owner = THIS_MODULE,
93 .start = bcm47xx_wdt_hard_start, 101 .start = bcm47xx_wdt_hard_start,
94 .stop = bcm47xx_wdt_hard_stop, 102 .stop = bcm47xx_wdt_hard_stop,
95 .ping = bcm47xx_wdt_hard_keepalive, 103 .ping = bcm47xx_wdt_hard_keepalive,
96 .set_timeout = bcm47xx_wdt_hard_set_timeout, 104 .set_timeout = bcm47xx_wdt_hard_set_timeout,
105 .restart = bcm47xx_wdt_restart,
97}; 106};
98 107
99static void bcm47xx_wdt_soft_timer_tick(unsigned long data) 108static void bcm47xx_wdt_soft_timer_tick(unsigned long data)
@@ -158,34 +167,13 @@ static const struct watchdog_info bcm47xx_wdt_info = {
158 WDIOF_MAGICCLOSE, 167 WDIOF_MAGICCLOSE,
159}; 168};
160 169
161static int bcm47xx_wdt_notify_sys(struct notifier_block *this,
162 unsigned long code, void *unused)
163{
164 struct bcm47xx_wdt *wdt;
165
166 wdt = container_of(this, struct bcm47xx_wdt, notifier);
167 if (code == SYS_DOWN || code == SYS_HALT)
168 wdt->wdd.ops->stop(&wdt->wdd);
169 return NOTIFY_DONE;
170}
171
172static int bcm47xx_wdt_restart(struct notifier_block *this, unsigned long mode,
173 void *cmd)
174{
175 struct bcm47xx_wdt *wdt;
176
177 wdt = container_of(this, struct bcm47xx_wdt, restart_handler);
178 wdt->timer_set(wdt, 1);
179
180 return NOTIFY_DONE;
181}
182
183static struct watchdog_ops bcm47xx_wdt_soft_ops = { 170static struct watchdog_ops bcm47xx_wdt_soft_ops = {
184 .owner = THIS_MODULE, 171 .owner = THIS_MODULE,
185 .start = bcm47xx_wdt_soft_start, 172 .start = bcm47xx_wdt_soft_start,
186 .stop = bcm47xx_wdt_soft_stop, 173 .stop = bcm47xx_wdt_soft_stop,
187 .ping = bcm47xx_wdt_soft_keepalive, 174 .ping = bcm47xx_wdt_soft_keepalive,
188 .set_timeout = bcm47xx_wdt_soft_set_timeout, 175 .set_timeout = bcm47xx_wdt_soft_set_timeout,
176 .restart = bcm47xx_wdt_restart,
189}; 177};
190 178
191static int bcm47xx_wdt_probe(struct platform_device *pdev) 179static int bcm47xx_wdt_probe(struct platform_device *pdev)
@@ -214,32 +202,18 @@ static int bcm47xx_wdt_probe(struct platform_device *pdev)
214 if (ret) 202 if (ret)
215 goto err_timer; 203 goto err_timer;
216 watchdog_set_nowayout(&wdt->wdd, nowayout); 204 watchdog_set_nowayout(&wdt->wdd, nowayout);
217 205 watchdog_set_restart_priority(&wdt->wdd, 64);
218 wdt->notifier.notifier_call = &bcm47xx_wdt_notify_sys; 206 watchdog_stop_on_reboot(&wdt->wdd);
219
220 ret = register_reboot_notifier(&wdt->notifier);
221 if (ret)
222 goto err_timer;
223
224 wdt->restart_handler.notifier_call = &bcm47xx_wdt_restart;
225 wdt->restart_handler.priority = 64;
226 ret = register_restart_handler(&wdt->restart_handler);
227 if (ret)
228 goto err_notifier;
229 207
230 ret = watchdog_register_device(&wdt->wdd); 208 ret = watchdog_register_device(&wdt->wdd);
231 if (ret) 209 if (ret)
232 goto err_handler; 210 goto err_timer;
233 211
234 dev_info(&pdev->dev, "BCM47xx Watchdog Timer enabled (%d seconds%s%s)\n", 212 dev_info(&pdev->dev, "BCM47xx Watchdog Timer enabled (%d seconds%s%s)\n",
235 timeout, nowayout ? ", nowayout" : "", 213 timeout, nowayout ? ", nowayout" : "",
236 soft ? ", Software Timer" : ""); 214 soft ? ", Software Timer" : "");
237 return 0; 215 return 0;
238 216
239err_handler:
240 unregister_restart_handler(&wdt->restart_handler);
241err_notifier:
242 unregister_reboot_notifier(&wdt->notifier);
243err_timer: 217err_timer:
244 if (soft) 218 if (soft)
245 del_timer_sync(&wdt->soft_timer); 219 del_timer_sync(&wdt->soft_timer);
@@ -255,7 +229,6 @@ static int bcm47xx_wdt_remove(struct platform_device *pdev)
255 return -ENXIO; 229 return -ENXIO;
256 230
257 watchdog_unregister_device(&wdt->wdd); 231 watchdog_unregister_device(&wdt->wdd);
258 unregister_reboot_notifier(&wdt->notifier);
259 232
260 return 0; 233 return 0;
261} 234}
diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c
index bcfd2a22208f..4dda9024e229 100644
--- a/drivers/watchdog/cadence_wdt.c
+++ b/drivers/watchdog/cadence_wdt.c
@@ -18,7 +18,6 @@
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/reboot.h>
22#include <linux/watchdog.h> 21#include <linux/watchdog.h>
23 22
24#define CDNS_WDT_DEFAULT_TIMEOUT 10 23#define CDNS_WDT_DEFAULT_TIMEOUT 10
@@ -72,7 +71,6 @@ MODULE_PARM_DESC(nowayout,
72 * @ctrl_clksel: counter clock prescaler selection 71 * @ctrl_clksel: counter clock prescaler selection
73 * @io_lock: spinlock for IO register access 72 * @io_lock: spinlock for IO register access
74 * @cdns_wdt_device: watchdog device structure 73 * @cdns_wdt_device: watchdog device structure
75 * @cdns_wdt_notifier: notifier structure
76 * 74 *
77 * Structure containing parameters specific to cadence watchdog. 75 * Structure containing parameters specific to cadence watchdog.
78 */ 76 */
@@ -84,7 +82,6 @@ struct cdns_wdt {
84 u32 ctrl_clksel; 82 u32 ctrl_clksel;
85 spinlock_t io_lock; 83 spinlock_t io_lock;
86 struct watchdog_device cdns_wdt_device; 84 struct watchdog_device cdns_wdt_device;
87 struct notifier_block cdns_wdt_notifier;
88}; 85};
89 86
90/* Write access to Registers */ 87/* Write access to Registers */
@@ -280,29 +277,6 @@ static struct watchdog_ops cdns_wdt_ops = {
280 .set_timeout = cdns_wdt_settimeout, 277 .set_timeout = cdns_wdt_settimeout,
281}; 278};
282 279
283/**
284 * cdns_wdt_notify_sys - Notifier for reboot or shutdown.
285 *
286 * @this: handle to notifier block
287 * @code: turn off indicator
288 * @unused: unused
289 * Return: NOTIFY_DONE
290 *
291 * This notifier is invoked whenever the system reboot or shutdown occur
292 * because we need to disable the WDT before system goes down as WDT might
293 * reset on the next boot.
294 */
295static int cdns_wdt_notify_sys(struct notifier_block *this, unsigned long code,
296 void *unused)
297{
298 struct cdns_wdt *wdt = container_of(this, struct cdns_wdt,
299 cdns_wdt_notifier);
300 if (code == SYS_DOWN || code == SYS_HALT)
301 cdns_wdt_stop(&wdt->cdns_wdt_device);
302
303 return NOTIFY_DONE;
304}
305
306/************************Platform Operations*****************************/ 280/************************Platform Operations*****************************/
307/** 281/**
308 * cdns_wdt_probe - Probe call for the device. 282 * cdns_wdt_probe - Probe call for the device.
@@ -360,6 +334,7 @@ static int cdns_wdt_probe(struct platform_device *pdev)
360 } 334 }
361 335
362 watchdog_set_nowayout(cdns_wdt_device, nowayout); 336 watchdog_set_nowayout(cdns_wdt_device, nowayout);
337 watchdog_stop_on_reboot(cdns_wdt_device);
363 watchdog_set_drvdata(cdns_wdt_device, wdt); 338 watchdog_set_drvdata(cdns_wdt_device, wdt);
364 339
365 wdt->clk = devm_clk_get(&pdev->dev, NULL); 340 wdt->clk = devm_clk_get(&pdev->dev, NULL);
@@ -386,14 +361,6 @@ static int cdns_wdt_probe(struct platform_device *pdev)
386 361
387 spin_lock_init(&wdt->io_lock); 362 spin_lock_init(&wdt->io_lock);
388 363
389 wdt->cdns_wdt_notifier.notifier_call = &cdns_wdt_notify_sys;
390 ret = register_reboot_notifier(&wdt->cdns_wdt_notifier);
391 if (ret != 0) {
392 dev_err(&pdev->dev, "cannot register reboot notifier err=%d)\n",
393 ret);
394 goto err_clk_disable;
395 }
396
397 ret = watchdog_register_device(cdns_wdt_device); 364 ret = watchdog_register_device(cdns_wdt_device);
398 if (ret) { 365 if (ret) {
399 dev_err(&pdev->dev, "Failed to register wdt device\n"); 366 dev_err(&pdev->dev, "Failed to register wdt device\n");
@@ -427,7 +394,6 @@ static int cdns_wdt_remove(struct platform_device *pdev)
427 394
428 cdns_wdt_stop(&wdt->cdns_wdt_device); 395 cdns_wdt_stop(&wdt->cdns_wdt_device);
429 watchdog_unregister_device(&wdt->cdns_wdt_device); 396 watchdog_unregister_device(&wdt->cdns_wdt_device);
430 unregister_reboot_notifier(&wdt->cdns_wdt_notifier);
431 clk_disable_unprepare(wdt->clk); 397 clk_disable_unprepare(wdt->clk);
432 398
433 return 0; 399 return 0;
@@ -455,8 +421,7 @@ static void cdns_wdt_shutdown(struct platform_device *pdev)
455 */ 421 */
456static int __maybe_unused cdns_wdt_suspend(struct device *dev) 422static int __maybe_unused cdns_wdt_suspend(struct device *dev)
457{ 423{
458 struct platform_device *pdev = container_of(dev, 424 struct platform_device *pdev = to_platform_device(dev);
459 struct platform_device, dev);
460 struct cdns_wdt *wdt = platform_get_drvdata(pdev); 425 struct cdns_wdt *wdt = platform_get_drvdata(pdev);
461 426
462 cdns_wdt_stop(&wdt->cdns_wdt_device); 427 cdns_wdt_stop(&wdt->cdns_wdt_device);
@@ -474,8 +439,7 @@ static int __maybe_unused cdns_wdt_suspend(struct device *dev)
474static int __maybe_unused cdns_wdt_resume(struct device *dev) 439static int __maybe_unused cdns_wdt_resume(struct device *dev)
475{ 440{
476 int ret; 441 int ret;
477 struct platform_device *pdev = container_of(dev, 442 struct platform_device *pdev = to_platform_device(dev);
478 struct platform_device, dev);
479 struct cdns_wdt *wdt = platform_get_drvdata(pdev); 443 struct cdns_wdt *wdt = platform_get_drvdata(pdev);
480 444
481 ret = clk_prepare_enable(wdt->clk); 445 ret = clk_prepare_enable(wdt->clk);
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c
index 67e67977bd29..2fc19a32a320 100644
--- a/drivers/watchdog/da9052_wdt.c
+++ b/drivers/watchdog/da9052_wdt.c
@@ -31,7 +31,6 @@
31struct da9052_wdt_data { 31struct da9052_wdt_data {
32 struct watchdog_device wdt; 32 struct watchdog_device wdt;
33 struct da9052 *da9052; 33 struct da9052 *da9052;
34 struct kref kref;
35 unsigned long jpast; 34 unsigned long jpast;
36}; 35};
37 36
@@ -51,10 +50,6 @@ static const struct {
51}; 50};
52 51
53 52
54static void da9052_wdt_release_resources(struct kref *r)
55{
56}
57
58static int da9052_wdt_set_timeout(struct watchdog_device *wdt_dev, 53static int da9052_wdt_set_timeout(struct watchdog_device *wdt_dev,
59 unsigned int timeout) 54 unsigned int timeout)
60{ 55{
@@ -104,20 +99,6 @@ static int da9052_wdt_set_timeout(struct watchdog_device *wdt_dev,
104 return 0; 99 return 0;
105} 100}
106 101
107static void da9052_wdt_ref(struct watchdog_device *wdt_dev)
108{
109 struct da9052_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);
110
111 kref_get(&driver_data->kref);
112}
113
114static void da9052_wdt_unref(struct watchdog_device *wdt_dev)
115{
116 struct da9052_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);
117
118 kref_put(&driver_data->kref, da9052_wdt_release_resources);
119}
120
121static int da9052_wdt_start(struct watchdog_device *wdt_dev) 102static int da9052_wdt_start(struct watchdog_device *wdt_dev)
122{ 103{
123 return da9052_wdt_set_timeout(wdt_dev, wdt_dev->timeout); 104 return da9052_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
@@ -170,8 +151,6 @@ static const struct watchdog_ops da9052_wdt_ops = {
170 .stop = da9052_wdt_stop, 151 .stop = da9052_wdt_stop,
171 .ping = da9052_wdt_ping, 152 .ping = da9052_wdt_ping,
172 .set_timeout = da9052_wdt_set_timeout, 153 .set_timeout = da9052_wdt_set_timeout,
173 .ref = da9052_wdt_ref,
174 .unref = da9052_wdt_unref,
175}; 154};
176 155
177 156
@@ -198,8 +177,6 @@ static int da9052_wdt_probe(struct platform_device *pdev)
198 da9052_wdt->parent = &pdev->dev; 177 da9052_wdt->parent = &pdev->dev;
199 watchdog_set_drvdata(da9052_wdt, driver_data); 178 watchdog_set_drvdata(da9052_wdt, driver_data);
200 179
201 kref_init(&driver_data->kref);
202
203 ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, 180 ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG,
204 DA9052_CONTROLD_TWDSCALE, 0); 181 DA9052_CONTROLD_TWDSCALE, 0);
205 if (ret < 0) { 182 if (ret < 0) {
@@ -225,7 +202,6 @@ static int da9052_wdt_remove(struct platform_device *pdev)
225 struct da9052_wdt_data *driver_data = platform_get_drvdata(pdev); 202 struct da9052_wdt_data *driver_data = platform_get_drvdata(pdev);
226 203
227 watchdog_unregister_device(&driver_data->wdt); 204 watchdog_unregister_device(&driver_data->wdt);
228 kref_put(&driver_data->kref, da9052_wdt_release_resources);
229 205
230 return 0; 206 return 0;
231} 207}
diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c
index 04d1430d93d2..8377c43f3f20 100644
--- a/drivers/watchdog/da9055_wdt.c
+++ b/drivers/watchdog/da9055_wdt.c
@@ -35,7 +35,6 @@ MODULE_PARM_DESC(nowayout,
35struct da9055_wdt_data { 35struct da9055_wdt_data {
36 struct watchdog_device wdt; 36 struct watchdog_device wdt;
37 struct da9055 *da9055; 37 struct da9055 *da9055;
38 struct kref kref;
39}; 38};
40 39
41static const struct { 40static const struct {
@@ -99,24 +98,6 @@ static int da9055_wdt_ping(struct watchdog_device *wdt_dev)
99 DA9055_WATCHDOG_MASK, 1); 98 DA9055_WATCHDOG_MASK, 1);
100} 99}
101 100
102static void da9055_wdt_release_resources(struct kref *r)
103{
104}
105
106static void da9055_wdt_ref(struct watchdog_device *wdt_dev)
107{
108 struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);
109
110 kref_get(&driver_data->kref);
111}
112
113static void da9055_wdt_unref(struct watchdog_device *wdt_dev)
114{
115 struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);
116
117 kref_put(&driver_data->kref, da9055_wdt_release_resources);
118}
119
120static int da9055_wdt_start(struct watchdog_device *wdt_dev) 101static int da9055_wdt_start(struct watchdog_device *wdt_dev)
121{ 102{
122 return da9055_wdt_set_timeout(wdt_dev, wdt_dev->timeout); 103 return da9055_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
@@ -138,8 +119,6 @@ static const struct watchdog_ops da9055_wdt_ops = {
138 .stop = da9055_wdt_stop, 119 .stop = da9055_wdt_stop,
139 .ping = da9055_wdt_ping, 120 .ping = da9055_wdt_ping,
140 .set_timeout = da9055_wdt_set_timeout, 121 .set_timeout = da9055_wdt_set_timeout,
141 .ref = da9055_wdt_ref,
142 .unref = da9055_wdt_unref,
143}; 122};
144 123
145static int da9055_wdt_probe(struct platform_device *pdev) 124static int da9055_wdt_probe(struct platform_device *pdev)
@@ -165,8 +144,6 @@ static int da9055_wdt_probe(struct platform_device *pdev)
165 watchdog_set_nowayout(da9055_wdt, nowayout); 144 watchdog_set_nowayout(da9055_wdt, nowayout);
166 watchdog_set_drvdata(da9055_wdt, driver_data); 145 watchdog_set_drvdata(da9055_wdt, driver_data);
167 146
168 kref_init(&driver_data->kref);
169
170 ret = da9055_wdt_stop(da9055_wdt); 147 ret = da9055_wdt_stop(da9055_wdt);
171 if (ret < 0) { 148 if (ret < 0) {
172 dev_err(&pdev->dev, "Failed to stop watchdog, %d\n", ret); 149 dev_err(&pdev->dev, "Failed to stop watchdog, %d\n", ret);
@@ -189,7 +166,6 @@ static int da9055_wdt_remove(struct platform_device *pdev)
189 struct da9055_wdt_data *driver_data = platform_get_drvdata(pdev); 166 struct da9055_wdt_data *driver_data = platform_get_drvdata(pdev);
190 167
191 watchdog_unregister_device(&driver_data->wdt); 168 watchdog_unregister_device(&driver_data->wdt);
192 kref_put(&driver_data->kref, da9055_wdt_release_resources);
193 169
194 return 0; 170 return 0;
195} 171}
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c
index 6bf130bd863d..11e887572649 100644
--- a/drivers/watchdog/da9063_wdt.c
+++ b/drivers/watchdog/da9063_wdt.c
@@ -20,7 +20,6 @@
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/mfd/da9063/registers.h> 21#include <linux/mfd/da9063/registers.h>
22#include <linux/mfd/da9063/core.h> 22#include <linux/mfd/da9063/core.h>
23#include <linux/reboot.h>
24#include <linux/regmap.h> 23#include <linux/regmap.h>
25 24
26/* 25/*
@@ -39,7 +38,6 @@ static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 };
39struct da9063_watchdog { 38struct da9063_watchdog {
40 struct da9063 *da9063; 39 struct da9063 *da9063;
41 struct watchdog_device wdtdev; 40 struct watchdog_device wdtdev;
42 struct notifier_block restart_handler;
43}; 41};
44 42
45static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs) 43static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs)
@@ -121,12 +119,9 @@ static int da9063_wdt_set_timeout(struct watchdog_device *wdd,
121 return ret; 119 return ret;
122} 120}
123 121
124static int da9063_wdt_restart_handler(struct notifier_block *this, 122static int da9063_wdt_restart(struct watchdog_device *wdd)
125 unsigned long mode, void *cmd)
126{ 123{
127 struct da9063_watchdog *wdt = container_of(this, 124 struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd);
128 struct da9063_watchdog,
129 restart_handler);
130 int ret; 125 int ret;
131 126
132 ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F, 127 ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F,
@@ -135,7 +130,7 @@ static int da9063_wdt_restart_handler(struct notifier_block *this,
135 dev_alert(wdt->da9063->dev, "Failed to shutdown (err = %d)\n", 130 dev_alert(wdt->da9063->dev, "Failed to shutdown (err = %d)\n",
136 ret); 131 ret);
137 132
138 return NOTIFY_DONE; 133 return ret;
139} 134}
140 135
141static const struct watchdog_info da9063_watchdog_info = { 136static const struct watchdog_info da9063_watchdog_info = {
@@ -149,6 +144,7 @@ static const struct watchdog_ops da9063_watchdog_ops = {
149 .stop = da9063_wdt_stop, 144 .stop = da9063_wdt_stop,
150 .ping = da9063_wdt_ping, 145 .ping = da9063_wdt_ping,
151 .set_timeout = da9063_wdt_set_timeout, 146 .set_timeout = da9063_wdt_set_timeout,
147 .restart = da9063_wdt_restart,
152}; 148};
153 149
154static int da9063_wdt_probe(struct platform_device *pdev) 150static int da9063_wdt_probe(struct platform_device *pdev)
@@ -179,6 +175,8 @@ static int da9063_wdt_probe(struct platform_device *pdev)
179 175
180 wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS; 176 wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
181 177
178 watchdog_set_restart_priority(&wdt->wdtdev, 128);
179
182 watchdog_set_drvdata(&wdt->wdtdev, wdt); 180 watchdog_set_drvdata(&wdt->wdtdev, wdt);
183 dev_set_drvdata(&pdev->dev, wdt); 181 dev_set_drvdata(&pdev->dev, wdt);
184 182
@@ -186,13 +184,6 @@ static int da9063_wdt_probe(struct platform_device *pdev)
186 if (ret) 184 if (ret)
187 return ret; 185 return ret;
188 186
189 wdt->restart_handler.notifier_call = da9063_wdt_restart_handler;
190 wdt->restart_handler.priority = 128;
191 ret = register_restart_handler(&wdt->restart_handler);
192 if (ret)
193 dev_err(wdt->da9063->dev,
194 "Failed to register restart handler (err = %d)\n", ret);
195
196 return 0; 187 return 0;
197} 188}
198 189
@@ -200,8 +191,6 @@ static int da9063_wdt_remove(struct platform_device *pdev)
200{ 191{
201 struct da9063_watchdog *wdt = dev_get_drvdata(&pdev->dev); 192 struct da9063_watchdog *wdt = dev_get_drvdata(&pdev->dev);
202 193
203 unregister_restart_handler(&wdt->restart_handler);
204
205 watchdog_unregister_device(&wdt->wdtdev); 194 watchdog_unregister_device(&wdt->wdtdev);
206 195
207 return 0; 196 return 0;
diff --git a/drivers/watchdog/diag288_wdt.c b/drivers/watchdog/diag288_wdt.c
index 3db9d0e0673d..861d3d3133f8 100644
--- a/drivers/watchdog/diag288_wdt.c
+++ b/drivers/watchdog/diag288_wdt.c
@@ -106,6 +106,10 @@ static int __diag288_lpar(unsigned int func, unsigned int timeout,
106 return __diag288(func, timeout, action, 0); 106 return __diag288(func, timeout, action, 0);
107} 107}
108 108
109static unsigned long wdt_status;
110
111#define DIAG_WDOG_BUSY 0
112
109static int wdt_start(struct watchdog_device *dev) 113static int wdt_start(struct watchdog_device *dev)
110{ 114{
111 char *ebc_cmd; 115 char *ebc_cmd;
@@ -113,12 +117,17 @@ static int wdt_start(struct watchdog_device *dev)
113 int ret; 117 int ret;
114 unsigned int func; 118 unsigned int func;
115 119
120 if (test_and_set_bit(DIAG_WDOG_BUSY, &wdt_status))
121 return -EBUSY;
122
116 ret = -ENODEV; 123 ret = -ENODEV;
117 124
118 if (MACHINE_IS_VM) { 125 if (MACHINE_IS_VM) {
119 ebc_cmd = kmalloc(MAX_CMDLEN, GFP_KERNEL); 126 ebc_cmd = kmalloc(MAX_CMDLEN, GFP_KERNEL);
120 if (!ebc_cmd) 127 if (!ebc_cmd) {
128 clear_bit(DIAG_WDOG_BUSY, &wdt_status);
121 return -ENOMEM; 129 return -ENOMEM;
130 }
122 len = strlcpy(ebc_cmd, wdt_cmd, MAX_CMDLEN); 131 len = strlcpy(ebc_cmd, wdt_cmd, MAX_CMDLEN);
123 ASCEBC(ebc_cmd, MAX_CMDLEN); 132 ASCEBC(ebc_cmd, MAX_CMDLEN);
124 EBC_TOUPPER(ebc_cmd, MAX_CMDLEN); 133 EBC_TOUPPER(ebc_cmd, MAX_CMDLEN);
@@ -135,6 +144,7 @@ static int wdt_start(struct watchdog_device *dev)
135 144
136 if (ret) { 145 if (ret) {
137 pr_err("The watchdog cannot be activated\n"); 146 pr_err("The watchdog cannot be activated\n");
147 clear_bit(DIAG_WDOG_BUSY, &wdt_status);
138 return ret; 148 return ret;
139 } 149 }
140 return 0; 150 return 0;
@@ -146,6 +156,9 @@ static int wdt_stop(struct watchdog_device *dev)
146 156
147 diag_stat_inc(DIAG_STAT_X288); 157 diag_stat_inc(DIAG_STAT_X288);
148 ret = __diag288(WDT_FUNC_CANCEL, 0, 0, 0); 158 ret = __diag288(WDT_FUNC_CANCEL, 0, 0, 0);
159
160 clear_bit(DIAG_WDOG_BUSY, &wdt_status);
161
149 return ret; 162 return ret;
150} 163}
151 164
@@ -220,17 +233,10 @@ static struct watchdog_device wdt_dev = {
220 * It makes no sense to go into suspend while the watchdog is running. 233 * It makes no sense to go into suspend while the watchdog is running.
221 * Depending on the memory size, the watchdog might trigger, while we 234 * Depending on the memory size, the watchdog might trigger, while we
222 * are still saving the memory. 235 * are still saving the memory.
223 * We reuse the open flag to ensure that suspend and watchdog open are
224 * exclusive operations
225 */ 236 */
226static int wdt_suspend(void) 237static int wdt_suspend(void)
227{ 238{
228 if (test_and_set_bit(WDOG_DEV_OPEN, &wdt_dev.status)) { 239 if (test_and_set_bit(DIAG_WDOG_BUSY, &wdt_status)) {
229 pr_err("Linux cannot be suspended while the watchdog is in use\n");
230 return notifier_from_errno(-EBUSY);
231 }
232 if (test_bit(WDOG_ACTIVE, &wdt_dev.status)) {
233 clear_bit(WDOG_DEV_OPEN, &wdt_dev.status);
234 pr_err("Linux cannot be suspended while the watchdog is in use\n"); 240 pr_err("Linux cannot be suspended while the watchdog is in use\n");
235 return notifier_from_errno(-EBUSY); 241 return notifier_from_errno(-EBUSY);
236 } 242 }
@@ -239,7 +245,7 @@ static int wdt_suspend(void)
239 245
240static int wdt_resume(void) 246static int wdt_resume(void)
241{ 247{
242 clear_bit(WDOG_DEV_OPEN, &wdt_dev.status); 248 clear_bit(DIAG_WDOG_BUSY, &wdt_status);
243 return NOTIFY_DONE; 249 return NOTIFY_DONE;
244} 250}
245 251
diff --git a/drivers/watchdog/digicolor_wdt.c b/drivers/watchdog/digicolor_wdt.c
index 50abe1bf62a5..1ccb0b239348 100644
--- a/drivers/watchdog/digicolor_wdt.c
+++ b/drivers/watchdog/digicolor_wdt.c
@@ -15,7 +15,6 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/watchdog.h> 17#include <linux/watchdog.h>
18#include <linux/reboot.h>
19#include <linux/platform_device.h> 18#include <linux/platform_device.h>
20#include <linux/of_address.h> 19#include <linux/of_address.h>
21 20
@@ -28,7 +27,6 @@
28struct dc_wdt { 27struct dc_wdt {
29 void __iomem *base; 28 void __iomem *base;
30 struct clk *clk; 29 struct clk *clk;
31 struct notifier_block restart_handler;
32 spinlock_t lock; 30 spinlock_t lock;
33}; 31};
34 32
@@ -50,16 +48,15 @@ static void dc_wdt_set(struct dc_wdt *wdt, u32 ticks)
50 spin_unlock_irqrestore(&wdt->lock, flags); 48 spin_unlock_irqrestore(&wdt->lock, flags);
51} 49}
52 50
53static int dc_restart_handler(struct notifier_block *this, unsigned long mode, 51static int dc_wdt_restart(struct watchdog_device *wdog)
54 void *cmd)
55{ 52{
56 struct dc_wdt *wdt = container_of(this, struct dc_wdt, restart_handler); 53 struct dc_wdt *wdt = watchdog_get_drvdata(wdog);
57 54
58 dc_wdt_set(wdt, 1); 55 dc_wdt_set(wdt, 1);
59 /* wait for reset to assert... */ 56 /* wait for reset to assert... */
60 mdelay(500); 57 mdelay(500);
61 58
62 return NOTIFY_DONE; 59 return 0;
63} 60}
64 61
65static int dc_wdt_start(struct watchdog_device *wdog) 62static int dc_wdt_start(struct watchdog_device *wdog)
@@ -104,6 +101,7 @@ static struct watchdog_ops dc_wdt_ops = {
104 .stop = dc_wdt_stop, 101 .stop = dc_wdt_stop,
105 .set_timeout = dc_wdt_set_timeout, 102 .set_timeout = dc_wdt_set_timeout,
106 .get_timeleft = dc_wdt_get_timeleft, 103 .get_timeleft = dc_wdt_get_timeleft,
104 .restart = dc_wdt_restart,
107}; 105};
108 106
109static struct watchdog_info dc_wdt_info = { 107static struct watchdog_info dc_wdt_info = {
@@ -148,6 +146,7 @@ static int dc_wdt_probe(struct platform_device *pdev)
148 spin_lock_init(&wdt->lock); 146 spin_lock_init(&wdt->lock);
149 147
150 watchdog_set_drvdata(&dc_wdt_wdd, wdt); 148 watchdog_set_drvdata(&dc_wdt_wdd, wdt);
149 watchdog_set_restart_priority(&dc_wdt_wdd, 128);
151 watchdog_init_timeout(&dc_wdt_wdd, timeout, dev); 150 watchdog_init_timeout(&dc_wdt_wdd, timeout, dev);
152 ret = watchdog_register_device(&dc_wdt_wdd); 151 ret = watchdog_register_device(&dc_wdt_wdd);
153 if (ret) { 152 if (ret) {
@@ -155,12 +154,6 @@ static int dc_wdt_probe(struct platform_device *pdev)
155 goto err_iounmap; 154 goto err_iounmap;
156 } 155 }
157 156
158 wdt->restart_handler.notifier_call = dc_restart_handler;
159 wdt->restart_handler.priority = 128;
160 ret = register_restart_handler(&wdt->restart_handler);
161 if (ret)
162 dev_warn(&pdev->dev, "cannot register restart handler\n");
163
164 return 0; 157 return 0;
165 158
166err_iounmap: 159err_iounmap:
@@ -172,7 +165,6 @@ static int dc_wdt_remove(struct platform_device *pdev)
172{ 165{
173 struct dc_wdt *wdt = platform_get_drvdata(pdev); 166 struct dc_wdt *wdt = platform_get_drvdata(pdev);
174 167
175 unregister_restart_handler(&wdt->restart_handler);
176 watchdog_unregister_device(&dc_wdt_wdd); 168 watchdog_unregister_device(&dc_wdt_wdd);
177 iounmap(wdt->base); 169 iounmap(wdt->base);
178 170
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index 6ea0634345e9..8fefa4ad46d4 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -81,7 +81,7 @@ static inline int dw_wdt_top_in_seconds(unsigned top)
81 * There are 16 possible timeout values in 0..15 where the number of 81 * There are 16 possible timeout values in 0..15 where the number of
82 * cycles is 2 ^ (16 + i) and the watchdog counts down. 82 * cycles is 2 ^ (16 + i) and the watchdog counts down.
83 */ 83 */
84 return (1 << (16 + top)) / clk_get_rate(dw_wdt.clk); 84 return (1U << (16 + top)) / clk_get_rate(dw_wdt.clk);
85} 85}
86 86
87static int dw_wdt_get_top(void) 87static int dw_wdt_get_top(void)
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
index 90d59d3f38a3..ba066e4a707b 100644
--- a/drivers/watchdog/gpio_wdt.c
+++ b/drivers/watchdog/gpio_wdt.c
@@ -12,10 +12,8 @@
12#include <linux/err.h> 12#include <linux/err.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/notifier.h>
16#include <linux/of_gpio.h> 15#include <linux/of_gpio.h>
17#include <linux/platform_device.h> 16#include <linux/platform_device.h>
18#include <linux/reboot.h>
19#include <linux/watchdog.h> 17#include <linux/watchdog.h>
20 18
21#define SOFT_TIMEOUT_MIN 1 19#define SOFT_TIMEOUT_MIN 1
@@ -36,7 +34,6 @@ struct gpio_wdt_priv {
36 unsigned int hw_algo; 34 unsigned int hw_algo;
37 unsigned int hw_margin; 35 unsigned int hw_margin;
38 unsigned long last_jiffies; 36 unsigned long last_jiffies;
39 struct notifier_block notifier;
40 struct timer_list timer; 37 struct timer_list timer;
41 struct watchdog_device wdd; 38 struct watchdog_device wdd;
42}; 39};
@@ -57,7 +54,8 @@ static void gpio_wdt_hwping(unsigned long data)
57 54
58 if (priv->armed && time_after(jiffies, priv->last_jiffies + 55 if (priv->armed && time_after(jiffies, priv->last_jiffies +
59 msecs_to_jiffies(wdd->timeout * 1000))) { 56 msecs_to_jiffies(wdd->timeout * 1000))) {
60 dev_crit(wdd->dev, "Timer expired. System will reboot soon!\n"); 57 dev_crit(wdd->parent,
58 "Timer expired. System will reboot soon!\n");
61 return; 59 return;
62 } 60 }
63 61
@@ -126,26 +124,6 @@ static int gpio_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
126 return gpio_wdt_ping(wdd); 124 return gpio_wdt_ping(wdd);
127} 125}
128 126
129static int gpio_wdt_notify_sys(struct notifier_block *nb, unsigned long code,
130 void *unused)
131{
132 struct gpio_wdt_priv *priv = container_of(nb, struct gpio_wdt_priv,
133 notifier);
134
135 mod_timer(&priv->timer, 0);
136
137 switch (code) {
138 case SYS_HALT:
139 case SYS_POWER_OFF:
140 gpio_wdt_disable(priv);
141 break;
142 default:
143 break;
144 }
145
146 return NOTIFY_DONE;
147}
148
149static const struct watchdog_info gpio_wdt_ident = { 127static const struct watchdog_info gpio_wdt_ident = {
150 .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | 128 .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING |
151 WDIOF_SETTIMEOUT, 129 WDIOF_SETTIMEOUT,
@@ -224,23 +202,16 @@ static int gpio_wdt_probe(struct platform_device *pdev)
224 202
225 setup_timer(&priv->timer, gpio_wdt_hwping, (unsigned long)&priv->wdd); 203 setup_timer(&priv->timer, gpio_wdt_hwping, (unsigned long)&priv->wdd);
226 204
205 watchdog_stop_on_reboot(&priv->wdd);
206
227 ret = watchdog_register_device(&priv->wdd); 207 ret = watchdog_register_device(&priv->wdd);
228 if (ret) 208 if (ret)
229 return ret; 209 return ret;
230 210
231 priv->notifier.notifier_call = gpio_wdt_notify_sys;
232 ret = register_reboot_notifier(&priv->notifier);
233 if (ret)
234 goto error_unregister;
235
236 if (priv->always_running) 211 if (priv->always_running)
237 gpio_wdt_start_impl(priv); 212 gpio_wdt_start_impl(priv);
238 213
239 return 0; 214 return 0;
240
241error_unregister:
242 watchdog_unregister_device(&priv->wdd);
243 return ret;
244} 215}
245 216
246static int gpio_wdt_remove(struct platform_device *pdev) 217static int gpio_wdt_remove(struct platform_device *pdev)
@@ -248,7 +219,6 @@ static int gpio_wdt_remove(struct platform_device *pdev)
248 struct gpio_wdt_priv *priv = platform_get_drvdata(pdev); 219 struct gpio_wdt_priv *priv = platform_get_drvdata(pdev);
249 220
250 del_timer_sync(&priv->timer); 221 del_timer_sync(&priv->timer);
251 unregister_reboot_notifier(&priv->notifier);
252 watchdog_unregister_device(&priv->wdd); 222 watchdog_unregister_device(&priv->wdd);
253 223
254 return 0; 224 return 0;
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 286369d4f0f5..92443c319e59 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * HP WatchDog Driver 2 * HPE WatchDog Driver
3 * based on 3 * based on
4 * 4 *
5 * SoftDog 0.05: A Software Watchdog Device 5 * SoftDog 0.05: A Software Watchdog Device
6 * 6 *
7 * (c) Copyright 2007 Hewlett-Packard Development Company, L.P. 7 * (c) Copyright 2015 Hewlett Packard Enterprise Development LP
8 * Thomas Mingarelli <thomas.mingarelli@hp.com> 8 * Thomas Mingarelli <thomas.mingarelli@hpe.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
@@ -580,7 +580,7 @@ static const struct watchdog_info ident = {
580 .options = WDIOF_SETTIMEOUT | 580 .options = WDIOF_SETTIMEOUT |
581 WDIOF_KEEPALIVEPING | 581 WDIOF_KEEPALIVEPING |
582 WDIOF_MAGICCLOSE, 582 WDIOF_MAGICCLOSE,
583 .identity = "HP iLO2+ HW Watchdog Timer", 583 .identity = "HPE iLO2+ HW Watchdog Timer",
584}; 584};
585 585
586static long hpwdt_ioctl(struct file *file, unsigned int cmd, 586static long hpwdt_ioctl(struct file *file, unsigned int cmd,
@@ -758,7 +758,7 @@ static int hpwdt_init_nmi_decoding(struct pci_dev *dev)
758 goto error2; 758 goto error2;
759 759
760 dev_info(&dev->dev, 760 dev_info(&dev->dev,
761 "HP Watchdog Timer Driver: NMI decoding initialized" 761 "HPE Watchdog Timer Driver: NMI decoding initialized"
762 ", allow kernel dump: %s (default = 1/ON)\n", 762 ", allow kernel dump: %s (default = 1/ON)\n",
763 (allow_kdump == 0) ? "OFF" : "ON"); 763 (allow_kdump == 0) ? "OFF" : "ON");
764 return 0; 764 return 0;
@@ -863,7 +863,7 @@ static int hpwdt_init_one(struct pci_dev *dev,
863 goto error_misc_register; 863 goto error_misc_register;
864 } 864 }
865 865
866 dev_info(&dev->dev, "HP Watchdog Timer Driver: %s" 866 dev_info(&dev->dev, "HPE Watchdog Timer Driver: %s"
867 ", timer margin: %d seconds (nowayout=%d).\n", 867 ", timer margin: %d seconds (nowayout=%d).\n",
868 HPWDT_VERSION, soft_margin, nowayout); 868 HPWDT_VERSION, soft_margin, nowayout);
869 return 0; 869 return 0;
diff --git a/drivers/watchdog/imgpdc_wdt.c b/drivers/watchdog/imgpdc_wdt.c
index 15ab07230960..3679f2e1922f 100644
--- a/drivers/watchdog/imgpdc_wdt.c
+++ b/drivers/watchdog/imgpdc_wdt.c
@@ -45,7 +45,6 @@
45#include <linux/log2.h> 45#include <linux/log2.h>
46#include <linux/module.h> 46#include <linux/module.h>
47#include <linux/platform_device.h> 47#include <linux/platform_device.h>
48#include <linux/reboot.h>
49#include <linux/slab.h> 48#include <linux/slab.h>
50#include <linux/watchdog.h> 49#include <linux/watchdog.h>
51 50
@@ -87,7 +86,6 @@ struct pdc_wdt_dev {
87 struct clk *wdt_clk; 86 struct clk *wdt_clk;
88 struct clk *sys_clk; 87 struct clk *sys_clk;
89 void __iomem *base; 88 void __iomem *base;
90 struct notifier_block restart_handler;
91}; 89};
92 90
93static int pdc_wdt_keepalive(struct watchdog_device *wdt_dev) 91static int pdc_wdt_keepalive(struct watchdog_device *wdt_dev)
@@ -152,6 +150,16 @@ static int pdc_wdt_start(struct watchdog_device *wdt_dev)
152 return 0; 150 return 0;
153} 151}
154 152
153static int pdc_wdt_restart(struct watchdog_device *wdt_dev)
154{
155 struct pdc_wdt_dev *wdt = watchdog_get_drvdata(wdt_dev);
156
157 /* Assert SOFT_RESET */
158 writel(0x1, wdt->base + PDC_WDT_SOFT_RESET);
159
160 return 0;
161}
162
155static struct watchdog_info pdc_wdt_info = { 163static struct watchdog_info pdc_wdt_info = {
156 .identity = "IMG PDC Watchdog", 164 .identity = "IMG PDC Watchdog",
157 .options = WDIOF_SETTIMEOUT | 165 .options = WDIOF_SETTIMEOUT |
@@ -165,20 +173,9 @@ static const struct watchdog_ops pdc_wdt_ops = {
165 .stop = pdc_wdt_stop, 173 .stop = pdc_wdt_stop,
166 .ping = pdc_wdt_keepalive, 174 .ping = pdc_wdt_keepalive,
167 .set_timeout = pdc_wdt_set_timeout, 175 .set_timeout = pdc_wdt_set_timeout,
176 .restart = pdc_wdt_restart,
168}; 177};
169 178
170static int pdc_wdt_restart(struct notifier_block *this, unsigned long mode,
171 void *cmd)
172{
173 struct pdc_wdt_dev *wdt = container_of(this, struct pdc_wdt_dev,
174 restart_handler);
175
176 /* Assert SOFT_RESET */
177 writel(0x1, wdt->base + PDC_WDT_SOFT_RESET);
178
179 return NOTIFY_OK;
180}
181
182static int pdc_wdt_probe(struct platform_device *pdev) 179static int pdc_wdt_probe(struct platform_device *pdev)
183{ 180{
184 u64 div; 181 u64 div;
@@ -282,6 +279,7 @@ static int pdc_wdt_probe(struct platform_device *pdev)
282 } 279 }
283 280
284 watchdog_set_nowayout(&pdc_wdt->wdt_dev, nowayout); 281 watchdog_set_nowayout(&pdc_wdt->wdt_dev, nowayout);
282 watchdog_set_restart_priority(&pdc_wdt->wdt_dev, 128);
285 283
286 platform_set_drvdata(pdev, pdc_wdt); 284 platform_set_drvdata(pdev, pdc_wdt);
287 285
@@ -289,13 +287,6 @@ static int pdc_wdt_probe(struct platform_device *pdev)
289 if (ret) 287 if (ret)
290 goto disable_wdt_clk; 288 goto disable_wdt_clk;
291 289
292 pdc_wdt->restart_handler.notifier_call = pdc_wdt_restart;
293 pdc_wdt->restart_handler.priority = 128;
294 ret = register_restart_handler(&pdc_wdt->restart_handler);
295 if (ret)
296 dev_warn(&pdev->dev, "failed to register restart handler: %d\n",
297 ret);
298
299 return 0; 290 return 0;
300 291
301disable_wdt_clk: 292disable_wdt_clk:
@@ -316,7 +307,6 @@ static int pdc_wdt_remove(struct platform_device *pdev)
316{ 307{
317 struct pdc_wdt_dev *pdc_wdt = platform_get_drvdata(pdev); 308 struct pdc_wdt_dev *pdc_wdt = platform_get_drvdata(pdev);
318 309
319 unregister_restart_handler(&pdc_wdt->restart_handler);
320 pdc_wdt_stop(&pdc_wdt->wdt_dev); 310 pdc_wdt_stop(&pdc_wdt->wdt_dev);
321 watchdog_unregister_device(&pdc_wdt->wdt_dev); 311 watchdog_unregister_device(&pdc_wdt->wdt_dev);
322 clk_disable_unprepare(pdc_wdt->wdt_clk); 312 clk_disable_unprepare(pdc_wdt->wdt_clk);
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 29ef719a6a3c..e47966aa2db0 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -29,10 +29,8 @@
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
32#include <linux/notifier.h>
33#include <linux/of_address.h> 32#include <linux/of_address.h>
34#include <linux/platform_device.h> 33#include <linux/platform_device.h>
35#include <linux/reboot.h>
36#include <linux/regmap.h> 34#include <linux/regmap.h>
37#include <linux/timer.h> 35#include <linux/timer.h>
38#include <linux/watchdog.h> 36#include <linux/watchdog.h>
@@ -64,7 +62,6 @@ struct imx2_wdt_device {
64 struct regmap *regmap; 62 struct regmap *regmap;
65 struct timer_list timer; /* Pings the watchdog when closed */ 63 struct timer_list timer; /* Pings the watchdog when closed */
66 struct watchdog_device wdog; 64 struct watchdog_device wdog;
67 struct notifier_block restart_handler;
68}; 65};
69 66
70static bool nowayout = WATCHDOG_NOWAYOUT; 67static bool nowayout = WATCHDOG_NOWAYOUT;
@@ -83,13 +80,11 @@ static const struct watchdog_info imx2_wdt_info = {
83 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 80 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
84}; 81};
85 82
86static int imx2_restart_handler(struct notifier_block *this, unsigned long mode, 83static int imx2_wdt_restart(struct watchdog_device *wdog)
87 void *cmd)
88{ 84{
85 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
89 unsigned int wcr_enable = IMX2_WDT_WCR_WDE; 86 unsigned int wcr_enable = IMX2_WDT_WCR_WDE;
90 struct imx2_wdt_device *wdev = container_of(this, 87
91 struct imx2_wdt_device,
92 restart_handler);
93 /* Assert SRS signal */ 88 /* Assert SRS signal */
94 regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable); 89 regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable);
95 /* 90 /*
@@ -105,7 +100,7 @@ static int imx2_restart_handler(struct notifier_block *this, unsigned long mode,
105 /* wait for reset to assert... */ 100 /* wait for reset to assert... */
106 mdelay(500); 101 mdelay(500);
107 102
108 return NOTIFY_DONE; 103 return 0;
109} 104}
110 105
111static inline void imx2_wdt_setup(struct watchdog_device *wdog) 106static inline void imx2_wdt_setup(struct watchdog_device *wdog)
@@ -213,6 +208,7 @@ static const struct watchdog_ops imx2_wdt_ops = {
213 .stop = imx2_wdt_stop, 208 .stop = imx2_wdt_stop,
214 .ping = imx2_wdt_ping, 209 .ping = imx2_wdt_ping,
215 .set_timeout = imx2_wdt_set_timeout, 210 .set_timeout = imx2_wdt_set_timeout,
211 .restart = imx2_wdt_restart,
216}; 212};
217 213
218static const struct regmap_config imx2_wdt_regmap_config = { 214static const struct regmap_config imx2_wdt_regmap_config = {
@@ -275,6 +271,7 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
275 platform_set_drvdata(pdev, wdog); 271 platform_set_drvdata(pdev, wdog);
276 watchdog_set_drvdata(wdog, wdev); 272 watchdog_set_drvdata(wdog, wdev);
277 watchdog_set_nowayout(wdog, nowayout); 273 watchdog_set_nowayout(wdog, nowayout);
274 watchdog_set_restart_priority(wdog, 128);
278 watchdog_init_timeout(wdog, timeout, &pdev->dev); 275 watchdog_init_timeout(wdog, timeout, &pdev->dev);
279 276
280 setup_timer(&wdev->timer, imx2_wdt_timer_ping, (unsigned long)wdog); 277 setup_timer(&wdev->timer, imx2_wdt_timer_ping, (unsigned long)wdog);
@@ -294,12 +291,6 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
294 goto disable_clk; 291 goto disable_clk;
295 } 292 }
296 293
297 wdev->restart_handler.notifier_call = imx2_restart_handler;
298 wdev->restart_handler.priority = 128;
299 ret = register_restart_handler(&wdev->restart_handler);
300 if (ret)
301 dev_err(&pdev->dev, "cannot register restart handler\n");
302
303 dev_info(&pdev->dev, "timeout %d sec (nowayout=%d)\n", 294 dev_info(&pdev->dev, "timeout %d sec (nowayout=%d)\n",
304 wdog->timeout, nowayout); 295 wdog->timeout, nowayout);
305 296
@@ -315,8 +306,6 @@ static int __exit imx2_wdt_remove(struct platform_device *pdev)
315 struct watchdog_device *wdog = platform_get_drvdata(pdev); 306 struct watchdog_device *wdog = platform_get_drvdata(pdev);
316 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); 307 struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
317 308
318 unregister_restart_handler(&wdev->restart_handler);
319
320 watchdog_unregister_device(wdog); 309 watchdog_unregister_device(wdog);
321 310
322 if (imx2_wdt_is_running(wdev)) { 311 if (imx2_wdt_is_running(wdev)) {
diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c
index ab7b8b185d99..6914c83aa6d9 100644
--- a/drivers/watchdog/lpc18xx_wdt.c
+++ b/drivers/watchdog/lpc18xx_wdt.c
@@ -18,7 +18,6 @@
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/reboot.h>
22#include <linux/watchdog.h> 21#include <linux/watchdog.h>
23 22
24/* Registers */ 23/* Registers */
@@ -59,7 +58,6 @@ struct lpc18xx_wdt_dev {
59 unsigned long clk_rate; 58 unsigned long clk_rate;
60 void __iomem *base; 59 void __iomem *base;
61 struct timer_list timer; 60 struct timer_list timer;
62 struct notifier_block restart_handler;
63 spinlock_t lock; 61 spinlock_t lock;
64}; 62};
65 63
@@ -155,27 +153,9 @@ static int lpc18xx_wdt_start(struct watchdog_device *wdt_dev)
155 return 0; 153 return 0;
156} 154}
157 155
158static struct watchdog_info lpc18xx_wdt_info = { 156static int lpc18xx_wdt_restart(struct watchdog_device *wdt_dev)
159 .identity = "NXP LPC18xx Watchdog",
160 .options = WDIOF_SETTIMEOUT |
161 WDIOF_KEEPALIVEPING |
162 WDIOF_MAGICCLOSE,
163};
164
165static const struct watchdog_ops lpc18xx_wdt_ops = {
166 .owner = THIS_MODULE,
167 .start = lpc18xx_wdt_start,
168 .stop = lpc18xx_wdt_stop,
169 .ping = lpc18xx_wdt_feed,
170 .set_timeout = lpc18xx_wdt_set_timeout,
171 .get_timeleft = lpc18xx_wdt_get_timeleft,
172};
173
174static int lpc18xx_wdt_restart(struct notifier_block *this, unsigned long mode,
175 void *cmd)
176{ 157{
177 struct lpc18xx_wdt_dev *lpc18xx_wdt = container_of(this, 158 struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
178 struct lpc18xx_wdt_dev, restart_handler);
179 unsigned long flags; 159 unsigned long flags;
180 int val; 160 int val;
181 161
@@ -197,9 +177,26 @@ static int lpc18xx_wdt_restart(struct notifier_block *this, unsigned long mode,
197 177
198 spin_unlock_irqrestore(&lpc18xx_wdt->lock, flags); 178 spin_unlock_irqrestore(&lpc18xx_wdt->lock, flags);
199 179
200 return NOTIFY_OK; 180 return 0;
201} 181}
202 182
183static struct watchdog_info lpc18xx_wdt_info = {
184 .identity = "NXP LPC18xx Watchdog",
185 .options = WDIOF_SETTIMEOUT |
186 WDIOF_KEEPALIVEPING |
187 WDIOF_MAGICCLOSE,
188};
189
190static const struct watchdog_ops lpc18xx_wdt_ops = {
191 .owner = THIS_MODULE,
192 .start = lpc18xx_wdt_start,
193 .stop = lpc18xx_wdt_stop,
194 .ping = lpc18xx_wdt_feed,
195 .set_timeout = lpc18xx_wdt_set_timeout,
196 .get_timeleft = lpc18xx_wdt_get_timeleft,
197 .restart = lpc18xx_wdt_restart,
198};
199
203static int lpc18xx_wdt_probe(struct platform_device *pdev) 200static int lpc18xx_wdt_probe(struct platform_device *pdev)
204{ 201{
205 struct lpc18xx_wdt_dev *lpc18xx_wdt; 202 struct lpc18xx_wdt_dev *lpc18xx_wdt;
@@ -273,6 +270,7 @@ static int lpc18xx_wdt_probe(struct platform_device *pdev)
273 (unsigned long)&lpc18xx_wdt->wdt_dev); 270 (unsigned long)&lpc18xx_wdt->wdt_dev);
274 271
275 watchdog_set_nowayout(&lpc18xx_wdt->wdt_dev, nowayout); 272 watchdog_set_nowayout(&lpc18xx_wdt->wdt_dev, nowayout);
273 watchdog_set_restart_priority(&lpc18xx_wdt->wdt_dev, 128);
276 274
277 platform_set_drvdata(pdev, lpc18xx_wdt); 275 platform_set_drvdata(pdev, lpc18xx_wdt);
278 276
@@ -280,12 +278,6 @@ static int lpc18xx_wdt_probe(struct platform_device *pdev)
280 if (ret) 278 if (ret)
281 goto disable_wdt_clk; 279 goto disable_wdt_clk;
282 280
283 lpc18xx_wdt->restart_handler.notifier_call = lpc18xx_wdt_restart;
284 lpc18xx_wdt->restart_handler.priority = 128;
285 ret = register_restart_handler(&lpc18xx_wdt->restart_handler);
286 if (ret)
287 dev_warn(dev, "failed to register restart handler: %d\n", ret);
288
289 return 0; 281 return 0;
290 282
291disable_wdt_clk: 283disable_wdt_clk:
@@ -306,8 +298,6 @@ static int lpc18xx_wdt_remove(struct platform_device *pdev)
306{ 298{
307 struct lpc18xx_wdt_dev *lpc18xx_wdt = platform_get_drvdata(pdev); 299 struct lpc18xx_wdt_dev *lpc18xx_wdt = platform_get_drvdata(pdev);
308 300
309 unregister_restart_handler(&lpc18xx_wdt->restart_handler);
310
311 dev_warn(&pdev->dev, "I quit now, hardware will probably reboot!\n"); 301 dev_warn(&pdev->dev, "I quit now, hardware will probably reboot!\n");
312 del_timer(&lpc18xx_wdt->timer); 302 del_timer(&lpc18xx_wdt->timer);
313 303
diff --git a/drivers/watchdog/mena21_wdt.c b/drivers/watchdog/mena21_wdt.c
index 098fa9c34d6d..af6a7c489f08 100644
--- a/drivers/watchdog/mena21_wdt.c
+++ b/drivers/watchdog/mena21_wdt.c
@@ -100,12 +100,12 @@ static int a21_wdt_set_timeout(struct watchdog_device *wdt,
100 struct a21_wdt_drv *drv = watchdog_get_drvdata(wdt); 100 struct a21_wdt_drv *drv = watchdog_get_drvdata(wdt);
101 101
102 if (timeout != 1 && timeout != 30) { 102 if (timeout != 1 && timeout != 30) {
103 dev_err(wdt->dev, "Only 1 and 30 allowed as timeout\n"); 103 dev_err(wdt->parent, "Only 1 and 30 allowed as timeout\n");
104 return -EINVAL; 104 return -EINVAL;
105 } 105 }
106 106
107 if (timeout == 30 && wdt->timeout == 1) { 107 if (timeout == 30 && wdt->timeout == 1) {
108 dev_err(wdt->dev, 108 dev_err(wdt->parent,
109 "Transition from fast to slow mode not allowed\n"); 109 "Transition from fast to slow mode not allowed\n");
110 return -EINVAL; 110 return -EINVAL;
111 } 111 }
diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c
index 1f4155ee3404..aea5d2f44ad7 100644
--- a/drivers/watchdog/meson_wdt.c
+++ b/drivers/watchdog/meson_wdt.c
@@ -17,51 +17,64 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
20#include <linux/notifier.h>
21#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_device.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/reboot.h>
24#include <linux/types.h> 23#include <linux/types.h>
25#include <linux/watchdog.h> 24#include <linux/watchdog.h>
26 25
27#define DRV_NAME "meson_wdt" 26#define DRV_NAME "meson_wdt"
28 27
29#define MESON_WDT_TC 0x00 28#define MESON_WDT_TC 0x00
30#define MESON_WDT_TC_EN BIT(22)
31#define MESON_WDT_TC_TM_MASK 0x3fffff
32#define MESON_WDT_DC_RESET (3 << 24) 29#define MESON_WDT_DC_RESET (3 << 24)
33 30
34#define MESON_WDT_RESET 0x04 31#define MESON_WDT_RESET 0x04
35 32
36#define MESON_WDT_TIMEOUT 30 33#define MESON_WDT_TIMEOUT 30
37#define MESON_WDT_MIN_TIMEOUT 1 34#define MESON_WDT_MIN_TIMEOUT 1
38#define MESON_WDT_MAX_TIMEOUT (MESON_WDT_TC_TM_MASK / 100000)
39 35
40#define MESON_SEC_TO_TC(s) ((s) * 100000) 36#define MESON_SEC_TO_TC(s, c) ((s) * (c))
41 37
42static bool nowayout = WATCHDOG_NOWAYOUT; 38static bool nowayout = WATCHDOG_NOWAYOUT;
43static unsigned int timeout = MESON_WDT_TIMEOUT; 39static unsigned int timeout = MESON_WDT_TIMEOUT;
44 40
41struct meson_wdt_data {
42 unsigned int enable;
43 unsigned int terminal_count_mask;
44 unsigned int count_unit;
45};
46
47static struct meson_wdt_data meson6_wdt_data = {
48 .enable = BIT(22),
49 .terminal_count_mask = 0x3fffff,
50 .count_unit = 100000, /* 10 us */
51};
52
53static struct meson_wdt_data meson8b_wdt_data = {
54 .enable = BIT(19),
55 .terminal_count_mask = 0xffff,
56 .count_unit = 7812, /* 128 us */
57};
58
45struct meson_wdt_dev { 59struct meson_wdt_dev {
46 struct watchdog_device wdt_dev; 60 struct watchdog_device wdt_dev;
47 void __iomem *wdt_base; 61 void __iomem *wdt_base;
48 struct notifier_block restart_handler; 62 const struct meson_wdt_data *data;
49}; 63};
50 64
51static int meson_restart_handle(struct notifier_block *this, unsigned long mode, 65static int meson_wdt_restart(struct watchdog_device *wdt_dev)
52 void *cmd)
53{ 66{
54 u32 tc_reboot = MESON_WDT_DC_RESET | MESON_WDT_TC_EN; 67 struct meson_wdt_dev *meson_wdt = watchdog_get_drvdata(wdt_dev);
55 struct meson_wdt_dev *meson_wdt = container_of(this, 68 u32 tc_reboot = MESON_WDT_DC_RESET;
56 struct meson_wdt_dev, 69
57 restart_handler); 70 tc_reboot |= meson_wdt->data->enable;
58 71
59 while (1) { 72 while (1) {
60 writel(tc_reboot, meson_wdt->wdt_base + MESON_WDT_TC); 73 writel(tc_reboot, meson_wdt->wdt_base + MESON_WDT_TC);
61 mdelay(5); 74 mdelay(5);
62 } 75 }
63 76
64 return NOTIFY_DONE; 77 return 0;
65} 78}
66 79
67static int meson_wdt_ping(struct watchdog_device *wdt_dev) 80static int meson_wdt_ping(struct watchdog_device *wdt_dev)
@@ -80,8 +93,8 @@ static void meson_wdt_change_timeout(struct watchdog_device *wdt_dev,
80 u32 reg; 93 u32 reg;
81 94
82 reg = readl(meson_wdt->wdt_base + MESON_WDT_TC); 95 reg = readl(meson_wdt->wdt_base + MESON_WDT_TC);
83 reg &= ~MESON_WDT_TC_TM_MASK; 96 reg &= ~meson_wdt->data->terminal_count_mask;
84 reg |= MESON_SEC_TO_TC(timeout); 97 reg |= MESON_SEC_TO_TC(timeout, meson_wdt->data->count_unit);
85 writel(reg, meson_wdt->wdt_base + MESON_WDT_TC); 98 writel(reg, meson_wdt->wdt_base + MESON_WDT_TC);
86} 99}
87 100
@@ -102,7 +115,7 @@ static int meson_wdt_stop(struct watchdog_device *wdt_dev)
102 u32 reg; 115 u32 reg;
103 116
104 reg = readl(meson_wdt->wdt_base + MESON_WDT_TC); 117 reg = readl(meson_wdt->wdt_base + MESON_WDT_TC);
105 reg &= ~MESON_WDT_TC_EN; 118 reg &= ~meson_wdt->data->enable;
106 writel(reg, meson_wdt->wdt_base + MESON_WDT_TC); 119 writel(reg, meson_wdt->wdt_base + MESON_WDT_TC);
107 120
108 return 0; 121 return 0;
@@ -117,7 +130,7 @@ static int meson_wdt_start(struct watchdog_device *wdt_dev)
117 meson_wdt_ping(wdt_dev); 130 meson_wdt_ping(wdt_dev);
118 131
119 reg = readl(meson_wdt->wdt_base + MESON_WDT_TC); 132 reg = readl(meson_wdt->wdt_base + MESON_WDT_TC);
120 reg |= MESON_WDT_TC_EN; 133 reg |= meson_wdt->data->enable;
121 writel(reg, meson_wdt->wdt_base + MESON_WDT_TC); 134 writel(reg, meson_wdt->wdt_base + MESON_WDT_TC);
122 135
123 return 0; 136 return 0;
@@ -136,12 +149,21 @@ static const struct watchdog_ops meson_wdt_ops = {
136 .stop = meson_wdt_stop, 149 .stop = meson_wdt_stop,
137 .ping = meson_wdt_ping, 150 .ping = meson_wdt_ping,
138 .set_timeout = meson_wdt_set_timeout, 151 .set_timeout = meson_wdt_set_timeout,
152 .restart = meson_wdt_restart,
153};
154
155static const struct of_device_id meson_wdt_dt_ids[] = {
156 { .compatible = "amlogic,meson6-wdt", .data = &meson6_wdt_data },
157 { .compatible = "amlogic,meson8b-wdt", .data = &meson8b_wdt_data },
158 { /* sentinel */ }
139}; 159};
160MODULE_DEVICE_TABLE(of, meson_wdt_dt_ids);
140 161
141static int meson_wdt_probe(struct platform_device *pdev) 162static int meson_wdt_probe(struct platform_device *pdev)
142{ 163{
143 struct resource *res; 164 struct resource *res;
144 struct meson_wdt_dev *meson_wdt; 165 struct meson_wdt_dev *meson_wdt;
166 const struct of_device_id *of_id;
145 int err; 167 int err;
146 168
147 meson_wdt = devm_kzalloc(&pdev->dev, sizeof(*meson_wdt), GFP_KERNEL); 169 meson_wdt = devm_kzalloc(&pdev->dev, sizeof(*meson_wdt), GFP_KERNEL);
@@ -153,17 +175,28 @@ static int meson_wdt_probe(struct platform_device *pdev)
153 if (IS_ERR(meson_wdt->wdt_base)) 175 if (IS_ERR(meson_wdt->wdt_base))
154 return PTR_ERR(meson_wdt->wdt_base); 176 return PTR_ERR(meson_wdt->wdt_base);
155 177
178 of_id = of_match_device(meson_wdt_dt_ids, &pdev->dev);
179 if (!of_id) {
180 dev_err(&pdev->dev, "Unable to initialize WDT data\n");
181 return -ENODEV;
182 }
183 meson_wdt->data = of_id->data;
184
156 meson_wdt->wdt_dev.parent = &pdev->dev; 185 meson_wdt->wdt_dev.parent = &pdev->dev;
157 meson_wdt->wdt_dev.info = &meson_wdt_info; 186 meson_wdt->wdt_dev.info = &meson_wdt_info;
158 meson_wdt->wdt_dev.ops = &meson_wdt_ops; 187 meson_wdt->wdt_dev.ops = &meson_wdt_ops;
159 meson_wdt->wdt_dev.timeout = MESON_WDT_TIMEOUT; 188 meson_wdt->wdt_dev.max_timeout =
160 meson_wdt->wdt_dev.max_timeout = MESON_WDT_MAX_TIMEOUT; 189 meson_wdt->data->terminal_count_mask / meson_wdt->data->count_unit;
161 meson_wdt->wdt_dev.min_timeout = MESON_WDT_MIN_TIMEOUT; 190 meson_wdt->wdt_dev.min_timeout = MESON_WDT_MIN_TIMEOUT;
191 meson_wdt->wdt_dev.timeout = min_t(unsigned int,
192 MESON_WDT_TIMEOUT,
193 meson_wdt->wdt_dev.max_timeout);
162 194
163 watchdog_set_drvdata(&meson_wdt->wdt_dev, meson_wdt); 195 watchdog_set_drvdata(&meson_wdt->wdt_dev, meson_wdt);
164 196
165 watchdog_init_timeout(&meson_wdt->wdt_dev, timeout, &pdev->dev); 197 watchdog_init_timeout(&meson_wdt->wdt_dev, timeout, &pdev->dev);
166 watchdog_set_nowayout(&meson_wdt->wdt_dev, nowayout); 198 watchdog_set_nowayout(&meson_wdt->wdt_dev, nowayout);
199 watchdog_set_restart_priority(&meson_wdt->wdt_dev, 128);
167 200
168 meson_wdt_stop(&meson_wdt->wdt_dev); 201 meson_wdt_stop(&meson_wdt->wdt_dev);
169 202
@@ -173,13 +206,6 @@ static int meson_wdt_probe(struct platform_device *pdev)
173 206
174 platform_set_drvdata(pdev, meson_wdt); 207 platform_set_drvdata(pdev, meson_wdt);
175 208
176 meson_wdt->restart_handler.notifier_call = meson_restart_handle;
177 meson_wdt->restart_handler.priority = 128;
178 err = register_restart_handler(&meson_wdt->restart_handler);
179 if (err)
180 dev_err(&pdev->dev,
181 "cannot register restart handler (err=%d)\n", err);
182
183 dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)", 209 dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)",
184 meson_wdt->wdt_dev.timeout, nowayout); 210 meson_wdt->wdt_dev.timeout, nowayout);
185 211
@@ -190,8 +216,6 @@ static int meson_wdt_remove(struct platform_device *pdev)
190{ 216{
191 struct meson_wdt_dev *meson_wdt = platform_get_drvdata(pdev); 217 struct meson_wdt_dev *meson_wdt = platform_get_drvdata(pdev);
192 218
193 unregister_restart_handler(&meson_wdt->restart_handler);
194
195 watchdog_unregister_device(&meson_wdt->wdt_dev); 219 watchdog_unregister_device(&meson_wdt->wdt_dev);
196 220
197 return 0; 221 return 0;
@@ -204,12 +228,6 @@ static void meson_wdt_shutdown(struct platform_device *pdev)
204 meson_wdt_stop(&meson_wdt->wdt_dev); 228 meson_wdt_stop(&meson_wdt->wdt_dev);
205} 229}
206 230
207static const struct of_device_id meson_wdt_dt_ids[] = {
208 { .compatible = "amlogic,meson6-wdt" },
209 { /* sentinel */ }
210};
211MODULE_DEVICE_TABLE(of, meson_wdt_dt_ids);
212
213static struct platform_driver meson_wdt_driver = { 231static struct platform_driver meson_wdt_driver = {
214 .probe = meson_wdt_probe, 232 .probe = meson_wdt_probe,
215 .remove = meson_wdt_remove, 233 .remove = meson_wdt_remove,
diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c
index 60b0605bd7e6..885c81bc4210 100644
--- a/drivers/watchdog/moxart_wdt.c
+++ b/drivers/watchdog/moxart_wdt.c
@@ -15,9 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/notifier.h>
19#include <linux/platform_device.h> 18#include <linux/platform_device.h>
20#include <linux/reboot.h>
21#include <linux/watchdog.h> 19#include <linux/watchdog.h>
22#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
23 21
@@ -29,22 +27,19 @@ struct moxart_wdt_dev {
29 struct watchdog_device dev; 27 struct watchdog_device dev;
30 void __iomem *base; 28 void __iomem *base;
31 unsigned int clock_frequency; 29 unsigned int clock_frequency;
32 struct notifier_block restart_handler;
33}; 30};
34 31
35static int heartbeat; 32static int heartbeat;
36 33
37static int moxart_restart_handle(struct notifier_block *this, 34static int moxart_wdt_restart(struct watchdog_device *wdt_dev)
38 unsigned long mode, void *cmd)
39{ 35{
40 struct moxart_wdt_dev *moxart_wdt = container_of(this, 36 struct moxart_wdt_dev *moxart_wdt = watchdog_get_drvdata(wdt_dev);
41 struct moxart_wdt_dev, 37
42 restart_handler);
43 writel(1, moxart_wdt->base + REG_COUNT); 38 writel(1, moxart_wdt->base + REG_COUNT);
44 writel(0x5ab9, moxart_wdt->base + REG_MODE); 39 writel(0x5ab9, moxart_wdt->base + REG_MODE);
45 writel(0x03, moxart_wdt->base + REG_ENABLE); 40 writel(0x03, moxart_wdt->base + REG_ENABLE);
46 41
47 return NOTIFY_DONE; 42 return 0;
48} 43}
49 44
50static int moxart_wdt_stop(struct watchdog_device *wdt_dev) 45static int moxart_wdt_stop(struct watchdog_device *wdt_dev)
@@ -87,6 +82,7 @@ static const struct watchdog_ops moxart_wdt_ops = {
87 .start = moxart_wdt_start, 82 .start = moxart_wdt_start,
88 .stop = moxart_wdt_stop, 83 .stop = moxart_wdt_stop,
89 .set_timeout = moxart_wdt_set_timeout, 84 .set_timeout = moxart_wdt_set_timeout,
85 .restart = moxart_wdt_restart,
90}; 86};
91 87
92static int moxart_wdt_probe(struct platform_device *pdev) 88static int moxart_wdt_probe(struct platform_device *pdev)
@@ -134,6 +130,7 @@ static int moxart_wdt_probe(struct platform_device *pdev)
134 130
135 watchdog_init_timeout(&moxart_wdt->dev, heartbeat, dev); 131 watchdog_init_timeout(&moxart_wdt->dev, heartbeat, dev);
136 watchdog_set_nowayout(&moxart_wdt->dev, nowayout); 132 watchdog_set_nowayout(&moxart_wdt->dev, nowayout);
133 watchdog_set_restart_priority(&moxart_wdt->dev, 128);
137 134
138 watchdog_set_drvdata(&moxart_wdt->dev, moxart_wdt); 135 watchdog_set_drvdata(&moxart_wdt->dev, moxart_wdt);
139 136
@@ -141,13 +138,6 @@ static int moxart_wdt_probe(struct platform_device *pdev)
141 if (err) 138 if (err)
142 return err; 139 return err;
143 140
144 moxart_wdt->restart_handler.notifier_call = moxart_restart_handle;
145 moxart_wdt->restart_handler.priority = 128;
146 err = register_restart_handler(&moxart_wdt->restart_handler);
147 if (err)
148 dev_err(dev, "cannot register restart notifier (err=%d)\n",
149 err);
150
151 dev_dbg(dev, "Watchdog enabled (heartbeat=%d sec, nowayout=%d)\n", 141 dev_dbg(dev, "Watchdog enabled (heartbeat=%d sec, nowayout=%d)\n",
152 moxart_wdt->dev.timeout, nowayout); 142 moxart_wdt->dev.timeout, nowayout);
153 143
@@ -158,7 +148,6 @@ static int moxart_wdt_remove(struct platform_device *pdev)
158{ 148{
159 struct moxart_wdt_dev *moxart_wdt = platform_get_drvdata(pdev); 149 struct moxart_wdt_dev *moxart_wdt = platform_get_drvdata(pdev);
160 150
161 unregister_restart_handler(&moxart_wdt->restart_handler);
162 moxart_wdt_stop(&moxart_wdt->dev); 151 moxart_wdt_stop(&moxart_wdt->dev);
163 152
164 return 0; 153 return 0;
diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c
new file mode 100644
index 000000000000..4a2290f900a8
--- /dev/null
+++ b/drivers/watchdog/mt7621_wdt.c
@@ -0,0 +1,186 @@
1/*
2 * Ralink MT7621/MT7628 built-in hardware watchdog timer
3 *
4 * Copyright (C) 2014 John Crispin <blogic@openwrt.org>
5 *
6 * This driver was based on: drivers/watchdog/rt2880_wdt.c
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/reset.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/watchdog.h>
18#include <linux/moduleparam.h>
19#include <linux/platform_device.h>
20
21#include <asm/mach-ralink/ralink_regs.h>
22
23#define SYSC_RSTSTAT 0x38
24#define WDT_RST_CAUSE BIT(1)
25
26#define RALINK_WDT_TIMEOUT 30
27
28#define TIMER_REG_TMRSTAT 0x00
29#define TIMER_REG_TMR1LOAD 0x24
30#define TIMER_REG_TMR1CTL 0x20
31
32#define TMR1CTL_ENABLE BIT(7)
33#define TMR1CTL_RESTART BIT(9)
34#define TMR1CTL_PRESCALE_SHIFT 16
35
36static void __iomem *mt7621_wdt_base;
37static struct reset_control *mt7621_wdt_reset;
38
39static bool nowayout = WATCHDOG_NOWAYOUT;
40module_param(nowayout, bool, 0);
41MODULE_PARM_DESC(nowayout,
42 "Watchdog cannot be stopped once started (default="
43 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
44
45static inline void rt_wdt_w32(unsigned reg, u32 val)
46{
47 iowrite32(val, mt7621_wdt_base + reg);
48}
49
50static inline u32 rt_wdt_r32(unsigned reg)
51{
52 return ioread32(mt7621_wdt_base + reg);
53}
54
55static int mt7621_wdt_ping(struct watchdog_device *w)
56{
57 rt_wdt_w32(TIMER_REG_TMRSTAT, TMR1CTL_RESTART);
58
59 return 0;
60}
61
62static int mt7621_wdt_set_timeout(struct watchdog_device *w, unsigned int t)
63{
64 w->timeout = t;
65 rt_wdt_w32(TIMER_REG_TMR1LOAD, t * 1000);
66 mt7621_wdt_ping(w);
67
68 return 0;
69}
70
71static int mt7621_wdt_start(struct watchdog_device *w)
72{
73 u32 t;
74
75 /* set the prescaler to 1ms == 1000us */
76 rt_wdt_w32(TIMER_REG_TMR1CTL, 1000 << TMR1CTL_PRESCALE_SHIFT);
77
78 mt7621_wdt_set_timeout(w, w->timeout);
79
80 t = rt_wdt_r32(TIMER_REG_TMR1CTL);
81 t |= TMR1CTL_ENABLE;
82 rt_wdt_w32(TIMER_REG_TMR1CTL, t);
83
84 return 0;
85}
86
87static int mt7621_wdt_stop(struct watchdog_device *w)
88{
89 u32 t;
90
91 mt7621_wdt_ping(w);
92
93 t = rt_wdt_r32(TIMER_REG_TMR1CTL);
94 t &= ~TMR1CTL_ENABLE;
95 rt_wdt_w32(TIMER_REG_TMR1CTL, t);
96
97 return 0;
98}
99
100static int mt7621_wdt_bootcause(void)
101{
102 if (rt_sysc_r32(SYSC_RSTSTAT) & WDT_RST_CAUSE)
103 return WDIOF_CARDRESET;
104
105 return 0;
106}
107
108static struct watchdog_info mt7621_wdt_info = {
109 .identity = "Mediatek Watchdog",
110 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
111};
112
113static struct watchdog_ops mt7621_wdt_ops = {
114 .owner = THIS_MODULE,
115 .start = mt7621_wdt_start,
116 .stop = mt7621_wdt_stop,
117 .ping = mt7621_wdt_ping,
118 .set_timeout = mt7621_wdt_set_timeout,
119};
120
121static struct watchdog_device mt7621_wdt_dev = {
122 .info = &mt7621_wdt_info,
123 .ops = &mt7621_wdt_ops,
124 .min_timeout = 1,
125 .max_timeout = 0xfffful / 1000,
126};
127
128static int mt7621_wdt_probe(struct platform_device *pdev)
129{
130 struct resource *res;
131 int ret;
132
133 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
134 mt7621_wdt_base = devm_ioremap_resource(&pdev->dev, res);
135 if (IS_ERR(mt7621_wdt_base))
136 return PTR_ERR(mt7621_wdt_base);
137
138 mt7621_wdt_reset = devm_reset_control_get(&pdev->dev, NULL);
139 if (!IS_ERR(mt7621_wdt_reset))
140 reset_control_deassert(mt7621_wdt_reset);
141
142 mt7621_wdt_dev.dev = &pdev->dev;
143 mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause();
144
145 watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout,
146 &pdev->dev);
147 watchdog_set_nowayout(&mt7621_wdt_dev, nowayout);
148
149 ret = watchdog_register_device(&mt7621_wdt_dev);
150
151 return 0;
152}
153
154static int mt7621_wdt_remove(struct platform_device *pdev)
155{
156 watchdog_unregister_device(&mt7621_wdt_dev);
157
158 return 0;
159}
160
161static void mt7621_wdt_shutdown(struct platform_device *pdev)
162{
163 mt7621_wdt_stop(&mt7621_wdt_dev);
164}
165
166static const struct of_device_id mt7621_wdt_match[] = {
167 { .compatible = "mediatek,mt7621-wdt" },
168 {},
169};
170MODULE_DEVICE_TABLE(of, mt7621_wdt_match);
171
172static struct platform_driver mt7621_wdt_driver = {
173 .probe = mt7621_wdt_probe,
174 .remove = mt7621_wdt_remove,
175 .shutdown = mt7621_wdt_shutdown,
176 .driver = {
177 .name = KBUILD_MODNAME,
178 .of_match_table = mt7621_wdt_match,
179 },
180};
181
182module_platform_driver(mt7621_wdt_driver);
183
184MODULE_DESCRIPTION("MediaTek MT762x hardware watchdog driver");
185MODULE_AUTHOR("John Crispin <blogic@openwrt.org");
186MODULE_LICENSE("GPL v2");
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index b751f43d76ed..b78776c05554 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -28,8 +28,6 @@
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/types.h> 29#include <linux/types.h>
30#include <linux/watchdog.h> 30#include <linux/watchdog.h>
31#include <linux/notifier.h>
32#include <linux/reboot.h>
33#include <linux/delay.h> 31#include <linux/delay.h>
34 32
35#define WDT_MAX_TIMEOUT 31 33#define WDT_MAX_TIMEOUT 31
@@ -64,16 +62,13 @@ static unsigned int timeout = WDT_MAX_TIMEOUT;
64struct mtk_wdt_dev { 62struct mtk_wdt_dev {
65 struct watchdog_device wdt_dev; 63 struct watchdog_device wdt_dev;
66 void __iomem *wdt_base; 64 void __iomem *wdt_base;
67 struct notifier_block restart_handler;
68}; 65};
69 66
70static int mtk_reset_handler(struct notifier_block *this, unsigned long mode, 67static int mtk_wdt_restart(struct watchdog_device *wdt_dev)
71 void *cmd)
72{ 68{
73 struct mtk_wdt_dev *mtk_wdt; 69 struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
74 void __iomem *wdt_base; 70 void __iomem *wdt_base;
75 71
76 mtk_wdt = container_of(this, struct mtk_wdt_dev, restart_handler);
77 wdt_base = mtk_wdt->wdt_base; 72 wdt_base = mtk_wdt->wdt_base;
78 73
79 while (1) { 74 while (1) {
@@ -81,7 +76,7 @@ static int mtk_reset_handler(struct notifier_block *this, unsigned long mode,
81 mdelay(5); 76 mdelay(5);
82 } 77 }
83 78
84 return NOTIFY_DONE; 79 return 0;
85} 80}
86 81
87static int mtk_wdt_ping(struct watchdog_device *wdt_dev) 82static int mtk_wdt_ping(struct watchdog_device *wdt_dev)
@@ -161,6 +156,7 @@ static const struct watchdog_ops mtk_wdt_ops = {
161 .stop = mtk_wdt_stop, 156 .stop = mtk_wdt_stop,
162 .ping = mtk_wdt_ping, 157 .ping = mtk_wdt_ping,
163 .set_timeout = mtk_wdt_set_timeout, 158 .set_timeout = mtk_wdt_set_timeout,
159 .restart = mtk_wdt_restart,
164}; 160};
165 161
166static int mtk_wdt_probe(struct platform_device *pdev) 162static int mtk_wdt_probe(struct platform_device *pdev)
@@ -189,6 +185,7 @@ static int mtk_wdt_probe(struct platform_device *pdev)
189 185
190 watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, &pdev->dev); 186 watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, &pdev->dev);
191 watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout); 187 watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout);
188 watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128);
192 189
193 watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt); 190 watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt);
194 191
@@ -198,13 +195,6 @@ static int mtk_wdt_probe(struct platform_device *pdev)
198 if (unlikely(err)) 195 if (unlikely(err))
199 return err; 196 return err;
200 197
201 mtk_wdt->restart_handler.notifier_call = mtk_reset_handler;
202 mtk_wdt->restart_handler.priority = 128;
203 err = register_restart_handler(&mtk_wdt->restart_handler);
204 if (err)
205 dev_warn(&pdev->dev,
206 "cannot register restart handler (err=%d)\n", err);
207
208 dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n", 198 dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n",
209 mtk_wdt->wdt_dev.timeout, nowayout); 199 mtk_wdt->wdt_dev.timeout, nowayout);
210 200
@@ -223,8 +213,6 @@ static int mtk_wdt_remove(struct platform_device *pdev)
223{ 213{
224 struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); 214 struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
225 215
226 unregister_restart_handler(&mtk_wdt->restart_handler);
227
228 watchdog_unregister_device(&mtk_wdt->wdt_dev); 216 watchdog_unregister_device(&mtk_wdt->wdt_dev);
229 217
230 return 0; 218 return 0;
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 6f17c935a6cf..1b02bfa81b29 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -271,7 +271,8 @@ static int omap_wdt_probe(struct platform_device *pdev)
271 wdev->wdog.bootstatus = WDIOF_CARDRESET; 271 wdev->wdog.bootstatus = WDIOF_CARDRESET;
272 } 272 }
273 273
274 omap_wdt_disable(wdev); 274 if (!early_enable)
275 omap_wdt_disable(wdev);
275 276
276 ret = watchdog_register_device(&wdev->wdog); 277 ret = watchdog_register_device(&wdev->wdog);
277 if (ret) { 278 if (ret) {
@@ -283,11 +284,11 @@ static int omap_wdt_probe(struct platform_device *pdev)
283 readl_relaxed(wdev->base + OMAP_WATCHDOG_REV) & 0xFF, 284 readl_relaxed(wdev->base + OMAP_WATCHDOG_REV) & 0xFF,
284 wdev->wdog.timeout); 285 wdev->wdog.timeout);
285 286
286 pm_runtime_put_sync(wdev->dev);
287
288 if (early_enable) 287 if (early_enable)
289 omap_wdt_start(&wdev->wdog); 288 omap_wdt_start(&wdev->wdog);
290 289
290 pm_runtime_put(wdev->dev);
291
291 return 0; 292 return 0;
292} 293}
293 294
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index 773dcfaee7b2..424f9a952fee 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -17,7 +17,6 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/of.h> 18#include <linux/of.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/reboot.h>
21#include <linux/watchdog.h> 20#include <linux/watchdog.h>
22 21
23#define WDT_RST 0x38 22#define WDT_RST 0x38
@@ -28,7 +27,6 @@ struct qcom_wdt {
28 struct watchdog_device wdd; 27 struct watchdog_device wdd;
29 struct clk *clk; 28 struct clk *clk;
30 unsigned long rate; 29 unsigned long rate;
31 struct notifier_block restart_nb;
32 void __iomem *base; 30 void __iomem *base;
33}; 31};
34 32
@@ -72,25 +70,9 @@ static int qcom_wdt_set_timeout(struct watchdog_device *wdd,
72 return qcom_wdt_start(wdd); 70 return qcom_wdt_start(wdd);
73} 71}
74 72
75static const struct watchdog_ops qcom_wdt_ops = { 73static int qcom_wdt_restart(struct watchdog_device *wdd)
76 .start = qcom_wdt_start,
77 .stop = qcom_wdt_stop,
78 .ping = qcom_wdt_ping,
79 .set_timeout = qcom_wdt_set_timeout,
80 .owner = THIS_MODULE,
81};
82
83static const struct watchdog_info qcom_wdt_info = {
84 .options = WDIOF_KEEPALIVEPING
85 | WDIOF_MAGICCLOSE
86 | WDIOF_SETTIMEOUT,
87 .identity = KBUILD_MODNAME,
88};
89
90static int qcom_wdt_restart(struct notifier_block *nb, unsigned long action,
91 void *data)
92{ 74{
93 struct qcom_wdt *wdt = container_of(nb, struct qcom_wdt, restart_nb); 75 struct qcom_wdt *wdt = to_qcom_wdt(wdd);
94 u32 timeout; 76 u32 timeout;
95 77
96 /* 78 /*
@@ -110,9 +92,25 @@ static int qcom_wdt_restart(struct notifier_block *nb, unsigned long action,
110 wmb(); 92 wmb();
111 93
112 msleep(150); 94 msleep(150);
113 return NOTIFY_DONE; 95 return 0;
114} 96}
115 97
98static const struct watchdog_ops qcom_wdt_ops = {
99 .start = qcom_wdt_start,
100 .stop = qcom_wdt_stop,
101 .ping = qcom_wdt_ping,
102 .set_timeout = qcom_wdt_set_timeout,
103 .restart = qcom_wdt_restart,
104 .owner = THIS_MODULE,
105};
106
107static const struct watchdog_info qcom_wdt_info = {
108 .options = WDIOF_KEEPALIVEPING
109 | WDIOF_MAGICCLOSE
110 | WDIOF_SETTIMEOUT,
111 .identity = KBUILD_MODNAME,
112};
113
116static int qcom_wdt_probe(struct platform_device *pdev) 114static int qcom_wdt_probe(struct platform_device *pdev)
117{ 115{
118 struct qcom_wdt *wdt; 116 struct qcom_wdt *wdt;
@@ -166,7 +164,6 @@ static int qcom_wdt_probe(struct platform_device *pdev)
166 goto err_clk_unprepare; 164 goto err_clk_unprepare;
167 } 165 }
168 166
169 wdt->wdd.dev = &pdev->dev;
170 wdt->wdd.info = &qcom_wdt_info; 167 wdt->wdd.info = &qcom_wdt_info;
171 wdt->wdd.ops = &qcom_wdt_ops; 168 wdt->wdd.ops = &qcom_wdt_ops;
172 wdt->wdd.min_timeout = 1; 169 wdt->wdd.min_timeout = 1;
@@ -187,14 +184,6 @@ static int qcom_wdt_probe(struct platform_device *pdev)
187 goto err_clk_unprepare; 184 goto err_clk_unprepare;
188 } 185 }
189 186
190 /*
191 * WDT restart notifier has priority 0 (use as a last resort)
192 */
193 wdt->restart_nb.notifier_call = qcom_wdt_restart;
194 ret = register_restart_handler(&wdt->restart_nb);
195 if (ret)
196 dev_err(&pdev->dev, "failed to setup restart handler\n");
197
198 platform_set_drvdata(pdev, wdt); 187 platform_set_drvdata(pdev, wdt);
199 return 0; 188 return 0;
200 189
@@ -207,7 +196,6 @@ static int qcom_wdt_remove(struct platform_device *pdev)
207{ 196{
208 struct qcom_wdt *wdt = platform_get_drvdata(pdev); 197 struct qcom_wdt *wdt = platform_get_drvdata(pdev);
209 198
210 unregister_restart_handler(&wdt->restart_nb);
211 watchdog_unregister_device(&wdt->wdd); 199 watchdog_unregister_device(&wdt->wdd);
212 clk_disable_unprepare(wdt->clk); 200 clk_disable_unprepare(wdt->clk);
213 return 0; 201 return 0;
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index d781000c7825..0093450441fe 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -41,7 +41,6 @@
41#include <linux/of.h> 41#include <linux/of.h>
42#include <linux/mfd/syscon.h> 42#include <linux/mfd/syscon.h>
43#include <linux/regmap.h> 43#include <linux/regmap.h>
44#include <linux/reboot.h>
45#include <linux/delay.h> 44#include <linux/delay.h>
46 45
47#define S3C2410_WTCON 0x00 46#define S3C2410_WTCON 0x00
@@ -130,7 +129,6 @@ struct s3c2410_wdt {
130 unsigned long wtdat_save; 129 unsigned long wtdat_save;
131 struct watchdog_device wdt_device; 130 struct watchdog_device wdt_device;
132 struct notifier_block freq_transition; 131 struct notifier_block freq_transition;
133 struct notifier_block restart_handler;
134 struct s3c2410_wdt_variant *drv_data; 132 struct s3c2410_wdt_variant *drv_data;
135 struct regmap *pmureg; 133 struct regmap *pmureg;
136}; 134};
@@ -351,6 +349,29 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeou
351 return 0; 349 return 0;
352} 350}
353 351
352static int s3c2410wdt_restart(struct watchdog_device *wdd)
353{
354 struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd);
355 void __iomem *wdt_base = wdt->reg_base;
356
357 /* disable watchdog, to be safe */
358 writel(0, wdt_base + S3C2410_WTCON);
359
360 /* put initial values into count and data */
361 writel(0x80, wdt_base + S3C2410_WTCNT);
362 writel(0x80, wdt_base + S3C2410_WTDAT);
363
364 /* set the watchdog to go and reset... */
365 writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV16 |
366 S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x20),
367 wdt_base + S3C2410_WTCON);
368
369 /* wait for reset to assert... */
370 mdelay(500);
371
372 return 0;
373}
374
354#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE) 375#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
355 376
356static const struct watchdog_info s3c2410_wdt_ident = { 377static const struct watchdog_info s3c2410_wdt_ident = {
@@ -365,6 +386,7 @@ static struct watchdog_ops s3c2410wdt_ops = {
365 .stop = s3c2410wdt_stop, 386 .stop = s3c2410wdt_stop,
366 .ping = s3c2410wdt_keepalive, 387 .ping = s3c2410wdt_keepalive,
367 .set_timeout = s3c2410wdt_set_heartbeat, 388 .set_timeout = s3c2410wdt_set_heartbeat,
389 .restart = s3c2410wdt_restart,
368}; 390};
369 391
370static struct watchdog_device s3c2410_wdd = { 392static struct watchdog_device s3c2410_wdd = {
@@ -452,31 +474,6 @@ static inline void s3c2410wdt_cpufreq_deregister(struct s3c2410_wdt *wdt)
452} 474}
453#endif 475#endif
454 476
455static int s3c2410wdt_restart(struct notifier_block *this,
456 unsigned long mode, void *cmd)
457{
458 struct s3c2410_wdt *wdt = container_of(this, struct s3c2410_wdt,
459 restart_handler);
460 void __iomem *wdt_base = wdt->reg_base;
461
462 /* disable watchdog, to be safe */
463 writel(0, wdt_base + S3C2410_WTCON);
464
465 /* put initial values into count and data */
466 writel(0x80, wdt_base + S3C2410_WTCNT);
467 writel(0x80, wdt_base + S3C2410_WTDAT);
468
469 /* set the watchdog to go and reset... */
470 writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV16 |
471 S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x20),
472 wdt_base + S3C2410_WTCON);
473
474 /* wait for reset to assert... */
475 mdelay(500);
476
477 return NOTIFY_DONE;
478}
479
480static inline unsigned int s3c2410wdt_get_bootstatus(struct s3c2410_wdt *wdt) 477static inline unsigned int s3c2410wdt_get_bootstatus(struct s3c2410_wdt *wdt)
481{ 478{
482 unsigned int rst_stat; 479 unsigned int rst_stat;
@@ -605,6 +602,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
605 } 602 }
606 603
607 watchdog_set_nowayout(&wdt->wdt_device, nowayout); 604 watchdog_set_nowayout(&wdt->wdt_device, nowayout);
605 watchdog_set_restart_priority(&wdt->wdt_device, 128);
608 606
609 wdt->wdt_device.bootstatus = s3c2410wdt_get_bootstatus(wdt); 607 wdt->wdt_device.bootstatus = s3c2410wdt_get_bootstatus(wdt);
610 wdt->wdt_device.parent = &pdev->dev; 608 wdt->wdt_device.parent = &pdev->dev;
@@ -632,12 +630,6 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
632 630
633 platform_set_drvdata(pdev, wdt); 631 platform_set_drvdata(pdev, wdt);
634 632
635 wdt->restart_handler.notifier_call = s3c2410wdt_restart;
636 wdt->restart_handler.priority = 128;
637 ret = register_restart_handler(&wdt->restart_handler);
638 if (ret)
639 pr_err("cannot register restart handler, %d\n", ret);
640
641 /* print out a statement of readiness */ 633 /* print out a statement of readiness */
642 634
643 wtcon = readl(wdt->reg_base + S3C2410_WTCON); 635 wtcon = readl(wdt->reg_base + S3C2410_WTCON);
@@ -667,8 +659,6 @@ static int s3c2410wdt_remove(struct platform_device *dev)
667 int ret; 659 int ret;
668 struct s3c2410_wdt *wdt = platform_get_drvdata(dev); 660 struct s3c2410_wdt *wdt = platform_get_drvdata(dev);
669 661
670 unregister_restart_handler(&wdt->restart_handler);
671
672 ret = s3c2410wdt_mask_and_disable_reset(wdt, true); 662 ret = s3c2410wdt_mask_and_disable_reset(wdt, true);
673 if (ret < 0) 663 if (ret < 0)
674 return ret; 664 return ret;
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c
index 0dc5e323d59d..99a06f9e3930 100644
--- a/drivers/watchdog/softdog.c
+++ b/drivers/watchdog/softdog.c
@@ -43,7 +43,6 @@
43#include <linux/types.h> 43#include <linux/types.h>
44#include <linux/timer.h> 44#include <linux/timer.h>
45#include <linux/watchdog.h> 45#include <linux/watchdog.h>
46#include <linux/notifier.h>
47#include <linux/reboot.h> 46#include <linux/reboot.h>
48#include <linux/init.h> 47#include <linux/init.h>
49#include <linux/jiffies.h> 48#include <linux/jiffies.h>
@@ -87,6 +86,7 @@ static struct timer_list watchdog_ticktock =
87 86
88static void watchdog_fire(unsigned long data) 87static void watchdog_fire(unsigned long data)
89{ 88{
89 module_put(THIS_MODULE);
90 if (soft_noboot) 90 if (soft_noboot)
91 pr_crit("Triggered - Reboot ignored\n"); 91 pr_crit("Triggered - Reboot ignored\n");
92 else if (soft_panic) { 92 else if (soft_panic) {
@@ -105,13 +105,16 @@ static void watchdog_fire(unsigned long data)
105 105
106static int softdog_ping(struct watchdog_device *w) 106static int softdog_ping(struct watchdog_device *w)
107{ 107{
108 mod_timer(&watchdog_ticktock, jiffies+(w->timeout*HZ)); 108 if (!mod_timer(&watchdog_ticktock, jiffies+(w->timeout*HZ)))
109 __module_get(THIS_MODULE);
109 return 0; 110 return 0;
110} 111}
111 112
112static int softdog_stop(struct watchdog_device *w) 113static int softdog_stop(struct watchdog_device *w)
113{ 114{
114 del_timer(&watchdog_ticktock); 115 if (del_timer(&watchdog_ticktock))
116 module_put(THIS_MODULE);
117
115 return 0; 118 return 0;
116} 119}
117 120
@@ -122,26 +125,9 @@ static int softdog_set_timeout(struct watchdog_device *w, unsigned int t)
122} 125}
123 126
124/* 127/*
125 * Notifier for system down
126 */
127
128static int softdog_notify_sys(struct notifier_block *this, unsigned long code,
129 void *unused)
130{
131 if (code == SYS_DOWN || code == SYS_HALT)
132 /* Turn the WDT off */
133 softdog_stop(NULL);
134 return NOTIFY_DONE;
135}
136
137/*
138 * Kernel Interfaces 128 * Kernel Interfaces
139 */ 129 */
140 130
141static struct notifier_block softdog_notifier = {
142 .notifier_call = softdog_notify_sys,
143};
144
145static struct watchdog_info softdog_info = { 131static struct watchdog_info softdog_info = {
146 .identity = "Software Watchdog", 132 .identity = "Software Watchdog",
147 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 133 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
@@ -175,18 +161,11 @@ static int __init watchdog_init(void)
175 softdog_dev.timeout = soft_margin; 161 softdog_dev.timeout = soft_margin;
176 162
177 watchdog_set_nowayout(&softdog_dev, nowayout); 163 watchdog_set_nowayout(&softdog_dev, nowayout);
178 164 watchdog_stop_on_reboot(&softdog_dev);
179 ret = register_reboot_notifier(&softdog_notifier);
180 if (ret) {
181 pr_err("cannot register reboot notifier (err=%d)\n", ret);
182 return ret;
183 }
184 165
185 ret = watchdog_register_device(&softdog_dev); 166 ret = watchdog_register_device(&softdog_dev);
186 if (ret) { 167 if (ret)
187 unregister_reboot_notifier(&softdog_notifier);
188 return ret; 168 return ret;
189 }
190 169
191 pr_info("Software Watchdog Timer: 0.08 initialized. soft_noboot=%d soft_margin=%d sec soft_panic=%d (nowayout=%d)\n", 170 pr_info("Software Watchdog Timer: 0.08 initialized. soft_noboot=%d soft_margin=%d sec soft_panic=%d (nowayout=%d)\n",
192 soft_noboot, soft_margin, soft_panic, nowayout); 171 soft_noboot, soft_margin, soft_panic, nowayout);
@@ -197,7 +176,6 @@ static int __init watchdog_init(void)
197static void __exit watchdog_exit(void) 176static void __exit watchdog_exit(void)
198{ 177{
199 watchdog_unregister_device(&softdog_dev); 178 watchdog_unregister_device(&softdog_dev);
200 unregister_reboot_notifier(&softdog_notifier);
201} 179}
202 180
203module_init(watchdog_init); 181module_init(watchdog_init);
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
index eb8044ef0ea0..6467b91f2245 100644
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -306,6 +306,10 @@ static struct miscdevice sp5100_tco_miscdev = {
306static const struct pci_device_id sp5100_tco_pci_tbl[] = { 306static const struct pci_device_id sp5100_tco_pci_tbl[] = {
307 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, PCI_ANY_ID, 307 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, PCI_ANY_ID,
308 PCI_ANY_ID, }, 308 PCI_ANY_ID, },
309 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, PCI_ANY_ID,
310 PCI_ANY_ID, },
311 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, PCI_ANY_ID,
312 PCI_ANY_ID, },
309 { 0, }, /* End of list */ 313 { 0, }, /* End of list */
310}; 314};
311MODULE_DEVICE_TABLE(pci, sp5100_tco_pci_tbl); 315MODULE_DEVICE_TABLE(pci, sp5100_tco_pci_tbl);
@@ -331,21 +335,24 @@ static unsigned char sp5100_tco_setupdevice(void)
331 if (!sp5100_tco_pci) 335 if (!sp5100_tco_pci)
332 return 0; 336 return 0;
333 337
334 pr_info("PCI Revision ID: 0x%x\n", sp5100_tco_pci->revision); 338 pr_info("PCI Vendor ID: 0x%x, Device ID: 0x%x, Revision ID: 0x%x\n",
339 sp5100_tco_pci->vendor, sp5100_tco_pci->device,
340 sp5100_tco_pci->revision);
335 341
336 /* 342 /*
337 * Determine type of southbridge chipset. 343 * Determine type of southbridge chipset.
338 */ 344 */
339 if (sp5100_tco_pci->revision >= 0x40) { 345 if (sp5100_tco_pci->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
340 dev_name = SB800_DEVNAME; 346 sp5100_tco_pci->revision < 0x40) {
341 index_reg = SB800_IO_PM_INDEX_REG;
342 data_reg = SB800_IO_PM_DATA_REG;
343 base_addr = SB800_PM_WATCHDOG_BASE;
344 } else {
345 dev_name = SP5100_DEVNAME; 347 dev_name = SP5100_DEVNAME;
346 index_reg = SP5100_IO_PM_INDEX_REG; 348 index_reg = SP5100_IO_PM_INDEX_REG;
347 data_reg = SP5100_IO_PM_DATA_REG; 349 data_reg = SP5100_IO_PM_DATA_REG;
348 base_addr = SP5100_PM_WATCHDOG_BASE; 350 base_addr = SP5100_PM_WATCHDOG_BASE;
351 } else {
352 dev_name = SB800_DEVNAME;
353 index_reg = SB800_IO_PM_INDEX_REG;
354 data_reg = SB800_IO_PM_DATA_REG;
355 base_addr = SB800_PM_WATCHDOG_BASE;
349 } 356 }
350 357
351 /* Request the IO ports used by this driver */ 358 /* Request the IO ports used by this driver */
@@ -381,7 +388,12 @@ static unsigned char sp5100_tco_setupdevice(void)
381 * Secondly, Find the watchdog timer MMIO address 388 * Secondly, Find the watchdog timer MMIO address
382 * from SBResource_MMIO register. 389 * from SBResource_MMIO register.
383 */ 390 */
384 if (sp5100_tco_pci->revision >= 0x40) { 391 if (sp5100_tco_pci->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
392 sp5100_tco_pci->revision < 0x40) {
393 /* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */
394 pci_read_config_dword(sp5100_tco_pci,
395 SP5100_SB_RESOURCE_MMIO_BASE, &val);
396 } else {
385 /* Read SBResource_MMIO from AcpiMmioEn(PM_Reg: 24h) */ 397 /* Read SBResource_MMIO from AcpiMmioEn(PM_Reg: 24h) */
386 outb(SB800_PM_ACPI_MMIO_EN+3, SB800_IO_PM_INDEX_REG); 398 outb(SB800_PM_ACPI_MMIO_EN+3, SB800_IO_PM_INDEX_REG);
387 val = inb(SB800_IO_PM_DATA_REG); 399 val = inb(SB800_IO_PM_DATA_REG);
@@ -391,10 +403,6 @@ static unsigned char sp5100_tco_setupdevice(void)
391 val = val << 8 | inb(SB800_IO_PM_DATA_REG); 403 val = val << 8 | inb(SB800_IO_PM_DATA_REG);
392 outb(SB800_PM_ACPI_MMIO_EN+0, SB800_IO_PM_INDEX_REG); 404 outb(SB800_PM_ACPI_MMIO_EN+0, SB800_IO_PM_INDEX_REG);
393 val = val << 8 | inb(SB800_IO_PM_DATA_REG); 405 val = val << 8 | inb(SB800_IO_PM_DATA_REG);
394 } else {
395 /* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */
396 pci_read_config_dword(sp5100_tco_pci,
397 SP5100_SB_RESOURCE_MMIO_BASE, &val);
398 } 406 }
399 407
400 /* The SBResource_MMIO is enabled and mapped memory space? */ 408 /* The SBResource_MMIO is enabled and mapped memory space? */
diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c
index 3ee6128a540e..d8b11eb269ad 100644
--- a/drivers/watchdog/stmp3xxx_rtc_wdt.c
+++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c
@@ -14,6 +14,8 @@
14#include <linux/watchdog.h> 14#include <linux/watchdog.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/stmp3xxx_rtc_wdt.h> 16#include <linux/stmp3xxx_rtc_wdt.h>
17#include <linux/notifier.h>
18#include <linux/reboot.h>
17 19
18#define WDOG_TICK_RATE 1000 /* 1 kHz clock */ 20#define WDOG_TICK_RATE 1000 /* 1 kHz clock */
19#define STMP3XXX_DEFAULT_TIMEOUT 19 21#define STMP3XXX_DEFAULT_TIMEOUT 19
@@ -69,6 +71,25 @@ static struct watchdog_device stmp3xxx_wdd = {
69 .status = WATCHDOG_NOWAYOUT_INIT_STATUS, 71 .status = WATCHDOG_NOWAYOUT_INIT_STATUS,
70}; 72};
71 73
74static int wdt_notify_sys(struct notifier_block *nb, unsigned long code,
75 void *unused)
76{
77 switch (code) {
78 case SYS_DOWN: /* keep enabled, system might crash while going down */
79 break;
80 case SYS_HALT: /* allow the system to actually halt */
81 case SYS_POWER_OFF:
82 wdt_stop(&stmp3xxx_wdd);
83 break;
84 }
85
86 return NOTIFY_DONE;
87}
88
89static struct notifier_block wdt_notifier = {
90 .notifier_call = wdt_notify_sys,
91};
92
72static int stmp3xxx_wdt_probe(struct platform_device *pdev) 93static int stmp3xxx_wdt_probe(struct platform_device *pdev)
73{ 94{
74 int ret; 95 int ret;
@@ -84,6 +105,9 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
84 return ret; 105 return ret;
85 } 106 }
86 107
108 if (register_reboot_notifier(&wdt_notifier))
109 dev_warn(&pdev->dev, "cannot register reboot notifier\n");
110
87 dev_info(&pdev->dev, "initialized watchdog with heartbeat %ds\n", 111 dev_info(&pdev->dev, "initialized watchdog with heartbeat %ds\n",
88 stmp3xxx_wdd.timeout); 112 stmp3xxx_wdd.timeout);
89 return 0; 113 return 0;
@@ -91,6 +115,7 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
91 115
92static int stmp3xxx_wdt_remove(struct platform_device *pdev) 116static int stmp3xxx_wdt_remove(struct platform_device *pdev)
93{ 117{
118 unregister_reboot_notifier(&wdt_notifier);
94 watchdog_unregister_device(&stmp3xxx_wdd); 119 watchdog_unregister_device(&stmp3xxx_wdd);
95 return 0; 120 return 0;
96} 121}
diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c
index 47bd8a14d01f..e027deb54740 100644
--- a/drivers/watchdog/sunxi_wdt.c
+++ b/drivers/watchdog/sunxi_wdt.c
@@ -21,11 +21,9 @@
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
24#include <linux/notifier.h>
25#include <linux/of.h> 24#include <linux/of.h>
26#include <linux/of_device.h> 25#include <linux/of_device.h>
27#include <linux/platform_device.h> 26#include <linux/platform_device.h>
28#include <linux/reboot.h>
29#include <linux/types.h> 27#include <linux/types.h>
30#include <linux/watchdog.h> 28#include <linux/watchdog.h>
31 29
@@ -60,7 +58,6 @@ struct sunxi_wdt_dev {
60 struct watchdog_device wdt_dev; 58 struct watchdog_device wdt_dev;
61 void __iomem *wdt_base; 59 void __iomem *wdt_base;
62 const struct sunxi_wdt_reg *wdt_regs; 60 const struct sunxi_wdt_reg *wdt_regs;
63 struct notifier_block restart_handler;
64}; 61};
65 62
66/* 63/*
@@ -86,12 +83,9 @@ static const int wdt_timeout_map[] = {
86}; 83};
87 84
88 85
89static int sunxi_restart_handle(struct notifier_block *this, unsigned long mode, 86static int sunxi_wdt_restart(struct watchdog_device *wdt_dev)
90 void *cmd)
91{ 87{
92 struct sunxi_wdt_dev *sunxi_wdt = container_of(this, 88 struct sunxi_wdt_dev *sunxi_wdt = watchdog_get_drvdata(wdt_dev);
93 struct sunxi_wdt_dev,
94 restart_handler);
95 void __iomem *wdt_base = sunxi_wdt->wdt_base; 89 void __iomem *wdt_base = sunxi_wdt->wdt_base;
96 const struct sunxi_wdt_reg *regs = sunxi_wdt->wdt_regs; 90 const struct sunxi_wdt_reg *regs = sunxi_wdt->wdt_regs;
97 u32 val; 91 u32 val;
@@ -120,7 +114,7 @@ static int sunxi_restart_handle(struct notifier_block *this, unsigned long mode,
120 val |= WDT_MODE_EN; 114 val |= WDT_MODE_EN;
121 writel(val, wdt_base + regs->wdt_mode); 115 writel(val, wdt_base + regs->wdt_mode);
122 } 116 }
123 return NOTIFY_DONE; 117 return 0;
124} 118}
125 119
126static int sunxi_wdt_ping(struct watchdog_device *wdt_dev) 120static int sunxi_wdt_ping(struct watchdog_device *wdt_dev)
@@ -208,6 +202,7 @@ static const struct watchdog_ops sunxi_wdt_ops = {
208 .stop = sunxi_wdt_stop, 202 .stop = sunxi_wdt_stop,
209 .ping = sunxi_wdt_ping, 203 .ping = sunxi_wdt_ping,
210 .set_timeout = sunxi_wdt_set_timeout, 204 .set_timeout = sunxi_wdt_set_timeout,
205 .restart = sunxi_wdt_restart,
211}; 206};
212 207
213static const struct sunxi_wdt_reg sun4i_wdt_reg = { 208static const struct sunxi_wdt_reg sun4i_wdt_reg = {
@@ -268,6 +263,7 @@ static int sunxi_wdt_probe(struct platform_device *pdev)
268 263
269 watchdog_init_timeout(&sunxi_wdt->wdt_dev, timeout, &pdev->dev); 264 watchdog_init_timeout(&sunxi_wdt->wdt_dev, timeout, &pdev->dev);
270 watchdog_set_nowayout(&sunxi_wdt->wdt_dev, nowayout); 265 watchdog_set_nowayout(&sunxi_wdt->wdt_dev, nowayout);
266 watchdog_set_restart_priority(&sunxi_wdt->wdt_dev, 128);
271 267
272 watchdog_set_drvdata(&sunxi_wdt->wdt_dev, sunxi_wdt); 268 watchdog_set_drvdata(&sunxi_wdt->wdt_dev, sunxi_wdt);
273 269
@@ -277,13 +273,6 @@ static int sunxi_wdt_probe(struct platform_device *pdev)
277 if (unlikely(err)) 273 if (unlikely(err))
278 return err; 274 return err;
279 275
280 sunxi_wdt->restart_handler.notifier_call = sunxi_restart_handle;
281 sunxi_wdt->restart_handler.priority = 128;
282 err = register_restart_handler(&sunxi_wdt->restart_handler);
283 if (err)
284 dev_err(&pdev->dev,
285 "cannot register restart handler (err=%d)\n", err);
286
287 dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)", 276 dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)",
288 sunxi_wdt->wdt_dev.timeout, nowayout); 277 sunxi_wdt->wdt_dev.timeout, nowayout);
289 278
@@ -294,8 +283,6 @@ static int sunxi_wdt_remove(struct platform_device *pdev)
294{ 283{
295 struct sunxi_wdt_dev *sunxi_wdt = platform_get_drvdata(pdev); 284 struct sunxi_wdt_dev *sunxi_wdt = platform_get_drvdata(pdev);
296 285
297 unregister_restart_handler(&sunxi_wdt->restart_handler);
298
299 watchdog_unregister_device(&sunxi_wdt->wdt_dev); 286 watchdog_unregister_device(&sunxi_wdt->wdt_dev);
300 watchdog_set_drvdata(&sunxi_wdt->wdt_dev, NULL); 287 watchdog_set_drvdata(&sunxi_wdt->wdt_dev, NULL);
301 288
diff --git a/drivers/watchdog/tangox_wdt.c b/drivers/watchdog/tangox_wdt.c
new file mode 100644
index 000000000000..709c1ed6fd79
--- /dev/null
+++ b/drivers/watchdog/tangox_wdt.c
@@ -0,0 +1,225 @@
1/*
2 * Copyright (C) 2015 Mans Rullgard <mans@mansr.com>
3 * SMP86xx/SMP87xx Watchdog driver
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#include <linux/bitops.h>
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/io.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/notifier.h>
19#include <linux/platform_device.h>
20#include <linux/reboot.h>
21#include <linux/watchdog.h>
22
23#define DEFAULT_TIMEOUT 30
24
25static bool nowayout = WATCHDOG_NOWAYOUT;
26module_param(nowayout, bool, 0);
27MODULE_PARM_DESC(nowayout,
28 "Watchdog cannot be stopped once started (default="
29 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
30
31static unsigned int timeout;
32module_param(timeout, int, 0);
33MODULE_PARM_DESC(timeout, "Watchdog timeout");
34
35/*
36 * Counter counts down from programmed value. Reset asserts when
37 * the counter reaches 1.
38 */
39#define WD_COUNTER 0
40
41#define WD_CONFIG 4
42#define WD_CONFIG_XTAL_IN BIT(0)
43#define WD_CONFIG_DISABLE BIT(31)
44
45struct tangox_wdt_device {
46 struct watchdog_device wdt;
47 void __iomem *base;
48 unsigned long clk_rate;
49 struct clk *clk;
50 struct notifier_block restart;
51};
52
53static int tangox_wdt_set_timeout(struct watchdog_device *wdt,
54 unsigned int new_timeout)
55{
56 wdt->timeout = new_timeout;
57
58 return 0;
59}
60
61static int tangox_wdt_start(struct watchdog_device *wdt)
62{
63 struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt);
64 u32 ticks;
65
66 ticks = 1 + wdt->timeout * dev->clk_rate;
67 writel(ticks, dev->base + WD_COUNTER);
68
69 return 0;
70}
71
72static int tangox_wdt_stop(struct watchdog_device *wdt)
73{
74 struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt);
75
76 writel(0, dev->base + WD_COUNTER);
77
78 return 0;
79}
80
81static unsigned int tangox_wdt_get_timeleft(struct watchdog_device *wdt)
82{
83 struct tangox_wdt_device *dev = watchdog_get_drvdata(wdt);
84 u32 count;
85
86 count = readl(dev->base + WD_COUNTER);
87
88 if (!count)
89 return 0;
90
91 return (count - 1) / dev->clk_rate;
92}
93
94static const struct watchdog_info tangox_wdt_info = {
95 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
96 .identity = "tangox watchdog",
97};
98
99static const struct watchdog_ops tangox_wdt_ops = {
100 .start = tangox_wdt_start,
101 .stop = tangox_wdt_stop,
102 .set_timeout = tangox_wdt_set_timeout,
103 .get_timeleft = tangox_wdt_get_timeleft,
104};
105
106static int tangox_wdt_restart(struct notifier_block *nb, unsigned long action,
107 void *data)
108{
109 struct tangox_wdt_device *dev =
110 container_of(nb, struct tangox_wdt_device, restart);
111
112 writel(1, dev->base + WD_COUNTER);
113
114 return NOTIFY_DONE;
115}
116
117static int tangox_wdt_probe(struct platform_device *pdev)
118{
119 struct tangox_wdt_device *dev;
120 struct resource *res;
121 u32 config;
122 int err;
123
124 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
125 if (!dev)
126 return -ENOMEM;
127
128 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
129 dev->base = devm_ioremap_resource(&pdev->dev, res);
130 if (IS_ERR(dev->base))
131 return PTR_ERR(dev->base);
132
133 dev->clk = devm_clk_get(&pdev->dev, NULL);
134 if (IS_ERR(dev->clk))
135 return PTR_ERR(dev->clk);
136
137 err = clk_prepare_enable(dev->clk);
138 if (err)
139 return err;
140
141 dev->clk_rate = clk_get_rate(dev->clk);
142
143 dev->wdt.parent = &pdev->dev;
144 dev->wdt.info = &tangox_wdt_info;
145 dev->wdt.ops = &tangox_wdt_ops;
146 dev->wdt.timeout = DEFAULT_TIMEOUT;
147 dev->wdt.min_timeout = 1;
148 dev->wdt.max_timeout = (U32_MAX - 1) / dev->clk_rate;
149
150 watchdog_init_timeout(&dev->wdt, timeout, &pdev->dev);
151 watchdog_set_nowayout(&dev->wdt, nowayout);
152 watchdog_set_drvdata(&dev->wdt, dev);
153
154 /*
155 * Deactivate counter if disable bit is set to avoid
156 * accidental reset.
157 */
158 config = readl(dev->base + WD_CONFIG);
159 if (config & WD_CONFIG_DISABLE)
160 writel(0, dev->base + WD_COUNTER);
161
162 writel(WD_CONFIG_XTAL_IN, dev->base + WD_CONFIG);
163
164 /*
165 * Mark as active and restart with configured timeout if
166 * already running.
167 */
168 if (readl(dev->base + WD_COUNTER)) {
169 set_bit(WDOG_ACTIVE, &dev->wdt.status);
170 tangox_wdt_start(&dev->wdt);
171 }
172
173 err = watchdog_register_device(&dev->wdt);
174 if (err) {
175 clk_disable_unprepare(dev->clk);
176 return err;
177 }
178
179 platform_set_drvdata(pdev, dev);
180
181 dev->restart.notifier_call = tangox_wdt_restart;
182 dev->restart.priority = 128;
183 err = register_restart_handler(&dev->restart);
184 if (err)
185 dev_warn(&pdev->dev, "failed to register restart handler\n");
186
187 dev_info(&pdev->dev, "SMP86xx/SMP87xx watchdog registered\n");
188
189 return 0;
190}
191
192static int tangox_wdt_remove(struct platform_device *pdev)
193{
194 struct tangox_wdt_device *dev = platform_get_drvdata(pdev);
195
196 tangox_wdt_stop(&dev->wdt);
197 clk_disable_unprepare(dev->clk);
198
199 unregister_restart_handler(&dev->restart);
200 watchdog_unregister_device(&dev->wdt);
201
202 return 0;
203}
204
205static const struct of_device_id tangox_wdt_dt_ids[] = {
206 { .compatible = "sigma,smp8642-wdt" },
207 { .compatible = "sigma,smp8759-wdt" },
208 { }
209};
210MODULE_DEVICE_TABLE(of, tangox_wdt_dt_ids);
211
212static struct platform_driver tangox_wdt_driver = {
213 .probe = tangox_wdt_probe,
214 .remove = tangox_wdt_remove,
215 .driver = {
216 .name = "tangox-wdt",
217 .of_match_table = tangox_wdt_dt_ids,
218 },
219};
220
221module_platform_driver(tangox_wdt_driver);
222
223MODULE_AUTHOR("Mans Rullgard <mans@mansr.com>");
224MODULE_DESCRIPTION("SMP86xx/SMP87xx Watchdog driver");
225MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/ts4800_wdt.c b/drivers/watchdog/ts4800_wdt.c
new file mode 100644
index 000000000000..2b8de8602b67
--- /dev/null
+++ b/drivers/watchdog/ts4800_wdt.c
@@ -0,0 +1,215 @@
1/*
2 * Watchdog driver for TS-4800 based boards
3 *
4 * Copyright (c) 2015 - Savoir-faire Linux
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/mfd/syscon.h>
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/platform_device.h>
16#include <linux/regmap.h>
17#include <linux/watchdog.h>
18
19static bool nowayout = WATCHDOG_NOWAYOUT;
20module_param(nowayout, bool, 0);
21MODULE_PARM_DESC(nowayout,
22 "Watchdog cannot be stopped once started (default="
23 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
24
25/* possible feed values */
26#define TS4800_WDT_FEED_2S 0x1
27#define TS4800_WDT_FEED_10S 0x2
28#define TS4800_WDT_DISABLE 0x3
29
30struct ts4800_wdt {
31 struct watchdog_device wdd;
32 struct regmap *regmap;
33 u32 feed_offset;
34 u32 feed_val;
35};
36
37/*
38 * TS-4800 supports the following timeout values:
39 *
40 * value desc
41 * ---------------------
42 * 0 feed for 338ms
43 * 1 feed for 2.706s
44 * 2 feed for 10.824s
45 * 3 disable watchdog
46 *
47 * Keep the regmap/timeout map ordered by timeout
48 */
49static const struct {
50 const int timeout;
51 const int regval;
52} ts4800_wdt_map[] = {
53 { 2, TS4800_WDT_FEED_2S },
54 { 10, TS4800_WDT_FEED_10S },
55};
56
57#define MAX_TIMEOUT_INDEX (ARRAY_SIZE(ts4800_wdt_map) - 1)
58
59static void ts4800_write_feed(struct ts4800_wdt *wdt, u32 val)
60{
61 regmap_write(wdt->regmap, wdt->feed_offset, val);
62}
63
64static int ts4800_wdt_start(struct watchdog_device *wdd)
65{
66 struct ts4800_wdt *wdt = watchdog_get_drvdata(wdd);
67
68 ts4800_write_feed(wdt, wdt->feed_val);
69 return 0;
70}
71
72static int ts4800_wdt_stop(struct watchdog_device *wdd)
73{
74 struct ts4800_wdt *wdt = watchdog_get_drvdata(wdd);
75
76 ts4800_write_feed(wdt, TS4800_WDT_DISABLE);
77 return 0;
78}
79
80static int ts4800_wdt_set_timeout(struct watchdog_device *wdd,
81 unsigned int timeout)
82{
83 struct ts4800_wdt *wdt = watchdog_get_drvdata(wdd);
84 int i;
85
86 for (i = 0; i < MAX_TIMEOUT_INDEX; i++) {
87 if (ts4800_wdt_map[i].timeout >= timeout)
88 break;
89 }
90
91 wdd->timeout = ts4800_wdt_map[i].timeout;
92 wdt->feed_val = ts4800_wdt_map[i].regval;
93
94 return 0;
95}
96
97static const struct watchdog_ops ts4800_wdt_ops = {
98 .owner = THIS_MODULE,
99 .start = ts4800_wdt_start,
100 .stop = ts4800_wdt_stop,
101 .set_timeout = ts4800_wdt_set_timeout,
102};
103
104static const struct watchdog_info ts4800_wdt_info = {
105 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
106 .identity = "TS-4800 Watchdog",
107};
108
109static int ts4800_wdt_probe(struct platform_device *pdev)
110{
111 struct device_node *np = pdev->dev.of_node;
112 struct device_node *syscon_np;
113 struct watchdog_device *wdd;
114 struct ts4800_wdt *wdt;
115 u32 reg;
116 int ret;
117
118 syscon_np = of_parse_phandle(np, "syscon", 0);
119 if (!syscon_np) {
120 dev_err(&pdev->dev, "no syscon property\n");
121 return -ENODEV;
122 }
123
124 ret = of_property_read_u32_index(np, "syscon", 1, &reg);
125 if (ret < 0) {
126 dev_err(&pdev->dev, "no offset in syscon\n");
127 return ret;
128 }
129
130 /* allocate memory for watchdog struct */
131 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
132 if (!wdt)
133 return -ENOMEM;
134
135 /* set regmap and offset to know where to write */
136 wdt->feed_offset = reg;
137 wdt->regmap = syscon_node_to_regmap(syscon_np);
138 if (IS_ERR(wdt->regmap)) {
139 dev_err(&pdev->dev, "cannot get parent's regmap\n");
140 return PTR_ERR(wdt->regmap);
141 }
142
143 /* Initialize struct watchdog_device */
144 wdd = &wdt->wdd;
145 wdd->parent = &pdev->dev;
146 wdd->info = &ts4800_wdt_info;
147 wdd->ops = &ts4800_wdt_ops;
148 wdd->min_timeout = ts4800_wdt_map[0].timeout;
149 wdd->max_timeout = ts4800_wdt_map[MAX_TIMEOUT_INDEX].timeout;
150
151 watchdog_set_drvdata(wdd, wdt);
152 watchdog_set_nowayout(wdd, nowayout);
153 watchdog_init_timeout(wdd, 0, &pdev->dev);
154
155 /*
156 * As this watchdog supports only a few values, ts4800_wdt_set_timeout
157 * must be called to initialize timeout and feed_val with valid values.
158 * Default to maximum timeout if none, or an invalid one, is provided in
159 * device tree.
160 */
161 if (!wdd->timeout)
162 wdd->timeout = wdd->max_timeout;
163 ts4800_wdt_set_timeout(wdd, wdd->timeout);
164
165 /*
166 * The feed register is write-only, so it is not possible to determine
167 * watchdog's state. Disable it to be in a known state.
168 */
169 ts4800_wdt_stop(wdd);
170
171 ret = watchdog_register_device(wdd);
172 if (ret) {
173 dev_err(&pdev->dev,
174 "failed to register watchdog device\n");
175 return ret;
176 }
177
178 platform_set_drvdata(pdev, wdt);
179
180 dev_info(&pdev->dev,
181 "initialized (timeout = %d sec, nowayout = %d)\n",
182 wdd->timeout, nowayout);
183
184 return 0;
185}
186
187static int ts4800_wdt_remove(struct platform_device *pdev)
188{
189 struct ts4800_wdt *wdt = platform_get_drvdata(pdev);
190
191 watchdog_unregister_device(&wdt->wdd);
192
193 return 0;
194}
195
196static const struct of_device_id ts4800_wdt_of_match[] = {
197 { .compatible = "technologic,ts4800-wdt", },
198 { },
199};
200MODULE_DEVICE_TABLE(of, ts4800_wdt_of_match);
201
202static struct platform_driver ts4800_wdt_driver = {
203 .probe = ts4800_wdt_probe,
204 .remove = ts4800_wdt_remove,
205 .driver = {
206 .name = "ts4800_wdt",
207 .of_match_table = ts4800_wdt_of_match,
208 },
209};
210
211module_platform_driver(ts4800_wdt_driver);
212
213MODULE_AUTHOR("Damien Riegel <damien.riegel@savoirfairelinux.com>");
214MODULE_LICENSE("GPL v2");
215MODULE_ALIAS("platform:ts4800_wdt");
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index 5824e25eebbb..cab14bc9106c 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -36,8 +36,6 @@
36#include <linux/types.h> 36#include <linux/types.h>
37#include <linux/watchdog.h> 37#include <linux/watchdog.h>
38#include <linux/ioport.h> 38#include <linux/ioport.h>
39#include <linux/notifier.h>
40#include <linux/reboot.h>
41#include <linux/init.h> 39#include <linux/init.h>
42#include <linux/io.h> 40#include <linux/io.h>
43 41
@@ -288,18 +286,6 @@ static unsigned int wdt_get_time(struct watchdog_device *wdog)
288} 286}
289 287
290/* 288/*
291 * Notifier for system down
292 */
293static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
294 void *unused)
295{
296 if (code == SYS_DOWN || code == SYS_HALT)
297 wdt_set_time(0); /* Turn the WDT off */
298
299 return NOTIFY_DONE;
300}
301
302/*
303 * Kernel Interfaces 289 * Kernel Interfaces
304 */ 290 */
305 291
@@ -329,10 +315,6 @@ static struct watchdog_device wdt_dev = {
329 * turn the timebomb registers off. 315 * turn the timebomb registers off.
330 */ 316 */
331 317
332static struct notifier_block wdt_notifier = {
333 .notifier_call = wdt_notify_sys,
334};
335
336static int wdt_find(int addr) 318static int wdt_find(int addr)
337{ 319{
338 u8 val; 320 u8 val;
@@ -456,6 +438,7 @@ static int __init wdt_init(void)
456 438
457 watchdog_init_timeout(&wdt_dev, timeout, NULL); 439 watchdog_init_timeout(&wdt_dev, timeout, NULL);
458 watchdog_set_nowayout(&wdt_dev, nowayout); 440 watchdog_set_nowayout(&wdt_dev, nowayout);
441 watchdog_stop_on_reboot(&wdt_dev);
459 442
460 ret = w83627hf_init(&wdt_dev, chip); 443 ret = w83627hf_init(&wdt_dev, chip);
461 if (ret) { 444 if (ret) {
@@ -463,30 +446,19 @@ static int __init wdt_init(void)
463 return ret; 446 return ret;
464 } 447 }
465 448
466 ret = register_reboot_notifier(&wdt_notifier);
467 if (ret != 0) {
468 pr_err("cannot register reboot notifier (err=%d)\n", ret);
469 return ret;
470 }
471
472 ret = watchdog_register_device(&wdt_dev); 449 ret = watchdog_register_device(&wdt_dev);
473 if (ret) 450 if (ret)
474 goto unreg_reboot; 451 return ret;
475 452
476 pr_info("initialized. timeout=%d sec (nowayout=%d)\n", 453 pr_info("initialized. timeout=%d sec (nowayout=%d)\n",
477 wdt_dev.timeout, nowayout); 454 wdt_dev.timeout, nowayout);
478 455
479 return ret; 456 return ret;
480
481unreg_reboot:
482 unregister_reboot_notifier(&wdt_notifier);
483 return ret;
484} 457}
485 458
486static void __exit wdt_exit(void) 459static void __exit wdt_exit(void)
487{ 460{
488 watchdog_unregister_device(&wdt_dev); 461 watchdog_unregister_device(&wdt_dev);
489 unregister_reboot_notifier(&wdt_notifier);
490} 462}
491 463
492module_init(wdt_init); 464module_init(wdt_init);
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
index 873f13972cf4..e600fd93b7de 100644
--- a/drivers/watchdog/watchdog_core.c
+++ b/drivers/watchdog/watchdog_core.c
@@ -32,6 +32,7 @@
32#include <linux/types.h> /* For standard types */ 32#include <linux/types.h> /* For standard types */
33#include <linux/errno.h> /* For the -ENODEV/... values */ 33#include <linux/errno.h> /* For the -ENODEV/... values */
34#include <linux/kernel.h> /* For printk/panic/... */ 34#include <linux/kernel.h> /* For printk/panic/... */
35#include <linux/reboot.h> /* For restart handler */
35#include <linux/watchdog.h> /* For watchdog specific items */ 36#include <linux/watchdog.h> /* For watchdog specific items */
36#include <linux/init.h> /* For __init/__exit/... */ 37#include <linux/init.h> /* For __init/__exit/... */
37#include <linux/idr.h> /* For ida_* macros */ 38#include <linux/idr.h> /* For ida_* macros */
@@ -41,7 +42,6 @@
41#include "watchdog_core.h" /* For watchdog_dev_register/... */ 42#include "watchdog_core.h" /* For watchdog_dev_register/... */
42 43
43static DEFINE_IDA(watchdog_ida); 44static DEFINE_IDA(watchdog_ida);
44static struct class *watchdog_class;
45 45
46/* 46/*
47 * Deferred Registration infrastructure. 47 * Deferred Registration infrastructure.
@@ -137,9 +137,63 @@ int watchdog_init_timeout(struct watchdog_device *wdd,
137} 137}
138EXPORT_SYMBOL_GPL(watchdog_init_timeout); 138EXPORT_SYMBOL_GPL(watchdog_init_timeout);
139 139
140static int watchdog_reboot_notifier(struct notifier_block *nb,
141 unsigned long code, void *data)
142{
143 struct watchdog_device *wdd = container_of(nb, struct watchdog_device,
144 reboot_nb);
145
146 if (code == SYS_DOWN || code == SYS_HALT) {
147 if (watchdog_active(wdd)) {
148 int ret;
149
150 ret = wdd->ops->stop(wdd);
151 if (ret)
152 return NOTIFY_BAD;
153 }
154 }
155
156 return NOTIFY_DONE;
157}
158
159static int watchdog_restart_notifier(struct notifier_block *nb,
160 unsigned long action, void *data)
161{
162 struct watchdog_device *wdd = container_of(nb, struct watchdog_device,
163 restart_nb);
164
165 int ret;
166
167 ret = wdd->ops->restart(wdd);
168 if (ret)
169 return NOTIFY_BAD;
170
171 return NOTIFY_DONE;
172}
173
174/**
175 * watchdog_set_restart_priority - Change priority of restart handler
176 * @wdd: watchdog device
177 * @priority: priority of the restart handler, should follow these guidelines:
178 * 0: use watchdog's restart function as last resort, has limited restart
179 * capabilies
180 * 128: default restart handler, use if no other handler is expected to be
181 * available and/or if restart is sufficient to restart the entire system
182 * 255: preempt all other handlers
183 *
184 * If a wdd->ops->restart function is provided when watchdog_register_device is
185 * called, it will be registered as a restart handler with the priority given
186 * here.
187 */
188void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority)
189{
190 wdd->restart_nb.priority = priority;
191}
192EXPORT_SYMBOL_GPL(watchdog_set_restart_priority);
193
140static int __watchdog_register_device(struct watchdog_device *wdd) 194static int __watchdog_register_device(struct watchdog_device *wdd)
141{ 195{
142 int ret, id = -1, devno; 196 int ret, id = -1;
143 197
144 if (wdd == NULL || wdd->info == NULL || wdd->ops == NULL) 198 if (wdd == NULL || wdd->info == NULL || wdd->ops == NULL)
145 return -EINVAL; 199 return -EINVAL;
@@ -156,8 +210,6 @@ static int __watchdog_register_device(struct watchdog_device *wdd)
156 * corrupted in a later stage then we expect a kernel panic! 210 * corrupted in a later stage then we expect a kernel panic!
157 */ 211 */
158 212
159 mutex_init(&wdd->lock);
160
161 /* Use alias for watchdog id if possible */ 213 /* Use alias for watchdog id if possible */
162 if (wdd->parent) { 214 if (wdd->parent) {
163 ret = of_alias_get_id(wdd->parent->of_node, "watchdog"); 215 ret = of_alias_get_id(wdd->parent->of_node, "watchdog");
@@ -192,14 +244,26 @@ static int __watchdog_register_device(struct watchdog_device *wdd)
192 } 244 }
193 } 245 }
194 246
195 devno = wdd->cdev.dev; 247 if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) {
196 wdd->dev = device_create(watchdog_class, wdd->parent, devno, 248 wdd->reboot_nb.notifier_call = watchdog_reboot_notifier;
197 NULL, "watchdog%d", wdd->id); 249
198 if (IS_ERR(wdd->dev)) { 250 ret = register_reboot_notifier(&wdd->reboot_nb);
199 watchdog_dev_unregister(wdd); 251 if (ret) {
200 ida_simple_remove(&watchdog_ida, id); 252 pr_err("watchdog%d: Cannot register reboot notifier (%d)\n",
201 ret = PTR_ERR(wdd->dev); 253 wdd->id, ret);
202 return ret; 254 watchdog_dev_unregister(wdd);
255 ida_simple_remove(&watchdog_ida, wdd->id);
256 return ret;
257 }
258 }
259
260 if (wdd->ops->restart) {
261 wdd->restart_nb.notifier_call = watchdog_restart_notifier;
262
263 ret = register_restart_handler(&wdd->restart_nb);
264 if (ret)
265 pr_warn("watchog%d: Cannot register restart handler (%d)\n",
266 wdd->id, ret);
203 } 267 }
204 268
205 return 0; 269 return 0;
@@ -232,19 +296,17 @@ EXPORT_SYMBOL_GPL(watchdog_register_device);
232 296
233static void __watchdog_unregister_device(struct watchdog_device *wdd) 297static void __watchdog_unregister_device(struct watchdog_device *wdd)
234{ 298{
235 int ret;
236 int devno;
237
238 if (wdd == NULL) 299 if (wdd == NULL)
239 return; 300 return;
240 301
241 devno = wdd->cdev.dev; 302 if (wdd->ops->restart)
242 ret = watchdog_dev_unregister(wdd); 303 unregister_restart_handler(&wdd->restart_nb);
243 if (ret) 304
244 pr_err("error unregistering /dev/watchdog (err=%d)\n", ret); 305 if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status))
245 device_destroy(watchdog_class, devno); 306 unregister_reboot_notifier(&wdd->reboot_nb);
307
308 watchdog_dev_unregister(wdd);
246 ida_simple_remove(&watchdog_ida, wdd->id); 309 ida_simple_remove(&watchdog_ida, wdd->id);
247 wdd->dev = NULL;
248} 310}
249 311
250/** 312/**
@@ -287,17 +349,9 @@ static int __init watchdog_init(void)
287{ 349{
288 int err; 350 int err;
289 351
290 watchdog_class = class_create(THIS_MODULE, "watchdog");
291 if (IS_ERR(watchdog_class)) {
292 pr_err("couldn't create class\n");
293 return PTR_ERR(watchdog_class);
294 }
295
296 err = watchdog_dev_init(); 352 err = watchdog_dev_init();
297 if (err < 0) { 353 if (err < 0)
298 class_destroy(watchdog_class);
299 return err; 354 return err;
300 }
301 355
302 watchdog_deferred_registration(); 356 watchdog_deferred_registration();
303 return 0; 357 return 0;
@@ -306,7 +360,6 @@ static int __init watchdog_init(void)
306static void __exit watchdog_exit(void) 360static void __exit watchdog_exit(void)
307{ 361{
308 watchdog_dev_exit(); 362 watchdog_dev_exit();
309 class_destroy(watchdog_class);
310 ida_destroy(&watchdog_ida); 363 ida_destroy(&watchdog_ida);
311} 364}
312 365
diff --git a/drivers/watchdog/watchdog_core.h b/drivers/watchdog/watchdog_core.h
index 6c951418fca7..86ff962d1e15 100644
--- a/drivers/watchdog/watchdog_core.h
+++ b/drivers/watchdog/watchdog_core.h
@@ -32,6 +32,6 @@
32 * Functions/procedures to be called by the core 32 * Functions/procedures to be called by the core
33 */ 33 */
34extern int watchdog_dev_register(struct watchdog_device *); 34extern int watchdog_dev_register(struct watchdog_device *);
35extern int watchdog_dev_unregister(struct watchdog_device *); 35extern void watchdog_dev_unregister(struct watchdog_device *);
36extern int __init watchdog_dev_init(void); 36extern int __init watchdog_dev_init(void);
37extern void __exit watchdog_dev_exit(void); 37extern void __exit watchdog_dev_exit(void);
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index 56a649e66eb2..ba2ecce4aae6 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -32,27 +32,51 @@
32 32
33#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 33#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
34 34
35#include <linux/module.h> /* For module stuff/... */ 35#include <linux/cdev.h> /* For character device */
36#include <linux/types.h> /* For standard types (like size_t) */
37#include <linux/errno.h> /* For the -ENODEV/... values */ 36#include <linux/errno.h> /* For the -ENODEV/... values */
38#include <linux/kernel.h> /* For printk/panic/... */
39#include <linux/fs.h> /* For file operations */ 37#include <linux/fs.h> /* For file operations */
40#include <linux/watchdog.h> /* For watchdog specific items */
41#include <linux/miscdevice.h> /* For handling misc devices */
42#include <linux/init.h> /* For __init/__exit/... */ 38#include <linux/init.h> /* For __init/__exit/... */
39#include <linux/kernel.h> /* For printk/panic/... */
40#include <linux/kref.h> /* For data references */
41#include <linux/miscdevice.h> /* For handling misc devices */
42#include <linux/module.h> /* For module stuff/... */
43#include <linux/mutex.h> /* For mutexes */
44#include <linux/slab.h> /* For memory functions */
45#include <linux/types.h> /* For standard types (like size_t) */
46#include <linux/watchdog.h> /* For watchdog specific items */
43#include <linux/uaccess.h> /* For copy_to_user/put_user/... */ 47#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
44 48
45#include "watchdog_core.h" 49#include "watchdog_core.h"
46 50
51/*
52 * struct watchdog_core_data - watchdog core internal data
53 * @kref: Reference count.
54 * @cdev: The watchdog's Character device.
55 * @wdd: Pointer to watchdog device.
56 * @lock: Lock for watchdog core.
57 * @status: Watchdog core internal status bits.
58 */
59struct watchdog_core_data {
60 struct kref kref;
61 struct cdev cdev;
62 struct watchdog_device *wdd;
63 struct mutex lock;
64 unsigned long status; /* Internal status bits */
65#define _WDOG_DEV_OPEN 0 /* Opened ? */
66#define _WDOG_ALLOW_RELEASE 1 /* Did we receive the magic char ? */
67};
68
47/* the dev_t structure to store the dynamically allocated watchdog devices */ 69/* the dev_t structure to store the dynamically allocated watchdog devices */
48static dev_t watchdog_devt; 70static dev_t watchdog_devt;
49/* the watchdog device behind /dev/watchdog */ 71/* Reference to watchdog device behind /dev/watchdog */
50static struct watchdog_device *old_wdd; 72static struct watchdog_core_data *old_wd_data;
51 73
52/* 74/*
53 * watchdog_ping: ping the watchdog. 75 * watchdog_ping: ping the watchdog.
54 * @wdd: the watchdog device to ping 76 * @wdd: the watchdog device to ping
55 * 77 *
78 * The caller must hold wd_data->lock.
79 *
56 * If the watchdog has no own ping operation then it needs to be 80 * If the watchdog has no own ping operation then it needs to be
57 * restarted via the start operation. This wrapper function does 81 * restarted via the start operation. This wrapper function does
58 * exactly that. 82 * exactly that.
@@ -61,25 +85,16 @@ static struct watchdog_device *old_wdd;
61 85
62static int watchdog_ping(struct watchdog_device *wdd) 86static int watchdog_ping(struct watchdog_device *wdd)
63{ 87{
64 int err = 0; 88 int err;
65
66 mutex_lock(&wdd->lock);
67
68 if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
69 err = -ENODEV;
70 goto out_ping;
71 }
72 89
73 if (!watchdog_active(wdd)) 90 if (!watchdog_active(wdd))
74 goto out_ping; 91 return 0;
75 92
76 if (wdd->ops->ping) 93 if (wdd->ops->ping)
77 err = wdd->ops->ping(wdd); /* ping the watchdog */ 94 err = wdd->ops->ping(wdd); /* ping the watchdog */
78 else 95 else
79 err = wdd->ops->start(wdd); /* restart watchdog */ 96 err = wdd->ops->start(wdd); /* restart watchdog */
80 97
81out_ping:
82 mutex_unlock(&wdd->lock);
83 return err; 98 return err;
84} 99}
85 100
@@ -87,6 +102,8 @@ out_ping:
87 * watchdog_start: wrapper to start the watchdog. 102 * watchdog_start: wrapper to start the watchdog.
88 * @wdd: the watchdog device to start 103 * @wdd: the watchdog device to start
89 * 104 *
105 * The caller must hold wd_data->lock.
106 *
90 * Start the watchdog if it is not active and mark it active. 107 * Start the watchdog if it is not active and mark it active.
91 * This function returns zero on success or a negative errno code for 108 * This function returns zero on success or a negative errno code for
92 * failure. 109 * failure.
@@ -94,24 +111,15 @@ out_ping:
94 111
95static int watchdog_start(struct watchdog_device *wdd) 112static int watchdog_start(struct watchdog_device *wdd)
96{ 113{
97 int err = 0; 114 int err;
98
99 mutex_lock(&wdd->lock);
100
101 if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
102 err = -ENODEV;
103 goto out_start;
104 }
105 115
106 if (watchdog_active(wdd)) 116 if (watchdog_active(wdd))
107 goto out_start; 117 return 0;
108 118
109 err = wdd->ops->start(wdd); 119 err = wdd->ops->start(wdd);
110 if (err == 0) 120 if (err == 0)
111 set_bit(WDOG_ACTIVE, &wdd->status); 121 set_bit(WDOG_ACTIVE, &wdd->status);
112 122
113out_start:
114 mutex_unlock(&wdd->lock);
115 return err; 123 return err;
116} 124}
117 125
@@ -119,6 +127,8 @@ out_start:
119 * watchdog_stop: wrapper to stop the watchdog. 127 * watchdog_stop: wrapper to stop the watchdog.
120 * @wdd: the watchdog device to stop 128 * @wdd: the watchdog device to stop
121 * 129 *
130 * The caller must hold wd_data->lock.
131 *
122 * Stop the watchdog if it is still active and unmark it active. 132 * Stop the watchdog if it is still active and unmark it active.
123 * This function returns zero on success or a negative errno code for 133 * This function returns zero on success or a negative errno code for
124 * failure. 134 * failure.
@@ -127,93 +137,59 @@ out_start:
127 137
128static int watchdog_stop(struct watchdog_device *wdd) 138static int watchdog_stop(struct watchdog_device *wdd)
129{ 139{
130 int err = 0; 140 int err;
131
132 mutex_lock(&wdd->lock);
133
134 if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
135 err = -ENODEV;
136 goto out_stop;
137 }
138 141
139 if (!watchdog_active(wdd)) 142 if (!watchdog_active(wdd))
140 goto out_stop; 143 return 0;
141 144
142 if (test_bit(WDOG_NO_WAY_OUT, &wdd->status)) { 145 if (test_bit(WDOG_NO_WAY_OUT, &wdd->status)) {
143 dev_info(wdd->dev, "nowayout prevents watchdog being stopped!\n"); 146 pr_info("watchdog%d: nowayout prevents watchdog being stopped!\n",
144 err = -EBUSY; 147 wdd->id);
145 goto out_stop; 148 return -EBUSY;
146 } 149 }
147 150
148 err = wdd->ops->stop(wdd); 151 err = wdd->ops->stop(wdd);
149 if (err == 0) 152 if (err == 0)
150 clear_bit(WDOG_ACTIVE, &wdd->status); 153 clear_bit(WDOG_ACTIVE, &wdd->status);
151 154
152out_stop:
153 mutex_unlock(&wdd->lock);
154 return err; 155 return err;
155} 156}
156 157
157/* 158/*
158 * watchdog_get_status: wrapper to get the watchdog status 159 * watchdog_get_status: wrapper to get the watchdog status
159 * @wdd: the watchdog device to get the status from 160 * @wdd: the watchdog device to get the status from
160 * @status: the status of the watchdog device 161 *
162 * The caller must hold wd_data->lock.
161 * 163 *
162 * Get the watchdog's status flags. 164 * Get the watchdog's status flags.
163 */ 165 */
164 166
165static int watchdog_get_status(struct watchdog_device *wdd, 167static unsigned int watchdog_get_status(struct watchdog_device *wdd)
166 unsigned int *status)
167{ 168{
168 int err = 0;
169
170 *status = 0;
171 if (!wdd->ops->status) 169 if (!wdd->ops->status)
172 return -EOPNOTSUPP; 170 return 0;
173
174 mutex_lock(&wdd->lock);
175
176 if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
177 err = -ENODEV;
178 goto out_status;
179 }
180
181 *status = wdd->ops->status(wdd);
182 171
183out_status: 172 return wdd->ops->status(wdd);
184 mutex_unlock(&wdd->lock);
185 return err;
186} 173}
187 174
188/* 175/*
189 * watchdog_set_timeout: set the watchdog timer timeout 176 * watchdog_set_timeout: set the watchdog timer timeout
190 * @wdd: the watchdog device to set the timeout for 177 * @wdd: the watchdog device to set the timeout for
191 * @timeout: timeout to set in seconds 178 * @timeout: timeout to set in seconds
179 *
180 * The caller must hold wd_data->lock.
192 */ 181 */
193 182
194static int watchdog_set_timeout(struct watchdog_device *wdd, 183static int watchdog_set_timeout(struct watchdog_device *wdd,
195 unsigned int timeout) 184 unsigned int timeout)
196{ 185{
197 int err;
198
199 if (!wdd->ops->set_timeout || !(wdd->info->options & WDIOF_SETTIMEOUT)) 186 if (!wdd->ops->set_timeout || !(wdd->info->options & WDIOF_SETTIMEOUT))
200 return -EOPNOTSUPP; 187 return -EOPNOTSUPP;
201 188
202 if (watchdog_timeout_invalid(wdd, timeout)) 189 if (watchdog_timeout_invalid(wdd, timeout))
203 return -EINVAL; 190 return -EINVAL;
204 191
205 mutex_lock(&wdd->lock); 192 return wdd->ops->set_timeout(wdd, timeout);
206
207 if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
208 err = -ENODEV;
209 goto out_timeout;
210 }
211
212 err = wdd->ops->set_timeout(wdd, timeout);
213
214out_timeout:
215 mutex_unlock(&wdd->lock);
216 return err;
217} 193}
218 194
219/* 195/*
@@ -221,59 +197,156 @@ out_timeout:
221 * @wdd: the watchdog device to get the remaining time from 197 * @wdd: the watchdog device to get the remaining time from
222 * @timeleft: the time that's left 198 * @timeleft: the time that's left
223 * 199 *
200 * The caller must hold wd_data->lock.
201 *
224 * Get the time before a watchdog will reboot (if not pinged). 202 * Get the time before a watchdog will reboot (if not pinged).
225 */ 203 */
226 204
227static int watchdog_get_timeleft(struct watchdog_device *wdd, 205static int watchdog_get_timeleft(struct watchdog_device *wdd,
228 unsigned int *timeleft) 206 unsigned int *timeleft)
229{ 207{
230 int err = 0;
231
232 *timeleft = 0; 208 *timeleft = 0;
209
233 if (!wdd->ops->get_timeleft) 210 if (!wdd->ops->get_timeleft)
234 return -EOPNOTSUPP; 211 return -EOPNOTSUPP;
235 212
236 mutex_lock(&wdd->lock); 213 *timeleft = wdd->ops->get_timeleft(wdd);
237 214
238 if (test_bit(WDOG_UNREGISTERED, &wdd->status)) { 215 return 0;
239 err = -ENODEV; 216}
240 goto out_timeleft;
241 }
242 217
243 *timeleft = wdd->ops->get_timeleft(wdd); 218#ifdef CONFIG_WATCHDOG_SYSFS
219static ssize_t nowayout_show(struct device *dev, struct device_attribute *attr,
220 char *buf)
221{
222 struct watchdog_device *wdd = dev_get_drvdata(dev);
244 223
245out_timeleft: 224 return sprintf(buf, "%d\n", !!test_bit(WDOG_NO_WAY_OUT, &wdd->status));
246 mutex_unlock(&wdd->lock); 225}
247 return err; 226static DEVICE_ATTR_RO(nowayout);
227
228static ssize_t status_show(struct device *dev, struct device_attribute *attr,
229 char *buf)
230{
231 struct watchdog_device *wdd = dev_get_drvdata(dev);
232 struct watchdog_core_data *wd_data = wdd->wd_data;
233 unsigned int status;
234
235 mutex_lock(&wd_data->lock);
236 status = watchdog_get_status(wdd);
237 mutex_unlock(&wd_data->lock);
238
239 return sprintf(buf, "%u\n", status);
240}
241static DEVICE_ATTR_RO(status);
242
243static ssize_t bootstatus_show(struct device *dev,
244 struct device_attribute *attr, char *buf)
245{
246 struct watchdog_device *wdd = dev_get_drvdata(dev);
247
248 return sprintf(buf, "%u\n", wdd->bootstatus);
249}
250static DEVICE_ATTR_RO(bootstatus);
251
252static ssize_t timeleft_show(struct device *dev, struct device_attribute *attr,
253 char *buf)
254{
255 struct watchdog_device *wdd = dev_get_drvdata(dev);
256 struct watchdog_core_data *wd_data = wdd->wd_data;
257 ssize_t status;
258 unsigned int val;
259
260 mutex_lock(&wd_data->lock);
261 status = watchdog_get_timeleft(wdd, &val);
262 mutex_unlock(&wd_data->lock);
263 if (!status)
264 status = sprintf(buf, "%u\n", val);
265
266 return status;
248} 267}
268static DEVICE_ATTR_RO(timeleft);
269
270static ssize_t timeout_show(struct device *dev, struct device_attribute *attr,
271 char *buf)
272{
273 struct watchdog_device *wdd = dev_get_drvdata(dev);
274
275 return sprintf(buf, "%u\n", wdd->timeout);
276}
277static DEVICE_ATTR_RO(timeout);
278
279static ssize_t identity_show(struct device *dev, struct device_attribute *attr,
280 char *buf)
281{
282 struct watchdog_device *wdd = dev_get_drvdata(dev);
283
284 return sprintf(buf, "%s\n", wdd->info->identity);
285}
286static DEVICE_ATTR_RO(identity);
287
288static ssize_t state_show(struct device *dev, struct device_attribute *attr,
289 char *buf)
290{
291 struct watchdog_device *wdd = dev_get_drvdata(dev);
292
293 if (watchdog_active(wdd))
294 return sprintf(buf, "active\n");
295
296 return sprintf(buf, "inactive\n");
297}
298static DEVICE_ATTR_RO(state);
299
300static umode_t wdt_is_visible(struct kobject *kobj, struct attribute *attr,
301 int n)
302{
303 struct device *dev = container_of(kobj, struct device, kobj);
304 struct watchdog_device *wdd = dev_get_drvdata(dev);
305 umode_t mode = attr->mode;
306
307 if (attr == &dev_attr_status.attr && !wdd->ops->status)
308 mode = 0;
309 else if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft)
310 mode = 0;
311
312 return mode;
313}
314static struct attribute *wdt_attrs[] = {
315 &dev_attr_state.attr,
316 &dev_attr_identity.attr,
317 &dev_attr_timeout.attr,
318 &dev_attr_timeleft.attr,
319 &dev_attr_bootstatus.attr,
320 &dev_attr_status.attr,
321 &dev_attr_nowayout.attr,
322 NULL,
323};
324
325static const struct attribute_group wdt_group = {
326 .attrs = wdt_attrs,
327 .is_visible = wdt_is_visible,
328};
329__ATTRIBUTE_GROUPS(wdt);
330#else
331#define wdt_groups NULL
332#endif
249 333
250/* 334/*
251 * watchdog_ioctl_op: call the watchdog drivers ioctl op if defined 335 * watchdog_ioctl_op: call the watchdog drivers ioctl op if defined
252 * @wdd: the watchdog device to do the ioctl on 336 * @wdd: the watchdog device to do the ioctl on
253 * @cmd: watchdog command 337 * @cmd: watchdog command
254 * @arg: argument pointer 338 * @arg: argument pointer
339 *
340 * The caller must hold wd_data->lock.
255 */ 341 */
256 342
257static int watchdog_ioctl_op(struct watchdog_device *wdd, unsigned int cmd, 343static int watchdog_ioctl_op(struct watchdog_device *wdd, unsigned int cmd,
258 unsigned long arg) 344 unsigned long arg)
259{ 345{
260 int err;
261
262 if (!wdd->ops->ioctl) 346 if (!wdd->ops->ioctl)
263 return -ENOIOCTLCMD; 347 return -ENOIOCTLCMD;
264 348
265 mutex_lock(&wdd->lock); 349 return wdd->ops->ioctl(wdd, cmd, arg);
266
267 if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
268 err = -ENODEV;
269 goto out_ioctl;
270 }
271
272 err = wdd->ops->ioctl(wdd, cmd, arg);
273
274out_ioctl:
275 mutex_unlock(&wdd->lock);
276 return err;
277} 350}
278 351
279/* 352/*
@@ -291,10 +364,11 @@ out_ioctl:
291static ssize_t watchdog_write(struct file *file, const char __user *data, 364static ssize_t watchdog_write(struct file *file, const char __user *data,
292 size_t len, loff_t *ppos) 365 size_t len, loff_t *ppos)
293{ 366{
294 struct watchdog_device *wdd = file->private_data; 367 struct watchdog_core_data *wd_data = file->private_data;
368 struct watchdog_device *wdd;
369 int err;
295 size_t i; 370 size_t i;
296 char c; 371 char c;
297 int err;
298 372
299 if (len == 0) 373 if (len == 0)
300 return 0; 374 return 0;
@@ -303,18 +377,25 @@ static ssize_t watchdog_write(struct file *file, const char __user *data,
303 * Note: just in case someone wrote the magic character 377 * Note: just in case someone wrote the magic character
304 * five months ago... 378 * five months ago...
305 */ 379 */
306 clear_bit(WDOG_ALLOW_RELEASE, &wdd->status); 380 clear_bit(_WDOG_ALLOW_RELEASE, &wd_data->status);
307 381
308 /* scan to see whether or not we got the magic character */ 382 /* scan to see whether or not we got the magic character */
309 for (i = 0; i != len; i++) { 383 for (i = 0; i != len; i++) {
310 if (get_user(c, data + i)) 384 if (get_user(c, data + i))
311 return -EFAULT; 385 return -EFAULT;
312 if (c == 'V') 386 if (c == 'V')
313 set_bit(WDOG_ALLOW_RELEASE, &wdd->status); 387 set_bit(_WDOG_ALLOW_RELEASE, &wd_data->status);
314 } 388 }
315 389
316 /* someone wrote to us, so we send the watchdog a keepalive ping */ 390 /* someone wrote to us, so we send the watchdog a keepalive ping */
317 err = watchdog_ping(wdd); 391
392 err = -ENODEV;
393 mutex_lock(&wd_data->lock);
394 wdd = wd_data->wdd;
395 if (wdd)
396 err = watchdog_ping(wdd);
397 mutex_unlock(&wd_data->lock);
398
318 if (err < 0) 399 if (err < 0)
319 return err; 400 return err;
320 401
@@ -334,71 +415,94 @@ static ssize_t watchdog_write(struct file *file, const char __user *data,
334static long watchdog_ioctl(struct file *file, unsigned int cmd, 415static long watchdog_ioctl(struct file *file, unsigned int cmd,
335 unsigned long arg) 416 unsigned long arg)
336{ 417{
337 struct watchdog_device *wdd = file->private_data; 418 struct watchdog_core_data *wd_data = file->private_data;
338 void __user *argp = (void __user *)arg; 419 void __user *argp = (void __user *)arg;
420 struct watchdog_device *wdd;
339 int __user *p = argp; 421 int __user *p = argp;
340 unsigned int val; 422 unsigned int val;
341 int err; 423 int err;
342 424
425 mutex_lock(&wd_data->lock);
426
427 wdd = wd_data->wdd;
428 if (!wdd) {
429 err = -ENODEV;
430 goto out_ioctl;
431 }
432
343 err = watchdog_ioctl_op(wdd, cmd, arg); 433 err = watchdog_ioctl_op(wdd, cmd, arg);
344 if (err != -ENOIOCTLCMD) 434 if (err != -ENOIOCTLCMD)
345 return err; 435 goto out_ioctl;
346 436
347 switch (cmd) { 437 switch (cmd) {
348 case WDIOC_GETSUPPORT: 438 case WDIOC_GETSUPPORT:
349 return copy_to_user(argp, wdd->info, 439 err = copy_to_user(argp, wdd->info,
350 sizeof(struct watchdog_info)) ? -EFAULT : 0; 440 sizeof(struct watchdog_info)) ? -EFAULT : 0;
441 break;
351 case WDIOC_GETSTATUS: 442 case WDIOC_GETSTATUS:
352 err = watchdog_get_status(wdd, &val); 443 val = watchdog_get_status(wdd);
353 if (err == -ENODEV) 444 err = put_user(val, p);
354 return err; 445 break;
355 return put_user(val, p);
356 case WDIOC_GETBOOTSTATUS: 446 case WDIOC_GETBOOTSTATUS:
357 return put_user(wdd->bootstatus, p); 447 err = put_user(wdd->bootstatus, p);
448 break;
358 case WDIOC_SETOPTIONS: 449 case WDIOC_SETOPTIONS:
359 if (get_user(val, p)) 450 if (get_user(val, p)) {
360 return -EFAULT; 451 err = -EFAULT;
452 break;
453 }
361 if (val & WDIOS_DISABLECARD) { 454 if (val & WDIOS_DISABLECARD) {
362 err = watchdog_stop(wdd); 455 err = watchdog_stop(wdd);
363 if (err < 0) 456 if (err < 0)
364 return err; 457 break;
365 } 458 }
366 if (val & WDIOS_ENABLECARD) { 459 if (val & WDIOS_ENABLECARD)
367 err = watchdog_start(wdd); 460 err = watchdog_start(wdd);
368 if (err < 0) 461 break;
369 return err;
370 }
371 return 0;
372 case WDIOC_KEEPALIVE: 462 case WDIOC_KEEPALIVE:
373 if (!(wdd->info->options & WDIOF_KEEPALIVEPING)) 463 if (!(wdd->info->options & WDIOF_KEEPALIVEPING)) {
374 return -EOPNOTSUPP; 464 err = -EOPNOTSUPP;
375 return watchdog_ping(wdd); 465 break;
466 }
467 err = watchdog_ping(wdd);
468 break;
376 case WDIOC_SETTIMEOUT: 469 case WDIOC_SETTIMEOUT:
377 if (get_user(val, p)) 470 if (get_user(val, p)) {
378 return -EFAULT; 471 err = -EFAULT;
472 break;
473 }
379 err = watchdog_set_timeout(wdd, val); 474 err = watchdog_set_timeout(wdd, val);
380 if (err < 0) 475 if (err < 0)
381 return err; 476 break;
382 /* If the watchdog is active then we send a keepalive ping 477 /* If the watchdog is active then we send a keepalive ping
383 * to make sure that the watchdog keep's running (and if 478 * to make sure that the watchdog keep's running (and if
384 * possible that it takes the new timeout) */ 479 * possible that it takes the new timeout) */
385 err = watchdog_ping(wdd); 480 err = watchdog_ping(wdd);
386 if (err < 0) 481 if (err < 0)
387 return err; 482 break;
388 /* Fall */ 483 /* Fall */
389 case WDIOC_GETTIMEOUT: 484 case WDIOC_GETTIMEOUT:
390 /* timeout == 0 means that we don't know the timeout */ 485 /* timeout == 0 means that we don't know the timeout */
391 if (wdd->timeout == 0) 486 if (wdd->timeout == 0) {
392 return -EOPNOTSUPP; 487 err = -EOPNOTSUPP;
393 return put_user(wdd->timeout, p); 488 break;
489 }
490 err = put_user(wdd->timeout, p);
491 break;
394 case WDIOC_GETTIMELEFT: 492 case WDIOC_GETTIMELEFT:
395 err = watchdog_get_timeleft(wdd, &val); 493 err = watchdog_get_timeleft(wdd, &val);
396 if (err) 494 if (err < 0)
397 return err; 495 break;
398 return put_user(val, p); 496 err = put_user(val, p);
497 break;
399 default: 498 default:
400 return -ENOTTY; 499 err = -ENOTTY;
500 break;
401 } 501 }
502
503out_ioctl:
504 mutex_unlock(&wd_data->lock);
505 return err;
402} 506}
403 507
404/* 508/*
@@ -413,45 +517,59 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
413 517
414static int watchdog_open(struct inode *inode, struct file *file) 518static int watchdog_open(struct inode *inode, struct file *file)
415{ 519{
416 int err = -EBUSY; 520 struct watchdog_core_data *wd_data;
417 struct watchdog_device *wdd; 521 struct watchdog_device *wdd;
522 int err;
418 523
419 /* Get the corresponding watchdog device */ 524 /* Get the corresponding watchdog device */
420 if (imajor(inode) == MISC_MAJOR) 525 if (imajor(inode) == MISC_MAJOR)
421 wdd = old_wdd; 526 wd_data = old_wd_data;
422 else 527 else
423 wdd = container_of(inode->i_cdev, struct watchdog_device, cdev); 528 wd_data = container_of(inode->i_cdev, struct watchdog_core_data,
529 cdev);
424 530
425 /* the watchdog is single open! */ 531 /* the watchdog is single open! */
426 if (test_and_set_bit(WDOG_DEV_OPEN, &wdd->status)) 532 if (test_and_set_bit(_WDOG_DEV_OPEN, &wd_data->status))
427 return -EBUSY; 533 return -EBUSY;
428 534
535 wdd = wd_data->wdd;
536
429 /* 537 /*
430 * If the /dev/watchdog device is open, we don't want the module 538 * If the /dev/watchdog device is open, we don't want the module
431 * to be unloaded. 539 * to be unloaded.
432 */ 540 */
433 if (!try_module_get(wdd->ops->owner)) 541 if (!try_module_get(wdd->ops->owner)) {
434 goto out; 542 err = -EBUSY;
543 goto out_clear;
544 }
435 545
436 err = watchdog_start(wdd); 546 err = watchdog_start(wdd);
437 if (err < 0) 547 if (err < 0)
438 goto out_mod; 548 goto out_mod;
439 549
440 file->private_data = wdd; 550 file->private_data = wd_data;
441 551
442 if (wdd->ops->ref) 552 kref_get(&wd_data->kref);
443 wdd->ops->ref(wdd);
444 553
445 /* dev/watchdog is a virtual (and thus non-seekable) filesystem */ 554 /* dev/watchdog is a virtual (and thus non-seekable) filesystem */
446 return nonseekable_open(inode, file); 555 return nonseekable_open(inode, file);
447 556
448out_mod: 557out_mod:
449 module_put(wdd->ops->owner); 558 module_put(wd_data->wdd->ops->owner);
450out: 559out_clear:
451 clear_bit(WDOG_DEV_OPEN, &wdd->status); 560 clear_bit(_WDOG_DEV_OPEN, &wd_data->status);
452 return err; 561 return err;
453} 562}
454 563
564static void watchdog_core_data_release(struct kref *kref)
565{
566 struct watchdog_core_data *wd_data;
567
568 wd_data = container_of(kref, struct watchdog_core_data, kref);
569
570 kfree(wd_data);
571}
572
455/* 573/*
456 * watchdog_release: release the watchdog device. 574 * watchdog_release: release the watchdog device.
457 * @inode: inode of device 575 * @inode: inode of device
@@ -464,9 +582,16 @@ out:
464 582
465static int watchdog_release(struct inode *inode, struct file *file) 583static int watchdog_release(struct inode *inode, struct file *file)
466{ 584{
467 struct watchdog_device *wdd = file->private_data; 585 struct watchdog_core_data *wd_data = file->private_data;
586 struct watchdog_device *wdd;
468 int err = -EBUSY; 587 int err = -EBUSY;
469 588
589 mutex_lock(&wd_data->lock);
590
591 wdd = wd_data->wdd;
592 if (!wdd)
593 goto done;
594
470 /* 595 /*
471 * We only stop the watchdog if we received the magic character 596 * We only stop the watchdog if we received the magic character
472 * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then 597 * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then
@@ -474,29 +599,24 @@ static int watchdog_release(struct inode *inode, struct file *file)
474 */ 599 */
475 if (!test_bit(WDOG_ACTIVE, &wdd->status)) 600 if (!test_bit(WDOG_ACTIVE, &wdd->status))
476 err = 0; 601 err = 0;
477 else if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) || 602 else if (test_and_clear_bit(_WDOG_ALLOW_RELEASE, &wd_data->status) ||
478 !(wdd->info->options & WDIOF_MAGICCLOSE)) 603 !(wdd->info->options & WDIOF_MAGICCLOSE))
479 err = watchdog_stop(wdd); 604 err = watchdog_stop(wdd);
480 605
481 /* If the watchdog was not stopped, send a keepalive ping */ 606 /* If the watchdog was not stopped, send a keepalive ping */
482 if (err < 0) { 607 if (err < 0) {
483 mutex_lock(&wdd->lock); 608 pr_crit("watchdog%d: watchdog did not stop!\n", wdd->id);
484 if (!test_bit(WDOG_UNREGISTERED, &wdd->status))
485 dev_crit(wdd->dev, "watchdog did not stop!\n");
486 mutex_unlock(&wdd->lock);
487 watchdog_ping(wdd); 609 watchdog_ping(wdd);
488 } 610 }
489 611
490 /* Allow the owner module to be unloaded again */
491 module_put(wdd->ops->owner);
492
493 /* make sure that /dev/watchdog can be re-opened */ 612 /* make sure that /dev/watchdog can be re-opened */
494 clear_bit(WDOG_DEV_OPEN, &wdd->status); 613 clear_bit(_WDOG_DEV_OPEN, &wd_data->status);
495
496 /* Note wdd may be gone after this, do not use after this! */
497 if (wdd->ops->unref)
498 wdd->ops->unref(wdd);
499 614
615done:
616 mutex_unlock(&wd_data->lock);
617 /* Allow the owner module to be unloaded again */
618 module_put(wd_data->cdev.owner);
619 kref_put(&wd_data->kref, watchdog_core_data_release);
500 return 0; 620 return 0;
501} 621}
502 622
@@ -515,20 +635,31 @@ static struct miscdevice watchdog_miscdev = {
515}; 635};
516 636
517/* 637/*
518 * watchdog_dev_register: register a watchdog device 638 * watchdog_cdev_register: register watchdog character device
519 * @wdd: watchdog device 639 * @wdd: watchdog device
640 * @devno: character device number
520 * 641 *
521 * Register a watchdog device including handling the legacy 642 * Register a watchdog character device including handling the legacy
522 * /dev/watchdog node. /dev/watchdog is actually a miscdevice and 643 * /dev/watchdog node. /dev/watchdog is actually a miscdevice and
523 * thus we set it up like that. 644 * thus we set it up like that.
524 */ 645 */
525 646
526int watchdog_dev_register(struct watchdog_device *wdd) 647static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
527{ 648{
528 int err, devno; 649 struct watchdog_core_data *wd_data;
650 int err;
651
652 wd_data = kzalloc(sizeof(struct watchdog_core_data), GFP_KERNEL);
653 if (!wd_data)
654 return -ENOMEM;
655 kref_init(&wd_data->kref);
656 mutex_init(&wd_data->lock);
657
658 wd_data->wdd = wdd;
659 wdd->wd_data = wd_data;
529 660
530 if (wdd->id == 0) { 661 if (wdd->id == 0) {
531 old_wdd = wdd; 662 old_wd_data = wd_data;
532 watchdog_miscdev.parent = wdd->parent; 663 watchdog_miscdev.parent = wdd->parent;
533 err = misc_register(&watchdog_miscdev); 664 err = misc_register(&watchdog_miscdev);
534 if (err != 0) { 665 if (err != 0) {
@@ -537,48 +668,106 @@ int watchdog_dev_register(struct watchdog_device *wdd)
537 if (err == -EBUSY) 668 if (err == -EBUSY)
538 pr_err("%s: a legacy watchdog module is probably present.\n", 669 pr_err("%s: a legacy watchdog module is probably present.\n",
539 wdd->info->identity); 670 wdd->info->identity);
540 old_wdd = NULL; 671 old_wd_data = NULL;
672 kfree(wd_data);
541 return err; 673 return err;
542 } 674 }
543 } 675 }
544 676
545 /* Fill in the data structures */ 677 /* Fill in the data structures */
546 devno = MKDEV(MAJOR(watchdog_devt), wdd->id); 678 cdev_init(&wd_data->cdev, &watchdog_fops);
547 cdev_init(&wdd->cdev, &watchdog_fops); 679 wd_data->cdev.owner = wdd->ops->owner;
548 wdd->cdev.owner = wdd->ops->owner;
549 680
550 /* Add the device */ 681 /* Add the device */
551 err = cdev_add(&wdd->cdev, devno, 1); 682 err = cdev_add(&wd_data->cdev, devno, 1);
552 if (err) { 683 if (err) {
553 pr_err("watchdog%d unable to add device %d:%d\n", 684 pr_err("watchdog%d unable to add device %d:%d\n",
554 wdd->id, MAJOR(watchdog_devt), wdd->id); 685 wdd->id, MAJOR(watchdog_devt), wdd->id);
555 if (wdd->id == 0) { 686 if (wdd->id == 0) {
556 misc_deregister(&watchdog_miscdev); 687 misc_deregister(&watchdog_miscdev);
557 old_wdd = NULL; 688 old_wd_data = NULL;
689 kref_put(&wd_data->kref, watchdog_core_data_release);
558 } 690 }
559 } 691 }
560 return err; 692 return err;
561} 693}
562 694
563/* 695/*
564 * watchdog_dev_unregister: unregister a watchdog device 696 * watchdog_cdev_unregister: unregister watchdog character device
565 * @watchdog: watchdog device 697 * @watchdog: watchdog device
566 * 698 *
567 * Unregister the watchdog and if needed the legacy /dev/watchdog device. 699 * Unregister watchdog character device and if needed the legacy
700 * /dev/watchdog device.
568 */ 701 */
569 702
570int watchdog_dev_unregister(struct watchdog_device *wdd) 703static void watchdog_cdev_unregister(struct watchdog_device *wdd)
571{ 704{
572 mutex_lock(&wdd->lock); 705 struct watchdog_core_data *wd_data = wdd->wd_data;
573 set_bit(WDOG_UNREGISTERED, &wdd->status);
574 mutex_unlock(&wdd->lock);
575 706
576 cdev_del(&wdd->cdev); 707 cdev_del(&wd_data->cdev);
577 if (wdd->id == 0) { 708 if (wdd->id == 0) {
578 misc_deregister(&watchdog_miscdev); 709 misc_deregister(&watchdog_miscdev);
579 old_wdd = NULL; 710 old_wd_data = NULL;
580 } 711 }
581 return 0; 712
713 mutex_lock(&wd_data->lock);
714 wd_data->wdd = NULL;
715 wdd->wd_data = NULL;
716 mutex_unlock(&wd_data->lock);
717
718 kref_put(&wd_data->kref, watchdog_core_data_release);
719}
720
721static struct class watchdog_class = {
722 .name = "watchdog",
723 .owner = THIS_MODULE,
724 .dev_groups = wdt_groups,
725};
726
727/*
728 * watchdog_dev_register: register a watchdog device
729 * @wdd: watchdog device
730 *
731 * Register a watchdog device including handling the legacy
732 * /dev/watchdog node. /dev/watchdog is actually a miscdevice and
733 * thus we set it up like that.
734 */
735
736int watchdog_dev_register(struct watchdog_device *wdd)
737{
738 struct device *dev;
739 dev_t devno;
740 int ret;
741
742 devno = MKDEV(MAJOR(watchdog_devt), wdd->id);
743
744 ret = watchdog_cdev_register(wdd, devno);
745 if (ret)
746 return ret;
747
748 dev = device_create_with_groups(&watchdog_class, wdd->parent,
749 devno, wdd, wdd->groups,
750 "watchdog%d", wdd->id);
751 if (IS_ERR(dev)) {
752 watchdog_cdev_unregister(wdd);
753 return PTR_ERR(dev);
754 }
755
756 return ret;
757}
758
759/*
760 * watchdog_dev_unregister: unregister a watchdog device
761 * @watchdog: watchdog device
762 *
763 * Unregister watchdog device and if needed the legacy
764 * /dev/watchdog device.
765 */
766
767void watchdog_dev_unregister(struct watchdog_device *wdd)
768{
769 device_destroy(&watchdog_class, wdd->wd_data->cdev.dev);
770 watchdog_cdev_unregister(wdd);
582} 771}
583 772
584/* 773/*
@@ -589,10 +778,22 @@ int watchdog_dev_unregister(struct watchdog_device *wdd)
589 778
590int __init watchdog_dev_init(void) 779int __init watchdog_dev_init(void)
591{ 780{
592 int err = alloc_chrdev_region(&watchdog_devt, 0, MAX_DOGS, "watchdog"); 781 int err;
593 if (err < 0) 782
783 err = class_register(&watchdog_class);
784 if (err < 0) {
785 pr_err("couldn't register class\n");
786 return err;
787 }
788
789 err = alloc_chrdev_region(&watchdog_devt, 0, MAX_DOGS, "watchdog");
790 if (err < 0) {
594 pr_err("watchdog: unable to allocate char dev region\n"); 791 pr_err("watchdog: unable to allocate char dev region\n");
595 return err; 792 class_unregister(&watchdog_class);
793 return err;
794 }
795
796 return 0;
596} 797}
597 798
598/* 799/*
@@ -604,4 +805,5 @@ int __init watchdog_dev_init(void)
604void __exit watchdog_dev_exit(void) 805void __exit watchdog_dev_exit(void)
605{ 806{
606 unregister_chrdev_region(watchdog_devt, MAX_DOGS); 807 unregister_chrdev_region(watchdog_devt, MAX_DOGS);
808 class_unregister(&watchdog_class);
607} 809}
diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c
new file mode 100644
index 000000000000..0c7cb7302cf0
--- /dev/null
+++ b/drivers/watchdog/ziirave_wdt.c
@@ -0,0 +1,367 @@
1/*
2 * Copyright (C) 2015 Zodiac Inflight Innovations
3 *
4 * Author: Martyn Welch <martyn.welch@collabora.co.uk>
5 *
6 * Based on twl4030_wdt.c by Timo Kokkonen <timo.t.kokkonen at nokia.com>:
7 *
8 * Copyright (C) Nokia Corporation
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 as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21#include <linux/i2c.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/slab.h>
25#include <linux/sysfs.h>
26#include <linux/types.h>
27#include <linux/version.h>
28#include <linux/watchdog.h>
29
30#define ZIIRAVE_TIMEOUT_MIN 3
31#define ZIIRAVE_TIMEOUT_MAX 255
32
33#define ZIIRAVE_PING_VALUE 0x0
34
35#define ZIIRAVE_STATE_INITIAL 0x0
36#define ZIIRAVE_STATE_OFF 0x1
37#define ZIIRAVE_STATE_ON 0x2
38
39static char *ziirave_reasons[] = {"power cycle", "triggered", NULL, NULL,
40 "host request", NULL, "illegal configuration",
41 "illegal instruction", "illegal trap",
42 "unknown"};
43
44#define ZIIRAVE_WDT_FIRM_VER_MAJOR 0x1
45#define ZIIRAVE_WDT_BOOT_VER_MAJOR 0x3
46#define ZIIRAVE_WDT_RESET_REASON 0x5
47#define ZIIRAVE_WDT_STATE 0x6
48#define ZIIRAVE_WDT_TIMEOUT 0x7
49#define ZIIRAVE_WDT_TIME_LEFT 0x8
50#define ZIIRAVE_WDT_PING 0x9
51#define ZIIRAVE_WDT_RESET_DURATION 0xa
52
53struct ziirave_wdt_rev {
54 unsigned char major;
55 unsigned char minor;
56};
57
58struct ziirave_wdt_data {
59 struct watchdog_device wdd;
60 struct ziirave_wdt_rev bootloader_rev;
61 struct ziirave_wdt_rev firmware_rev;
62 int reset_reason;
63};
64
65static int wdt_timeout;
66module_param(wdt_timeout, int, 0);
67MODULE_PARM_DESC(wdt_timeout, "Watchdog timeout in seconds");
68
69static int reset_duration;
70module_param(reset_duration, int, 0);
71MODULE_PARM_DESC(reset_duration,
72 "Watchdog reset pulse duration in milliseconds");
73
74static bool nowayout = WATCHDOG_NOWAYOUT;
75module_param(nowayout, bool, 0);
76MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started default="
77 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
78
79static int ziirave_wdt_revision(struct i2c_client *client,
80 struct ziirave_wdt_rev *rev, u8 command)
81{
82 int ret;
83
84 ret = i2c_smbus_read_byte_data(client, command);
85 if (ret < 0)
86 return ret;
87
88 rev->major = ret;
89
90 ret = i2c_smbus_read_byte_data(client, command + 1);
91 if (ret < 0)
92 return ret;
93
94 rev->minor = ret;
95
96 return 0;
97}
98
99static int ziirave_wdt_set_state(struct watchdog_device *wdd, int state)
100{
101 struct i2c_client *client = to_i2c_client(wdd->parent);
102
103 return i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_STATE, state);
104}
105
106static int ziirave_wdt_start(struct watchdog_device *wdd)
107{
108 return ziirave_wdt_set_state(wdd, ZIIRAVE_STATE_ON);
109}
110
111static int ziirave_wdt_stop(struct watchdog_device *wdd)
112{
113 return ziirave_wdt_set_state(wdd, ZIIRAVE_STATE_OFF);
114}
115
116static int ziirave_wdt_ping(struct watchdog_device *wdd)
117{
118 struct i2c_client *client = to_i2c_client(wdd->parent);
119
120 return i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_PING,
121 ZIIRAVE_PING_VALUE);
122}
123
124static int ziirave_wdt_set_timeout(struct watchdog_device *wdd,
125 unsigned int timeout)
126{
127 struct i2c_client *client = to_i2c_client(wdd->parent);
128 int ret;
129
130 ret = i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_TIMEOUT, timeout);
131 if (!ret)
132 wdd->timeout = timeout;
133
134 return ret;
135}
136
137static unsigned int ziirave_wdt_get_timeleft(struct watchdog_device *wdd)
138{
139 struct i2c_client *client = to_i2c_client(wdd->parent);
140 int ret;
141
142 ret = i2c_smbus_read_byte_data(client, ZIIRAVE_WDT_TIME_LEFT);
143 if (ret < 0)
144 ret = 0;
145
146 return ret;
147}
148
149static const struct watchdog_info ziirave_wdt_info = {
150 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
151 .identity = "Zodiac RAVE Watchdog",
152};
153
154static const struct watchdog_ops ziirave_wdt_ops = {
155 .owner = THIS_MODULE,
156 .start = ziirave_wdt_start,
157 .stop = ziirave_wdt_stop,
158 .ping = ziirave_wdt_ping,
159 .set_timeout = ziirave_wdt_set_timeout,
160 .get_timeleft = ziirave_wdt_get_timeleft,
161};
162
163static ssize_t ziirave_wdt_sysfs_show_firm(struct device *dev,
164 struct device_attribute *attr,
165 char *buf)
166{
167 struct i2c_client *client = to_i2c_client(dev->parent);
168 struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
169
170 return sprintf(buf, "02.%02u.%02u", w_priv->firmware_rev.major,
171 w_priv->firmware_rev.minor);
172}
173
174static DEVICE_ATTR(firmware_version, S_IRUGO, ziirave_wdt_sysfs_show_firm,
175 NULL);
176
177static ssize_t ziirave_wdt_sysfs_show_boot(struct device *dev,
178 struct device_attribute *attr,
179 char *buf)
180{
181 struct i2c_client *client = to_i2c_client(dev->parent);
182 struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
183
184 return sprintf(buf, "01.%02u.%02u", w_priv->bootloader_rev.major,
185 w_priv->bootloader_rev.minor);
186}
187
188static DEVICE_ATTR(bootloader_version, S_IRUGO, ziirave_wdt_sysfs_show_boot,
189 NULL);
190
191static ssize_t ziirave_wdt_sysfs_show_reason(struct device *dev,
192 struct device_attribute *attr,
193 char *buf)
194{
195 struct i2c_client *client = to_i2c_client(dev->parent);
196 struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
197
198 return sprintf(buf, "%s", ziirave_reasons[w_priv->reset_reason]);
199}
200
201static DEVICE_ATTR(reset_reason, S_IRUGO, ziirave_wdt_sysfs_show_reason,
202 NULL);
203
204static struct attribute *ziirave_wdt_attrs[] = {
205 &dev_attr_firmware_version.attr,
206 &dev_attr_bootloader_version.attr,
207 &dev_attr_reset_reason.attr,
208 NULL
209};
210ATTRIBUTE_GROUPS(ziirave_wdt);
211
212static int ziirave_wdt_init_duration(struct i2c_client *client)
213{
214 int ret;
215
216 if (!reset_duration) {
217 /* See if the reset pulse duration is provided in an of_node */
218 if (!client->dev.of_node)
219 ret = -ENODEV;
220 else
221 ret = of_property_read_u32(client->dev.of_node,
222 "reset-duration-ms",
223 &reset_duration);
224 if (ret) {
225 dev_info(&client->dev,
226 "Unable to set reset pulse duration, using default\n");
227 return 0;
228 }
229 }
230
231 if (reset_duration < 1 || reset_duration > 255)
232 return -EINVAL;
233
234 dev_info(&client->dev, "Setting reset duration to %dms",
235 reset_duration);
236
237 return i2c_smbus_write_byte_data(client, ZIIRAVE_WDT_RESET_DURATION,
238 reset_duration);
239}
240
241static int ziirave_wdt_probe(struct i2c_client *client,
242 const struct i2c_device_id *id)
243{
244 int ret;
245 struct ziirave_wdt_data *w_priv;
246 int val;
247
248 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
249 return -ENODEV;
250
251 w_priv = devm_kzalloc(&client->dev, sizeof(*w_priv), GFP_KERNEL);
252 if (!w_priv)
253 return -ENOMEM;
254
255 w_priv->wdd.info = &ziirave_wdt_info;
256 w_priv->wdd.ops = &ziirave_wdt_ops;
257 w_priv->wdd.min_timeout = ZIIRAVE_TIMEOUT_MIN;
258 w_priv->wdd.max_timeout = ZIIRAVE_TIMEOUT_MAX;
259 w_priv->wdd.parent = &client->dev;
260 w_priv->wdd.groups = ziirave_wdt_groups;
261
262 ret = watchdog_init_timeout(&w_priv->wdd, wdt_timeout, &client->dev);
263 if (ret) {
264 dev_info(&client->dev,
265 "Unable to select timeout value, using default\n");
266 }
267
268 /*
269 * The default value set in the watchdog should be perfectly valid, so
270 * pass that in if we haven't provided one via the module parameter or
271 * of property.
272 */
273 if (w_priv->wdd.timeout == 0) {
274 val = i2c_smbus_read_byte_data(client, ZIIRAVE_WDT_TIMEOUT);
275 if (val < 0)
276 return val;
277
278 if (val < ZIIRAVE_TIMEOUT_MIN)
279 return -ENODEV;
280
281 w_priv->wdd.timeout = val;
282 } else {
283 ret = ziirave_wdt_set_timeout(&w_priv->wdd,
284 w_priv->wdd.timeout);
285 if (ret)
286 return ret;
287
288 dev_info(&client->dev, "Timeout set to %ds.",
289 w_priv->wdd.timeout);
290 }
291
292 watchdog_set_nowayout(&w_priv->wdd, nowayout);
293
294 i2c_set_clientdata(client, w_priv);
295
296 /* If in unconfigured state, set to stopped */
297 val = i2c_smbus_read_byte_data(client, ZIIRAVE_WDT_STATE);
298 if (val < 0)
299 return val;
300
301 if (val == ZIIRAVE_STATE_INITIAL)
302 ziirave_wdt_stop(&w_priv->wdd);
303
304 ret = ziirave_wdt_init_duration(client);
305 if (ret)
306 return ret;
307
308 ret = ziirave_wdt_revision(client, &w_priv->firmware_rev,
309 ZIIRAVE_WDT_FIRM_VER_MAJOR);
310 if (ret)
311 return ret;
312
313 ret = ziirave_wdt_revision(client, &w_priv->bootloader_rev,
314 ZIIRAVE_WDT_BOOT_VER_MAJOR);
315 if (ret)
316 return ret;
317
318 w_priv->reset_reason = i2c_smbus_read_byte_data(client,
319 ZIIRAVE_WDT_RESET_REASON);
320 if (w_priv->reset_reason < 0)
321 return w_priv->reset_reason;
322
323 if (w_priv->reset_reason >= ARRAY_SIZE(ziirave_reasons) ||
324 !ziirave_reasons[w_priv->reset_reason])
325 return -ENODEV;
326
327 ret = watchdog_register_device(&w_priv->wdd);
328
329 return ret;
330}
331
332static int ziirave_wdt_remove(struct i2c_client *client)
333{
334 struct ziirave_wdt_data *w_priv = i2c_get_clientdata(client);
335
336 watchdog_unregister_device(&w_priv->wdd);
337
338 return 0;
339}
340
341static struct i2c_device_id ziirave_wdt_id[] = {
342 { "ziirave-wdt", 0 },
343 { }
344};
345MODULE_DEVICE_TABLE(i2c, ziirave_wdt_id);
346
347static const struct of_device_id zrv_wdt_of_match[] = {
348 { .compatible = "zii,rave-wdt", },
349 { },
350};
351MODULE_DEVICE_TABLE(of, zrv_wdt_of_match);
352
353static struct i2c_driver ziirave_wdt_driver = {
354 .driver = {
355 .name = "ziirave_wdt",
356 .of_match_table = zrv_wdt_of_match,
357 },
358 .probe = ziirave_wdt_probe,
359 .remove = ziirave_wdt_remove,
360 .id_table = ziirave_wdt_id,
361};
362
363module_i2c_driver(ziirave_wdt_driver);
364
365MODULE_AUTHOR("Martyn Welch <martyn.welch@collabora.co.uk");
366MODULE_DESCRIPTION("Zodiac Aerospace RAVE Switch Watchdog Processor Driver");
367MODULE_LICENSE("GPL");
diff --git a/include/linux/bcm47xx_wdt.h b/include/linux/bcm47xx_wdt.h
index 5582c211f594..8d9d07ec22a5 100644
--- a/include/linux/bcm47xx_wdt.h
+++ b/include/linux/bcm47xx_wdt.h
@@ -1,7 +1,6 @@
1#ifndef LINUX_BCM47XX_WDT_H_ 1#ifndef LINUX_BCM47XX_WDT_H_
2#define LINUX_BCM47XX_WDT_H_ 2#define LINUX_BCM47XX_WDT_H_
3 3
4#include <linux/notifier.h>
5#include <linux/timer.h> 4#include <linux/timer.h>
6#include <linux/types.h> 5#include <linux/types.h>
7#include <linux/watchdog.h> 6#include <linux/watchdog.h>
@@ -15,8 +14,6 @@ struct bcm47xx_wdt {
15 void *driver_data; 14 void *driver_data;
16 15
17 struct watchdog_device wdd; 16 struct watchdog_device wdd;
18 struct notifier_block notifier;
19 struct notifier_block restart_handler;
20 17
21 struct timer_list soft_timer; 18 struct timer_list soft_timer;
22 atomic_t soft_ticks; 19 atomic_t soft_ticks;
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index 027b1f43f12d..b585fa2507ee 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -12,10 +12,12 @@
12#include <linux/bitops.h> 12#include <linux/bitops.h>
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/cdev.h> 14#include <linux/cdev.h>
15#include <linux/notifier.h>
15#include <uapi/linux/watchdog.h> 16#include <uapi/linux/watchdog.h>
16 17
17struct watchdog_ops; 18struct watchdog_ops;
18struct watchdog_device; 19struct watchdog_device;
20struct watchdog_core_data;
19 21
20/** struct watchdog_ops - The watchdog-devices operations 22/** struct watchdog_ops - The watchdog-devices operations
21 * 23 *
@@ -26,8 +28,7 @@ struct watchdog_device;
26 * @status: The routine that shows the status of the watchdog device. 28 * @status: The routine that shows the status of the watchdog device.
27 * @set_timeout:The routine for setting the watchdog devices timeout value (in seconds). 29 * @set_timeout:The routine for setting the watchdog devices timeout value (in seconds).
28 * @get_timeleft:The routine that gets the time left before a reset (in seconds). 30 * @get_timeleft:The routine that gets the time left before a reset (in seconds).
29 * @ref: The ref operation for dyn. allocated watchdog_device structs 31 * @restart: The routine for restarting the machine.
30 * @unref: The unref operation for dyn. allocated watchdog_device structs
31 * @ioctl: The routines that handles extra ioctl calls. 32 * @ioctl: The routines that handles extra ioctl calls.
32 * 33 *
33 * The watchdog_ops structure contains a list of low-level operations 34 * The watchdog_ops structure contains a list of low-level operations
@@ -45,25 +46,26 @@ struct watchdog_ops {
45 unsigned int (*status)(struct watchdog_device *); 46 unsigned int (*status)(struct watchdog_device *);
46 int (*set_timeout)(struct watchdog_device *, unsigned int); 47 int (*set_timeout)(struct watchdog_device *, unsigned int);
47 unsigned int (*get_timeleft)(struct watchdog_device *); 48 unsigned int (*get_timeleft)(struct watchdog_device *);
48 void (*ref)(struct watchdog_device *); 49 int (*restart)(struct watchdog_device *);
49 void (*unref)(struct watchdog_device *);
50 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long); 50 long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
51}; 51};
52 52
53/** struct watchdog_device - The structure that defines a watchdog device 53/** struct watchdog_device - The structure that defines a watchdog device
54 * 54 *
55 * @id: The watchdog's ID. (Allocated by watchdog_register_device) 55 * @id: The watchdog's ID. (Allocated by watchdog_register_device)
56 * @cdev: The watchdog's Character device.
57 * @dev: The device for our watchdog
58 * @parent: The parent bus device 56 * @parent: The parent bus device
57 * @groups: List of sysfs attribute groups to create when creating the
58 * watchdog device.
59 * @info: Pointer to a watchdog_info structure. 59 * @info: Pointer to a watchdog_info structure.
60 * @ops: Pointer to the list of watchdog operations. 60 * @ops: Pointer to the list of watchdog operations.
61 * @bootstatus: Status of the watchdog device at boot. 61 * @bootstatus: Status of the watchdog device at boot.
62 * @timeout: The watchdog devices timeout value (in seconds). 62 * @timeout: The watchdog devices timeout value (in seconds).
63 * @min_timeout:The watchdog devices minimum timeout value (in seconds). 63 * @min_timeout:The watchdog devices minimum timeout value (in seconds).
64 * @max_timeout:The watchdog devices maximum timeout value (in seconds). 64 * @max_timeout:The watchdog devices maximum timeout value (in seconds).
65 * @driver-data:Pointer to the drivers private data. 65 * @reboot_nb: The notifier block to stop watchdog on reboot.
66 * @lock: Lock for watchdog core internal use only. 66 * @restart_nb: The notifier block to register a restart function.
67 * @driver_data:Pointer to the drivers private data.
68 * @wd_data: Pointer to watchdog core internal data.
67 * @status: Field that contains the devices internal status bits. 69 * @status: Field that contains the devices internal status bits.
68 * @deferred: entry in wtd_deferred_reg_list which is used to 70 * @deferred: entry in wtd_deferred_reg_list which is used to
69 * register early initialized watchdogs. 71 * register early initialized watchdogs.
@@ -79,24 +81,23 @@ struct watchdog_ops {
79 */ 81 */
80struct watchdog_device { 82struct watchdog_device {
81 int id; 83 int id;
82 struct cdev cdev;
83 struct device *dev;
84 struct device *parent; 84 struct device *parent;
85 const struct attribute_group **groups;
85 const struct watchdog_info *info; 86 const struct watchdog_info *info;
86 const struct watchdog_ops *ops; 87 const struct watchdog_ops *ops;
87 unsigned int bootstatus; 88 unsigned int bootstatus;
88 unsigned int timeout; 89 unsigned int timeout;
89 unsigned int min_timeout; 90 unsigned int min_timeout;
90 unsigned int max_timeout; 91 unsigned int max_timeout;
92 struct notifier_block reboot_nb;
93 struct notifier_block restart_nb;
91 void *driver_data; 94 void *driver_data;
92 struct mutex lock; 95 struct watchdog_core_data *wd_data;
93 unsigned long status; 96 unsigned long status;
94/* Bit numbers for status flags */ 97/* Bit numbers for status flags */
95#define WDOG_ACTIVE 0 /* Is the watchdog running/active */ 98#define WDOG_ACTIVE 0 /* Is the watchdog running/active */
96#define WDOG_DEV_OPEN 1 /* Opened via /dev/watchdog ? */ 99#define WDOG_NO_WAY_OUT 1 /* Is 'nowayout' feature set ? */
97#define WDOG_ALLOW_RELEASE 2 /* Did we receive the magic char ? */ 100#define WDOG_STOP_ON_REBOOT 2 /* Should be stopped on reboot */
98#define WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set ? */
99#define WDOG_UNREGISTERED 4 /* Has the device been unregistered */
100 struct list_head deferred; 101 struct list_head deferred;
101}; 102};
102 103
@@ -116,6 +117,12 @@ static inline void watchdog_set_nowayout(struct watchdog_device *wdd, bool noway
116 set_bit(WDOG_NO_WAY_OUT, &wdd->status); 117 set_bit(WDOG_NO_WAY_OUT, &wdd->status);
117} 118}
118 119
120/* Use the following function to stop the watchdog on reboot */
121static inline void watchdog_stop_on_reboot(struct watchdog_device *wdd)
122{
123 set_bit(WDOG_STOP_ON_REBOOT, &wdd->status);
124}
125
119/* Use the following function to check if a timeout value is invalid */ 126/* Use the following function to check if a timeout value is invalid */
120static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigned int t) 127static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigned int t)
121{ 128{
@@ -142,6 +149,7 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd)
142} 149}
143 150
144/* drivers/watchdog/watchdog_core.c */ 151/* drivers/watchdog/watchdog_core.c */
152void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority);
145extern int watchdog_init_timeout(struct watchdog_device *wdd, 153extern int watchdog_init_timeout(struct watchdog_device *wdd,
146 unsigned int timeout_parm, struct device *dev); 154 unsigned int timeout_parm, struct device *dev);
147extern int watchdog_register_device(struct watchdog_device *); 155extern int watchdog_register_device(struct watchdog_device *);