aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ts72xx.h2
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c21
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c2
-rw-r--r--drivers/watchdog/Kconfig20
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/acquirewdt.c2
-rw-r--r--drivers/watchdog/advantechwdt.c2
-rw-r--r--drivers/watchdog/adx_wdt.c2
-rw-r--r--drivers/watchdog/alim1535_wdt.c2
-rw-r--r--drivers/watchdog/alim7101_wdt.c2
-rw-r--r--drivers/watchdog/ar7_wdt.c2
-rw-r--r--drivers/watchdog/at32ap700x_wdt.c2
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c2
-rw-r--r--drivers/watchdog/bcm47xx_wdt.c2
-rw-r--r--drivers/watchdog/bfin_wdt.c56
-rw-r--r--drivers/watchdog/booke_wdt.c2
-rw-r--r--drivers/watchdog/coh901327_wdt.c2
-rw-r--r--drivers/watchdog/cpu5wdt.c2
-rw-r--r--drivers/watchdog/cpwd.c2
-rw-r--r--drivers/watchdog/davinci_wdt.c2
-rw-r--r--drivers/watchdog/ep93xx_wdt.c2
-rw-r--r--drivers/watchdog/eurotechwdt.c2
-rw-r--r--drivers/watchdog/gef_wdt.c16
-rw-r--r--drivers/watchdog/geodewdt.c2
-rw-r--r--drivers/watchdog/hpwdt.c2
-rw-r--r--drivers/watchdog/i6300esb.c101
-rw-r--r--drivers/watchdog/iTCO_wdt.c21
-rw-r--r--drivers/watchdog/ib700wdt.c2
-rw-r--r--drivers/watchdog/indydog.c2
-rw-r--r--drivers/watchdog/it8712f_wdt.c2
-rw-r--r--drivers/watchdog/it87_wdt.c2
-rw-r--r--drivers/watchdog/ixp2000_wdt.c2
-rw-r--r--drivers/watchdog/ixp4xx_wdt.c2
-rw-r--r--drivers/watchdog/ks8695_wdt.c2
-rw-r--r--drivers/watchdog/machzwd.c2
-rw-r--r--drivers/watchdog/max63xx_wdt.c397
-rw-r--r--drivers/watchdog/mixcomwd.c2
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c2
-rw-r--r--drivers/watchdog/mpcore_wdt.c2
-rw-r--r--drivers/watchdog/mv64x60_wdt.c2
-rw-r--r--drivers/watchdog/pc87413_wdt.c2
-rw-r--r--drivers/watchdog/pcwd.c2
-rw-r--r--drivers/watchdog/pcwd_pci.c2
-rw-r--r--drivers/watchdog/pcwd_usb.c2
-rw-r--r--drivers/watchdog/pika_wdt.c2
-rw-r--r--drivers/watchdog/pnx833x_wdt.c2
-rw-r--r--drivers/watchdog/rc32434_wdt.c2
-rw-r--r--drivers/watchdog/rdc321x_wdt.c2
-rw-r--r--drivers/watchdog/riowd.c2
-rw-r--r--drivers/watchdog/sbc_fitpc2_wdt.c2
-rw-r--r--drivers/watchdog/sch311x_wdt.c2
-rw-r--r--drivers/watchdog/stmp3xxx_wdt.c2
-rw-r--r--drivers/watchdog/ts72xx_wdt.c520
-rw-r--r--drivers/watchdog/txx9wdt.c25
-rw-r--r--drivers/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/watchdog/w83977f_wdt.c2
-rw-r--r--drivers/watchdog/wdrtas.c2
-rw-r--r--drivers/watchdog/wdt.c2
-rw-r--r--drivers/watchdog/wdt_pci.c2
-rw-r--r--drivers/watchdog/wm831x_wdt.c2
-rw-r--r--drivers/watchdog/wm8350_wdt.c2
61 files changed, 1088 insertions, 193 deletions
diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
index 3bd934e9a7f1..93107d88ff3a 100644
--- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h
+++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
@@ -65,6 +65,8 @@
65#define TS72XX_RTC_DATA_PHYS_BASE 0x11700000 65#define TS72XX_RTC_DATA_PHYS_BASE 0x11700000
66#define TS72XX_RTC_DATA_SIZE 0x00001000 66#define TS72XX_RTC_DATA_SIZE 0x00001000
67 67
68#define TS72XX_WDT_CONTROL_PHYS_BASE 0x23800000
69#define TS72XX_WDT_FEED_PHYS_BASE 0x23c00000
68 70
69#ifndef __ASSEMBLY__ 71#ifndef __ASSEMBLY__
70 72
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 259f7822ba52..fac1ec7a60fb 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -166,6 +166,26 @@ static struct platform_device ts72xx_rtc_device = {
166 .num_resources = 0, 166 .num_resources = 0,
167}; 167};
168 168
169static struct resource ts72xx_wdt_resources[] = {
170 {
171 .start = TS72XX_WDT_CONTROL_PHYS_BASE,
172 .end = TS72XX_WDT_CONTROL_PHYS_BASE + SZ_4K - 1,
173 .flags = IORESOURCE_MEM,
174 },
175 {
176 .start = TS72XX_WDT_FEED_PHYS_BASE,
177 .end = TS72XX_WDT_FEED_PHYS_BASE + SZ_4K - 1,
178 .flags = IORESOURCE_MEM,
179 },
180};
181
182static struct platform_device ts72xx_wdt_device = {
183 .name = "ts72xx-wdt",
184 .id = -1,
185 .num_resources = ARRAY_SIZE(ts72xx_wdt_resources),
186 .resource = ts72xx_wdt_resources,
187};
188
169static struct ep93xx_eth_data ts72xx_eth_data = { 189static struct ep93xx_eth_data ts72xx_eth_data = {
170 .phy_id = 1, 190 .phy_id = 1,
171}; 191};
@@ -175,6 +195,7 @@ static void __init ts72xx_init_machine(void)
175 ep93xx_init_devices(); 195 ep93xx_init_devices();
176 ts72xx_register_flash(); 196 ts72xx_register_flash();
177 platform_device_register(&ts72xx_rtc_device); 197 platform_device_register(&ts72xx_rtc_device);
198 platform_device_register(&ts72xx_wdt_device);
178 199
179 ep93xx_register_eth(&ts72xx_eth_data, 1); 200 ep93xx_register_eth(&ts72xx_eth_data, 1);
180} 201}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 6f8ebe1085b3..072b948b2e2d 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -553,7 +553,7 @@ static ssize_t mpc52xx_wdt_write(struct file *file, const char __user *data,
553 return 0; 553 return 0;
554} 554}
555 555
556static struct watchdog_info mpc5200_wdt_info = { 556static const struct watchdog_info mpc5200_wdt_info = {
557 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 557 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
558 .identity = WDT_IDENTITY, 558 .identity = WDT_IDENTITY,
559}; 559};
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3da3f48720a7..bdcdbd53da89 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -55,6 +55,11 @@ config SOFT_WATCHDOG
55 To compile this driver as a module, choose M here: the 55 To compile this driver as a module, choose M here: the
56 module will be called softdog. 56 module will be called softdog.
57 57
58config MAX63XX_WATCHDOG
59 tristate "Max63xx watchdog"
60 help
61 Support for memory mapped max63{69,70,71,72,73,74} watchdog timer.
62
58config WM831X_WATCHDOG 63config WM831X_WATCHDOG
59 tristate "WM831x watchdog" 64 tristate "WM831x watchdog"
60 depends on MFD_WM831X 65 depends on MFD_WM831X
@@ -289,6 +294,17 @@ config ADX_WATCHDOG
289 Say Y here if you want support for the watchdog timer on Avionic 294 Say Y here if you want support for the watchdog timer on Avionic
290 Design Xanthos boards. 295 Design Xanthos boards.
291 296
297config TS72XX_WATCHDOG
298 tristate "TS-72XX SBC Watchdog"
299 depends on MACH_TS72XX
300 help
301 Technologic Systems TS-7200, TS-7250 and TS-7260 boards have
302 watchdog timer implemented in a external CPLD chip. Say Y here
303 if you want to support for the watchdog timer on TS-72XX boards.
304
305 To compile this driver as a module, choose M here: the
306 module will be called ts72xx_wdt.
307
292# AVR32 Architecture 308# AVR32 Architecture
293 309
294config AT32AP700X_WDT 310config AT32AP700X_WDT
@@ -845,10 +861,10 @@ config TXX9_WDT
845# POWERPC Architecture 861# POWERPC Architecture
846 862
847config GEF_WDT 863config GEF_WDT
848 tristate "GE Fanuc Watchdog Timer" 864 tristate "GE Watchdog Timer"
849 depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A 865 depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A
850 ---help--- 866 ---help---
851 Watchdog timer found in a number of GE Fanuc single board computers. 867 Watchdog timer found in a number of GE single board computers.
852 868
853config MPC5200_WDT 869config MPC5200_WDT
854 bool "MPC52xx Watchdog Timer" 870 bool "MPC52xx Watchdog Timer"
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 475c61100069..5e3cb95bb0e9 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
46obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o 46obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o
47obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o 47obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
48obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o 48obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o
49obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
49 50
50# AVR32 Architecture 51# AVR32 Architecture
51obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o 52obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
@@ -142,4 +143,5 @@ obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o
142# Architecture Independant 143# Architecture Independant
143obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o 144obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
144obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o 145obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
146obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
145obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o 147obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c
index 4d18c874d963..2ffce4d75443 100644
--- a/drivers/watchdog/acquirewdt.c
+++ b/drivers/watchdog/acquirewdt.c
@@ -150,7 +150,7 @@ static long acq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
150 int options, retval = -EINVAL; 150 int options, retval = -EINVAL;
151 void __user *argp = (void __user *)arg; 151 void __user *argp = (void __user *)arg;
152 int __user *p = argp; 152 int __user *p = argp;
153 static struct watchdog_info ident = { 153 static const struct watchdog_info ident = {
154 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 154 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
155 .firmware_version = 1, 155 .firmware_version = 1,
156 .identity = WATCHDOG_NAME, 156 .identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
index 824d076a5cd6..4d40965d2c9f 100644
--- a/drivers/watchdog/advantechwdt.c
+++ b/drivers/watchdog/advantechwdt.c
@@ -137,7 +137,7 @@ static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
137 int new_timeout; 137 int new_timeout;
138 void __user *argp = (void __user *)arg; 138 void __user *argp = (void __user *)arg;
139 int __user *p = argp; 139 int __user *p = argp;
140 static struct watchdog_info ident = { 140 static const struct watchdog_info ident = {
141 .options = WDIOF_KEEPALIVEPING | 141 .options = WDIOF_KEEPALIVEPING |
142 WDIOF_SETTIMEOUT | 142 WDIOF_SETTIMEOUT |
143 WDIOF_MAGICCLOSE, 143 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c
index 9d7d155364f8..a5ca7a6ee133 100644
--- a/drivers/watchdog/adx_wdt.c
+++ b/drivers/watchdog/adx_wdt.c
@@ -37,7 +37,7 @@ struct adx_wdt {
37 spinlock_t lock; 37 spinlock_t lock;
38}; 38};
39 39
40static struct watchdog_info adx_wdt_info = { 40static const struct watchdog_info adx_wdt_info = {
41 .identity = "Avionic Design Xanthos Watchdog", 41 .identity = "Avionic Design Xanthos Watchdog",
42 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 42 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
43}; 43};
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
index 937a80fb61e1..1e9caea8ff8a 100644
--- a/drivers/watchdog/alim1535_wdt.c
+++ b/drivers/watchdog/alim1535_wdt.c
@@ -180,7 +180,7 @@ static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
180{ 180{
181 void __user *argp = (void __user *)arg; 181 void __user *argp = (void __user *)arg;
182 int __user *p = argp; 182 int __user *p = argp;
183 static struct watchdog_info ident = { 183 static const struct watchdog_info ident = {
184 .options = WDIOF_KEEPALIVEPING | 184 .options = WDIOF_KEEPALIVEPING |
185 WDIOF_SETTIMEOUT | 185 WDIOF_SETTIMEOUT |
186 WDIOF_MAGICCLOSE, 186 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index f90afdb1b255..d8d4da9a483d 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -238,7 +238,7 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
238{ 238{
239 void __user *argp = (void __user *)arg; 239 void __user *argp = (void __user *)arg;
240 int __user *p = argp; 240 int __user *p = argp;
241 static struct watchdog_info ident = { 241 static const struct watchdog_info ident = {
242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT 242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
243 | WDIOF_MAGICCLOSE, 243 | WDIOF_MAGICCLOSE,
244 .firmware_version = 1, 244 .firmware_version = 1,
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index 2bb95cd308c1..c764c52412e4 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -219,7 +219,7 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data,
219static long ar7_wdt_ioctl(struct file *file, 219static long ar7_wdt_ioctl(struct file *file,
220 unsigned int cmd, unsigned long arg) 220 unsigned int cmd, unsigned long arg)
221{ 221{
222 static struct watchdog_info ident = { 222 static const struct watchdog_info ident = {
223 .identity = LONGNAME, 223 .identity = LONGNAME,
224 .firmware_version = 1, 224 .firmware_version = 1,
225 .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | 225 .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
index 037847923dcb..6873376f986c 100644
--- a/drivers/watchdog/at32ap700x_wdt.c
+++ b/drivers/watchdog/at32ap700x_wdt.c
@@ -202,7 +202,7 @@ static int at32_wdt_get_status(void)
202 return status; 202 return status;
203} 203}
204 204
205static struct watchdog_info at32_wdt_info = { 205static const struct watchdog_info at32_wdt_info = {
206 .identity = "at32ap700x watchdog", 206 .identity = "at32ap700x watchdog",
207 .options = WDIOF_SETTIMEOUT | 207 .options = WDIOF_SETTIMEOUT |
208 WDIOF_KEEPALIVEPING | 208 WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index b185dafe1494..b3046dc4b56c 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -121,7 +121,7 @@ static int at91_wdt_settimeout(int new_time)
121 return 0; 121 return 0;
122} 122}
123 123
124static struct watchdog_info at91_wdt_info = { 124static const struct watchdog_info at91_wdt_info = {
125 .identity = "at91 watchdog", 125 .identity = "at91 watchdog",
126 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 126 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
127}; 127};
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index 751c003864ad..5f245522397b 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -149,7 +149,7 @@ static ssize_t bcm47xx_wdt_write(struct file *file, const char __user *data,
149 return len; 149 return len;
150} 150}
151 151
152static struct watchdog_info bcm47xx_wdt_info = { 152static const struct watchdog_info bcm47xx_wdt_info = {
153 .identity = DRV_NAME, 153 .identity = DRV_NAME,
154 .options = WDIOF_SETTIMEOUT | 154 .options = WDIOF_SETTIMEOUT |
155 WDIOF_KEEPALIVEPING | 155 WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index 2159e668751c..9c7ccd1e9088 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -19,8 +19,6 @@
19#include <linux/miscdevice.h> 19#include <linux/miscdevice.h>
20#include <linux/watchdog.h> 20#include <linux/watchdog.h>
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/notifier.h>
23#include <linux/reboot.h>
24#include <linux/init.h> 22#include <linux/init.h>
25#include <linux/interrupt.h> 23#include <linux/interrupt.h>
26#include <linux/uaccess.h> 24#include <linux/uaccess.h>
@@ -74,7 +72,7 @@
74 72
75static unsigned int timeout = WATCHDOG_TIMEOUT; 73static unsigned int timeout = WATCHDOG_TIMEOUT;
76static int nowayout = WATCHDOG_NOWAYOUT; 74static int nowayout = WATCHDOG_NOWAYOUT;
77static struct watchdog_info bfin_wdt_info; 75static const struct watchdog_info bfin_wdt_info;
78static unsigned long open_check; 76static unsigned long open_check;
79static char expect_close; 77static char expect_close;
80static DEFINE_SPINLOCK(bfin_wdt_spinlock); 78static DEFINE_SPINLOCK(bfin_wdt_spinlock);
@@ -309,26 +307,6 @@ static long bfin_wdt_ioctl(struct file *file,
309 } 307 }
310} 308}
311 309
312/**
313 * bfin_wdt_notify_sys - Notifier Handler
314 * @this: notifier block
315 * @code: notifier event
316 * @unused: unused
317 *
318 * Handles specific events, such as turning off the watchdog during a
319 * shutdown event.
320 */
321static int bfin_wdt_notify_sys(struct notifier_block *this,
322 unsigned long code, void *unused)
323{
324 stampit();
325
326 if (code == SYS_DOWN || code == SYS_HALT)
327 bfin_wdt_stop();
328
329 return NOTIFY_DONE;
330}
331
332#ifdef CONFIG_PM 310#ifdef CONFIG_PM
333static int state_before_suspend; 311static int state_before_suspend;
334 312
@@ -388,40 +366,28 @@ static struct miscdevice bfin_wdt_miscdev = {
388 .fops = &bfin_wdt_fops, 366 .fops = &bfin_wdt_fops,
389}; 367};
390 368
391static struct watchdog_info bfin_wdt_info = { 369static const struct watchdog_info bfin_wdt_info = {
392 .identity = "Blackfin Watchdog", 370 .identity = "Blackfin Watchdog",
393 .options = WDIOF_SETTIMEOUT | 371 .options = WDIOF_SETTIMEOUT |
394 WDIOF_KEEPALIVEPING | 372 WDIOF_KEEPALIVEPING |
395 WDIOF_MAGICCLOSE, 373 WDIOF_MAGICCLOSE,
396}; 374};
397 375
398static struct notifier_block bfin_wdt_notifier = {
399 .notifier_call = bfin_wdt_notify_sys,
400};
401
402/** 376/**
403 * bfin_wdt_probe - Initialize module 377 * bfin_wdt_probe - Initialize module
404 * 378 *
405 * Registers the misc device and notifier handler. Actual device 379 * Registers the misc device. Actual device
406 * initialization is handled by bfin_wdt_open(). 380 * initialization is handled by bfin_wdt_open().
407 */ 381 */
408static int __devinit bfin_wdt_probe(struct platform_device *pdev) 382static int __devinit bfin_wdt_probe(struct platform_device *pdev)
409{ 383{
410 int ret; 384 int ret;
411 385
412 ret = register_reboot_notifier(&bfin_wdt_notifier);
413 if (ret) {
414 pr_devinit(KERN_ERR PFX
415 "cannot register reboot notifier (err=%d)\n", ret);
416 return ret;
417 }
418
419 ret = misc_register(&bfin_wdt_miscdev); 386 ret = misc_register(&bfin_wdt_miscdev);
420 if (ret) { 387 if (ret) {
421 pr_devinit(KERN_ERR PFX 388 pr_devinit(KERN_ERR PFX
422 "cannot register miscdev on minor=%d (err=%d)\n", 389 "cannot register miscdev on minor=%d (err=%d)\n",
423 WATCHDOG_MINOR, ret); 390 WATCHDOG_MINOR, ret);
424 unregister_reboot_notifier(&bfin_wdt_notifier);
425 return ret; 391 return ret;
426 } 392 }
427 393
@@ -434,21 +400,33 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev)
434/** 400/**
435 * bfin_wdt_remove - Initialize module 401 * bfin_wdt_remove - Initialize module
436 * 402 *
437 * Unregisters the misc device and notifier handler. Actual device 403 * Unregisters the misc device. Actual device
438 * deinitialization is handled by bfin_wdt_close(). 404 * deinitialization is handled by bfin_wdt_close().
439 */ 405 */
440static int __devexit bfin_wdt_remove(struct platform_device *pdev) 406static int __devexit bfin_wdt_remove(struct platform_device *pdev)
441{ 407{
442 misc_deregister(&bfin_wdt_miscdev); 408 misc_deregister(&bfin_wdt_miscdev);
443 unregister_reboot_notifier(&bfin_wdt_notifier);
444 return 0; 409 return 0;
445} 410}
446 411
412/**
413 * bfin_wdt_shutdown - Soft Shutdown Handler
414 *
415 * Handles the soft shutdown event.
416 */
417static void bfin_wdt_shutdown(struct platform_device *pdev)
418{
419 stampit();
420
421 bfin_wdt_stop();
422}
423
447static struct platform_device *bfin_wdt_device; 424static struct platform_device *bfin_wdt_device;
448 425
449static struct platform_driver bfin_wdt_driver = { 426static struct platform_driver bfin_wdt_driver = {
450 .probe = bfin_wdt_probe, 427 .probe = bfin_wdt_probe,
451 .remove = __devexit_p(bfin_wdt_remove), 428 .remove = __devexit_p(bfin_wdt_remove),
429 .shutdown = bfin_wdt_shutdown,
452 .suspend = bfin_wdt_suspend, 430 .suspend = bfin_wdt_suspend,
453 .resume = bfin_wdt_resume, 431 .resume = bfin_wdt_resume,
454 .driver = { 432 .driver = {
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index e8380ef65c1c..8b724aad6825 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -121,7 +121,7 @@ static ssize_t booke_wdt_write(struct file *file, const char __user *buf,
121 return count; 121 return count;
122} 122}
123 123
124static struct watchdog_info ident = { 124static const struct watchdog_info ident = {
125 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 125 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
126 .identity = "PowerPC Book-E Watchdog", 126 .identity = "PowerPC Book-E Watchdog",
127}; 127};
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index 923cc68dba26..9291506b8b23 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -257,7 +257,7 @@ static long coh901327_ioctl(struct file *file, unsigned int cmd,
257 struct watchdog_info __user *ident; 257 struct watchdog_info __user *ident;
258 int __user *i; 258 int __user *i;
259 } uarg; 259 } uarg;
260 static struct watchdog_info ident = { 260 static const struct watchdog_info ident = {
261 .options = WDIOF_CARDRESET | 261 .options = WDIOF_CARDRESET |
262 WDIOF_SETTIMEOUT | 262 WDIOF_SETTIMEOUT |
263 WDIOF_KEEPALIVEPING, 263 WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
index 71f6d7eec9a8..edd3475f41db 100644
--- a/drivers/watchdog/cpu5wdt.c
+++ b/drivers/watchdog/cpu5wdt.c
@@ -154,7 +154,7 @@ static long cpu5wdt_ioctl(struct file *file, unsigned int cmd,
154 void __user *argp = (void __user *)arg; 154 void __user *argp = (void __user *)arg;
155 int __user *p = argp; 155 int __user *p = argp;
156 unsigned int value; 156 unsigned int value;
157 static struct watchdog_info ident = { 157 static const struct watchdog_info ident = {
158 .options = WDIOF_CARDRESET, 158 .options = WDIOF_CARDRESET,
159 .identity = "CPU5 WDT", 159 .identity = "CPU5 WDT",
160 }; 160 };
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 081f2955419e..37ea052d4dee 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -403,7 +403,7 @@ static int cpwd_release(struct inode *inode, struct file *file)
403 403
404static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 404static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
405{ 405{
406 static struct watchdog_info info = { 406 static const struct watchdog_info info = {
407 .options = WDIOF_SETTIMEOUT, 407 .options = WDIOF_SETTIMEOUT,
408 .firmware_version = 1, 408 .firmware_version = 1,
409 .identity = DRIVER_NAME, 409 .identity = DRIVER_NAME,
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 887136de1857..56162c87f5d8 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -142,7 +142,7 @@ davinci_wdt_write(struct file *file, const char *data, size_t len,
142 return len; 142 return len;
143} 143}
144 144
145static struct watchdog_info ident = { 145static const struct watchdog_info ident = {
146 .options = WDIOF_KEEPALIVEPING, 146 .options = WDIOF_KEEPALIVEPING,
147 .identity = "DaVinci Watchdog", 147 .identity = "DaVinci Watchdog",
148}; 148};
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index cdd55e0d09f8..88ed54e50f74 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -131,7 +131,7 @@ ep93xx_wdt_write(struct file *file, const char __user *data, size_t len,
131 return len; 131 return len;
132} 132}
133 133
134static struct watchdog_info ident = { 134static const struct watchdog_info ident = {
135 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE, 135 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE,
136 .identity = "EP93xx Watchdog", 136 .identity = "EP93xx Watchdog",
137}; 137};
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index 9add3541fb42..d1c4e55b1db0 100644
--- a/drivers/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
@@ -238,7 +238,7 @@ static long eurwdt_ioctl(struct file *file,
238{ 238{
239 void __user *argp = (void __user *)arg; 239 void __user *argp = (void __user *)arg;
240 int __user *p = argp; 240 int __user *p = argp;
241 static struct watchdog_info ident = { 241 static const struct watchdog_info ident = {
242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT 242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
243 | WDIOF_MAGICCLOSE, 243 | WDIOF_MAGICCLOSE,
244 .firmware_version = 1, 244 .firmware_version = 1,
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c
index 734d9806a872..abdbad034a6c 100644
--- a/drivers/watchdog/gef_wdt.c
+++ b/drivers/watchdog/gef_wdt.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * GE Fanuc watchdog userspace interface 2 * GE watchdog userspace interface
3 * 3 *
4 * Author: Martyn Welch <martyn.welch@gefanuc.com> 4 * Author: Martyn Welch <martyn.welch@ge.com>
5 * 5 *
6 * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. 6 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
@@ -161,11 +161,11 @@ static long gef_wdt_ioctl(struct file *file, unsigned int cmd,
161 int timeout; 161 int timeout;
162 int options; 162 int options;
163 void __user *argp = (void __user *)arg; 163 void __user *argp = (void __user *)arg;
164 static struct watchdog_info info = { 164 static const struct watchdog_info info = {
165 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | 165 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
166 WDIOF_KEEPALIVEPING, 166 WDIOF_KEEPALIVEPING,
167 .firmware_version = 0, 167 .firmware_version = 0,
168 .identity = "GE Fanuc watchdog", 168 .identity = "GE watchdog",
169 }; 169 };
170 170
171 switch (cmd) { 171 switch (cmd) {
@@ -311,7 +311,7 @@ static struct of_platform_driver gef_wdt_driver = {
311 311
312static int __init gef_wdt_init(void) 312static int __init gef_wdt_init(void)
313{ 313{
314 printk(KERN_INFO "GE Fanuc watchdog driver\n"); 314 printk(KERN_INFO "GE watchdog driver\n");
315 return of_register_platform_driver(&gef_wdt_driver); 315 return of_register_platform_driver(&gef_wdt_driver);
316} 316}
317 317
@@ -323,8 +323,8 @@ static void __exit gef_wdt_exit(void)
323module_init(gef_wdt_init); 323module_init(gef_wdt_init);
324module_exit(gef_wdt_exit); 324module_exit(gef_wdt_exit);
325 325
326MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com>"); 326MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
327MODULE_DESCRIPTION("GE Fanuc watchdog driver"); 327MODULE_DESCRIPTION("GE watchdog driver");
328MODULE_LICENSE("GPL"); 328MODULE_LICENSE("GPL");
329MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 329MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
330MODULE_ALIAS("platform: gef_wdt"); 330MODULE_ALIAS("platform: gef_wdt");
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c
index 38252ff828ca..9b49b125ad5a 100644
--- a/drivers/watchdog/geodewdt.c
+++ b/drivers/watchdog/geodewdt.c
@@ -142,7 +142,7 @@ static long geodewdt_ioctl(struct file *file, unsigned int cmd,
142 int __user *p = argp; 142 int __user *p = argp;
143 int interval; 143 int interval;
144 144
145 static struct watchdog_info ident = { 145 static const struct watchdog_info ident = {
146 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING 146 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING
147 | WDIOF_MAGICCLOSE, 147 | WDIOF_MAGICCLOSE,
148 .firmware_version = 1, 148 .firmware_version = 1,
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index a6c5674c78e6..70c2c24660d0 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -554,7 +554,7 @@ static ssize_t hpwdt_write(struct file *file, const char __user *data,
554 return len; 554 return len;
555} 555}
556 556
557static struct watchdog_info ident = { 557static const struct watchdog_info ident = {
558 .options = WDIOF_SETTIMEOUT | 558 .options = WDIOF_SETTIMEOUT |
559 WDIOF_KEEPALIVEPING | 559 WDIOF_KEEPALIVEPING |
560 WDIOF_MAGICCLOSE, 560 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index 7ba0b11ec525..bb9750a03942 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -34,7 +34,6 @@
34#include <linux/mm.h> 34#include <linux/mm.h>
35#include <linux/miscdevice.h> 35#include <linux/miscdevice.h>
36#include <linux/watchdog.h> 36#include <linux/watchdog.h>
37#include <linux/platform_device.h>
38#include <linux/init.h> 37#include <linux/init.h>
39#include <linux/pci.h> 38#include <linux/pci.h>
40#include <linux/ioport.h> 39#include <linux/ioport.h>
@@ -42,7 +41,7 @@
42#include <linux/io.h> 41#include <linux/io.h>
43 42
44/* Module and version information */ 43/* Module and version information */
45#define ESB_VERSION "0.04" 44#define ESB_VERSION "0.05"
46#define ESB_MODULE_NAME "i6300ESB timer" 45#define ESB_MODULE_NAME "i6300ESB timer"
47#define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION 46#define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
48#define PFX ESB_MODULE_NAME ": " 47#define PFX ESB_MODULE_NAME ": "
@@ -65,7 +64,7 @@
65/* Config register bits */ 64/* Config register bits */
66#define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ 65#define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */
67#define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ 66#define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */
68#define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */ 67#define ESB_WDT_INTTYPE (0x03 << 0) /* Interrupt type on timer1 timeout */
69 68
70/* Reload register bits */ 69/* Reload register bits */
71#define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */ 70#define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */
@@ -82,7 +81,9 @@ static unsigned long timer_alive;
82static struct pci_dev *esb_pci; 81static struct pci_dev *esb_pci;
83static unsigned short triggered; /* The status of the watchdog upon boot */ 82static unsigned short triggered; /* The status of the watchdog upon boot */
84static char esb_expect_close; 83static char esb_expect_close;
85static struct platform_device *esb_platform_device; 84
85/* We can only use 1 card due to the /dev/watchdog restriction */
86static int cards_found;
86 87
87/* module parameters */ 88/* module parameters */
88/* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ 89/* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
@@ -111,8 +112,8 @@ MODULE_PARM_DESC(nowayout,
111 */ 112 */
112static inline void esb_unlock_registers(void) 113static inline void esb_unlock_registers(void)
113{ 114{
114 writeb(ESB_UNLOCK1, ESB_RELOAD_REG); 115 writew(ESB_UNLOCK1, ESB_RELOAD_REG);
115 writeb(ESB_UNLOCK2, ESB_RELOAD_REG); 116 writew(ESB_UNLOCK2, ESB_RELOAD_REG);
116} 117}
117 118
118static int esb_timer_start(void) 119static int esb_timer_start(void)
@@ -256,7 +257,7 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
256 int new_heartbeat; 257 int new_heartbeat;
257 void __user *argp = (void __user *)arg; 258 void __user *argp = (void __user *)arg;
258 int __user *p = argp; 259 int __user *p = argp;
259 static struct watchdog_info ident = { 260 static const struct watchdog_info ident = {
260 .options = WDIOF_SETTIMEOUT | 261 .options = WDIOF_SETTIMEOUT |
261 WDIOF_KEEPALIVEPING | 262 WDIOF_KEEPALIVEPING |
262 WDIOF_MAGICCLOSE, 263 WDIOF_MAGICCLOSE,
@@ -332,11 +333,6 @@ static struct miscdevice esb_miscdev = {
332 333
333/* 334/*
334 * Data for PCI driver interface 335 * Data for PCI driver interface
335 *
336 * This data only exists for exporting the supported
337 * PCI ids via MODULE_DEVICE_TABLE. We do not actually
338 * register a pci_driver, because someone else might one day
339 * want to register another driver on the same PCI id.
340 */ 336 */
341static struct pci_device_id esb_pci_tbl[] = { 337static struct pci_device_id esb_pci_tbl[] = {
342 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, 338 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
@@ -348,29 +344,19 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
348 * Init & exit routines 344 * Init & exit routines
349 */ 345 */
350 346
351static unsigned char __devinit esb_getdevice(void) 347static unsigned char __devinit esb_getdevice(struct pci_dev *pdev)
352{ 348{
353 /* 349 if (pci_enable_device(pdev)) {
354 * Find the PCI device
355 */
356
357 esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL,
358 PCI_DEVICE_ID_INTEL_ESB_9, NULL);
359
360 if (!esb_pci)
361 return 0;
362
363 if (pci_enable_device(esb_pci)) {
364 printk(KERN_ERR PFX "failed to enable device\n"); 350 printk(KERN_ERR PFX "failed to enable device\n");
365 goto err_devput; 351 goto err_devput;
366 } 352 }
367 353
368 if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { 354 if (pci_request_region(pdev, 0, ESB_MODULE_NAME)) {
369 printk(KERN_ERR PFX "failed to request region\n"); 355 printk(KERN_ERR PFX "failed to request region\n");
370 goto err_disable; 356 goto err_disable;
371 } 357 }
372 358
373 BASEADDR = pci_ioremap_bar(esb_pci, 0); 359 BASEADDR = pci_ioremap_bar(pdev, 0);
374 if (BASEADDR == NULL) { 360 if (BASEADDR == NULL) {
375 /* Something's wrong here, BASEADDR has to be set */ 361 /* Something's wrong here, BASEADDR has to be set */
376 printk(KERN_ERR PFX "failed to get BASEADDR\n"); 362 printk(KERN_ERR PFX "failed to get BASEADDR\n");
@@ -378,14 +364,14 @@ static unsigned char __devinit esb_getdevice(void)
378 } 364 }
379 365
380 /* Done */ 366 /* Done */
367 esb_pci = pdev;
381 return 1; 368 return 1;
382 369
383err_release: 370err_release:
384 pci_release_region(esb_pci, 0); 371 pci_release_region(pdev, 0);
385err_disable: 372err_disable:
386 pci_disable_device(esb_pci); 373 pci_disable_device(pdev);
387err_devput: 374err_devput:
388 pci_dev_put(esb_pci);
389 return 0; 375 return 0;
390} 376}
391 377
@@ -430,12 +416,23 @@ static void __devinit esb_initdevice(void)
430 esb_timer_set_heartbeat(heartbeat); 416 esb_timer_set_heartbeat(heartbeat);
431} 417}
432 418
433static int __devinit esb_probe(struct platform_device *dev) 419static int __devinit esb_probe(struct pci_dev *pdev,
420 const struct pci_device_id *ent)
434{ 421{
435 int ret; 422 int ret;
436 423
424 cards_found++;
425 if (cards_found == 1)
426 printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n",
427 ESB_VERSION);
428
429 if (cards_found > 1) {
430 printk(KERN_ERR PFX "This driver only supports 1 device\n");
431 return -ENODEV;
432 }
433
437 /* Check whether or not the hardware watchdog is there */ 434 /* Check whether or not the hardware watchdog is there */
438 if (!esb_getdevice() || esb_pci == NULL) 435 if (!esb_getdevice(pdev) || esb_pci == NULL)
439 return -ENODEV; 436 return -ENODEV;
440 437
441 /* Check that the heartbeat value is within it's range; 438 /* Check that the heartbeat value is within it's range;
@@ -467,11 +464,11 @@ err_unmap:
467 iounmap(BASEADDR); 464 iounmap(BASEADDR);
468 pci_release_region(esb_pci, 0); 465 pci_release_region(esb_pci, 0);
469 pci_disable_device(esb_pci); 466 pci_disable_device(esb_pci);
470 pci_dev_put(esb_pci); 467 esb_pci = NULL;
471 return ret; 468 return ret;
472} 469}
473 470
474static int __devexit esb_remove(struct platform_device *dev) 471static void __devexit esb_remove(struct pci_dev *pdev)
475{ 472{
476 /* Stop the timer before we leave */ 473 /* Stop the timer before we leave */
477 if (!nowayout) 474 if (!nowayout)
@@ -482,54 +479,30 @@ static int __devexit esb_remove(struct platform_device *dev)
482 iounmap(BASEADDR); 479 iounmap(BASEADDR);
483 pci_release_region(esb_pci, 0); 480 pci_release_region(esb_pci, 0);
484 pci_disable_device(esb_pci); 481 pci_disable_device(esb_pci);
485 pci_dev_put(esb_pci); 482 esb_pci = NULL;
486 return 0;
487} 483}
488 484
489static void esb_shutdown(struct platform_device *dev) 485static void esb_shutdown(struct pci_dev *pdev)
490{ 486{
491 esb_timer_stop(); 487 esb_timer_stop();
492} 488}
493 489
494static struct platform_driver esb_platform_driver = { 490static struct pci_driver esb_driver = {
491 .name = ESB_MODULE_NAME,
492 .id_table = esb_pci_tbl,
495 .probe = esb_probe, 493 .probe = esb_probe,
496 .remove = __devexit_p(esb_remove), 494 .remove = __devexit_p(esb_remove),
497 .shutdown = esb_shutdown, 495 .shutdown = esb_shutdown,
498 .driver = {
499 .owner = THIS_MODULE,
500 .name = ESB_MODULE_NAME,
501 },
502}; 496};
503 497
504static int __init watchdog_init(void) 498static int __init watchdog_init(void)
505{ 499{
506 int err; 500 return pci_register_driver(&esb_driver);
507
508 printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n",
509 ESB_VERSION);
510
511 err = platform_driver_register(&esb_platform_driver);
512 if (err)
513 return err;
514
515 esb_platform_device = platform_device_register_simple(ESB_MODULE_NAME,
516 -1, NULL, 0);
517 if (IS_ERR(esb_platform_device)) {
518 err = PTR_ERR(esb_platform_device);
519 goto unreg_platform_driver;
520 }
521
522 return 0;
523
524unreg_platform_driver:
525 platform_driver_unregister(&esb_platform_driver);
526 return err;
527} 501}
528 502
529static void __exit watchdog_cleanup(void) 503static void __exit watchdog_cleanup(void)
530{ 504{
531 platform_device_unregister(esb_platform_device); 505 pci_unregister_driver(&esb_driver);
532 platform_driver_unregister(&esb_platform_driver);
533 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); 506 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
534} 507}
535 508
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 4bdb7f1a9077..44bc6aa46edf 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -584,7 +584,7 @@ static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd,
584 int new_heartbeat; 584 int new_heartbeat;
585 void __user *argp = (void __user *)arg; 585 void __user *argp = (void __user *)arg;
586 int __user *p = argp; 586 int __user *p = argp;
587 static struct watchdog_info ident = { 587 static const struct watchdog_info ident = {
588 .options = WDIOF_SETTIMEOUT | 588 .options = WDIOF_SETTIMEOUT |
589 WDIOF_KEEPALIVEPING | 589 WDIOF_KEEPALIVEPING |
590 WDIOF_MAGICCLOSE, 590 WDIOF_MAGICCLOSE,
@@ -698,7 +698,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
698 if (iTCO_wdt_private.iTCO_version == 2) { 698 if (iTCO_wdt_private.iTCO_version == 2) {
699 pci_read_config_dword(pdev, 0xf0, &base_address); 699 pci_read_config_dword(pdev, 0xf0, &base_address);
700 if ((base_address & 1) == 0) { 700 if ((base_address & 1) == 0) {
701 printk(KERN_ERR PFX "RCBA is disabled by harddware\n"); 701 printk(KERN_ERR PFX "RCBA is disabled by hardware\n");
702 ret = -ENODEV; 702 ret = -ENODEV;
703 goto out; 703 goto out;
704 } 704 }
@@ -708,8 +708,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
708 708
709 /* Check chipset's NO_REBOOT bit */ 709 /* Check chipset's NO_REBOOT bit */
710 if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { 710 if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
711 printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " 711 printk(KERN_INFO PFX "unable to reset NO_REBOOT flag, "
712 "reboot disabled by hardware\n"); 712 "platform may have disabled it\n");
713 ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ 713 ret = -ENODEV; /* Cannot reset NO_REBOOT bit */
714 goto out_unmap; 714 goto out_unmap;
715 } 715 }
@@ -805,6 +805,7 @@ static void __devexit iTCO_wdt_cleanup(void)
805 805
806static int __devinit iTCO_wdt_probe(struct platform_device *dev) 806static int __devinit iTCO_wdt_probe(struct platform_device *dev)
807{ 807{
808 int ret = -ENODEV;
808 int found = 0; 809 int found = 0;
809 struct pci_dev *pdev = NULL; 810 struct pci_dev *pdev = NULL;
810 const struct pci_device_id *ent; 811 const struct pci_device_id *ent;
@@ -814,19 +815,17 @@ static int __devinit iTCO_wdt_probe(struct platform_device *dev)
814 for_each_pci_dev(pdev) { 815 for_each_pci_dev(pdev) {
815 ent = pci_match_id(iTCO_wdt_pci_tbl, pdev); 816 ent = pci_match_id(iTCO_wdt_pci_tbl, pdev);
816 if (ent) { 817 if (ent) {
817 if (!(iTCO_wdt_init(pdev, ent, dev))) { 818 found++;
818 found++; 819 ret = iTCO_wdt_init(pdev, ent, dev);
820 if (!ret)
819 break; 821 break;
820 }
821 } 822 }
822 } 823 }
823 824
824 if (!found) { 825 if (!found)
825 printk(KERN_INFO PFX "No card detected\n"); 826 printk(KERN_INFO PFX "No card detected\n");
826 return -ENODEV;
827 }
828 827
829 return 0; 828 return ret;
830} 829}
831 830
832static int __devexit iTCO_wdt_remove(struct platform_device *dev) 831static int __devexit iTCO_wdt_remove(struct platform_device *dev)
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c
index 4bef3ddff4a5..0149d8dfc81d 100644
--- a/drivers/watchdog/ib700wdt.c
+++ b/drivers/watchdog/ib700wdt.c
@@ -174,7 +174,7 @@ static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
174 void __user *argp = (void __user *)arg; 174 void __user *argp = (void __user *)arg;
175 int __user *p = argp; 175 int __user *p = argp;
176 176
177 static struct watchdog_info ident = { 177 static const struct watchdog_info ident = {
178 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT 178 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
179 | WDIOF_MAGICCLOSE, 179 | WDIOF_MAGICCLOSE,
180 .firmware_version = 1, 180 .firmware_version = 1,
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c
index bea8a124a559..1cc5609666d1 100644
--- a/drivers/watchdog/indydog.c
+++ b/drivers/watchdog/indydog.c
@@ -111,7 +111,7 @@ static long indydog_ioctl(struct file *file, unsigned int cmd,
111 unsigned long arg) 111 unsigned long arg)
112{ 112{
113 int options, retval = -EINVAL; 113 int options, retval = -EINVAL;
114 static struct watchdog_info ident = { 114 static const struct watchdog_info ident = {
115 .options = WDIOF_KEEPALIVEPING, 115 .options = WDIOF_KEEPALIVEPING,
116 .firmware_version = 0, 116 .firmware_version = 0,
117 .identity = "Hardware Watchdog for SGI IP22", 117 .identity = "Hardware Watchdog for SGI IP22",
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
index daed48ded7fe..f52c162b1bea 100644
--- a/drivers/watchdog/it8712f_wdt.c
+++ b/drivers/watchdog/it8712f_wdt.c
@@ -236,7 +236,7 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
236{ 236{
237 void __user *argp = (void __user *)arg; 237 void __user *argp = (void __user *)arg;
238 int __user *p = argp; 238 int __user *p = argp;
239 static struct watchdog_info ident = { 239 static const struct watchdog_info ident = {
240 .identity = "IT8712F Watchdog", 240 .identity = "IT8712F Watchdog",
241 .firmware_version = 1, 241 .firmware_version = 1,
242 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | 242 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c
index cc133c531d08..b709b3b2d1ef 100644
--- a/drivers/watchdog/it87_wdt.c
+++ b/drivers/watchdog/it87_wdt.c
@@ -421,7 +421,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf,
421 return count; 421 return count;
422} 422}
423 423
424static struct watchdog_info ident = { 424static const struct watchdog_info ident = {
425 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 425 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
426 .firmware_version = 1, 426 .firmware_version = 1,
427 .identity = WATCHDOG_NAME, 427 .identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
index 3c79dc587958..e86952a7168c 100644
--- a/drivers/watchdog/ixp2000_wdt.c
+++ b/drivers/watchdog/ixp2000_wdt.c
@@ -100,7 +100,7 @@ static ssize_t ixp2000_wdt_write(struct file *file, const char *data,
100} 100}
101 101
102 102
103static struct watchdog_info ident = { 103static const struct watchdog_info ident = {
104 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | 104 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
105 WDIOF_KEEPALIVEPING, 105 WDIOF_KEEPALIVEPING,
106 .identity = "IXP2000 Watchdog", 106 .identity = "IXP2000 Watchdog",
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c
index 147b4d5c63b3..e02c0ecda26b 100644
--- a/drivers/watchdog/ixp4xx_wdt.c
+++ b/drivers/watchdog/ixp4xx_wdt.c
@@ -89,7 +89,7 @@ ixp4xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
89 return len; 89 return len;
90} 90}
91 91
92static struct watchdog_info ident = { 92static const struct watchdog_info ident = {
93 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | 93 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
94 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 94 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
95 .identity = "IXP4xx Watchdog", 95 .identity = "IXP4xx Watchdog",
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index e1c82769b08e..2852bb2e3fd9 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -145,7 +145,7 @@ static int ks8695_wdt_close(struct inode *inode, struct file *file)
145 return 0; 145 return 0;
146} 146}
147 147
148static struct watchdog_info ks8695_wdt_info = { 148static const struct watchdog_info ks8695_wdt_info = {
149 .identity = "ks8695 watchdog", 149 .identity = "ks8695 watchdog",
150 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 150 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
151}; 151};
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
index 47d719717a3b..2d118cf022fc 100644
--- a/drivers/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
@@ -101,7 +101,7 @@ MODULE_PARM_DESC(nowayout,
101 101
102#define PFX "machzwd" 102#define PFX "machzwd"
103 103
104static struct watchdog_info zf_info = { 104static const struct watchdog_info zf_info = {
105 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 105 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
106 .firmware_version = 1, 106 .firmware_version = 1,
107 .identity = "ZF-Logic watchdog", 107 .identity = "ZF-Logic watchdog",
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c
new file mode 100644
index 000000000000..6eb91d757604
--- /dev/null
+++ b/drivers/watchdog/max63xx_wdt.c
@@ -0,0 +1,397 @@
1/*
2 * drivers/char/watchdog/max63xx_wdt.c
3 *
4 * Driver for max63{69,70,71,72,73,74} watchdog timers
5 *
6 * Copyright (C) 2009 Marc Zyngier <maz@misterjones.org>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 *
12 * This driver assumes the watchdog pins are memory mapped (as it is
13 * the case for the Arcom Zeus). Should it be connected over GPIOs or
14 * another interface, some abstraction will have to be introduced.
15 */
16
17#include <linux/module.h>
18#include <linux/moduleparam.h>
19#include <linux/types.h>
20#include <linux/kernel.h>
21#include <linux/fs.h>
22#include <linux/miscdevice.h>
23#include <linux/watchdog.h>
24#include <linux/init.h>
25#include <linux/bitops.h>
26#include <linux/platform_device.h>
27#include <linux/spinlock.h>
28#include <linux/uaccess.h>
29#include <linux/io.h>
30#include <linux/device.h>
31
32#define DEFAULT_HEARTBEAT 60
33#define MAX_HEARTBEAT 60
34
35static int heartbeat = DEFAULT_HEARTBEAT;
36static int nowayout = WATCHDOG_NOWAYOUT;
37
38/*
39 * Memory mapping: a single byte, 3 first lower bits to select bit 3
40 * to ping the watchdog.
41 */
42#define MAX6369_WDSET (7 << 0)
43#define MAX6369_WDI (1 << 3)
44
45static DEFINE_SPINLOCK(io_lock);
46
47static unsigned long wdt_status;
48#define WDT_IN_USE 0
49#define WDT_RUNNING 1
50#define WDT_OK_TO_CLOSE 2
51
52static int nodelay;
53static struct resource *wdt_mem;
54static void __iomem *wdt_base;
55static struct platform_device *max63xx_pdev;
56
57/*
58 * The timeout values used are actually the absolute minimum the chip
59 * offers. Typical values on my board are slightly over twice as long
60 * (10s setting ends up with a 25s timeout), and can be up to 3 times
61 * the nominal setting (according to the datasheet). So please take
62 * these values with a grain of salt. Same goes for the initial delay
63 * "feature". Only max6373/74 have a few settings without this initial
64 * delay (selected with the "nodelay" parameter).
65 *
66 * I also decided to remove from the tables any timeout smaller than a
67 * second, as it looked completly overkill...
68 */
69
70/* Timeouts in second */
71struct max63xx_timeout {
72 u8 wdset;
73 u8 tdelay;
74 u8 twd;
75};
76
77static struct max63xx_timeout max6369_table[] = {
78 { 5, 1, 1 },
79 { 6, 10, 10 },
80 { 7, 60, 60 },
81 { },
82};
83
84static struct max63xx_timeout max6371_table[] = {
85 { 6, 60, 3 },
86 { 7, 60, 60 },
87 { },
88};
89
90static struct max63xx_timeout max6373_table[] = {
91 { 2, 60, 1 },
92 { 5, 0, 1 },
93 { 1, 3, 3 },
94 { 7, 60, 10 },
95 { 6, 0, 10 },
96 { },
97};
98
99static struct max63xx_timeout *current_timeout;
100
101static struct max63xx_timeout *
102max63xx_select_timeout(struct max63xx_timeout *table, int value)
103{
104 while (table->twd) {
105 if (value <= table->twd) {
106 if (nodelay && table->tdelay == 0)
107 return table;
108
109 if (!nodelay)
110 return table;
111 }
112
113 table++;
114 }
115
116 return NULL;
117}
118
119static void max63xx_wdt_ping(void)
120{
121 u8 val;
122
123 spin_lock(&io_lock);
124
125 val = __raw_readb(wdt_base);
126
127 __raw_writeb(val | MAX6369_WDI, wdt_base);
128 __raw_writeb(val & ~MAX6369_WDI, wdt_base);
129
130 spin_unlock(&io_lock);
131}
132
133static void max63xx_wdt_enable(struct max63xx_timeout *entry)
134{
135 u8 val;
136
137 if (test_and_set_bit(WDT_RUNNING, &wdt_status))
138 return;
139
140 spin_lock(&io_lock);
141
142 val = __raw_readb(wdt_base);
143 val &= ~MAX6369_WDSET;
144 val |= entry->wdset;
145 __raw_writeb(val, wdt_base);
146
147 spin_unlock(&io_lock);
148
149 /* check for a edge triggered startup */
150 if (entry->tdelay == 0)
151 max63xx_wdt_ping();
152}
153
154static void max63xx_wdt_disable(void)
155{
156 spin_lock(&io_lock);
157
158 __raw_writeb(3, wdt_base);
159
160 spin_unlock(&io_lock);
161
162 clear_bit(WDT_RUNNING, &wdt_status);
163}
164
165static int max63xx_wdt_open(struct inode *inode, struct file *file)
166{
167 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
168 return -EBUSY;
169
170 max63xx_wdt_enable(current_timeout);
171 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
172
173 return nonseekable_open(inode, file);
174}
175
176static ssize_t max63xx_wdt_write(struct file *file, const char *data,
177 size_t len, loff_t *ppos)
178{
179 if (len) {
180 if (!nowayout) {
181 size_t i;
182
183 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
184 for (i = 0; i != len; i++) {
185 char c;
186
187 if (get_user(c, data + i))
188 return -EFAULT;
189
190 if (c == 'V')
191 set_bit(WDT_OK_TO_CLOSE, &wdt_status);
192 }
193 }
194
195 max63xx_wdt_ping();
196 }
197
198 return len;
199}
200
201static const struct watchdog_info ident = {
202 .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
203 .identity = "max63xx Watchdog",
204};
205
206static long max63xx_wdt_ioctl(struct file *file, unsigned int cmd,
207 unsigned long arg)
208{
209 int ret = -ENOTTY;
210
211 switch (cmd) {
212 case WDIOC_GETSUPPORT:
213 ret = copy_to_user((struct watchdog_info *)arg, &ident,
214 sizeof(ident)) ? -EFAULT : 0;
215 break;
216
217 case WDIOC_GETSTATUS:
218 case WDIOC_GETBOOTSTATUS:
219 ret = put_user(0, (int *)arg);
220 break;
221
222 case WDIOC_KEEPALIVE:
223 max63xx_wdt_ping();
224 ret = 0;
225 break;
226
227 case WDIOC_GETTIMEOUT:
228 ret = put_user(heartbeat, (int *)arg);
229 break;
230 }
231 return ret;
232}
233
234static int max63xx_wdt_release(struct inode *inode, struct file *file)
235{
236 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
237 max63xx_wdt_disable();
238 else
239 dev_crit(&max63xx_pdev->dev,
240 "device closed unexpectedly - timer will not stop\n");
241
242 clear_bit(WDT_IN_USE, &wdt_status);
243 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
244
245 return 0;
246}
247
248static const struct file_operations max63xx_wdt_fops = {
249 .owner = THIS_MODULE,
250 .llseek = no_llseek,
251 .write = max63xx_wdt_write,
252 .unlocked_ioctl = max63xx_wdt_ioctl,
253 .open = max63xx_wdt_open,
254 .release = max63xx_wdt_release,
255};
256
257static struct miscdevice max63xx_wdt_miscdev = {
258 .minor = WATCHDOG_MINOR,
259 .name = "watchdog",
260 .fops = &max63xx_wdt_fops,
261};
262
263static int __devinit max63xx_wdt_probe(struct platform_device *pdev)
264{
265 int ret = 0;
266 int size;
267 struct resource *res;
268 struct device *dev = &pdev->dev;
269 struct max63xx_timeout *table;
270
271 table = (struct max63xx_timeout *)pdev->id_entry->driver_data;
272
273 if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
274 heartbeat = DEFAULT_HEARTBEAT;
275
276 dev_info(dev, "requesting %ds heartbeat\n", heartbeat);
277 current_timeout = max63xx_select_timeout(table, heartbeat);
278
279 if (!current_timeout) {
280 dev_err(dev, "unable to satisfy heartbeat request\n");
281 return -EINVAL;
282 }
283
284 dev_info(dev, "using %ds heartbeat with %ds initial delay\n",
285 current_timeout->twd, current_timeout->tdelay);
286
287 heartbeat = current_timeout->twd;
288
289 max63xx_pdev = pdev;
290
291 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
292 if (res == NULL) {
293 dev_err(dev, "failed to get memory region resource\n");
294 return -ENOENT;
295 }
296
297 size = resource_size(res);
298 wdt_mem = request_mem_region(res->start, size, pdev->name);
299
300 if (wdt_mem == NULL) {
301 dev_err(dev, "failed to get memory region\n");
302 return -ENOENT;
303 }
304
305 wdt_base = ioremap(res->start, size);
306 if (!wdt_base) {
307 dev_err(dev, "failed to map memory region\n");
308 ret = -ENOMEM;
309 goto out_request;
310 }
311
312 ret = misc_register(&max63xx_wdt_miscdev);
313 if (ret < 0) {
314 dev_err(dev, "cannot register misc device\n");
315 goto out_unmap;
316 }
317
318 return 0;
319
320out_unmap:
321 iounmap(wdt_base);
322out_request:
323 release_resource(wdt_mem);
324 kfree(wdt_mem);
325
326 return ret;
327}
328
329static int __devexit max63xx_wdt_remove(struct platform_device *pdev)
330{
331 misc_deregister(&max63xx_wdt_miscdev);
332 if (wdt_mem) {
333 release_resource(wdt_mem);
334 kfree(wdt_mem);
335 wdt_mem = NULL;
336 }
337
338 if (wdt_base)
339 iounmap(wdt_base);
340
341 return 0;
342}
343
344static struct platform_device_id max63xx_id_table[] = {
345 { "max6369_wdt", (kernel_ulong_t)max6369_table, },
346 { "max6370_wdt", (kernel_ulong_t)max6369_table, },
347 { "max6371_wdt", (kernel_ulong_t)max6371_table, },
348 { "max6372_wdt", (kernel_ulong_t)max6371_table, },
349 { "max6373_wdt", (kernel_ulong_t)max6373_table, },
350 { "max6374_wdt", (kernel_ulong_t)max6373_table, },
351 { },
352};
353MODULE_DEVICE_TABLE(platform, max63xx_id_table);
354
355static struct platform_driver max63xx_wdt_driver = {
356 .probe = max63xx_wdt_probe,
357 .remove = __devexit_p(max63xx_wdt_remove),
358 .id_table = max63xx_id_table,
359 .driver = {
360 .name = "max63xx_wdt",
361 .owner = THIS_MODULE,
362 },
363};
364
365static int __init max63xx_wdt_init(void)
366{
367 return platform_driver_register(&max63xx_wdt_driver);
368}
369
370static void __exit max63xx_wdt_exit(void)
371{
372 platform_driver_unregister(&max63xx_wdt_driver);
373}
374
375module_init(max63xx_wdt_init);
376module_exit(max63xx_wdt_exit);
377
378MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>");
379MODULE_DESCRIPTION("max63xx Watchdog Driver");
380
381module_param(heartbeat, int, 0);
382MODULE_PARM_DESC(heartbeat,
383 "Watchdog heartbeat period in seconds from 1 to "
384 __MODULE_STRING(MAX_HEARTBEAT) ", default "
385 __MODULE_STRING(DEFAULT_HEARTBEAT));
386
387module_param(nowayout, int, 0);
388MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
389 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
390
391module_param(nodelay, int, 0);
392MODULE_PARM_DESC(nodelay,
393 "Force selection of a timeout setting without initial delay "
394 "(max6373/74 only, default=0)");
395
396MODULE_LICENSE("GPL");
397MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c
index 407b025cb104..bc820d16699a 100644
--- a/drivers/watchdog/mixcomwd.c
+++ b/drivers/watchdog/mixcomwd.c
@@ -201,7 +201,7 @@ static long mixcomwd_ioctl(struct file *file,
201 void __user *argp = (void __user *)arg; 201 void __user *argp = (void __user *)arg;
202 int __user *p = argp; 202 int __user *p = argp;
203 int status; 203 int status;
204 static struct watchdog_info ident = { 204 static const struct watchdog_info ident = {
205 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 205 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
206 .firmware_version = 1, 206 .firmware_version = 1,
207 .identity = "MixCOM watchdog", 207 .identity = "MixCOM watchdog",
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index 38c588ee694f..4e3941c5e293 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -148,7 +148,7 @@ static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd,
148{ 148{
149 void __user *argp = (void __user *)arg; 149 void __user *argp = (void __user *)arg;
150 int __user *p = argp; 150 int __user *p = argp;
151 static struct watchdog_info ident = { 151 static const struct watchdog_info ident = {
152 .options = WDIOF_KEEPALIVEPING, 152 .options = WDIOF_KEEPALIVEPING,
153 .firmware_version = 1, 153 .firmware_version = 1,
154 .identity = "MPC8xxx", 154 .identity = "MPC8xxx",
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index a2dc07c2ed49..b0646dac924e 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -213,7 +213,7 @@ static ssize_t mpcore_wdt_write(struct file *file, const char *data,
213 return len; 213 return len;
214} 214}
215 215
216static struct watchdog_info ident = { 216static const struct watchdog_info ident = {
217 .options = WDIOF_SETTIMEOUT | 217 .options = WDIOF_SETTIMEOUT |
218 WDIOF_KEEPALIVEPING | 218 WDIOF_KEEPALIVEPING |
219 WDIOF_MAGICCLOSE, 219 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c
index a51dbe4c43da..97f8a48d8b78 100644
--- a/drivers/watchdog/mv64x60_wdt.c
+++ b/drivers/watchdog/mv64x60_wdt.c
@@ -179,7 +179,7 @@ static long mv64x60_wdt_ioctl(struct file *file,
179 int timeout; 179 int timeout;
180 int options; 180 int options;
181 void __user *argp = (void __user *)arg; 181 void __user *argp = (void __user *)arg;
182 static struct watchdog_info info = { 182 static const struct watchdog_info info = {
183 .options = WDIOF_SETTIMEOUT | 183 .options = WDIOF_SETTIMEOUT |
184 WDIOF_MAGICCLOSE | 184 WDIOF_MAGICCLOSE |
185 WDIOF_KEEPALIVEPING, 185 WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c
index 1a2b916e3f8d..d3aa2f1fe61d 100644
--- a/drivers/watchdog/pc87413_wdt.c
+++ b/drivers/watchdog/pc87413_wdt.c
@@ -407,7 +407,7 @@ static long pc87413_ioctl(struct file *file, unsigned int cmd,
407 int __user *i; 407 int __user *i;
408 } uarg; 408 } uarg;
409 409
410 static struct watchdog_info ident = { 410 static const struct watchdog_info ident = {
411 .options = WDIOF_KEEPALIVEPING | 411 .options = WDIOF_KEEPALIVEPING |
412 WDIOF_SETTIMEOUT | 412 WDIOF_SETTIMEOUT |
413 WDIOF_MAGICCLOSE, 413 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c
index aa9512321f3a..06f7922606c0 100644
--- a/drivers/watchdog/pcwd.c
+++ b/drivers/watchdog/pcwd.c
@@ -606,7 +606,7 @@ static long pcwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
606 int temperature; 606 int temperature;
607 int new_heartbeat; 607 int new_heartbeat;
608 int __user *argp = (int __user *)arg; 608 int __user *argp = (int __user *)arg;
609 static struct watchdog_info ident = { 609 static const struct watchdog_info ident = {
610 .options = WDIOF_OVERHEAT | 610 .options = WDIOF_OVERHEAT |
611 WDIOF_CARDRESET | 611 WDIOF_CARDRESET |
612 WDIOF_KEEPALIVEPING | 612 WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index 698f51bff1bc..64374d636f09 100644
--- a/drivers/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
@@ -481,7 +481,7 @@ static long pcipcwd_ioctl(struct file *file, unsigned int cmd,
481{ 481{
482 void __user *argp = (void __user *)arg; 482 void __user *argp = (void __user *)arg;
483 int __user *p = argp; 483 int __user *p = argp;
484 static struct watchdog_info ident = { 484 static const struct watchdog_info ident = {
485 .options = WDIOF_OVERHEAT | 485 .options = WDIOF_OVERHEAT |
486 WDIOF_CARDRESET | 486 WDIOF_CARDRESET |
487 WDIOF_KEEPALIVEPING | 487 WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index 052fe451851f..8e4eacc5bb52 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -404,7 +404,7 @@ static long usb_pcwd_ioctl(struct file *file, unsigned int cmd,
404{ 404{
405 void __user *argp = (void __user *)arg; 405 void __user *argp = (void __user *)arg;
406 int __user *p = argp; 406 int __user *p = argp;
407 static struct watchdog_info ident = { 407 static const struct watchdog_info ident = {
408 .options = WDIOF_KEEPALIVEPING | 408 .options = WDIOF_KEEPALIVEPING |
409 WDIOF_SETTIMEOUT | 409 WDIOF_SETTIMEOUT |
410 WDIOF_MAGICCLOSE, 410 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/pika_wdt.c b/drivers/watchdog/pika_wdt.c
index 2d22e996e996..435ec2aed4fe 100644
--- a/drivers/watchdog/pika_wdt.c
+++ b/drivers/watchdog/pika_wdt.c
@@ -52,7 +52,7 @@ static struct {
52 struct timer_list timer; /* The timer that pings the watchdog */ 52 struct timer_list timer; /* The timer that pings the watchdog */
53} pikawdt_private; 53} pikawdt_private;
54 54
55static struct watchdog_info ident = { 55static const struct watchdog_info ident = {
56 .identity = DRV_NAME, 56 .identity = DRV_NAME,
57 .options = WDIOF_CARDRESET | 57 .options = WDIOF_CARDRESET |
58 WDIOF_SETTIMEOUT | 58 WDIOF_SETTIMEOUT |
diff --git a/drivers/watchdog/pnx833x_wdt.c b/drivers/watchdog/pnx833x_wdt.c
index 538ec2c05197..09102f09e681 100644
--- a/drivers/watchdog/pnx833x_wdt.c
+++ b/drivers/watchdog/pnx833x_wdt.c
@@ -141,7 +141,7 @@ static long pnx833x_wdt_ioctl(struct file *file, unsigned int cmd,
141 int options, new_timeout = 0; 141 int options, new_timeout = 0;
142 uint32_t timeout, timeout_left = 0; 142 uint32_t timeout, timeout_left = 0;
143 143
144 static struct watchdog_info ident = { 144 static const struct watchdog_info ident = {
145 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, 145 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
146 .firmware_version = 0, 146 .firmware_version = 0,
147 .identity = "Hardware Watchdog for PNX833x", 147 .identity = "Hardware Watchdog for PNX833x",
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
index bf12d06b5877..d4c29b5311a4 100644
--- a/drivers/watchdog/rc32434_wdt.c
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -198,7 +198,7 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd,
198 void __user *argp = (void __user *)arg; 198 void __user *argp = (void __user *)arg;
199 int new_timeout; 199 int new_timeout;
200 unsigned int value; 200 unsigned int value;
201 static struct watchdog_info ident = { 201 static const struct watchdog_info ident = {
202 .options = WDIOF_SETTIMEOUT | 202 .options = WDIOF_SETTIMEOUT |
203 WDIOF_KEEPALIVEPING | 203 WDIOF_KEEPALIVEPING |
204 WDIOF_MAGICCLOSE, 204 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 4976bfd1fce6..69c6adbd8205 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -149,7 +149,7 @@ static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd,
149{ 149{
150 void __user *argp = (void __user *)arg; 150 void __user *argp = (void __user *)arg;
151 unsigned int value; 151 unsigned int value;
152 static struct watchdog_info ident = { 152 static const struct watchdog_info ident = {
153 .options = WDIOF_CARDRESET, 153 .options = WDIOF_CARDRESET,
154 .identity = "RDC321x WDT", 154 .identity = "RDC321x WDT",
155 }; 155 };
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c
index c14ae8676903..ae57bf9e1b03 100644
--- a/drivers/watchdog/riowd.c
+++ b/drivers/watchdog/riowd.c
@@ -85,7 +85,7 @@ static int riowd_release(struct inode *inode, struct file *filp)
85 85
86static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 86static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
87{ 87{
88 static struct watchdog_info info = { 88 static const struct watchdog_info info = {
89 .options = WDIOF_SETTIMEOUT, 89 .options = WDIOF_SETTIMEOUT,
90 .firmware_version = 1, 90 .firmware_version = 1,
91 .identity = DRIVER_NAME, 91 .identity = DRIVER_NAME,
diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c
index e6763d2a567b..8d44c9b6fb5b 100644
--- a/drivers/watchdog/sbc_fitpc2_wdt.c
+++ b/drivers/watchdog/sbc_fitpc2_wdt.c
@@ -111,7 +111,7 @@ out:
111} 111}
112 112
113 113
114static struct watchdog_info ident = { 114static const struct watchdog_info ident = {
115 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | 115 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
116 WDIOF_KEEPALIVEPING, 116 WDIOF_KEEPALIVEPING,
117 .identity = WATCHDOG_NAME, 117 .identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c
index 569eb295a7a8..9c40f48804f5 100644
--- a/drivers/watchdog/sch311x_wdt.c
+++ b/drivers/watchdog/sch311x_wdt.c
@@ -250,7 +250,7 @@ static long sch311x_wdt_ioctl(struct file *file, unsigned int cmd,
250 int new_timeout; 250 int new_timeout;
251 void __user *argp = (void __user *)arg; 251 void __user *argp = (void __user *)arg;
252 int __user *p = argp; 252 int __user *p = argp;
253 static struct watchdog_info ident = { 253 static const struct watchdog_info ident = {
254 .options = WDIOF_KEEPALIVEPING | 254 .options = WDIOF_KEEPALIVEPING |
255 WDIOF_SETTIMEOUT | 255 WDIOF_SETTIMEOUT |
256 WDIOF_MAGICCLOSE, 256 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/stmp3xxx_wdt.c b/drivers/watchdog/stmp3xxx_wdt.c
index 5dd952681f32..b3421fd2cda8 100644
--- a/drivers/watchdog/stmp3xxx_wdt.c
+++ b/drivers/watchdog/stmp3xxx_wdt.c
@@ -94,7 +94,7 @@ static ssize_t stmp3xxx_wdt_write(struct file *file, const char __user *data,
94 return len; 94 return len;
95} 95}
96 96
97static struct watchdog_info ident = { 97static const struct watchdog_info ident = {
98 .options = WDIOF_CARDRESET | 98 .options = WDIOF_CARDRESET |
99 WDIOF_MAGICCLOSE | 99 WDIOF_MAGICCLOSE |
100 WDIOF_SETTIMEOUT | 100 WDIOF_SETTIMEOUT |
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c
new file mode 100644
index 000000000000..565a2c3321e5
--- /dev/null
+++ b/drivers/watchdog/ts72xx_wdt.c
@@ -0,0 +1,520 @@
1/*
2 * Watchdog driver for Technologic Systems TS-72xx based SBCs
3 * (TS-7200, TS-7250 and TS-7260). These boards have external
4 * glue logic CPLD chip, which includes programmable watchdog
5 * timer.
6 *
7 * Copyright (c) 2009 Mika Westerberg <mika.westerberg@iki.fi>
8 *
9 * This driver is based on ep93xx_wdt and wm831x_wdt drivers.
10 *
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * warranty of any kind, whether express or implied.
14 */
15
16#include <linux/fs.h>
17#include <linux/io.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/miscdevice.h>
21#include <linux/mutex.h>
22#include <linux/platform_device.h>
23#include <linux/watchdog.h>
24#include <linux/uaccess.h>
25
26#define TS72XX_WDT_FEED_VAL 0x05
27#define TS72XX_WDT_DEFAULT_TIMEOUT 8
28
29static int timeout = TS72XX_WDT_DEFAULT_TIMEOUT;
30module_param(timeout, int, 0);
31MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. "
32 "(1 <= timeout <= 8, default="
33 __MODULE_STRING(TS72XX_WDT_DEFAULT_TIMEOUT)
34 ")");
35
36static int nowayout = WATCHDOG_NOWAYOUT;
37module_param(nowayout, int, 0);
38MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
39
40/**
41 * struct ts72xx_wdt - watchdog control structure
42 * @lock: lock that protects this structure
43 * @regval: watchdog timeout value suitable for control register
44 * @flags: flags controlling watchdog device state
45 * @control_reg: watchdog control register
46 * @feed_reg: watchdog feed register
47 * @pdev: back pointer to platform dev
48 */
49struct ts72xx_wdt {
50 struct mutex lock;
51 int regval;
52
53#define TS72XX_WDT_BUSY_FLAG 1
54#define TS72XX_WDT_EXPECT_CLOSE_FLAG 2
55 int flags;
56
57 void __iomem *control_reg;
58 void __iomem *feed_reg;
59
60 struct platform_device *pdev;
61};
62
63struct platform_device *ts72xx_wdt_pdev;
64
65/*
66 * TS-72xx Watchdog supports following timeouts (value written
67 * to control register):
68 * value description
69 * -------------------------
70 * 0x00 watchdog disabled
71 * 0x01 250ms
72 * 0x02 500ms
73 * 0x03 1s
74 * 0x04 reserved
75 * 0x05 2s
76 * 0x06 4s
77 * 0x07 8s
78 *
79 * Timeouts below 1s are not very usable so we don't
80 * allow them at all.
81 *
82 * We provide two functions that convert between these:
83 * timeout_to_regval() and regval_to_timeout().
84 */
85static const struct {
86 int timeout;
87 int regval;
88} ts72xx_wdt_map[] = {
89 { 1, 3 },
90 { 2, 5 },
91 { 4, 6 },
92 { 8, 7 },
93};
94
95/**
96 * timeout_to_regval() - converts given timeout to control register value
97 * @new_timeout: timeout in seconds to be converted
98 *
99 * Function converts given @new_timeout into valid value that can
100 * be programmed into watchdog control register. When conversion is
101 * not possible, function returns %-EINVAL.
102 */
103static int timeout_to_regval(int new_timeout)
104{
105 int i;
106
107 /* first limit it to 1 - 8 seconds */
108 new_timeout = clamp_val(new_timeout, 1, 8);
109
110 for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) {
111 if (ts72xx_wdt_map[i].timeout >= new_timeout)
112 return ts72xx_wdt_map[i].regval;
113 }
114
115 return -EINVAL;
116}
117
118/**
119 * regval_to_timeout() - converts control register value to timeout
120 * @regval: control register value to be converted
121 *
122 * Function converts given @regval to timeout in seconds (1, 2, 4 or 8).
123 * If @regval cannot be converted, function returns %-EINVAL.
124 */
125static int regval_to_timeout(int regval)
126{
127 int i;
128
129 for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) {
130 if (ts72xx_wdt_map[i].regval == regval)
131 return ts72xx_wdt_map[i].timeout;
132 }
133
134 return -EINVAL;
135}
136
137/**
138 * ts72xx_wdt_kick() - kick the watchdog
139 * @wdt: watchdog to be kicked
140 *
141 * Called with @wdt->lock held.
142 */
143static inline void ts72xx_wdt_kick(struct ts72xx_wdt *wdt)
144{
145 __raw_writeb(TS72XX_WDT_FEED_VAL, wdt->feed_reg);
146}
147
148/**
149 * ts72xx_wdt_start() - starts the watchdog timer
150 * @wdt: watchdog to be started
151 *
152 * This function programs timeout to watchdog timer
153 * and starts it.
154 *
155 * Called with @wdt->lock held.
156 */
157static void ts72xx_wdt_start(struct ts72xx_wdt *wdt)
158{
159 /*
160 * To program the wdt, it first must be "fed" and
161 * only after that (within 30 usecs) the configuration
162 * can be changed.
163 */
164 ts72xx_wdt_kick(wdt);
165 __raw_writeb((u8)wdt->regval, wdt->control_reg);
166}
167
168/**
169 * ts72xx_wdt_stop() - stops the watchdog timer
170 * @wdt: watchdog to be stopped
171 *
172 * Called with @wdt->lock held.
173 */
174static void ts72xx_wdt_stop(struct ts72xx_wdt *wdt)
175{
176 ts72xx_wdt_kick(wdt);
177 __raw_writeb(0, wdt->control_reg);
178}
179
180static int ts72xx_wdt_open(struct inode *inode, struct file *file)
181{
182 struct ts72xx_wdt *wdt = platform_get_drvdata(ts72xx_wdt_pdev);
183 int regval;
184
185 /*
186 * Try to convert default timeout to valid register
187 * value first.
188 */
189 regval = timeout_to_regval(timeout);
190 if (regval < 0) {
191 dev_err(&wdt->pdev->dev,
192 "failed to convert timeout (%d) to register value\n",
193 timeout);
194 return -EINVAL;
195 }
196
197 if (mutex_lock_interruptible(&wdt->lock))
198 return -ERESTARTSYS;
199
200 if ((wdt->flags & TS72XX_WDT_BUSY_FLAG) != 0) {
201 mutex_unlock(&wdt->lock);
202 return -EBUSY;
203 }
204
205 wdt->flags = TS72XX_WDT_BUSY_FLAG;
206 wdt->regval = regval;
207 file->private_data = wdt;
208
209 ts72xx_wdt_start(wdt);
210
211 mutex_unlock(&wdt->lock);
212 return nonseekable_open(inode, file);
213}
214
215static int ts72xx_wdt_release(struct inode *inode, struct file *file)
216{
217 struct ts72xx_wdt *wdt = file->private_data;
218
219 if (mutex_lock_interruptible(&wdt->lock))
220 return -ERESTARTSYS;
221
222 if ((wdt->flags & TS72XX_WDT_EXPECT_CLOSE_FLAG) != 0) {
223 ts72xx_wdt_stop(wdt);
224 } else {
225 dev_warn(&wdt->pdev->dev,
226 "TS-72XX WDT device closed unexpectly. "
227 "Watchdog timer will not stop!\n");
228 /*
229 * Kick it one more time, to give userland some time
230 * to recover (for example, respawning the kicker
231 * daemon).
232 */
233 ts72xx_wdt_kick(wdt);
234 }
235
236 wdt->flags = 0;
237
238 mutex_unlock(&wdt->lock);
239 return 0;
240}
241
242static ssize_t ts72xx_wdt_write(struct file *file,
243 const char __user *data,
244 size_t len,
245 loff_t *ppos)
246{
247 struct ts72xx_wdt *wdt = file->private_data;
248
249 if (!len)
250 return 0;
251
252 if (mutex_lock_interruptible(&wdt->lock))
253 return -ERESTARTSYS;
254
255 ts72xx_wdt_kick(wdt);
256
257 /*
258 * Support for magic character closing. User process
259 * writes 'V' into the device, just before it is closed.
260 * This means that we know that the wdt timer can be
261 * stopped after user closes the device.
262 */
263 if (!nowayout) {
264 int i;
265
266 for (i = 0; i < len; i++) {
267 char c;
268
269 /* In case it was set long ago */
270 wdt->flags &= ~TS72XX_WDT_EXPECT_CLOSE_FLAG;
271
272 if (get_user(c, data + i)) {
273 mutex_unlock(&wdt->lock);
274 return -EFAULT;
275 }
276 if (c == 'V') {
277 wdt->flags |= TS72XX_WDT_EXPECT_CLOSE_FLAG;
278 break;
279 }
280 }
281 }
282
283 mutex_unlock(&wdt->lock);
284 return len;
285}
286
287static const struct watchdog_info winfo = {
288 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
289 WDIOF_MAGICCLOSE,
290 .firmware_version = 1,
291 .identity = "TS-72XX WDT",
292};
293
294static long ts72xx_wdt_ioctl(struct file *file, unsigned int cmd,
295 unsigned long arg)
296{
297 struct ts72xx_wdt *wdt = file->private_data;
298 void __user *argp = (void __user *)arg;
299 int __user *p = (int __user *)argp;
300 int error = 0;
301
302 if (mutex_lock_interruptible(&wdt->lock))
303 return -ERESTARTSYS;
304
305 switch (cmd) {
306 case WDIOC_GETSUPPORT:
307 error = copy_to_user(argp, &winfo, sizeof(winfo));
308 break;
309
310 case WDIOC_GETSTATUS:
311 case WDIOC_GETBOOTSTATUS:
312 return put_user(0, p);
313
314 case WDIOC_KEEPALIVE:
315 ts72xx_wdt_kick(wdt);
316 break;
317
318 case WDIOC_SETOPTIONS: {
319 int options;
320
321 if (get_user(options, p)) {
322 error = -EFAULT;
323 break;
324 }
325
326 error = -EINVAL;
327
328 if ((options & WDIOS_DISABLECARD) != 0) {
329 ts72xx_wdt_stop(wdt);
330 error = 0;
331 }
332 if ((options & WDIOS_ENABLECARD) != 0) {
333 ts72xx_wdt_start(wdt);
334 error = 0;
335 }
336
337 break;
338 }
339
340 case WDIOC_SETTIMEOUT: {
341 int new_timeout;
342
343 if (get_user(new_timeout, p)) {
344 error = -EFAULT;
345 } else {
346 int regval;
347
348 regval = timeout_to_regval(new_timeout);
349 if (regval < 0) {
350 error = -EINVAL;
351 } else {
352 ts72xx_wdt_stop(wdt);
353 wdt->regval = regval;
354 ts72xx_wdt_start(wdt);
355 }
356 }
357 if (error)
358 break;
359
360 /*FALLTHROUGH*/
361 }
362
363 case WDIOC_GETTIMEOUT:
364 if (put_user(regval_to_timeout(wdt->regval), p))
365 error = -EFAULT;
366 break;
367
368 default:
369 error = -ENOTTY;
370 break;
371 }
372
373 mutex_unlock(&wdt->lock);
374 return error;
375}
376
377static const struct file_operations ts72xx_wdt_fops = {
378 .owner = THIS_MODULE,
379 .llseek = no_llseek,
380 .open = ts72xx_wdt_open,
381 .release = ts72xx_wdt_release,
382 .write = ts72xx_wdt_write,
383 .unlocked_ioctl = ts72xx_wdt_ioctl,
384};
385
386static struct miscdevice ts72xx_wdt_miscdev = {
387 .minor = WATCHDOG_MINOR,
388 .name = "watchdog",
389 .fops = &ts72xx_wdt_fops,
390};
391
392static __devinit int ts72xx_wdt_probe(struct platform_device *pdev)
393{
394 struct ts72xx_wdt *wdt;
395 struct resource *r1, *r2;
396 int error = 0;
397
398 wdt = kzalloc(sizeof(struct ts72xx_wdt), GFP_KERNEL);
399 if (!wdt) {
400 dev_err(&pdev->dev, "failed to allocate memory\n");
401 return -ENOMEM;
402 }
403
404 r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
405 if (!r1) {
406 dev_err(&pdev->dev, "failed to get memory resource\n");
407 error = -ENODEV;
408 goto fail;
409 }
410
411 r1 = request_mem_region(r1->start, resource_size(r1), pdev->name);
412 if (!r1) {
413 dev_err(&pdev->dev, "cannot request memory region\n");
414 error = -EBUSY;
415 goto fail;
416 }
417
418 wdt->control_reg = ioremap(r1->start, resource_size(r1));
419 if (!wdt->control_reg) {
420 dev_err(&pdev->dev, "failed to map memory\n");
421 error = -ENODEV;
422 goto fail_free_control;
423 }
424
425 r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
426 if (!r2) {
427 dev_err(&pdev->dev, "failed to get memory resource\n");
428 error = -ENODEV;
429 goto fail_unmap_control;
430 }
431
432 r2 = request_mem_region(r2->start, resource_size(r2), pdev->name);
433 if (!r2) {
434 dev_err(&pdev->dev, "cannot request memory region\n");
435 error = -EBUSY;
436 goto fail_unmap_control;
437 }
438
439 wdt->feed_reg = ioremap(r2->start, resource_size(r2));
440 if (!wdt->feed_reg) {
441 dev_err(&pdev->dev, "failed to map memory\n");
442 error = -ENODEV;
443 goto fail_free_feed;
444 }
445
446 platform_set_drvdata(pdev, wdt);
447 ts72xx_wdt_pdev = pdev;
448 wdt->pdev = pdev;
449 mutex_init(&wdt->lock);
450
451 error = misc_register(&ts72xx_wdt_miscdev);
452 if (error) {
453 dev_err(&pdev->dev, "failed to register miscdev\n");
454 goto fail_unmap_feed;
455 }
456
457 dev_info(&pdev->dev, "TS-72xx Watchdog driver\n");
458
459 return 0;
460
461fail_unmap_feed:
462 platform_set_drvdata(pdev, NULL);
463 iounmap(wdt->feed_reg);
464fail_free_feed:
465 release_mem_region(r2->start, resource_size(r2));
466fail_unmap_control:
467 iounmap(wdt->control_reg);
468fail_free_control:
469 release_mem_region(r1->start, resource_size(r1));
470fail:
471 kfree(wdt);
472 return error;
473}
474
475static __devexit int ts72xx_wdt_remove(struct platform_device *pdev)
476{
477 struct ts72xx_wdt *wdt = platform_get_drvdata(pdev);
478 struct resource *res;
479 int error;
480
481 error = misc_deregister(&ts72xx_wdt_miscdev);
482 platform_set_drvdata(pdev, NULL);
483
484 iounmap(wdt->feed_reg);
485 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
486 release_mem_region(res->start, resource_size(res));
487
488 iounmap(wdt->control_reg);
489 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
490 release_mem_region(res->start, resource_size(res));
491
492 kfree(wdt);
493 return error;
494}
495
496static struct platform_driver ts72xx_wdt_driver = {
497 .probe = ts72xx_wdt_probe,
498 .remove = __devexit_p(ts72xx_wdt_remove),
499 .driver = {
500 .name = "ts72xx-wdt",
501 .owner = THIS_MODULE,
502 },
503};
504
505static __init int ts72xx_wdt_init(void)
506{
507 return platform_driver_register(&ts72xx_wdt_driver);
508}
509module_init(ts72xx_wdt_init);
510
511static __exit void ts72xx_wdt_exit(void)
512{
513 platform_driver_unregister(&ts72xx_wdt_driver);
514}
515module_exit(ts72xx_wdt_exit);
516
517MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
518MODULE_DESCRIPTION("TS-72xx SBC Watchdog");
519MODULE_LICENSE("GPL");
520MODULE_ALIAS("platform:ts72xx-wdt");
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index d635566e9307..9e9ed7bfabcb 100644
--- a/drivers/watchdog/txx9wdt.c
+++ b/drivers/watchdog/txx9wdt.c
@@ -13,7 +13,6 @@
13#include <linux/miscdevice.h> 13#include <linux/miscdevice.h>
14#include <linux/watchdog.h> 14#include <linux/watchdog.h>
15#include <linux/fs.h> 15#include <linux/fs.h>
16#include <linux/reboot.h>
17#include <linux/init.h> 16#include <linux/init.h>
18#include <linux/uaccess.h> 17#include <linux/uaccess.h>
19#include <linux/platform_device.h> 18#include <linux/platform_device.h>
@@ -166,14 +165,6 @@ static long txx9wdt_ioctl(struct file *file, unsigned int cmd,
166 } 165 }
167} 166}
168 167
169static int txx9wdt_notify_sys(struct notifier_block *this, unsigned long code,
170 void *unused)
171{
172 if (code == SYS_DOWN || code == SYS_HALT)
173 txx9wdt_stop();
174 return NOTIFY_DONE;
175}
176
177static const struct file_operations txx9wdt_fops = { 168static const struct file_operations txx9wdt_fops = {
178 .owner = THIS_MODULE, 169 .owner = THIS_MODULE,
179 .llseek = no_llseek, 170 .llseek = no_llseek,
@@ -189,10 +180,6 @@ static struct miscdevice txx9wdt_miscdev = {
189 .fops = &txx9wdt_fops, 180 .fops = &txx9wdt_fops,
190}; 181};
191 182
192static struct notifier_block txx9wdt_notifier = {
193 .notifier_call = txx9wdt_notify_sys,
194};
195
196static int __init txx9wdt_probe(struct platform_device *dev) 183static int __init txx9wdt_probe(struct platform_device *dev)
197{ 184{
198 struct resource *res; 185 struct resource *res;
@@ -221,13 +208,8 @@ static int __init txx9wdt_probe(struct platform_device *dev)
221 if (!txx9wdt_reg) 208 if (!txx9wdt_reg)
222 goto exit_busy; 209 goto exit_busy;
223 210
224 ret = register_reboot_notifier(&txx9wdt_notifier);
225 if (ret)
226 goto exit;
227
228 ret = misc_register(&txx9wdt_miscdev); 211 ret = misc_register(&txx9wdt_miscdev);
229 if (ret) { 212 if (ret) {
230 unregister_reboot_notifier(&txx9wdt_notifier);
231 goto exit; 213 goto exit;
232 } 214 }
233 215
@@ -249,14 +231,19 @@ exit:
249static int __exit txx9wdt_remove(struct platform_device *dev) 231static int __exit txx9wdt_remove(struct platform_device *dev)
250{ 232{
251 misc_deregister(&txx9wdt_miscdev); 233 misc_deregister(&txx9wdt_miscdev);
252 unregister_reboot_notifier(&txx9wdt_notifier);
253 clk_disable(txx9_imclk); 234 clk_disable(txx9_imclk);
254 clk_put(txx9_imclk); 235 clk_put(txx9_imclk);
255 return 0; 236 return 0;
256} 237}
257 238
239static void txx9wdt_shutdown(struct platform_device *dev)
240{
241 txx9wdt_stop();
242}
243
258static struct platform_driver txx9wdt_driver = { 244static struct platform_driver txx9wdt_driver = {
259 .remove = __exit_p(txx9wdt_remove), 245 .remove = __exit_p(txx9wdt_remove),
246 .shutdown = txx9wdt_shutdown,
260 .driver = { 247 .driver = {
261 .name = "txx9wdt", 248 .name = "txx9wdt",
262 .owner = THIS_MODULE, 249 .owner = THIS_MODULE,
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index f201accc4e3d..0f5288df0091 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -201,7 +201,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
201 void __user *argp = (void __user *)arg; 201 void __user *argp = (void __user *)arg;
202 int __user *p = argp; 202 int __user *p = argp;
203 int new_timeout; 203 int new_timeout;
204 static struct watchdog_info ident = { 204 static const struct watchdog_info ident = {
205 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 205 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
206 WDIOF_MAGICCLOSE, 206 WDIOF_MAGICCLOSE,
207 .firmware_version = 1, 207 .firmware_version = 1,
diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c
index 0560182a1d09..6e6743d1066f 100644
--- a/drivers/watchdog/w83977f_wdt.c
+++ b/drivers/watchdog/w83977f_wdt.c
@@ -371,7 +371,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf,
371 * according to their available features. 371 * according to their available features.
372 */ 372 */
373 373
374static struct watchdog_info ident = { 374static const struct watchdog_info ident = {
375 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 375 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
376 .firmware_version = 1, 376 .firmware_version = 1,
377 .identity = WATCHDOG_NAME, 377 .identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index 5bfb1f2c5319..94ec22b9e66b 100644
--- a/drivers/watchdog/wdrtas.c
+++ b/drivers/watchdog/wdrtas.c
@@ -312,7 +312,7 @@ static long wdrtas_ioctl(struct file *file, unsigned int cmd,
312{ 312{
313 int __user *argp = (void __user *)arg; 313 int __user *argp = (void __user *)arg;
314 int i; 314 int i;
315 static struct watchdog_info wdinfo = { 315 static const struct watchdog_info wdinfo = {
316 .options = WDRTAS_SUPPORTED_MASK, 316 .options = WDRTAS_SUPPORTED_MASK,
317 .firmware_version = 0, 317 .firmware_version = 0,
318 .identity = "wdrtas", 318 .identity = "wdrtas",
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c
index 3bbefe9a2634..bfda2e99dd89 100644
--- a/drivers/watchdog/wdt.c
+++ b/drivers/watchdog/wdt.c
@@ -358,7 +358,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
358 int new_heartbeat; 358 int new_heartbeat;
359 int status; 359 int status;
360 360
361 static struct watchdog_info ident = { 361 struct watchdog_info ident = {
362 .options = WDIOF_SETTIMEOUT| 362 .options = WDIOF_SETTIMEOUT|
363 WDIOF_MAGICCLOSE| 363 WDIOF_MAGICCLOSE|
364 WDIOF_KEEPALIVEPING, 364 WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index f368dd87083a..7b22e3cdbc81 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -412,7 +412,7 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd,
412 int new_heartbeat; 412 int new_heartbeat;
413 int status; 413 int status;
414 414
415 static struct watchdog_info ident = { 415 struct watchdog_info ident = {
416 .options = WDIOF_SETTIMEOUT| 416 .options = WDIOF_SETTIMEOUT|
417 WDIOF_MAGICCLOSE| 417 WDIOF_MAGICCLOSE|
418 WDIOF_KEEPALIVEPING, 418 WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 775bcd807f31..8c4b2d5bb7da 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -213,7 +213,7 @@ static ssize_t wm831x_wdt_write(struct file *file,
213 return count; 213 return count;
214} 214}
215 215
216static struct watchdog_info ident = { 216static const struct watchdog_info ident = {
217 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 217 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
218 .identity = "WM831x Watchdog", 218 .identity = "WM831x Watchdog",
219}; 219};
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
index a2d2e8eb2282..89dd7b035295 100644
--- a/drivers/watchdog/wm8350_wdt.c
+++ b/drivers/watchdog/wm8350_wdt.c
@@ -177,7 +177,7 @@ static ssize_t wm8350_wdt_write(struct file *file,
177 return count; 177 return count;
178} 178}
179 179
180static struct watchdog_info ident = { 180static const struct watchdog_info ident = {
181 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 181 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
182 .identity = "WM8350 Watchdog", 182 .identity = "WM8350 Watchdog",
183}; 183};