aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/Kconfig49
-rw-r--r--drivers/watchdog/Makefile4
-rw-r--r--drivers/watchdog/acquirewdt.c2
-rw-r--r--drivers/watchdog/advantechwdt.c2
-rw-r--r--drivers/watchdog/adx_wdt.c9
-rw-r--r--drivers/watchdog/alim1535_wdt.c2
-rw-r--r--drivers/watchdog/alim7101_wdt.c2
-rw-r--r--drivers/watchdog/ar7_wdt.c20
-rw-r--r--drivers/watchdog/at32ap700x_wdt.c5
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c2
-rw-r--r--drivers/watchdog/bcm47xx_wdt.c2
-rw-r--r--drivers/watchdog/bfin_wdt.c69
-rw-r--r--drivers/watchdog/booke_wdt.c2
-rw-r--r--drivers/watchdog/coh901327_wdt.c4
-rw-r--r--drivers/watchdog/cpu5wdt.c2
-rw-r--r--drivers/watchdog/cpwd.c3
-rw-r--r--drivers/watchdog/davinci_wdt.c5
-rw-r--r--drivers/watchdog/ep93xx_wdt.c4
-rw-r--r--drivers/watchdog/eurotechwdt.c2
-rw-r--r--drivers/watchdog/gef_wdt.c16
-rw-r--r--drivers/watchdog/geodewdt.c42
-rw-r--r--drivers/watchdog/hpwdt.c5
-rw-r--r--drivers/watchdog/i6300esb.c101
-rw-r--r--drivers/watchdog/iTCO_wdt.c223
-rw-r--r--drivers/watchdog/ib700wdt.c2
-rw-r--r--drivers/watchdog/ibmasr.c1
-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.c3
-rw-r--r--drivers/watchdog/ixp4xx_wdt.c2
-rw-r--r--drivers/watchdog/ks8695_wdt.c2
-rw-r--r--drivers/watchdog/machzwd.c4
-rw-r--r--drivers/watchdog/max63xx_wdt.c403
-rw-r--r--drivers/watchdog/mixcomwd.c2
-rw-r--r--drivers/watchdog/mpc5200_wdt.c293
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c2
-rw-r--r--drivers/watchdog/mpcore_wdt.c26
-rw-r--r--drivers/watchdog/mv64x60_wdt.c4
-rw-r--r--drivers/watchdog/nuc900_wdt.c1
-rw-r--r--drivers/watchdog/omap_wdt.c12
-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/pnx4008_wdt.c42
-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.c9
-rw-r--r--drivers/watchdog/rm9k_wdt.c419
-rw-r--r--drivers/watchdog/s3c2410_wdt.c92
-rw-r--r--drivers/watchdog/sb_wdog.c8
-rw-r--r--drivers/watchdog/sbc_fitpc2_wdt.c25
-rw-r--r--drivers/watchdog/sch311x_wdt.c2
-rw-r--r--drivers/watchdog/stmp3xxx_wdt.c2
-rw-r--r--drivers/watchdog/ts72xx_wdt.c521
-rw-r--r--drivers/watchdog/twl4030_wdt.c5
-rw-r--r--drivers/watchdog/txx9wdt.c31
-rw-r--r--drivers/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/watchdog/w83977f_wdt.c2
-rw-r--r--drivers/watchdog/wdrtas.c8
-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
66 files changed, 1459 insertions, 1071 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3711b888d482..b87ba23442d2 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -175,7 +175,7 @@ config SA1100_WATCHDOG
175 175
176config MPCORE_WATCHDOG 176config MPCORE_WATCHDOG
177 tristate "MPcore watchdog" 177 tristate "MPcore watchdog"
178 depends on ARM_MPCORE_PLATFORM && LOCAL_TIMERS 178 depends on HAVE_ARM_TWD
179 help 179 help
180 Watchdog timer embedded into the MPcore system. 180 Watchdog timer embedded into the MPcore system.
181 181
@@ -194,10 +194,10 @@ config EP93XX_WATCHDOG
194 194
195config OMAP_WATCHDOG 195config OMAP_WATCHDOG
196 tristate "OMAP Watchdog" 196 tristate "OMAP Watchdog"
197 depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX 197 depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
198 help 198 help
199 Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog. Say 'Y' 199 Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog. Say 'Y'
200 here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer. 200 here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
201 201
202config PNX4008_WATCHDOG 202config PNX4008_WATCHDOG
203 tristate "PNX4008 Watchdog" 203 tristate "PNX4008 Watchdog"
@@ -289,6 +289,23 @@ config ADX_WATCHDOG
289 Say Y here if you want support for the watchdog timer on Avionic 289 Say Y here if you want support for the watchdog timer on Avionic
290 Design Xanthos boards. 290 Design Xanthos boards.
291 291
292config TS72XX_WATCHDOG
293 tristate "TS-72XX SBC Watchdog"
294 depends on MACH_TS72XX
295 help
296 Technologic Systems TS-7200, TS-7250 and TS-7260 boards have
297 watchdog timer implemented in a external CPLD chip. Say Y here
298 if you want to support for the watchdog timer on TS-72XX boards.
299
300 To compile this driver as a module, choose M here: the
301 module will be called ts72xx_wdt.
302
303config MAX63XX_WATCHDOG
304 tristate "Max63xx watchdog"
305 depends on ARM && HAS_IOMEM
306 help
307 Support for memory mapped max63{69,70,71,72,73,74} watchdog timer.
308
292# AVR32 Architecture 309# AVR32 Architecture
293 310
294config AT32AP700X_WDT 311config AT32AP700X_WDT
@@ -368,7 +385,7 @@ config ALIM7101_WDT
368 385
369config GEODE_WDT 386config GEODE_WDT
370 tristate "AMD Geode CS5535/CS5536 Watchdog" 387 tristate "AMD Geode CS5535/CS5536 Watchdog"
371 depends on MGEODE_LX 388 depends on CS5535_MFGPT
372 help 389 help
373 This driver enables a watchdog capability built into the 390 This driver enables a watchdog capability built into the
374 CS5535/CS5536 companion chips for the AMD Geode GX and LX 391 CS5535/CS5536 companion chips for the AMD Geode GX and LX
@@ -396,8 +413,8 @@ config SBC_FITPC2_WATCHDOG
396 tristate "Compulab SBC-FITPC2 watchdog" 413 tristate "Compulab SBC-FITPC2 watchdog"
397 depends on X86 414 depends on X86
398 ---help--- 415 ---help---
399 This is the driver for the built-in watchdog timer on the fit-PC2 416 This is the driver for the built-in watchdog timer on the fit-PC2,
400 Single-board computer made by Compulab. 417 fit-PC2i, CM-iAM single-board computers made by Compulab.
401 418
402 It`s possible to enable watchdog timer either from BIOS (F2) or from booted Linux. 419 It`s possible to enable watchdog timer either from BIOS (F2) or from booted Linux.
403 When "Watchdog Timer Value" enabled one can set 31-255 s operational range. 420 When "Watchdog Timer Value" enabled one can set 31-255 s operational range.
@@ -815,16 +832,6 @@ config PNX833X_WDT
815 timer has expired and no process has written to /dev/watchdog during 832 timer has expired and no process has written to /dev/watchdog during
816 that time. 833 that time.
817 834
818config WDT_RM9K_GPI
819 tristate "RM9000/GPI hardware watchdog"
820 depends on CPU_RM9000
821 help
822 Watchdog implementation using the GPI hardware found on
823 PMC-Sierra RM9xxx CPUs.
824
825 To compile this driver as a module, choose M here: the
826 module will be called rm9k_wdt.
827
828config SIBYTE_WDOG 835config SIBYTE_WDOG
829 tristate "Sibyte SoC hardware watchdog" 836 tristate "Sibyte SoC hardware watchdog"
830 depends on CPU_SB1 837 depends on CPU_SB1
@@ -855,14 +862,16 @@ config TXX9_WDT
855# POWERPC Architecture 862# POWERPC Architecture
856 863
857config GEF_WDT 864config GEF_WDT
858 tristate "GE Fanuc Watchdog Timer" 865 tristate "GE Watchdog Timer"
859 depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A 866 depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A
860 ---help--- 867 ---help---
861 Watchdog timer found in a number of GE Fanuc single board computers. 868 Watchdog timer found in a number of GE single board computers.
862 869
863config MPC5200_WDT 870config MPC5200_WDT
864 tristate "MPC5200 Watchdog Timer" 871 bool "MPC52xx Watchdog Timer"
865 depends on PPC_MPC52xx 872 depends on PPC_MPC52xx
873 help
874 Use General Purpose Timer (GPT) 0 on the MPC5200 as Watchdog.
866 875
867config 8xxx_WDT 876config 8xxx_WDT
868 tristate "MPC8xxx Platform Watchdog Timer" 877 tristate "MPC8xxx Platform Watchdog Timer"
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 699199b1baa6..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
@@ -109,7 +110,6 @@ obj-$(CONFIG_RC32434_WDT) += rc32434_wdt.o
109obj-$(CONFIG_INDYDOG) += indydog.o 110obj-$(CONFIG_INDYDOG) += indydog.o
110obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o 111obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
111obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o 112obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o
112obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
113obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o 113obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
114obj-$(CONFIG_AR7_WDT) += ar7_wdt.o 114obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
115obj-$(CONFIG_TXX9_WDT) += txx9wdt.o 115obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
@@ -118,7 +118,6 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
118 118
119# POWERPC Architecture 119# POWERPC Architecture
120obj-$(CONFIG_GEF_WDT) += gef_wdt.o 120obj-$(CONFIG_GEF_WDT) += gef_wdt.o
121obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o
122obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o 121obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o
123obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o 122obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
124obj-$(CONFIG_PIKA_WDT) += pika_wdt.o 123obj-$(CONFIG_PIKA_WDT) += pika_wdt.o
@@ -144,4 +143,5 @@ obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o
144# Architecture Independant 143# Architecture Independant
145obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o 144obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
146obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o 145obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
146obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
147obj-$(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 77afb0acc500..af6e6b16475a 100644
--- a/drivers/watchdog/adx_wdt.c
+++ b/drivers/watchdog/adx_wdt.c
@@ -7,6 +7,7 @@
7 */ 7 */
8 8
9#include <linux/fs.h> 9#include <linux/fs.h>
10#include <linux/gfp.h>
10#include <linux/io.h> 11#include <linux/io.h>
11#include <linux/miscdevice.h> 12#include <linux/miscdevice.h>
12#include <linux/module.h> 13#include <linux/module.h>
@@ -37,7 +38,7 @@ struct adx_wdt {
37 spinlock_t lock; 38 spinlock_t lock;
38}; 39};
39 40
40static struct watchdog_info adx_wdt_info = { 41static const struct watchdog_info adx_wdt_info = {
41 .identity = "Avionic Design Xanthos Watchdog", 42 .identity = "Avionic Design Xanthos Watchdog",
42 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 43 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
43}; 44};
@@ -242,14 +243,14 @@ static int __devinit adx_wdt_probe(struct platform_device *pdev)
242 } 243 }
243 244
244 res = devm_request_mem_region(&pdev->dev, res->start, 245 res = devm_request_mem_region(&pdev->dev, res->start,
245 res->end - res->start + 1, res->name); 246 resource_size(res), res->name);
246 if (!res) { 247 if (!res) {
247 dev_err(&pdev->dev, "cannot request I/O memory region\n"); 248 dev_err(&pdev->dev, "cannot request I/O memory region\n");
248 return -ENXIO; 249 return -ENXIO;
249 } 250 }
250 251
251 wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, 252 wdt->base = devm_ioremap_nocache(&pdev->dev, res->start,
252 res->end - res->start + 1); 253 resource_size(res));
253 if (!wdt->base) { 254 if (!wdt->base) {
254 dev_err(&pdev->dev, "cannot remap I/O memory region\n"); 255 dev_err(&pdev->dev, "cannot remap I/O memory region\n");
255 return -ENXIO; 256 return -ENXIO;
@@ -314,7 +315,7 @@ static int adx_wdt_resume(struct device *dev)
314 return 0; 315 return 0;
315} 316}
316 317
317static struct dev_pm_ops adx_wdt_pm_ops = { 318static const struct dev_pm_ops adx_wdt_pm_ops = {
318 .suspend = adx_wdt_suspend, 319 .suspend = adx_wdt_suspend,
319 .resume = adx_wdt_resume, 320 .resume = adx_wdt_resume,
320}; 321};
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 2e94b71b20d9..c764c52412e4 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -34,6 +34,7 @@
34#include <linux/ioport.h> 34#include <linux/ioport.h>
35#include <linux/io.h> 35#include <linux/io.h>
36#include <linux/uaccess.h> 36#include <linux/uaccess.h>
37#include <linux/clk.h>
37 38
38#include <asm/addrspace.h> 39#include <asm/addrspace.h>
39#include <asm/mach-ar7/ar7.h> 40#include <asm/mach-ar7/ar7.h>
@@ -80,6 +81,8 @@ static struct resource *ar7_regs_wdt;
80/* Pointer to the remapped WDT IO space */ 81/* Pointer to the remapped WDT IO space */
81static struct ar7_wdt *ar7_wdt; 82static struct ar7_wdt *ar7_wdt;
82 83
84static struct clk *vbus_clk;
85
83static void ar7_wdt_kick(u32 value) 86static void ar7_wdt_kick(u32 value)
84{ 87{
85 WRITE_REG(ar7_wdt->kick_lock, 0x5555); 88 WRITE_REG(ar7_wdt->kick_lock, 0x5555);
@@ -138,17 +141,19 @@ static void ar7_wdt_disable(u32 value)
138static void ar7_wdt_update_margin(int new_margin) 141static void ar7_wdt_update_margin(int new_margin)
139{ 142{
140 u32 change; 143 u32 change;
144 u32 vbus_rate;
141 145
142 change = new_margin * (ar7_vbus_freq() / prescale_value); 146 vbus_rate = clk_get_rate(vbus_clk);
147 change = new_margin * (vbus_rate / prescale_value);
143 if (change < 1) 148 if (change < 1)
144 change = 1; 149 change = 1;
145 if (change > 0xffff) 150 if (change > 0xffff)
146 change = 0xffff; 151 change = 0xffff;
147 ar7_wdt_change(change); 152 ar7_wdt_change(change);
148 margin = change * prescale_value / ar7_vbus_freq(); 153 margin = change * prescale_value / vbus_rate;
149 printk(KERN_INFO DRVNAME 154 printk(KERN_INFO DRVNAME
150 ": timer margin %d seconds (prescale %d, change %d, freq %d)\n", 155 ": timer margin %d seconds (prescale %d, change %d, freq %d)\n",
151 margin, prescale_value, change, ar7_vbus_freq()); 156 margin, prescale_value, change, vbus_rate);
152} 157}
153 158
154static void ar7_wdt_enable_wdt(void) 159static void ar7_wdt_enable_wdt(void)
@@ -214,7 +219,7 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data,
214static long ar7_wdt_ioctl(struct file *file, 219static long ar7_wdt_ioctl(struct file *file,
215 unsigned int cmd, unsigned long arg) 220 unsigned int cmd, unsigned long arg)
216{ 221{
217 static struct watchdog_info ident = { 222 static const struct watchdog_info ident = {
218 .identity = LONGNAME, 223 .identity = LONGNAME,
219 .firmware_version = 1, 224 .firmware_version = 1,
220 .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | 225 .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
@@ -298,6 +303,13 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev)
298 goto out_mem_region; 303 goto out_mem_region;
299 } 304 }
300 305
306 vbus_clk = clk_get(NULL, "vbus");
307 if (IS_ERR(vbus_clk)) {
308 printk(KERN_ERR DRVNAME ": could not get vbus clock\n");
309 rc = PTR_ERR(vbus_clk);
310 goto out_mem_region;
311 }
312
301 ar7_wdt_disable_wdt(); 313 ar7_wdt_disable_wdt();
302 ar7_wdt_prescale(prescale_value); 314 ar7_wdt_prescale(prescale_value);
303 ar7_wdt_update_margin(margin); 315 ar7_wdt_update_margin(margin);
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
index e8ae638e5804..1cddf92cb9a6 100644
--- a/drivers/watchdog/at32ap700x_wdt.c
+++ b/drivers/watchdog/at32ap700x_wdt.c
@@ -32,6 +32,7 @@
32#include <linux/uaccess.h> 32#include <linux/uaccess.h>
33#include <linux/io.h> 33#include <linux/io.h>
34#include <linux/spinlock.h> 34#include <linux/spinlock.h>
35#include <linux/slab.h>
35 36
36#define TIMEOUT_MIN 1 37#define TIMEOUT_MIN 1
37#define TIMEOUT_MAX 2 38#define TIMEOUT_MAX 2
@@ -202,7 +203,7 @@ static int at32_wdt_get_status(void)
202 return status; 203 return status;
203} 204}
204 205
205static struct watchdog_info at32_wdt_info = { 206static const struct watchdog_info at32_wdt_info = {
206 .identity = "at32ap700x watchdog", 207 .identity = "at32ap700x watchdog",
207 .options = WDIOF_SETTIMEOUT | 208 .options = WDIOF_SETTIMEOUT |
208 WDIOF_KEEPALIVEPING | 209 WDIOF_KEEPALIVEPING |
@@ -326,7 +327,7 @@ static int __init at32_wdt_probe(struct platform_device *pdev)
326 return -ENOMEM; 327 return -ENOMEM;
327 } 328 }
328 329
329 wdt->regs = ioremap(regs->start, regs->end - regs->start + 1); 330 wdt->regs = ioremap(regs->start, resource_size(regs));
330 if (!wdt->regs) { 331 if (!wdt->regs) {
331 ret = -ENOMEM; 332 ret = -ENOMEM;
332 dev_dbg(&pdev->dev, "could not map I/O memory\n"); 333 dev_dbg(&pdev->dev, "could not map I/O memory\n");
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 c7b3f9df2317..9c7ccd1e9088 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -1,9 +1,8 @@
1/* 1/*
2 * Blackfin On-Chip Watchdog Driver 2 * Blackfin On-Chip Watchdog Driver
3 * Supports BF53[123]/BF53[467]/BF54[2489]/BF561
4 * 3 *
5 * Originally based on softdog.c 4 * Originally based on softdog.c
6 * Copyright 2006-2007 Analog Devices Inc. 5 * Copyright 2006-2010 Analog Devices Inc.
7 * Copyright 2006-2007 Michele d'Amico 6 * Copyright 2006-2007 Michele d'Amico
8 * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk> 7 * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>
9 * 8 *
@@ -20,8 +19,6 @@
20#include <linux/miscdevice.h> 19#include <linux/miscdevice.h>
21#include <linux/watchdog.h> 20#include <linux/watchdog.h>
22#include <linux/fs.h> 21#include <linux/fs.h>
23#include <linux/notifier.h>
24#include <linux/reboot.h>
25#include <linux/init.h> 22#include <linux/init.h>
26#include <linux/interrupt.h> 23#include <linux/interrupt.h>
27#include <linux/uaccess.h> 24#include <linux/uaccess.h>
@@ -75,7 +72,7 @@
75 72
76static unsigned int timeout = WATCHDOG_TIMEOUT; 73static unsigned int timeout = WATCHDOG_TIMEOUT;
77static int nowayout = WATCHDOG_NOWAYOUT; 74static int nowayout = WATCHDOG_NOWAYOUT;
78static struct watchdog_info bfin_wdt_info; 75static const struct watchdog_info bfin_wdt_info;
79static unsigned long open_check; 76static unsigned long open_check;
80static char expect_close; 77static char expect_close;
81static DEFINE_SPINLOCK(bfin_wdt_spinlock); 78static DEFINE_SPINLOCK(bfin_wdt_spinlock);
@@ -137,13 +134,15 @@ static int bfin_wdt_running(void)
137 */ 134 */
138static int bfin_wdt_set_timeout(unsigned long t) 135static int bfin_wdt_set_timeout(unsigned long t)
139{ 136{
140 u32 cnt; 137 u32 cnt, max_t, sclk;
141 unsigned long flags; 138 unsigned long flags;
142 139
143 stampit(); 140 sclk = get_sclk();
141 max_t = -1 / sclk;
142 cnt = t * sclk;
143 stamp("maxtimeout=%us newtimeout=%lus (cnt=%#x)", max_t, t, cnt);
144 144
145 cnt = t * get_sclk(); 145 if (t > max_t) {
146 if (cnt < get_sclk()) {
147 printk(KERN_WARNING PFX "timeout value is too large\n"); 146 printk(KERN_WARNING PFX "timeout value is too large\n");
148 return -EINVAL; 147 return -EINVAL;
149 } 148 }
@@ -308,26 +307,6 @@ static long bfin_wdt_ioctl(struct file *file,
308 } 307 }
309} 308}
310 309
311/**
312 * bfin_wdt_notify_sys - Notifier Handler
313 * @this: notifier block
314 * @code: notifier event
315 * @unused: unused
316 *
317 * Handles specific events, such as turning off the watchdog during a
318 * shutdown event.
319 */
320static int bfin_wdt_notify_sys(struct notifier_block *this,
321 unsigned long code, void *unused)
322{
323 stampit();
324
325 if (code == SYS_DOWN || code == SYS_HALT)
326 bfin_wdt_stop();
327
328 return NOTIFY_DONE;
329}
330
331#ifdef CONFIG_PM 310#ifdef CONFIG_PM
332static int state_before_suspend; 311static int state_before_suspend;
333 312
@@ -387,40 +366,28 @@ static struct miscdevice bfin_wdt_miscdev = {
387 .fops = &bfin_wdt_fops, 366 .fops = &bfin_wdt_fops,
388}; 367};
389 368
390static struct watchdog_info bfin_wdt_info = { 369static const struct watchdog_info bfin_wdt_info = {
391 .identity = "Blackfin Watchdog", 370 .identity = "Blackfin Watchdog",
392 .options = WDIOF_SETTIMEOUT | 371 .options = WDIOF_SETTIMEOUT |
393 WDIOF_KEEPALIVEPING | 372 WDIOF_KEEPALIVEPING |
394 WDIOF_MAGICCLOSE, 373 WDIOF_MAGICCLOSE,
395}; 374};
396 375
397static struct notifier_block bfin_wdt_notifier = {
398 .notifier_call = bfin_wdt_notify_sys,
399};
400
401/** 376/**
402 * bfin_wdt_probe - Initialize module 377 * bfin_wdt_probe - Initialize module
403 * 378 *
404 * Registers the misc device and notifier handler. Actual device 379 * Registers the misc device. Actual device
405 * initialization is handled by bfin_wdt_open(). 380 * initialization is handled by bfin_wdt_open().
406 */ 381 */
407static int __devinit bfin_wdt_probe(struct platform_device *pdev) 382static int __devinit bfin_wdt_probe(struct platform_device *pdev)
408{ 383{
409 int ret; 384 int ret;
410 385
411 ret = register_reboot_notifier(&bfin_wdt_notifier);
412 if (ret) {
413 pr_devinit(KERN_ERR PFX
414 "cannot register reboot notifier (err=%d)\n", ret);
415 return ret;
416 }
417
418 ret = misc_register(&bfin_wdt_miscdev); 386 ret = misc_register(&bfin_wdt_miscdev);
419 if (ret) { 387 if (ret) {
420 pr_devinit(KERN_ERR PFX 388 pr_devinit(KERN_ERR PFX
421 "cannot register miscdev on minor=%d (err=%d)\n", 389 "cannot register miscdev on minor=%d (err=%d)\n",
422 WATCHDOG_MINOR, ret); 390 WATCHDOG_MINOR, ret);
423 unregister_reboot_notifier(&bfin_wdt_notifier);
424 return ret; 391 return ret;
425 } 392 }
426 393
@@ -433,21 +400,33 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev)
433/** 400/**
434 * bfin_wdt_remove - Initialize module 401 * bfin_wdt_remove - Initialize module
435 * 402 *
436 * Unregisters the misc device and notifier handler. Actual device 403 * Unregisters the misc device. Actual device
437 * deinitialization is handled by bfin_wdt_close(). 404 * deinitialization is handled by bfin_wdt_close().
438 */ 405 */
439static int __devexit bfin_wdt_remove(struct platform_device *pdev) 406static int __devexit bfin_wdt_remove(struct platform_device *pdev)
440{ 407{
441 misc_deregister(&bfin_wdt_miscdev); 408 misc_deregister(&bfin_wdt_miscdev);
442 unregister_reboot_notifier(&bfin_wdt_notifier);
443 return 0; 409 return 0;
444} 410}
445 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
446static struct platform_device *bfin_wdt_device; 424static struct platform_device *bfin_wdt_device;
447 425
448static struct platform_driver bfin_wdt_driver = { 426static struct platform_driver bfin_wdt_driver = {
449 .probe = bfin_wdt_probe, 427 .probe = bfin_wdt_probe,
450 .remove = __devexit_p(bfin_wdt_remove), 428 .remove = __devexit_p(bfin_wdt_remove),
429 .shutdown = bfin_wdt_shutdown,
451 .suspend = bfin_wdt_suspend, 430 .suspend = bfin_wdt_suspend,
452 .resume = bfin_wdt_resume, 431 .resume = bfin_wdt_resume,
453 .driver = { 432 .driver = {
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index e8380ef65c1c..801ead191499 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -44,7 +44,7 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
44 44
45#ifdef CONFIG_FSL_BOOKE 45#ifdef CONFIG_FSL_BOOKE
46#define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15)) 46#define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15))
47#define WDTP_MASK (WDTP(0)) 47#define WDTP_MASK (WDTP(0x3f))
48#else 48#else
49#define WDTP(x) (TCR_WP(x)) 49#define WDTP(x) (TCR_WP(x))
50#define WDTP_MASK (TCR_WP_MASK) 50#define WDTP_MASK (TCR_WP_MASK)
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index 381026c0bd7b..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,
@@ -508,7 +508,7 @@ void coh901327_watchdog_reset(void)
508 * deactivating the watchdog before it is shut down by it. 508 * deactivating the watchdog before it is shut down by it.
509 * 509 *
510 * NOTE: on future versions of the watchdog, this restriction is 510 * NOTE: on future versions of the watchdog, this restriction is
511 * gone: the watchdog will be reloaded with a defaul value (1 min) 511 * gone: the watchdog will be reloaded with a default value (1 min)
512 * instead of last value, and you can conveniently set the watchdog 512 * instead of last value, and you can conveniently set the watchdog
513 * timeout to 10ms (value = 1) without any problems. 513 * timeout to 10ms (value = 1) without any problems.
514 */ 514 */
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..ba2efce4b40e 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -24,6 +24,7 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <linux/timer.h> 26#include <linux/timer.h>
27#include <linux/slab.h>
27#include <linux/smp_lock.h> 28#include <linux/smp_lock.h>
28#include <linux/io.h> 29#include <linux/io.h>
29#include <linux/of.h> 30#include <linux/of.h>
@@ -403,7 +404,7 @@ static int cpwd_release(struct inode *inode, struct file *file)
403 404
404static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 405static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
405{ 406{
406 static struct watchdog_info info = { 407 static const struct watchdog_info info = {
407 .options = WDIOF_SETTIMEOUT, 408 .options = WDIOF_SETTIMEOUT,
408 .firmware_version = 1, 409 .firmware_version = 1,
409 .identity = DRIVER_NAME, 410 .identity = DRIVER_NAME,
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 9d7520fa9e9c..596ba604e78d 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -26,6 +26,7 @@
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/clk.h> 28#include <linux/clk.h>
29#include <linux/slab.h>
29 30
30#define MODULE_NAME "DAVINCI-WDT: " 31#define MODULE_NAME "DAVINCI-WDT: "
31 32
@@ -142,7 +143,7 @@ davinci_wdt_write(struct file *file, const char *data, size_t len,
142 return len; 143 return len;
143} 144}
144 145
145static struct watchdog_info ident = { 146static const struct watchdog_info ident = {
146 .options = WDIOF_KEEPALIVEPING, 147 .options = WDIOF_KEEPALIVEPING,
147 .identity = "DaVinci Watchdog", 148 .identity = "DaVinci Watchdog",
148}; 149};
@@ -221,7 +222,7 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev)
221 return -ENOENT; 222 return -ENOENT;
222 } 223 }
223 224
224 size = res->end - res->start + 1; 225 size = resource_size(res);
225 wdt_mem = request_mem_region(res->start, size, pdev->name); 226 wdt_mem = request_mem_region(res->start, size, pdev->name);
226 227
227 if (wdt_mem == NULL) { 228 if (wdt_mem == NULL) {
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index cdd55e0d09f8..59359c9a5e01 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};
@@ -244,7 +244,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
244module_param(timeout, int, 0); 244module_param(timeout, int, 0);
245MODULE_PARM_DESC(timeout, 245MODULE_PARM_DESC(timeout,
246 "Watchdog timeout in seconds. (1<=timeout<=3600, default=" 246 "Watchdog timeout in seconds. (1<=timeout<=3600, default="
247 __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 247 __MODULE_STRING(WDT_TIMEOUT) ")");
248 248
249MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>," 249MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>,"
250 "Alessandro Zummo <a.zummo@towertech.it>"); 250 "Alessandro Zummo <a.zummo@towertech.it>");
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 9acf0015a1e7..9b49b125ad5a 100644
--- a/drivers/watchdog/geodewdt.c
+++ b/drivers/watchdog/geodewdt.c
@@ -1,6 +1,7 @@
1/* Watchdog timer for the Geode GX/LX with the CS5535/CS5536 companion chip 1/* Watchdog timer for machines with the CS5535/CS5536 companion chip
2 * 2 *
3 * Copyright (C) 2006-2007, Advanced Micro Devices, Inc. 3 * Copyright (C) 2006-2007, Advanced Micro Devices, Inc.
4 * Copyright (C) 2009 Andres Salomon <dilinger@collabora.co.uk>
4 * 5 *
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -19,7 +20,7 @@
19#include <linux/reboot.h> 20#include <linux/reboot.h>
20#include <linux/uaccess.h> 21#include <linux/uaccess.h>
21 22
22#include <asm/geode.h> 23#include <linux/cs5535.h>
23 24
24#define GEODEWDT_HZ 500 25#define GEODEWDT_HZ 500
25#define GEODEWDT_SCALE 6 26#define GEODEWDT_SCALE 6
@@ -46,25 +47,25 @@ MODULE_PARM_DESC(nowayout,
46 47
47static struct platform_device *geodewdt_platform_device; 48static struct platform_device *geodewdt_platform_device;
48static unsigned long wdt_flags; 49static unsigned long wdt_flags;
49static int wdt_timer; 50static struct cs5535_mfgpt_timer *wdt_timer;
50static int safe_close; 51static int safe_close;
51 52
52static void geodewdt_ping(void) 53static void geodewdt_ping(void)
53{ 54{
54 /* Stop the counter */ 55 /* Stop the counter */
55 geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); 56 cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0);
56 57
57 /* Reset the counter */ 58 /* Reset the counter */
58 geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); 59 cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0);
59 60
60 /* Enable the counter */ 61 /* Enable the counter */
61 geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); 62 cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
62} 63}
63 64
64static void geodewdt_disable(void) 65static void geodewdt_disable(void)
65{ 66{
66 geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); 67 cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0);
67 geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); 68 cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0);
68} 69}
69 70
70static int geodewdt_set_heartbeat(int val) 71static int geodewdt_set_heartbeat(int val)
@@ -72,10 +73,10 @@ static int geodewdt_set_heartbeat(int val)
72 if (val < 1 || val > GEODEWDT_MAX_SECONDS) 73 if (val < 1 || val > GEODEWDT_MAX_SECONDS)
73 return -EINVAL; 74 return -EINVAL;
74 75
75 geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); 76 cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0);
76 geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, val * GEODEWDT_HZ); 77 cs5535_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, val * GEODEWDT_HZ);
77 geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); 78 cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0);
78 geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); 79 cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
79 80
80 timeout = val; 81 timeout = val;
81 return 0; 82 return 0;
@@ -141,7 +142,7 @@ static long geodewdt_ioctl(struct file *file, unsigned int cmd,
141 int __user *p = argp; 142 int __user *p = argp;
142 int interval; 143 int interval;
143 144
144 static struct watchdog_info ident = { 145 static const struct watchdog_info ident = {
145 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING 146 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING
146 | WDIOF_MAGICCLOSE, 147 | WDIOF_MAGICCLOSE,
147 .firmware_version = 1, 148 .firmware_version = 1,
@@ -215,28 +216,25 @@ static struct miscdevice geodewdt_miscdev = {
215 216
216static int __devinit geodewdt_probe(struct platform_device *dev) 217static int __devinit geodewdt_probe(struct platform_device *dev)
217{ 218{
218 int ret, timer; 219 int ret;
219
220 timer = geode_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING);
221 220
222 if (timer == -1) { 221 wdt_timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING);
222 if (!wdt_timer) {
223 printk(KERN_ERR "geodewdt: No timers were available\n"); 223 printk(KERN_ERR "geodewdt: No timers were available\n");
224 return -ENODEV; 224 return -ENODEV;
225 } 225 }
226 226
227 wdt_timer = timer;
228
229 /* Set up the timer */ 227 /* Set up the timer */
230 228
231 geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 229 cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP,
232 GEODEWDT_SCALE | (3 << 8)); 230 GEODEWDT_SCALE | (3 << 8));
233 231
234 /* Set up comparator 2 to reset when the event fires */ 232 /* Set up comparator 2 to reset when the event fires */
235 geode_mfgpt_toggle_event(wdt_timer, MFGPT_CMP2, MFGPT_EVENT_RESET, 1); 233 cs5535_mfgpt_toggle_event(wdt_timer, MFGPT_CMP2, MFGPT_EVENT_RESET, 1);
236 234
237 /* Set up the initial timeout */ 235 /* Set up the initial timeout */
238 236
239 geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, 237 cs5535_mfgpt_write(wdt_timer, MFGPT_REG_CMP2,
240 timeout * GEODEWDT_HZ); 238 timeout * GEODEWDT_HZ);
241 239
242 ret = misc_register(&geodewdt_miscdev); 240 ret = misc_register(&geodewdt_miscdev);
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index a6c5674c78e6..809e7167a624 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -39,7 +39,6 @@
39#include <linux/efi.h> 39#include <linux/efi.h>
40#include <linux/string.h> 40#include <linux/string.h>
41#include <linux/bootmem.h> 41#include <linux/bootmem.h>
42#include <linux/slab.h>
43#include <asm/desc.h> 42#include <asm/desc.h>
44#include <asm/cacheflush.h> 43#include <asm/cacheflush.h>
45 44
@@ -443,7 +442,7 @@ static void hpwdt_ping(void)
443static int hpwdt_change_timer(int new_margin) 442static int hpwdt_change_timer(int new_margin)
444{ 443{
445 /* Arbitrary, can't find the card's limits */ 444 /* Arbitrary, can't find the card's limits */
446 if (new_margin < 30 || new_margin > 600) { 445 if (new_margin < 5 || new_margin > 600) {
447 printk(KERN_WARNING 446 printk(KERN_WARNING
448 "hpwdt: New value passed in is invalid: %d seconds.\n", 447 "hpwdt: New value passed in is invalid: %d seconds.\n",
449 new_margin); 448 new_margin);
@@ -554,7 +553,7 @@ static ssize_t hpwdt_write(struct file *file, const char __user *data,
554 return len; 553 return len;
555} 554}
556 555
557static struct watchdog_info ident = { 556static const struct watchdog_info ident = {
558 .options = WDIOF_SETTIMEOUT | 557 .options = WDIOF_SETTIMEOUT |
559 WDIOF_KEEPALIVEPING | 558 WDIOF_KEEPALIVEPING |
560 WDIOF_MAGICCLOSE, 559 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 6a51edde6ea7..8da886035374 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets) 2 * intel TCO Watchdog Driver
3 * 3 *
4 * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>. 4 * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>.
5 * 5 *
@@ -14,47 +14,24 @@
14 * 14 *
15 * The TCO watchdog is implemented in the following I/O controller hubs: 15 * The TCO watchdog is implemented in the following I/O controller hubs:
16 * (See the intel documentation on http://developer.intel.com.) 16 * (See the intel documentation on http://developer.intel.com.)
17 * 82801AA (ICH) : document number 290655-003, 290677-014, 17 * document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO)
18 * 82801AB (ICHO) : document number 290655-003, 290677-014, 18 * document number 290687-002, 298242-027: 82801BA (ICH2)
19 * 82801BA (ICH2) : document number 290687-002, 298242-027, 19 * document number 290733-003, 290739-013: 82801CA (ICH3-S)
20 * 82801BAM (ICH2-M) : document number 290687-002, 298242-027, 20 * document number 290716-001, 290718-007: 82801CAM (ICH3-M)
21 * 82801CA (ICH3-S) : document number 290733-003, 290739-013, 21 * document number 290744-001, 290745-025: 82801DB (ICH4)
22 * 82801CAM (ICH3-M) : document number 290716-001, 290718-007, 22 * document number 252337-001, 252663-008: 82801DBM (ICH4-M)
23 * 82801DB (ICH4) : document number 290744-001, 290745-025, 23 * document number 273599-001, 273645-002: 82801E (C-ICH)
24 * 82801DBM (ICH4-M) : document number 252337-001, 252663-008, 24 * document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R)
25 * 82801E (C-ICH) : document number 273599-001, 273645-002, 25 * document number 300641-004, 300884-013: 6300ESB
26 * 82801EB (ICH5) : document number 252516-001, 252517-028, 26 * document number 301473-002, 301474-026: 82801F (ICH6)
27 * 82801ER (ICH5R) : document number 252516-001, 252517-028, 27 * document number 313082-001, 313075-006: 631xESB, 632xESB
28 * 6300ESB (6300ESB) : document number 300641-004, 300884-013, 28 * document number 307013-003, 307014-024: 82801G (ICH7)
29 * 82801FB (ICH6) : document number 301473-002, 301474-026, 29 * document number 313056-003, 313057-017: 82801H (ICH8)
30 * 82801FR (ICH6R) : document number 301473-002, 301474-026, 30 * document number 316972-004, 316973-012: 82801I (ICH9)
31 * 82801FBM (ICH6-M) : document number 301473-002, 301474-026, 31 * document number 319973-002, 319974-002: 82801J (ICH10)
32 * 82801FW (ICH6W) : document number 301473-001, 301474-026, 32 * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH)
33 * 82801FRW (ICH6RW) : document number 301473-001, 301474-026, 33 * document number 320066-003, 320257-008: EP80597 (IICH)
34 * 631xESB (631xESB) : document number 313082-001, 313075-006, 34 * document number TBD : Cougar Point (CPT)
35 * 632xESB (632xESB) : document number 313082-001, 313075-006,
36 * 82801GB (ICH7) : document number 307013-003, 307014-024,
37 * 82801GR (ICH7R) : document number 307013-003, 307014-024,
38 * 82801GDH (ICH7DH) : document number 307013-003, 307014-024,
39 * 82801GBM (ICH7-M) : document number 307013-003, 307014-024,
40 * 82801GHM (ICH7-M DH) : document number 307013-003, 307014-024,
41 * 82801GU (ICH7-U) : document number 307013-003, 307014-024,
42 * 82801HB (ICH8) : document number 313056-003, 313057-017,
43 * 82801HR (ICH8R) : document number 313056-003, 313057-017,
44 * 82801HBM (ICH8M) : document number 313056-003, 313057-017,
45 * 82801HH (ICH8DH) : document number 313056-003, 313057-017,
46 * 82801HO (ICH8DO) : document number 313056-003, 313057-017,
47 * 82801HEM (ICH8M-E) : document number 313056-003, 313057-017,
48 * 82801IB (ICH9) : document number 316972-004, 316973-012,
49 * 82801IR (ICH9R) : document number 316972-004, 316973-012,
50 * 82801IH (ICH9DH) : document number 316972-004, 316973-012,
51 * 82801IO (ICH9DO) : document number 316972-004, 316973-012,
52 * 82801IBM (ICH9M) : document number 316972-004, 316973-012,
53 * 82801IEM (ICH9M-E) : document number 316972-004, 316973-012,
54 * 82801JIB (ICH10) : document number 319973-002, 319974-002,
55 * 82801JIR (ICH10R) : document number 319973-002, 319974-002,
56 * 82801JD (ICH10D) : document number 319973-002, 319974-002,
57 * 82801JDO (ICH10DO) : document number 319973-002, 319974-002
58 */ 35 */
59 36
60/* 37/*
@@ -122,6 +99,53 @@ enum iTCO_chipsets {
122 TCO_ICH10R, /* ICH10R */ 99 TCO_ICH10R, /* ICH10R */
123 TCO_ICH10D, /* ICH10D */ 100 TCO_ICH10D, /* ICH10D */
124 TCO_ICH10DO, /* ICH10DO */ 101 TCO_ICH10DO, /* ICH10DO */
102 TCO_PCH, /* PCH Desktop Full Featured */
103 TCO_PCHM, /* PCH Mobile Full Featured */
104 TCO_P55, /* P55 */
105 TCO_PM55, /* PM55 */
106 TCO_H55, /* H55 */
107 TCO_QM57, /* QM57 */
108 TCO_H57, /* H57 */
109 TCO_HM55, /* HM55 */
110 TCO_Q57, /* Q57 */
111 TCO_HM57, /* HM57 */
112 TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */
113 TCO_QS57, /* QS57 */
114 TCO_3400, /* 3400 */
115 TCO_3420, /* 3420 */
116 TCO_3450, /* 3450 */
117 TCO_EP80579, /* EP80579 */
118 TCO_CPT1, /* Cougar Point */
119 TCO_CPT2, /* Cougar Point Desktop */
120 TCO_CPT3, /* Cougar Point Mobile */
121 TCO_CPT4, /* Cougar Point */
122 TCO_CPT5, /* Cougar Point */
123 TCO_CPT6, /* Cougar Point */
124 TCO_CPT7, /* Cougar Point */
125 TCO_CPT8, /* Cougar Point */
126 TCO_CPT9, /* Cougar Point */
127 TCO_CPT10, /* Cougar Point */
128 TCO_CPT11, /* Cougar Point */
129 TCO_CPT12, /* Cougar Point */
130 TCO_CPT13, /* Cougar Point */
131 TCO_CPT14, /* Cougar Point */
132 TCO_CPT15, /* Cougar Point */
133 TCO_CPT16, /* Cougar Point */
134 TCO_CPT17, /* Cougar Point */
135 TCO_CPT18, /* Cougar Point */
136 TCO_CPT19, /* Cougar Point */
137 TCO_CPT20, /* Cougar Point */
138 TCO_CPT21, /* Cougar Point */
139 TCO_CPT22, /* Cougar Point */
140 TCO_CPT23, /* Cougar Point */
141 TCO_CPT24, /* Cougar Point */
142 TCO_CPT25, /* Cougar Point */
143 TCO_CPT26, /* Cougar Point */
144 TCO_CPT27, /* Cougar Point */
145 TCO_CPT28, /* Cougar Point */
146 TCO_CPT29, /* Cougar Point */
147 TCO_CPT30, /* Cougar Point */
148 TCO_CPT31, /* Cougar Point */
125}; 149};
126 150
127static struct { 151static struct {
@@ -162,6 +186,53 @@ static struct {
162 {"ICH10R", 2}, 186 {"ICH10R", 2},
163 {"ICH10D", 2}, 187 {"ICH10D", 2},
164 {"ICH10DO", 2}, 188 {"ICH10DO", 2},
189 {"PCH Desktop Full Featured", 2},
190 {"PCH Mobile Full Featured", 2},
191 {"P55", 2},
192 {"PM55", 2},
193 {"H55", 2},
194 {"QM57", 2},
195 {"H57", 2},
196 {"HM55", 2},
197 {"Q57", 2},
198 {"HM57", 2},
199 {"PCH Mobile SFF Full Featured", 2},
200 {"QS57", 2},
201 {"3400", 2},
202 {"3420", 2},
203 {"3450", 2},
204 {"EP80579", 2},
205 {"Cougar Point", 2},
206 {"Cougar Point", 2},
207 {"Cougar Point", 2},
208 {"Cougar Point", 2},
209 {"Cougar Point", 2},
210 {"Cougar Point", 2},
211 {"Cougar Point", 2},
212 {"Cougar Point", 2},
213 {"Cougar Point", 2},
214 {"Cougar Point", 2},
215 {"Cougar Point", 2},
216 {"Cougar Point", 2},
217 {"Cougar Point", 2},
218 {"Cougar Point", 2},
219 {"Cougar Point", 2},
220 {"Cougar Point", 2},
221 {"Cougar Point", 2},
222 {"Cougar Point", 2},
223 {"Cougar Point", 2},
224 {"Cougar Point", 2},
225 {"Cougar Point", 2},
226 {"Cougar Point", 2},
227 {"Cougar Point", 2},
228 {"Cougar Point", 2},
229 {"Cougar Point", 2},
230 {"Cougar Point", 2},
231 {"Cougar Point", 2},
232 {"Cougar Point", 2},
233 {"Cougar Point", 2},
234 {"Cougar Point", 2},
235 {"Cougar Point", 2},
165 {NULL, 0} 236 {NULL, 0}
166}; 237};
167 238
@@ -230,6 +301,53 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
230 { ITCO_PCI_DEVICE(0x3a16, TCO_ICH10R)}, 301 { ITCO_PCI_DEVICE(0x3a16, TCO_ICH10R)},
231 { ITCO_PCI_DEVICE(0x3a1a, TCO_ICH10D)}, 302 { ITCO_PCI_DEVICE(0x3a1a, TCO_ICH10D)},
232 { ITCO_PCI_DEVICE(0x3a14, TCO_ICH10DO)}, 303 { ITCO_PCI_DEVICE(0x3a14, TCO_ICH10DO)},
304 { ITCO_PCI_DEVICE(0x3b00, TCO_PCH)},
305 { ITCO_PCI_DEVICE(0x3b01, TCO_PCHM)},
306 { ITCO_PCI_DEVICE(0x3b02, TCO_P55)},
307 { ITCO_PCI_DEVICE(0x3b03, TCO_PM55)},
308 { ITCO_PCI_DEVICE(0x3b06, TCO_H55)},
309 { ITCO_PCI_DEVICE(0x3b07, TCO_QM57)},
310 { ITCO_PCI_DEVICE(0x3b08, TCO_H57)},
311 { ITCO_PCI_DEVICE(0x3b09, TCO_HM55)},
312 { ITCO_PCI_DEVICE(0x3b0a, TCO_Q57)},
313 { ITCO_PCI_DEVICE(0x3b0b, TCO_HM57)},
314 { ITCO_PCI_DEVICE(0x3b0d, TCO_PCHMSFF)},
315 { ITCO_PCI_DEVICE(0x3b0f, TCO_QS57)},
316 { ITCO_PCI_DEVICE(0x3b12, TCO_3400)},
317 { ITCO_PCI_DEVICE(0x3b14, TCO_3420)},
318 { ITCO_PCI_DEVICE(0x3b16, TCO_3450)},
319 { ITCO_PCI_DEVICE(0x5031, TCO_EP80579)},
320 { ITCO_PCI_DEVICE(0x1c41, TCO_CPT1)},
321 { ITCO_PCI_DEVICE(0x1c42, TCO_CPT2)},
322 { ITCO_PCI_DEVICE(0x1c43, TCO_CPT3)},
323 { ITCO_PCI_DEVICE(0x1c44, TCO_CPT4)},
324 { ITCO_PCI_DEVICE(0x1c45, TCO_CPT5)},
325 { ITCO_PCI_DEVICE(0x1c46, TCO_CPT6)},
326 { ITCO_PCI_DEVICE(0x1c47, TCO_CPT7)},
327 { ITCO_PCI_DEVICE(0x1c48, TCO_CPT8)},
328 { ITCO_PCI_DEVICE(0x1c49, TCO_CPT9)},
329 { ITCO_PCI_DEVICE(0x1c4a, TCO_CPT10)},
330 { ITCO_PCI_DEVICE(0x1c4b, TCO_CPT11)},
331 { ITCO_PCI_DEVICE(0x1c4c, TCO_CPT12)},
332 { ITCO_PCI_DEVICE(0x1c4d, TCO_CPT13)},
333 { ITCO_PCI_DEVICE(0x1c4e, TCO_CPT14)},
334 { ITCO_PCI_DEVICE(0x1c4f, TCO_CPT15)},
335 { ITCO_PCI_DEVICE(0x1c50, TCO_CPT16)},
336 { ITCO_PCI_DEVICE(0x1c51, TCO_CPT17)},
337 { ITCO_PCI_DEVICE(0x1c52, TCO_CPT18)},
338 { ITCO_PCI_DEVICE(0x1c53, TCO_CPT19)},
339 { ITCO_PCI_DEVICE(0x1c54, TCO_CPT20)},
340 { ITCO_PCI_DEVICE(0x1c55, TCO_CPT21)},
341 { ITCO_PCI_DEVICE(0x1c56, TCO_CPT22)},
342 { ITCO_PCI_DEVICE(0x1c57, TCO_CPT23)},
343 { ITCO_PCI_DEVICE(0x1c58, TCO_CPT24)},
344 { ITCO_PCI_DEVICE(0x1c59, TCO_CPT25)},
345 { ITCO_PCI_DEVICE(0x1c5a, TCO_CPT26)},
346 { ITCO_PCI_DEVICE(0x1c5b, TCO_CPT27)},
347 { ITCO_PCI_DEVICE(0x1c5c, TCO_CPT28)},
348 { ITCO_PCI_DEVICE(0x1c5d, TCO_CPT29)},
349 { ITCO_PCI_DEVICE(0x1c5e, TCO_CPT30)},
350 { ITCO_PCI_DEVICE(0x1c5f, TCO_CPT31)},
233 { 0, }, /* End of list */ 351 { 0, }, /* End of list */
234}; 352};
235MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); 353MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
@@ -553,7 +671,7 @@ static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd,
553 int new_heartbeat; 671 int new_heartbeat;
554 void __user *argp = (void __user *)arg; 672 void __user *argp = (void __user *)arg;
555 int __user *p = argp; 673 int __user *p = argp;
556 static struct watchdog_info ident = { 674 static const struct watchdog_info ident = {
557 .options = WDIOF_SETTIMEOUT | 675 .options = WDIOF_SETTIMEOUT |
558 WDIOF_KEEPALIVEPING | 676 WDIOF_KEEPALIVEPING |
559 WDIOF_MAGICCLOSE, 677 WDIOF_MAGICCLOSE,
@@ -667,7 +785,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
667 if (iTCO_wdt_private.iTCO_version == 2) { 785 if (iTCO_wdt_private.iTCO_version == 2) {
668 pci_read_config_dword(pdev, 0xf0, &base_address); 786 pci_read_config_dword(pdev, 0xf0, &base_address);
669 if ((base_address & 1) == 0) { 787 if ((base_address & 1) == 0) {
670 printk(KERN_ERR PFX "RCBA is disabled by harddware\n"); 788 printk(KERN_ERR PFX "RCBA is disabled by hardware\n");
671 ret = -ENODEV; 789 ret = -ENODEV;
672 goto out; 790 goto out;
673 } 791 }
@@ -677,8 +795,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
677 795
678 /* Check chipset's NO_REBOOT bit */ 796 /* Check chipset's NO_REBOOT bit */
679 if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { 797 if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
680 printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " 798 printk(KERN_INFO PFX "unable to reset NO_REBOOT flag, "
681 "reboot disabled by hardware\n"); 799 "platform may have disabled it\n");
682 ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ 800 ret = -ENODEV; /* Cannot reset NO_REBOOT bit */
683 goto out_unmap; 801 goto out_unmap;
684 } 802 }
@@ -774,6 +892,7 @@ static void __devexit iTCO_wdt_cleanup(void)
774 892
775static int __devinit iTCO_wdt_probe(struct platform_device *dev) 893static int __devinit iTCO_wdt_probe(struct platform_device *dev)
776{ 894{
895 int ret = -ENODEV;
777 int found = 0; 896 int found = 0;
778 struct pci_dev *pdev = NULL; 897 struct pci_dev *pdev = NULL;
779 const struct pci_device_id *ent; 898 const struct pci_device_id *ent;
@@ -783,19 +902,17 @@ static int __devinit iTCO_wdt_probe(struct platform_device *dev)
783 for_each_pci_dev(pdev) { 902 for_each_pci_dev(pdev) {
784 ent = pci_match_id(iTCO_wdt_pci_tbl, pdev); 903 ent = pci_match_id(iTCO_wdt_pci_tbl, pdev);
785 if (ent) { 904 if (ent) {
786 if (!(iTCO_wdt_init(pdev, ent, dev))) { 905 found++;
787 found++; 906 ret = iTCO_wdt_init(pdev, ent, dev);
907 if (!ret)
788 break; 908 break;
789 }
790 } 909 }
791 } 910 }
792 911
793 if (!found) { 912 if (!found)
794 printk(KERN_INFO PFX "No card detected\n"); 913 printk(KERN_INFO PFX "No card detected\n");
795 return -ENODEV;
796 }
797 914
798 return 0; 915 return ret;
799} 916}
800 917
801static int __devexit iTCO_wdt_remove(struct platform_device *dev) 918static 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/ibmasr.c b/drivers/watchdog/ibmasr.c
index 89fcefcc8510..195e0f798e76 100644
--- a/drivers/watchdog/ibmasr.c
+++ b/drivers/watchdog/ibmasr.c
@@ -12,7 +12,6 @@
12 12
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/slab.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/pci.h> 16#include <linux/pci.h>
18#include <linux/timer.h> 17#include <linux/timer.h>
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 4f4b35a20d84..e86952a7168c 100644
--- a/drivers/watchdog/ixp2000_wdt.c
+++ b/drivers/watchdog/ixp2000_wdt.c
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/timer.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
23#include <linux/fs.h> 24#include <linux/fs.h>
24#include <linux/miscdevice.h> 25#include <linux/miscdevice.h>
@@ -99,7 +100,7 @@ static ssize_t ixp2000_wdt_write(struct file *file, const char *data,
99} 100}
100 101
101 102
102static struct watchdog_info ident = { 103static const struct watchdog_info ident = {
103 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | 104 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
104 WDIOF_KEEPALIVEPING, 105 WDIOF_KEEPALIVEPING,
105 .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 b6b3f59ab446..2d118cf022fc 100644
--- a/drivers/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
@@ -21,7 +21,7 @@
21 * wd#1 - 2 seconds; 21 * wd#1 - 2 seconds;
22 * wd#2 - 7.2 ms; 22 * wd#2 - 7.2 ms;
23 * After the expiration of wd#1, it can generate a NMI, SCI, SMI, or 23 * After the expiration of wd#1, it can generate a NMI, SCI, SMI, or
24 * a system RESET and it starts wd#2 that unconditionaly will RESET 24 * a system RESET and it starts wd#2 that unconditionally will RESET
25 * the system when the counter reaches zero. 25 * the system when the counter reaches zero.
26 * 26 *
27 * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com> 27 * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
@@ -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..3053ff05ca41
--- /dev/null
+++ b/drivers/watchdog/max63xx_wdt.c
@@ -0,0 +1,403 @@
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#include <linux/slab.h>
32
33#define DEFAULT_HEARTBEAT 60
34#define MAX_HEARTBEAT 60
35
36static int heartbeat = DEFAULT_HEARTBEAT;
37static int nowayout = WATCHDOG_NOWAYOUT;
38
39/*
40 * Memory mapping: a single byte, 3 first lower bits to select bit 3
41 * to ping the watchdog.
42 */
43#define MAX6369_WDSET (7 << 0)
44#define MAX6369_WDI (1 << 3)
45
46static DEFINE_SPINLOCK(io_lock);
47
48static unsigned long wdt_status;
49#define WDT_IN_USE 0
50#define WDT_RUNNING 1
51#define WDT_OK_TO_CLOSE 2
52
53static int nodelay;
54static struct resource *wdt_mem;
55static void __iomem *wdt_base;
56static struct platform_device *max63xx_pdev;
57
58/*
59 * The timeout values used are actually the absolute minimum the chip
60 * offers. Typical values on my board are slightly over twice as long
61 * (10s setting ends up with a 25s timeout), and can be up to 3 times
62 * the nominal setting (according to the datasheet). So please take
63 * these values with a grain of salt. Same goes for the initial delay
64 * "feature". Only max6373/74 have a few settings without this initial
65 * delay (selected with the "nodelay" parameter).
66 *
67 * I also decided to remove from the tables any timeout smaller than a
68 * second, as it looked completly overkill...
69 */
70
71/* Timeouts in second */
72struct max63xx_timeout {
73 u8 wdset;
74 u8 tdelay;
75 u8 twd;
76};
77
78static struct max63xx_timeout max6369_table[] = {
79 { 5, 1, 1 },
80 { 6, 10, 10 },
81 { 7, 60, 60 },
82 { },
83};
84
85static struct max63xx_timeout max6371_table[] = {
86 { 6, 60, 3 },
87 { 7, 60, 60 },
88 { },
89};
90
91static struct max63xx_timeout max6373_table[] = {
92 { 2, 60, 1 },
93 { 5, 0, 1 },
94 { 1, 3, 3 },
95 { 7, 60, 10 },
96 { 6, 0, 10 },
97 { },
98};
99
100static struct max63xx_timeout *current_timeout;
101
102static struct max63xx_timeout *
103max63xx_select_timeout(struct max63xx_timeout *table, int value)
104{
105 while (table->twd) {
106 if (value <= table->twd) {
107 if (nodelay && table->tdelay == 0)
108 return table;
109
110 if (!nodelay)
111 return table;
112 }
113
114 table++;
115 }
116
117 return NULL;
118}
119
120static void max63xx_wdt_ping(void)
121{
122 u8 val;
123
124 spin_lock(&io_lock);
125
126 val = __raw_readb(wdt_base);
127
128 __raw_writeb(val | MAX6369_WDI, wdt_base);
129 __raw_writeb(val & ~MAX6369_WDI, wdt_base);
130
131 spin_unlock(&io_lock);
132}
133
134static void max63xx_wdt_enable(struct max63xx_timeout *entry)
135{
136 u8 val;
137
138 if (test_and_set_bit(WDT_RUNNING, &wdt_status))
139 return;
140
141 spin_lock(&io_lock);
142
143 val = __raw_readb(wdt_base);
144 val &= ~MAX6369_WDSET;
145 val |= entry->wdset;
146 __raw_writeb(val, wdt_base);
147
148 spin_unlock(&io_lock);
149
150 /* check for a edge triggered startup */
151 if (entry->tdelay == 0)
152 max63xx_wdt_ping();
153}
154
155static void max63xx_wdt_disable(void)
156{
157 u8 val;
158
159 spin_lock(&io_lock);
160
161 val = __raw_readb(wdt_base);
162 val &= ~MAX6369_WDSET;
163 val |= 3;
164 __raw_writeb(val, wdt_base);
165
166 spin_unlock(&io_lock);
167
168 clear_bit(WDT_RUNNING, &wdt_status);
169}
170
171static int max63xx_wdt_open(struct inode *inode, struct file *file)
172{
173 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
174 return -EBUSY;
175
176 max63xx_wdt_enable(current_timeout);
177 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
178
179 return nonseekable_open(inode, file);
180}
181
182static ssize_t max63xx_wdt_write(struct file *file, const char *data,
183 size_t len, loff_t *ppos)
184{
185 if (len) {
186 if (!nowayout) {
187 size_t i;
188
189 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
190 for (i = 0; i != len; i++) {
191 char c;
192
193 if (get_user(c, data + i))
194 return -EFAULT;
195
196 if (c == 'V')
197 set_bit(WDT_OK_TO_CLOSE, &wdt_status);
198 }
199 }
200
201 max63xx_wdt_ping();
202 }
203
204 return len;
205}
206
207static const struct watchdog_info ident = {
208 .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
209 .identity = "max63xx Watchdog",
210};
211
212static long max63xx_wdt_ioctl(struct file *file, unsigned int cmd,
213 unsigned long arg)
214{
215 int ret = -ENOTTY;
216
217 switch (cmd) {
218 case WDIOC_GETSUPPORT:
219 ret = copy_to_user((struct watchdog_info *)arg, &ident,
220 sizeof(ident)) ? -EFAULT : 0;
221 break;
222
223 case WDIOC_GETSTATUS:
224 case WDIOC_GETBOOTSTATUS:
225 ret = put_user(0, (int *)arg);
226 break;
227
228 case WDIOC_KEEPALIVE:
229 max63xx_wdt_ping();
230 ret = 0;
231 break;
232
233 case WDIOC_GETTIMEOUT:
234 ret = put_user(heartbeat, (int *)arg);
235 break;
236 }
237 return ret;
238}
239
240static int max63xx_wdt_release(struct inode *inode, struct file *file)
241{
242 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
243 max63xx_wdt_disable();
244 else
245 dev_crit(&max63xx_pdev->dev,
246 "device closed unexpectedly - timer will not stop\n");
247
248 clear_bit(WDT_IN_USE, &wdt_status);
249 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
250
251 return 0;
252}
253
254static const struct file_operations max63xx_wdt_fops = {
255 .owner = THIS_MODULE,
256 .llseek = no_llseek,
257 .write = max63xx_wdt_write,
258 .unlocked_ioctl = max63xx_wdt_ioctl,
259 .open = max63xx_wdt_open,
260 .release = max63xx_wdt_release,
261};
262
263static struct miscdevice max63xx_wdt_miscdev = {
264 .minor = WATCHDOG_MINOR,
265 .name = "watchdog",
266 .fops = &max63xx_wdt_fops,
267};
268
269static int __devinit max63xx_wdt_probe(struct platform_device *pdev)
270{
271 int ret = 0;
272 int size;
273 struct resource *res;
274 struct device *dev = &pdev->dev;
275 struct max63xx_timeout *table;
276
277 table = (struct max63xx_timeout *)pdev->id_entry->driver_data;
278
279 if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
280 heartbeat = DEFAULT_HEARTBEAT;
281
282 dev_info(dev, "requesting %ds heartbeat\n", heartbeat);
283 current_timeout = max63xx_select_timeout(table, heartbeat);
284
285 if (!current_timeout) {
286 dev_err(dev, "unable to satisfy heartbeat request\n");
287 return -EINVAL;
288 }
289
290 dev_info(dev, "using %ds heartbeat with %ds initial delay\n",
291 current_timeout->twd, current_timeout->tdelay);
292
293 heartbeat = current_timeout->twd;
294
295 max63xx_pdev = pdev;
296
297 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
298 if (res == NULL) {
299 dev_err(dev, "failed to get memory region resource\n");
300 return -ENOENT;
301 }
302
303 size = resource_size(res);
304 wdt_mem = request_mem_region(res->start, size, pdev->name);
305
306 if (wdt_mem == NULL) {
307 dev_err(dev, "failed to get memory region\n");
308 return -ENOENT;
309 }
310
311 wdt_base = ioremap(res->start, size);
312 if (!wdt_base) {
313 dev_err(dev, "failed to map memory region\n");
314 ret = -ENOMEM;
315 goto out_request;
316 }
317
318 ret = misc_register(&max63xx_wdt_miscdev);
319 if (ret < 0) {
320 dev_err(dev, "cannot register misc device\n");
321 goto out_unmap;
322 }
323
324 return 0;
325
326out_unmap:
327 iounmap(wdt_base);
328out_request:
329 release_resource(wdt_mem);
330 kfree(wdt_mem);
331
332 return ret;
333}
334
335static int __devexit max63xx_wdt_remove(struct platform_device *pdev)
336{
337 misc_deregister(&max63xx_wdt_miscdev);
338 if (wdt_mem) {
339 release_resource(wdt_mem);
340 kfree(wdt_mem);
341 wdt_mem = NULL;
342 }
343
344 if (wdt_base)
345 iounmap(wdt_base);
346
347 return 0;
348}
349
350static struct platform_device_id max63xx_id_table[] = {
351 { "max6369_wdt", (kernel_ulong_t)max6369_table, },
352 { "max6370_wdt", (kernel_ulong_t)max6369_table, },
353 { "max6371_wdt", (kernel_ulong_t)max6371_table, },
354 { "max6372_wdt", (kernel_ulong_t)max6371_table, },
355 { "max6373_wdt", (kernel_ulong_t)max6373_table, },
356 { "max6374_wdt", (kernel_ulong_t)max6373_table, },
357 { },
358};
359MODULE_DEVICE_TABLE(platform, max63xx_id_table);
360
361static struct platform_driver max63xx_wdt_driver = {
362 .probe = max63xx_wdt_probe,
363 .remove = __devexit_p(max63xx_wdt_remove),
364 .id_table = max63xx_id_table,
365 .driver = {
366 .name = "max63xx_wdt",
367 .owner = THIS_MODULE,
368 },
369};
370
371static int __init max63xx_wdt_init(void)
372{
373 return platform_driver_register(&max63xx_wdt_driver);
374}
375
376static void __exit max63xx_wdt_exit(void)
377{
378 platform_driver_unregister(&max63xx_wdt_driver);
379}
380
381module_init(max63xx_wdt_init);
382module_exit(max63xx_wdt_exit);
383
384MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>");
385MODULE_DESCRIPTION("max63xx Watchdog Driver");
386
387module_param(heartbeat, int, 0);
388MODULE_PARM_DESC(heartbeat,
389 "Watchdog heartbeat period in seconds from 1 to "
390 __MODULE_STRING(MAX_HEARTBEAT) ", default "
391 __MODULE_STRING(DEFAULT_HEARTBEAT));
392
393module_param(nowayout, int, 0);
394MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
395 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
396
397module_param(nodelay, int, 0);
398MODULE_PARM_DESC(nodelay,
399 "Force selection of a timeout setting without initial delay "
400 "(max6373/74 only, default=0)");
401
402MODULE_LICENSE("GPL");
403MODULE_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/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c
deleted file mode 100644
index fa9c47ce0ae7..000000000000
--- a/drivers/watchdog/mpc5200_wdt.c
+++ /dev/null
@@ -1,293 +0,0 @@
1#include <linux/init.h>
2#include <linux/module.h>
3#include <linux/miscdevice.h>
4#include <linux/watchdog.h>
5#include <linux/io.h>
6#include <linux/spinlock.h>
7#include <linux/of_platform.h>
8#include <linux/uaccess.h>
9#include <asm/mpc52xx.h>
10
11
12#define GPT_MODE_WDT (1 << 15)
13#define GPT_MODE_CE (1 << 12)
14#define GPT_MODE_MS_TIMER (0x4)
15
16
17struct mpc5200_wdt {
18 unsigned count; /* timer ticks before watchdog kicks in */
19 long ipb_freq;
20 struct miscdevice miscdev;
21 struct resource mem;
22 struct mpc52xx_gpt __iomem *regs;
23 spinlock_t io_lock;
24};
25
26/* is_active stores wether or not the /dev/watchdog device is opened */
27static unsigned long is_active;
28
29/* misc devices don't provide a way, to get back to 'dev' or 'miscdev' from
30 * file operations, which sucks. But there can be max 1 watchdog anyway, so...
31 */
32static struct mpc5200_wdt *wdt_global;
33
34
35/* helper to calculate timeout in timer counts */
36static void mpc5200_wdt_set_timeout(struct mpc5200_wdt *wdt, int timeout)
37{
38 /* use biggest prescaler of 64k */
39 wdt->count = (wdt->ipb_freq + 0xffff) / 0x10000 * timeout;
40
41 if (wdt->count > 0xffff)
42 wdt->count = 0xffff;
43}
44/* return timeout in seconds (calculated from timer count) */
45static int mpc5200_wdt_get_timeout(struct mpc5200_wdt *wdt)
46{
47 return wdt->count * 0x10000 / wdt->ipb_freq;
48}
49
50
51/* watchdog operations */
52static int mpc5200_wdt_start(struct mpc5200_wdt *wdt)
53{
54 spin_lock(&wdt->io_lock);
55 /* disable */
56 out_be32(&wdt->regs->mode, 0);
57 /* set timeout, with maximum prescaler */
58 out_be32(&wdt->regs->count, 0x0 | wdt->count);
59 /* enable watchdog */
60 out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT |
61 GPT_MODE_MS_TIMER);
62 spin_unlock(&wdt->io_lock);
63
64 return 0;
65}
66static int mpc5200_wdt_ping(struct mpc5200_wdt *wdt)
67{
68 spin_lock(&wdt->io_lock);
69 /* writing A5 to OCPW resets the watchdog */
70 out_be32(&wdt->regs->mode, 0xA5000000 |
71 (0xffffff & in_be32(&wdt->regs->mode)));
72 spin_unlock(&wdt->io_lock);
73 return 0;
74}
75static int mpc5200_wdt_stop(struct mpc5200_wdt *wdt)
76{
77 spin_lock(&wdt->io_lock);
78 /* disable */
79 out_be32(&wdt->regs->mode, 0);
80 spin_unlock(&wdt->io_lock);
81 return 0;
82}
83
84
85/* file operations */
86static ssize_t mpc5200_wdt_write(struct file *file, const char __user *data,
87 size_t len, loff_t *ppos)
88{
89 struct mpc5200_wdt *wdt = file->private_data;
90 mpc5200_wdt_ping(wdt);
91 return 0;
92}
93static struct watchdog_info mpc5200_wdt_info = {
94 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
95 .identity = "mpc5200 watchdog on GPT0",
96};
97static long mpc5200_wdt_ioctl(struct file *file, unsigned int cmd,
98 unsigned long arg)
99{
100 struct mpc5200_wdt *wdt = file->private_data;
101 int __user *data = (int __user *)arg;
102 int timeout;
103 int ret = 0;
104
105 switch (cmd) {
106 case WDIOC_GETSUPPORT:
107 ret = copy_to_user(data, &mpc5200_wdt_info,
108 sizeof(mpc5200_wdt_info));
109 if (ret)
110 ret = -EFAULT;
111 break;
112
113 case WDIOC_GETSTATUS:
114 case WDIOC_GETBOOTSTATUS:
115 ret = put_user(0, data);
116 break;
117
118 case WDIOC_KEEPALIVE:
119 mpc5200_wdt_ping(wdt);
120 break;
121
122 case WDIOC_SETTIMEOUT:
123 ret = get_user(timeout, data);
124 if (ret)
125 break;
126 mpc5200_wdt_set_timeout(wdt, timeout);
127 mpc5200_wdt_start(wdt);
128 /* fall through and return the timeout */
129
130 case WDIOC_GETTIMEOUT:
131 timeout = mpc5200_wdt_get_timeout(wdt);
132 ret = put_user(timeout, data);
133 break;
134
135 default:
136 ret = -ENOTTY;
137 }
138 return ret;
139}
140
141static int mpc5200_wdt_open(struct inode *inode, struct file *file)
142{
143 /* /dev/watchdog can only be opened once */
144 if (test_and_set_bit(0, &is_active))
145 return -EBUSY;
146
147 /* Set and activate the watchdog */
148 mpc5200_wdt_set_timeout(wdt_global, 30);
149 mpc5200_wdt_start(wdt_global);
150 file->private_data = wdt_global;
151 return nonseekable_open(inode, file);
152}
153static int mpc5200_wdt_release(struct inode *inode, struct file *file)
154{
155#if WATCHDOG_NOWAYOUT == 0
156 struct mpc5200_wdt *wdt = file->private_data;
157 mpc5200_wdt_stop(wdt);
158 wdt->count = 0; /* == disabled */
159#endif
160 clear_bit(0, &is_active);
161 return 0;
162}
163
164static const struct file_operations mpc5200_wdt_fops = {
165 .owner = THIS_MODULE,
166 .write = mpc5200_wdt_write,
167 .unlocked_ioctl = mpc5200_wdt_ioctl,
168 .open = mpc5200_wdt_open,
169 .release = mpc5200_wdt_release,
170};
171
172/* module operations */
173static int mpc5200_wdt_probe(struct of_device *op,
174 const struct of_device_id *match)
175{
176 struct mpc5200_wdt *wdt;
177 int err;
178 const void *has_wdt;
179 int size;
180
181 has_wdt = of_get_property(op->node, "has-wdt", NULL);
182 if (!has_wdt)
183 has_wdt = of_get_property(op->node, "fsl,has-wdt", NULL);
184 if (!has_wdt)
185 return -ENODEV;
186
187 wdt = kzalloc(sizeof(*wdt), GFP_KERNEL);
188 if (!wdt)
189 return -ENOMEM;
190
191 wdt->ipb_freq = mpc5xxx_get_bus_frequency(op->node);
192
193 err = of_address_to_resource(op->node, 0, &wdt->mem);
194 if (err)
195 goto out_free;
196 size = wdt->mem.end - wdt->mem.start + 1;
197 if (!request_mem_region(wdt->mem.start, size, "mpc5200_wdt")) {
198 err = -ENODEV;
199 goto out_free;
200 }
201 wdt->regs = ioremap(wdt->mem.start, size);
202 if (!wdt->regs) {
203 err = -ENODEV;
204 goto out_release;
205 }
206
207 dev_set_drvdata(&op->dev, wdt);
208 spin_lock_init(&wdt->io_lock);
209
210 wdt->miscdev = (struct miscdevice) {
211 .minor = WATCHDOG_MINOR,
212 .name = "watchdog",
213 .fops = &mpc5200_wdt_fops,
214 .parent = &op->dev,
215 };
216 wdt_global = wdt;
217 err = misc_register(&wdt->miscdev);
218 if (!err)
219 return 0;
220
221 iounmap(wdt->regs);
222out_release:
223 release_mem_region(wdt->mem.start, size);
224out_free:
225 kfree(wdt);
226 return err;
227}
228
229static int mpc5200_wdt_remove(struct of_device *op)
230{
231 struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
232
233 mpc5200_wdt_stop(wdt);
234 misc_deregister(&wdt->miscdev);
235 iounmap(wdt->regs);
236 release_mem_region(wdt->mem.start, wdt->mem.end - wdt->mem.start + 1);
237 kfree(wdt);
238
239 return 0;
240}
241static int mpc5200_wdt_suspend(struct of_device *op, pm_message_t state)
242{
243 struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
244 mpc5200_wdt_stop(wdt);
245 return 0;
246}
247static int mpc5200_wdt_resume(struct of_device *op)
248{
249 struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
250 if (wdt->count)
251 mpc5200_wdt_start(wdt);
252 return 0;
253}
254static int mpc5200_wdt_shutdown(struct of_device *op)
255{
256 struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
257 mpc5200_wdt_stop(wdt);
258 return 0;
259}
260
261static struct of_device_id mpc5200_wdt_match[] = {
262 { .compatible = "mpc5200-gpt", },
263 { .compatible = "fsl,mpc5200-gpt", },
264 {},
265};
266static struct of_platform_driver mpc5200_wdt_driver = {
267 .owner = THIS_MODULE,
268 .name = "mpc5200-gpt-wdt",
269 .match_table = mpc5200_wdt_match,
270 .probe = mpc5200_wdt_probe,
271 .remove = mpc5200_wdt_remove,
272 .suspend = mpc5200_wdt_suspend,
273 .resume = mpc5200_wdt_resume,
274 .shutdown = mpc5200_wdt_shutdown,
275};
276
277
278static int __init mpc5200_wdt_init(void)
279{
280 return of_register_platform_driver(&mpc5200_wdt_driver);
281}
282
283static void __exit mpc5200_wdt_exit(void)
284{
285 of_unregister_platform_driver(&mpc5200_wdt_driver);
286}
287
288module_init(mpc5200_wdt_init);
289module_exit(mpc5200_wdt_exit);
290
291MODULE_AUTHOR("Domen Puncer <domen.puncer@telargo.com>");
292MODULE_LICENSE("Dual BSD/GPL");
293MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
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 83fa34b214b4..b8ec7aca3c8e 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -30,8 +30,10 @@
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/uaccess.h> 32#include <linux/uaccess.h>
33#include <linux/slab.h>
34#include <linux/io.h>
33 35
34#include <asm/hardware/arm_twd.h> 36#include <asm/smp_twd.h>
35 37
36struct mpcore_wdt { 38struct mpcore_wdt {
37 unsigned long timer_alive; 39 unsigned long timer_alive;
@@ -43,7 +45,7 @@ struct mpcore_wdt {
43}; 45};
44 46
45static struct platform_device *mpcore_wdt_dev; 47static struct platform_device *mpcore_wdt_dev;
46extern unsigned int mpcore_timer_rate; 48static DEFINE_SPINLOCK(wdt_lock);
47 49
48#define TIMER_MARGIN 60 50#define TIMER_MARGIN 60
49static int mpcore_margin = TIMER_MARGIN; 51static int mpcore_margin = TIMER_MARGIN;
@@ -93,13 +95,15 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
93 */ 95 */
94static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt) 96static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
95{ 97{
96 unsigned int count; 98 unsigned long count;
97 99
100 spin_lock(&wdt_lock);
98 /* Assume prescale is set to 256 */ 101 /* Assume prescale is set to 256 */
99 count = (mpcore_timer_rate / 256) * mpcore_margin; 102 count = __raw_readl(wdt->base + TWD_WDOG_COUNTER);
103 count = (0xFFFFFFFFU - count) * (HZ / 5);
104 count = (count / 256) * mpcore_margin;
100 105
101 /* Reload the counter */ 106 /* Reload the counter */
102 spin_lock(&wdt_lock);
103 writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); 107 writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
104 wdt->perturb = wdt->perturb ? 0 : 1; 108 wdt->perturb = wdt->perturb ? 0 : 1;
105 spin_unlock(&wdt_lock); 109 spin_unlock(&wdt_lock);
@@ -118,7 +122,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt)
118{ 122{
119 dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); 123 dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n");
120 124
121 spin_lock(&wdt_lock);
122 /* This loads the count register but does NOT start the count yet */ 125 /* This loads the count register but does NOT start the count yet */
123 mpcore_wdt_keepalive(wdt); 126 mpcore_wdt_keepalive(wdt);
124 127
@@ -129,7 +132,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt)
129 /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ 132 /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
130 writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); 133 writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
131 } 134 }
132 spin_unlock(&wdt_lock);
133} 135}
134 136
135static int mpcore_wdt_set_heartbeat(int t) 137static int mpcore_wdt_set_heartbeat(int t)
@@ -213,7 +215,7 @@ static ssize_t mpcore_wdt_write(struct file *file, const char *data,
213 return len; 215 return len;
214} 216}
215 217
216static struct watchdog_info ident = { 218static const struct watchdog_info ident = {
217 .options = WDIOF_SETTIMEOUT | 219 .options = WDIOF_SETTIMEOUT |
218 WDIOF_KEEPALIVEPING | 220 WDIOF_KEEPALIVEPING |
219 WDIOF_MAGICCLOSE, 221 WDIOF_MAGICCLOSE,
@@ -350,7 +352,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
350 ret = -ENXIO; 352 ret = -ENXIO;
351 goto err_free; 353 goto err_free;
352 } 354 }
353 wdt->base = ioremap(res->start, res->end - res->start + 1); 355 wdt->base = ioremap(res->start, resource_size(res));
354 if (!wdt->base) { 356 if (!wdt->base) {
355 ret = -ENOMEM; 357 ret = -ENOMEM;
356 goto err_free; 358 goto err_free;
@@ -359,7 +361,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
359 mpcore_wdt_miscdev.parent = &dev->dev; 361 mpcore_wdt_miscdev.parent = &dev->dev;
360 ret = misc_register(&mpcore_wdt_miscdev); 362 ret = misc_register(&mpcore_wdt_miscdev);
361 if (ret) { 363 if (ret) {
362 dev_printk(KERN_ERR, _dev, 364 dev_printk(KERN_ERR, wdt->dev,
363 "cannot register miscdev on minor=%d (err=%d)\n", 365 "cannot register miscdev on minor=%d (err=%d)\n",
364 WATCHDOG_MINOR, ret); 366 WATCHDOG_MINOR, ret);
365 goto err_misc; 367 goto err_misc;
@@ -368,13 +370,13 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
368 ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, 370 ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED,
369 "mpcore_wdt", wdt); 371 "mpcore_wdt", wdt);
370 if (ret) { 372 if (ret) {
371 dev_printk(KERN_ERR, _dev, 373 dev_printk(KERN_ERR, wdt->dev,
372 "cannot register IRQ%d for watchdog\n", wdt->irq); 374 "cannot register IRQ%d for watchdog\n", wdt->irq);
373 goto err_irq; 375 goto err_irq;
374 } 376 }
375 377
376 mpcore_wdt_stop(wdt); 378 mpcore_wdt_stop(wdt);
377 platform_set_drvdata(&dev->dev, wdt); 379 platform_set_drvdata(dev, wdt);
378 mpcore_wdt_dev = dev; 380 mpcore_wdt_dev = dev;
379 381
380 return 0; 382 return 0;
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c
index acf589dc057c..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,
@@ -275,7 +275,7 @@ static int __devinit mv64x60_wdt_probe(struct platform_device *dev)
275 if (!r) 275 if (!r)
276 return -ENODEV; 276 return -ENODEV;
277 277
278 mv64x60_wdt_regs = ioremap(r->start, r->end - r->start + 1); 278 mv64x60_wdt_regs = ioremap(r->start, resource_size(r));
279 if (mv64x60_wdt_regs == NULL) 279 if (mv64x60_wdt_regs == NULL)
280 return -ENOMEM; 280 return -ENOMEM;
281 281
diff --git a/drivers/watchdog/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c
index adefe3a9d510..6cee33d4b161 100644
--- a/drivers/watchdog/nuc900_wdt.c
+++ b/drivers/watchdog/nuc900_wdt.c
@@ -20,6 +20,7 @@
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/slab.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
24#include <linux/types.h> 25#include <linux/types.h>
25#include <linux/watchdog.h> 26#include <linux/watchdog.h>
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 3ed571a2ab18..76b58abf4451 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -42,8 +42,9 @@
42#include <linux/bitops.h> 42#include <linux/bitops.h>
43#include <linux/io.h> 43#include <linux/io.h>
44#include <linux/uaccess.h> 44#include <linux/uaccess.h>
45#include <linux/slab.h>
45#include <mach/hardware.h> 46#include <mach/hardware.h>
46#include <mach/prcm.h> 47#include <plat/prcm.h>
47 48
48#include "omap_wdt.h" 49#include "omap_wdt.h"
49 50
@@ -277,8 +278,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
277 goto err_busy; 278 goto err_busy;
278 } 279 }
279 280
280 mem = request_mem_region(res->start, res->end - res->start + 1, 281 mem = request_mem_region(res->start, resource_size(res), pdev->name);
281 pdev->name);
282 if (!mem) { 282 if (!mem) {
283 ret = -EBUSY; 283 ret = -EBUSY;
284 goto err_busy; 284 goto err_busy;
@@ -306,7 +306,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev)
306 goto err_clk; 306 goto err_clk;
307 } 307 }
308 308
309 wdev->base = ioremap(res->start, res->end - res->start + 1); 309 wdev->base = ioremap(res->start, resource_size(res));
310 if (!wdev->base) { 310 if (!wdev->base) {
311 ret = -ENOMEM; 311 ret = -ENOMEM;
312 goto err_ioremap; 312 goto err_ioremap;
@@ -358,7 +358,7 @@ err_clk:
358 kfree(wdev); 358 kfree(wdev);
359 359
360err_kzalloc: 360err_kzalloc:
361 release_mem_region(res->start, res->end - res->start + 1); 361 release_mem_region(res->start, resource_size(res));
362 362
363err_busy: 363err_busy:
364err_get_resource: 364err_get_resource:
@@ -383,7 +383,7 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev)
383 return -ENOENT; 383 return -ENOENT;
384 384
385 misc_deregister(&(wdev->omap_wdt_miscdev)); 385 misc_deregister(&(wdev->omap_wdt_miscdev));
386 release_mem_region(res->start, res->end - res->start + 1); 386 release_mem_region(res->start, resource_size(res));
387 platform_set_drvdata(pdev, NULL); 387 platform_set_drvdata(pdev, NULL);
388 388
389 clk_put(wdev->ick); 389 clk_put(wdev->ick);
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/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 4d227b152001..bf5b97c546eb 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -30,6 +30,7 @@
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31#include <linux/uaccess.h> 31#include <linux/uaccess.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/slab.h>
33#include <mach/hardware.h> 34#include <mach/hardware.h>
34 35
35#define MODULE_NAME "PNX4008-WDT: " 36#define MODULE_NAME "PNX4008-WDT: "
@@ -96,9 +97,6 @@ static void wdt_enable(void)
96{ 97{
97 spin_lock(&io_lock); 98 spin_lock(&io_lock);
98 99
99 if (wdt_clk)
100 clk_set_rate(wdt_clk, 1);
101
102 /* stop counter, initiate counter reset */ 100 /* stop counter, initiate counter reset */
103 __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base)); 101 __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base));
104 /*wait for reset to complete. 100% guarantee event */ 102 /*wait for reset to complete. 100% guarantee event */
@@ -125,19 +123,25 @@ static void wdt_disable(void)
125 spin_lock(&io_lock); 123 spin_lock(&io_lock);
126 124
127 __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ 125 __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */
128 if (wdt_clk)
129 clk_set_rate(wdt_clk, 0);
130 126
131 spin_unlock(&io_lock); 127 spin_unlock(&io_lock);
132} 128}
133 129
134static int pnx4008_wdt_open(struct inode *inode, struct file *file) 130static int pnx4008_wdt_open(struct inode *inode, struct file *file)
135{ 131{
132 int ret;
133
136 if (test_and_set_bit(WDT_IN_USE, &wdt_status)) 134 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
137 return -EBUSY; 135 return -EBUSY;
138 136
139 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 137 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
140 138
139 ret = clk_enable(wdt_clk);
140 if (ret) {
141 clear_bit(WDT_IN_USE, &wdt_status);
142 return ret;
143 }
144
141 wdt_enable(); 145 wdt_enable();
142 146
143 return nonseekable_open(inode, file); 147 return nonseekable_open(inode, file);
@@ -225,6 +229,7 @@ static int pnx4008_wdt_release(struct inode *inode, struct file *file)
225 printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n"); 229 printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n");
226 230
227 wdt_disable(); 231 wdt_disable();
232 clk_disable(wdt_clk);
228 clear_bit(WDT_IN_USE, &wdt_status); 233 clear_bit(WDT_IN_USE, &wdt_status);
229 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 234 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
230 235
@@ -264,7 +269,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
264 return -ENOENT; 269 return -ENOENT;
265 } 270 }
266 271
267 size = res->end - res->start + 1; 272 size = resource_size(res);
268 wdt_mem = request_mem_region(res->start, size, pdev->name); 273 wdt_mem = request_mem_region(res->start, size, pdev->name);
269 274
270 if (wdt_mem == NULL) { 275 if (wdt_mem == NULL) {
@@ -273,25 +278,33 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
273 } 278 }
274 wdt_base = (void __iomem *)IO_ADDRESS(res->start); 279 wdt_base = (void __iomem *)IO_ADDRESS(res->start);
275 280
276 wdt_clk = clk_get(&pdev->dev, "wdt_ck"); 281 wdt_clk = clk_get(&pdev->dev, NULL);
277 if (IS_ERR(wdt_clk)) { 282 if (IS_ERR(wdt_clk)) {
278 ret = PTR_ERR(wdt_clk); 283 ret = PTR_ERR(wdt_clk);
279 release_resource(wdt_mem); 284 release_resource(wdt_mem);
280 kfree(wdt_mem); 285 kfree(wdt_mem);
281 goto out; 286 goto out;
282 } else 287 }
283 clk_set_rate(wdt_clk, 1); 288
289 ret = clk_enable(wdt_clk);
290 if (ret) {
291 release_resource(wdt_mem);
292 kfree(wdt_mem);
293 goto out;
294 }
284 295
285 ret = misc_register(&pnx4008_wdt_miscdev); 296 ret = misc_register(&pnx4008_wdt_miscdev);
286 if (ret < 0) { 297 if (ret < 0) {
287 printk(KERN_ERR MODULE_NAME "cannot register misc device\n"); 298 printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
288 release_resource(wdt_mem); 299 release_resource(wdt_mem);
289 kfree(wdt_mem); 300 kfree(wdt_mem);
290 clk_set_rate(wdt_clk, 0); 301 clk_disable(wdt_clk);
302 clk_put(wdt_clk);
291 } else { 303 } else {
292 boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? 304 boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
293 WDIOF_CARDRESET : 0; 305 WDIOF_CARDRESET : 0;
294 wdt_disable(); /*disable for now */ 306 wdt_disable(); /*disable for now */
307 clk_disable(wdt_clk);
295 set_bit(WDT_DEVICE_INITED, &wdt_status); 308 set_bit(WDT_DEVICE_INITED, &wdt_status);
296 } 309 }
297 310
@@ -302,11 +315,10 @@ out:
302static int __devexit pnx4008_wdt_remove(struct platform_device *pdev) 315static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
303{ 316{
304 misc_deregister(&pnx4008_wdt_miscdev); 317 misc_deregister(&pnx4008_wdt_miscdev);
305 if (wdt_clk) { 318
306 clk_set_rate(wdt_clk, 0); 319 clk_disable(wdt_clk);
307 clk_put(wdt_clk); 320 clk_put(wdt_clk);
308 wdt_clk = NULL; 321
309 }
310 if (wdt_mem) { 322 if (wdt_mem) {
311 release_resource(wdt_mem); 323 release_resource(wdt_mem);
312 kfree(wdt_mem); 324 kfree(wdt_mem);
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 d3c824dc2358..ea7f803f6248 100644
--- a/drivers/watchdog/riowd.c
+++ b/drivers/watchdog/riowd.c
@@ -10,12 +10,12 @@
10#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/miscdevice.h> 12#include <linux/miscdevice.h>
13#include <linux/smp_lock.h>
14#include <linux/watchdog.h> 13#include <linux/watchdog.h>
15#include <linux/of.h> 14#include <linux/of.h>
16#include <linux/of_device.h> 15#include <linux/of_device.h>
17#include <linux/io.h> 16#include <linux/io.h>
18#include <linux/uaccess.h> 17#include <linux/uaccess.h>
18#include <linux/slab.h>
19 19
20 20
21/* RIO uses the NatSemi Super I/O power management logical device 21/* RIO uses the NatSemi Super I/O power management logical device
@@ -75,7 +75,6 @@ static void riowd_writereg(struct riowd *p, u8 val, int index)
75 75
76static int riowd_open(struct inode *inode, struct file *filp) 76static int riowd_open(struct inode *inode, struct file *filp)
77{ 77{
78 cycle_kernel_lock();
79 nonseekable_open(inode, filp); 78 nonseekable_open(inode, filp);
80 return 0; 79 return 0;
81} 80}
@@ -87,7 +86,7 @@ static int riowd_release(struct inode *inode, struct file *filp)
87 86
88static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 87static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
89{ 88{
90 static struct watchdog_info info = { 89 static const struct watchdog_info info = {
91 .options = WDIOF_SETTIMEOUT, 90 .options = WDIOF_SETTIMEOUT,
92 .firmware_version = 1, 91 .firmware_version = 1,
93 .identity = DRIVER_NAME, 92 .identity = DRIVER_NAME,
@@ -194,6 +193,8 @@ static int __devinit riowd_probe(struct of_device *op,
194 printk(KERN_ERR PFX "Cannot map registers.\n"); 193 printk(KERN_ERR PFX "Cannot map registers.\n");
195 goto out_free; 194 goto out_free;
196 } 195 }
196 /* Make miscdev useable right away */
197 riowd_device = p;
197 198
198 err = misc_register(&riowd_miscdev); 199 err = misc_register(&riowd_miscdev);
199 if (err) { 200 if (err) {
@@ -205,10 +206,10 @@ static int __devinit riowd_probe(struct of_device *op,
205 "regs at %p\n", riowd_timeout, p->regs); 206 "regs at %p\n", riowd_timeout, p->regs);
206 207
207 dev_set_drvdata(&op->dev, p); 208 dev_set_drvdata(&op->dev, p);
208 riowd_device = p;
209 return 0; 209 return 0;
210 210
211out_iounmap: 211out_iounmap:
212 riowd_device = NULL;
212 of_iounmap(&op->resource[0], p->regs, 2); 213 of_iounmap(&op->resource[0], p->regs, 2);
213 214
214out_free: 215out_free:
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
deleted file mode 100644
index bb66958b9433..000000000000
--- a/drivers/watchdog/rm9k_wdt.c
+++ /dev/null
@@ -1,419 +0,0 @@
1/*
2 * Watchdog implementation for GPI h/w found on PMC-Sierra RM9xxx
3 * chips.
4 *
5 * Copyright (C) 2004 by Basler Vision Technologies AG
6 * Author: Thomas Koeller <thomas.koeller@baslerweb.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/platform_device.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/interrupt.h>
27#include <linux/fs.h>
28#include <linux/reboot.h>
29#include <linux/notifier.h>
30#include <linux/miscdevice.h>
31#include <linux/watchdog.h>
32#include <linux/io.h>
33#include <linux/uaccess.h>
34#include <asm/atomic.h>
35#include <asm/processor.h>
36#include <asm/system.h>
37#include <asm/rm9k-ocd.h>
38
39#include <rm9k_wdt.h>
40
41
42#define CLOCK 125000000
43#define MAX_TIMEOUT_SECONDS 32
44#define CPCCR 0x0080
45#define CPGIG1SR 0x0044
46#define CPGIG1ER 0x0054
47
48
49/* Function prototypes */
50static irqreturn_t wdt_gpi_irqhdl(int, void *);
51static void wdt_gpi_start(void);
52static void wdt_gpi_stop(void);
53static void wdt_gpi_set_timeout(unsigned int);
54static int wdt_gpi_open(struct inode *, struct file *);
55static int wdt_gpi_release(struct inode *, struct file *);
56static ssize_t wdt_gpi_write(struct file *, const char __user *, size_t,
57 loff_t *);
58static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long);
59static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *);
60static const struct resource *wdt_gpi_get_resource(struct platform_device *,
61 const char *, unsigned int);
62static int __init wdt_gpi_probe(struct platform_device *);
63static int __exit wdt_gpi_remove(struct platform_device *);
64
65
66static const char wdt_gpi_name[] = "wdt_gpi";
67static atomic_t opencnt;
68static int expect_close;
69static int locked;
70
71
72/* These are set from device resources */
73static void __iomem *wd_regs;
74static unsigned int wd_irq, wd_ctr;
75
76
77/* Module arguments */
78static int timeout = MAX_TIMEOUT_SECONDS;
79module_param(timeout, int, 0444);
80MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds");
81
82static unsigned long resetaddr = 0xbffdc200;
83module_param(resetaddr, ulong, 0444);
84MODULE_PARM_DESC(resetaddr, "Address to write to to force a reset");
85
86static unsigned long flagaddr = 0xbffdc104;
87module_param(flagaddr, ulong, 0444);
88MODULE_PARM_DESC(flagaddr, "Address to write to boot flags to");
89
90static int powercycle;
91module_param(powercycle, bool, 0444);
92MODULE_PARM_DESC(powercycle, "Cycle power if watchdog expires");
93
94static int nowayout = WATCHDOG_NOWAYOUT;
95module_param(nowayout, bool, 0444);
96MODULE_PARM_DESC(nowayout, "Watchdog cannot be disabled once started");
97
98
99/* Kernel interfaces */
100static const struct file_operations fops = {
101 .owner = THIS_MODULE,
102 .open = wdt_gpi_open,
103 .release = wdt_gpi_release,
104 .write = wdt_gpi_write,
105 .unlocked_ioctl = wdt_gpi_ioctl,
106};
107
108static struct miscdevice miscdev = {
109 .minor = WATCHDOG_MINOR,
110 .name = wdt_gpi_name,
111 .fops = &fops,
112};
113
114static struct notifier_block wdt_gpi_shutdown = {
115 .notifier_call = wdt_gpi_notify,
116};
117
118
119/* Interrupt handler */
120static irqreturn_t wdt_gpi_irqhdl(int irq, void *ctxt)
121{
122 if (!unlikely(__raw_readl(wd_regs + 0x0008) & 0x1))
123 return IRQ_NONE;
124 __raw_writel(0x1, wd_regs + 0x0008);
125
126
127 printk(KERN_CRIT "%s: watchdog expired - resetting system\n",
128 wdt_gpi_name);
129
130 *(volatile char *) flagaddr |= 0x01;
131 *(volatile char *) resetaddr = powercycle ? 0x01 : 0x2;
132 iob();
133 while (1)
134 cpu_relax();
135}
136
137
138/* Watchdog functions */
139static void wdt_gpi_start(void)
140{
141 u32 reg;
142
143 lock_titan_regs();
144 reg = titan_readl(CPGIG1ER);
145 titan_writel(reg | (0x100 << wd_ctr), CPGIG1ER);
146 iob();
147 unlock_titan_regs();
148}
149
150static void wdt_gpi_stop(void)
151{
152 u32 reg;
153
154 lock_titan_regs();
155 reg = titan_readl(CPCCR) & ~(0xf << (wd_ctr * 4));
156 titan_writel(reg, CPCCR);
157 reg = titan_readl(CPGIG1ER);
158 titan_writel(reg & ~(0x100 << wd_ctr), CPGIG1ER);
159 iob();
160 unlock_titan_regs();
161}
162
163static void wdt_gpi_set_timeout(unsigned int to)
164{
165 u32 reg;
166 const u32 wdval = (to * CLOCK) & ~0x0000000f;
167
168 lock_titan_regs();
169 reg = titan_readl(CPCCR) & ~(0xf << (wd_ctr * 4));
170 titan_writel(reg, CPCCR);
171 wmb();
172 __raw_writel(wdval, wd_regs + 0x0000);
173 wmb();
174 titan_writel(reg | (0x2 << (wd_ctr * 4)), CPCCR);
175 wmb();
176 titan_writel(reg | (0x5 << (wd_ctr * 4)), CPCCR);
177 iob();
178 unlock_titan_regs();
179}
180
181
182/* /dev/watchdog operations */
183static int wdt_gpi_open(struct inode *inode, struct file *file)
184{
185 int res;
186
187 if (unlikely(atomic_dec_if_positive(&opencnt) < 0))
188 return -EBUSY;
189
190 expect_close = 0;
191 if (locked) {
192 module_put(THIS_MODULE);
193 free_irq(wd_irq, &miscdev);
194 locked = 0;
195 }
196
197 res = request_irq(wd_irq, wdt_gpi_irqhdl, IRQF_SHARED | IRQF_DISABLED,
198 wdt_gpi_name, &miscdev);
199 if (unlikely(res))
200 return res;
201
202 wdt_gpi_set_timeout(timeout);
203 wdt_gpi_start();
204
205 printk(KERN_INFO "%s: watchdog started, timeout = %u seconds\n",
206 wdt_gpi_name, timeout);
207 return nonseekable_open(inode, file);
208}
209
210static int wdt_gpi_release(struct inode *inode, struct file *file)
211{
212 if (nowayout) {
213 printk(KERN_INFO "%s: no way out - watchdog left running\n",
214 wdt_gpi_name);
215 __module_get(THIS_MODULE);
216 locked = 1;
217 } else {
218 if (expect_close) {
219 wdt_gpi_stop();
220 free_irq(wd_irq, &miscdev);
221 printk(KERN_INFO "%s: watchdog stopped\n",
222 wdt_gpi_name);
223 } else {
224 printk(KERN_CRIT "%s: unexpected close() -"
225 " watchdog left running\n",
226 wdt_gpi_name);
227 wdt_gpi_set_timeout(timeout);
228 __module_get(THIS_MODULE);
229 locked = 1;
230 }
231 }
232
233 atomic_inc(&opencnt);
234 return 0;
235}
236
237static ssize_t wdt_gpi_write(struct file *f, const char __user *d, size_t s,
238 loff_t *o)
239{
240 char val;
241
242 wdt_gpi_set_timeout(timeout);
243 expect_close = (s > 0) && !get_user(val, d) && (val == 'V');
244 return s ? 1 : 0;
245}
246
247static long wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
248{
249 long res = -ENOTTY;
250 const long size = _IOC_SIZE(cmd);
251 int stat;
252 void __user *argp = (void __user *)arg;
253 static struct watchdog_info wdinfo = {
254 .identity = "RM9xxx/GPI watchdog",
255 .firmware_version = 0,
256 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING
257 };
258
259 if (unlikely(_IOC_TYPE(cmd) != WATCHDOG_IOCTL_BASE))
260 return -ENOTTY;
261
262 if ((_IOC_DIR(cmd) & _IOC_READ)
263 && !access_ok(VERIFY_WRITE, arg, size))
264 return -EFAULT;
265
266 if ((_IOC_DIR(cmd) & _IOC_WRITE)
267 && !access_ok(VERIFY_READ, arg, size))
268 return -EFAULT;
269
270 expect_close = 0;
271
272 switch (cmd) {
273 case WDIOC_GETSUPPORT:
274 wdinfo.options = nowayout ?
275 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING :
276 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
277 WDIOF_MAGICCLOSE;
278 res = __copy_to_user(argp, &wdinfo, size) ? -EFAULT : size;
279 break;
280
281 case WDIOC_GETSTATUS:
282 break;
283
284 case WDIOC_GETBOOTSTATUS:
285 stat = (*(volatile char *) flagaddr & 0x01)
286 ? WDIOF_CARDRESET : 0;
287 res = __copy_to_user(argp, &stat, size) ?
288 -EFAULT : size;
289 break;
290
291 case WDIOC_SETOPTIONS:
292 break;
293
294 case WDIOC_KEEPALIVE:
295 wdt_gpi_set_timeout(timeout);
296 res = size;
297 break;
298
299 case WDIOC_SETTIMEOUT:
300 {
301 int val;
302 if (unlikely(__copy_from_user(&val, argp, size))) {
303 res = -EFAULT;
304 break;
305 }
306
307 if (val > MAX_TIMEOUT_SECONDS)
308 val = MAX_TIMEOUT_SECONDS;
309 timeout = val;
310 wdt_gpi_set_timeout(val);
311 res = size;
312 printk(KERN_INFO "%s: timeout set to %u seconds\n",
313 wdt_gpi_name, timeout);
314 }
315 break;
316
317 case WDIOC_GETTIMEOUT:
318 res = __copy_to_user(argp, &timeout, size) ?
319 -EFAULT : size;
320 break;
321 }
322
323 return res;
324}
325
326
327/* Shutdown notifier */
328static int wdt_gpi_notify(struct notifier_block *this, unsigned long code,
329 void *unused)
330{
331 if (code == SYS_DOWN || code == SYS_HALT)
332 wdt_gpi_stop();
333
334 return NOTIFY_DONE;
335}
336
337
338/* Init & exit procedures */
339static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv,
340 const char *name, unsigned int type)
341{
342 char buf[80];
343 if (snprintf(buf, sizeof(buf), "%s_0", name) >= sizeof(buf))
344 return NULL;
345 return platform_get_resource_byname(pdv, type, buf);
346}
347
348/* No hotplugging on the platform bus - use __devinit */
349static int __devinit wdt_gpi_probe(struct platform_device *pdv)
350{
351 int res;
352 const struct resource
353 * const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS,
354 IORESOURCE_MEM),
355 * const ri = wdt_gpi_get_resource(pdv, WDT_RESOURCE_IRQ,
356 IORESOURCE_IRQ),
357 * const rc = wdt_gpi_get_resource(pdv, WDT_RESOURCE_COUNTER,
358 0);
359
360 if (unlikely(!rr || !ri || !rc))
361 return -ENXIO;
362
363 wd_regs = ioremap_nocache(rr->start, rr->end + 1 - rr->start);
364 if (unlikely(!wd_regs))
365 return -ENOMEM;
366 wd_irq = ri->start;
367 wd_ctr = rc->start;
368 res = misc_register(&miscdev);
369 if (res)
370 iounmap(wd_regs);
371 else
372 register_reboot_notifier(&wdt_gpi_shutdown);
373 return res;
374}
375
376static int __devexit wdt_gpi_remove(struct platform_device *dev)
377{
378 int res;
379
380 unregister_reboot_notifier(&wdt_gpi_shutdown);
381 res = misc_deregister(&miscdev);
382 iounmap(wd_regs);
383 wd_regs = NULL;
384 return res;
385}
386
387
388/* Device driver init & exit */
389static struct platform_driver wgt_gpi_driver = {
390 .driver = {
391 .name = wdt_gpi_name,
392 .owner = THIS_MODULE,
393 },
394 .probe = wdt_gpi_probe,
395 .remove = __devexit_p(wdt_gpi_remove),
396};
397
398static int __init wdt_gpi_init_module(void)
399{
400 atomic_set(&opencnt, 1);
401 if (timeout > MAX_TIMEOUT_SECONDS)
402 timeout = MAX_TIMEOUT_SECONDS;
403 return platform_driver_register(&wdt_gpi_driver);
404}
405
406static void __exit wdt_gpi_cleanup_module(void)
407{
408 platform_driver_unregister(&wdt_gpi_driver);
409}
410
411module_init(wdt_gpi_init_module);
412module_exit(wdt_gpi_cleanup_module);
413
414MODULE_AUTHOR("Thomas Koeller <thomas.koeller@baslerweb.com>");
415MODULE_DESCRIPTION("Basler eXcite watchdog driver for gpi devices");
416MODULE_VERSION("0.1");
417MODULE_LICENSE("GPL");
418MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
419
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index b57ac6b49147..e4cebef55177 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -36,6 +36,8 @@
36#include <linux/clk.h> 36#include <linux/clk.h>
37#include <linux/uaccess.h> 37#include <linux/uaccess.h>
38#include <linux/io.h> 38#include <linux/io.h>
39#include <linux/cpufreq.h>
40#include <linux/slab.h>
39 41
40#include <mach/map.h> 42#include <mach/map.h>
41 43
@@ -142,9 +144,14 @@ static void s3c2410wdt_start(void)
142 spin_unlock(&wdt_lock); 144 spin_unlock(&wdt_lock);
143} 145}
144 146
147static inline int s3c2410wdt_is_running(void)
148{
149 return readl(wdt_base + S3C2410_WTCON) & S3C2410_WTCON_ENABLE;
150}
151
145static int s3c2410wdt_set_heartbeat(int timeout) 152static int s3c2410wdt_set_heartbeat(int timeout)
146{ 153{
147 unsigned int freq = clk_get_rate(wdt_clock); 154 unsigned long freq = clk_get_rate(wdt_clock);
148 unsigned int count; 155 unsigned int count;
149 unsigned int divisor = 1; 156 unsigned int divisor = 1;
150 unsigned long wtcon; 157 unsigned long wtcon;
@@ -155,7 +162,7 @@ static int s3c2410wdt_set_heartbeat(int timeout)
155 freq /= 128; 162 freq /= 128;
156 count = timeout * freq; 163 count = timeout * freq;
157 164
158 DBG("%s: count=%d, timeout=%d, freq=%d\n", 165 DBG("%s: count=%d, timeout=%d, freq=%lu\n",
159 __func__, count, timeout, freq); 166 __func__, count, timeout, freq);
160 167
161 /* if the count is bigger than the watchdog register, 168 /* if the count is bigger than the watchdog register,
@@ -324,6 +331,73 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param)
324 s3c2410wdt_keepalive(); 331 s3c2410wdt_keepalive();
325 return IRQ_HANDLED; 332 return IRQ_HANDLED;
326} 333}
334
335
336#ifdef CONFIG_CPU_FREQ
337
338static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb,
339 unsigned long val, void *data)
340{
341 int ret;
342
343 if (!s3c2410wdt_is_running())
344 goto done;
345
346 if (val == CPUFREQ_PRECHANGE) {
347 /* To ensure that over the change we don't cause the
348 * watchdog to trigger, we perform an keep-alive if
349 * the watchdog is running.
350 */
351
352 s3c2410wdt_keepalive();
353 } else if (val == CPUFREQ_POSTCHANGE) {
354 s3c2410wdt_stop();
355
356 ret = s3c2410wdt_set_heartbeat(tmr_margin);
357
358 if (ret >= 0)
359 s3c2410wdt_start();
360 else
361 goto err;
362 }
363
364done:
365 return 0;
366
367 err:
368 dev_err(wdt_dev, "cannot set new value for timeout %d\n", tmr_margin);
369 return ret;
370}
371
372static struct notifier_block s3c2410wdt_cpufreq_transition_nb = {
373 .notifier_call = s3c2410wdt_cpufreq_transition,
374};
375
376static inline int s3c2410wdt_cpufreq_register(void)
377{
378 return cpufreq_register_notifier(&s3c2410wdt_cpufreq_transition_nb,
379 CPUFREQ_TRANSITION_NOTIFIER);
380}
381
382static inline void s3c2410wdt_cpufreq_deregister(void)
383{
384 cpufreq_unregister_notifier(&s3c2410wdt_cpufreq_transition_nb,
385 CPUFREQ_TRANSITION_NOTIFIER);
386}
387
388#else
389static inline int s3c2410wdt_cpufreq_register(void)
390{
391 return 0;
392}
393
394static inline void s3c2410wdt_cpufreq_deregister(void)
395{
396}
397#endif
398
399
400
327/* device interface */ 401/* device interface */
328 402
329static int __devinit s3c2410wdt_probe(struct platform_device *pdev) 403static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
@@ -348,7 +422,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
348 return -ENOENT; 422 return -ENOENT;
349 } 423 }
350 424
351 size = (res->end - res->start) + 1; 425 size = resource_size(res);
352 wdt_mem = request_mem_region(res->start, size, pdev->name); 426 wdt_mem = request_mem_region(res->start, size, pdev->name);
353 if (wdt_mem == NULL) { 427 if (wdt_mem == NULL) {
354 dev_err(dev, "failed to get memory region\n"); 428 dev_err(dev, "failed to get memory region\n");
@@ -387,6 +461,11 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
387 461
388 clk_enable(wdt_clock); 462 clk_enable(wdt_clock);
389 463
464 if (s3c2410wdt_cpufreq_register() < 0) {
465 printk(KERN_ERR PFX "failed to register cpufreq\n");
466 goto err_clk;
467 }
468
390 /* see if we can actually set the requested timer margin, and if 469 /* see if we can actually set the requested timer margin, and if
391 * not, try the default value */ 470 * not, try the default value */
392 471
@@ -407,7 +486,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
407 if (ret) { 486 if (ret) {
408 dev_err(dev, "cannot register miscdev on minor=%d (%d)\n", 487 dev_err(dev, "cannot register miscdev on minor=%d (%d)\n",
409 WATCHDOG_MINOR, ret); 488 WATCHDOG_MINOR, ret);
410 goto err_clk; 489 goto err_cpufreq;
411 } 490 }
412 491
413 if (tmr_atboot && started == 0) { 492 if (tmr_atboot && started == 0) {
@@ -432,6 +511,9 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
432 511
433 return 0; 512 return 0;
434 513
514 err_cpufreq:
515 s3c2410wdt_cpufreq_deregister();
516
435 err_clk: 517 err_clk:
436 clk_disable(wdt_clock); 518 clk_disable(wdt_clock);
437 clk_put(wdt_clock); 519 clk_put(wdt_clock);
@@ -451,6 +533,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
451 533
452static int __devexit s3c2410wdt_remove(struct platform_device *dev) 534static int __devexit s3c2410wdt_remove(struct platform_device *dev)
453{ 535{
536 s3c2410wdt_cpufreq_deregister();
537
454 release_resource(wdt_mem); 538 release_resource(wdt_mem);
455 kfree(wdt_mem); 539 kfree(wdt_mem);
456 wdt_mem = NULL; 540 wdt_mem = NULL;
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
index 9748eed73196..88c83aa57303 100644
--- a/drivers/watchdog/sb_wdog.c
+++ b/drivers/watchdog/sb_wdog.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Watchdog driver for SiByte SB1 SoCs 2 * Watchdog driver for SiByte SB1 SoCs
3 * 3 *
4 * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp <andy.sharp@onstor.com> 4 * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp <andy.sharp@lsi.com>
5 * 5 *
6 * This driver is intended to make the second of two hardware watchdogs 6 * This driver is intended to make the second of two hardware watchdogs
7 * on the Sibyte 12XX and 11XX SoCs available to the user. There are two 7 * on the Sibyte 12XX and 11XX SoCs available to the user. There are two
@@ -67,8 +67,8 @@ static DEFINE_SPINLOCK(sbwd_lock);
67void sbwdog_set(char __iomem *wdog, unsigned long t) 67void sbwdog_set(char __iomem *wdog, unsigned long t)
68{ 68{
69 spin_lock(&sbwd_lock); 69 spin_lock(&sbwd_lock);
70 __raw_writeb(0, wdog - 0x10); 70 __raw_writeb(0, wdog);
71 __raw_writeq(t & 0x7fffffUL, wdog); 71 __raw_writeq(t & 0x7fffffUL, wdog - 0x10);
72 spin_unlock(&sbwd_lock); 72 spin_unlock(&sbwd_lock);
73} 73}
74 74
@@ -326,7 +326,7 @@ static void __exit sbwdog_exit(void)
326module_init(sbwdog_init); 326module_init(sbwdog_init);
327module_exit(sbwdog_exit); 327module_exit(sbwdog_exit);
328 328
329MODULE_AUTHOR("Andrew Sharp <andy.sharp@onstor.com>"); 329MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>");
330MODULE_DESCRIPTION("SiByte Watchdog"); 330MODULE_DESCRIPTION("SiByte Watchdog");
331 331
332module_param(timeout, ulong, 0); 332module_param(timeout, ulong, 0);
diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c
index 91430a89107c..c7d67e9a7465 100644
--- a/drivers/watchdog/sbc_fitpc2_wdt.c
+++ b/drivers/watchdog/sbc_fitpc2_wdt.c
@@ -30,7 +30,7 @@
30static int nowayout = WATCHDOG_NOWAYOUT; 30static int nowayout = WATCHDOG_NOWAYOUT;
31static unsigned int margin = 60; /* (secs) Default is 1 minute */ 31static unsigned int margin = 60; /* (secs) Default is 1 minute */
32static unsigned long wdt_status; 32static unsigned long wdt_status;
33static DEFINE_SPINLOCK(wdt_lock); 33static DEFINE_MUTEX(wdt_lock);
34 34
35#define WDT_IN_USE 0 35#define WDT_IN_USE 0
36#define WDT_OK_TO_CLOSE 1 36#define WDT_OK_TO_CLOSE 1
@@ -45,26 +45,26 @@ static DEFINE_SPINLOCK(wdt_lock);
45 45
46static void wdt_send_data(unsigned char command, unsigned char data) 46static void wdt_send_data(unsigned char command, unsigned char data)
47{ 47{
48 outb(command, COMMAND_PORT);
49 mdelay(100);
50 outb(data, DATA_PORT); 48 outb(data, DATA_PORT);
51 mdelay(200); 49 msleep(200);
50 outb(command, COMMAND_PORT);
51 msleep(100);
52} 52}
53 53
54static void wdt_enable(void) 54static void wdt_enable(void)
55{ 55{
56 spin_lock(&wdt_lock); 56 mutex_lock(&wdt_lock);
57 wdt_send_data(IFACE_ON_COMMAND, 1); 57 wdt_send_data(IFACE_ON_COMMAND, 1);
58 wdt_send_data(REBOOT_COMMAND, margin); 58 wdt_send_data(REBOOT_COMMAND, margin);
59 spin_unlock(&wdt_lock); 59 mutex_unlock(&wdt_lock);
60} 60}
61 61
62static void wdt_disable(void) 62static void wdt_disable(void)
63{ 63{
64 spin_lock(&wdt_lock); 64 mutex_lock(&wdt_lock);
65 wdt_send_data(IFACE_ON_COMMAND, 0); 65 wdt_send_data(IFACE_ON_COMMAND, 0);
66 wdt_send_data(REBOOT_COMMAND, 0); 66 wdt_send_data(REBOOT_COMMAND, 0);
67 spin_unlock(&wdt_lock); 67 mutex_unlock(&wdt_lock);
68} 68}
69 69
70static int fitpc2_wdt_open(struct inode *inode, struct file *file) 70static int fitpc2_wdt_open(struct inode *inode, struct file *file)
@@ -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,
@@ -202,11 +202,10 @@ static int __init fitpc2_wdt_init(void)
202{ 202{
203 int err; 203 int err;
204 204
205 if (strcmp("SBC-FITPC2", dmi_get_system_info(DMI_BOARD_NAME))) { 205 if (!strstr(dmi_get_system_info(DMI_BOARD_NAME), "SBC-FITPC2"))
206 pr_info("board name is: %s. Should be SBC-FITPC2\n",
207 dmi_get_system_info(DMI_BOARD_NAME));
208 return -ENODEV; 206 return -ENODEV;
209 } 207
208 pr_info("%s found\n", dmi_get_system_info(DMI_BOARD_NAME));
210 209
211 if (!request_region(COMMAND_PORT, 1, WATCHDOG_NAME)) { 210 if (!request_region(COMMAND_PORT, 1, WATCHDOG_NAME)) {
212 pr_err("I/O address 0x%04x already in use\n", COMMAND_PORT); 211 pr_err("I/O address 0x%04x already in use\n", COMMAND_PORT);
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..458c499c1223
--- /dev/null
+++ b/drivers/watchdog/ts72xx_wdt.c
@@ -0,0 +1,521 @@
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/slab.h>
24#include <linux/watchdog.h>
25#include <linux/uaccess.h>
26
27#define TS72XX_WDT_FEED_VAL 0x05
28#define TS72XX_WDT_DEFAULT_TIMEOUT 8
29
30static int timeout = TS72XX_WDT_DEFAULT_TIMEOUT;
31module_param(timeout, int, 0);
32MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. "
33 "(1 <= timeout <= 8, default="
34 __MODULE_STRING(TS72XX_WDT_DEFAULT_TIMEOUT)
35 ")");
36
37static int nowayout = WATCHDOG_NOWAYOUT;
38module_param(nowayout, int, 0);
39MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
40
41/**
42 * struct ts72xx_wdt - watchdog control structure
43 * @lock: lock that protects this structure
44 * @regval: watchdog timeout value suitable for control register
45 * @flags: flags controlling watchdog device state
46 * @control_reg: watchdog control register
47 * @feed_reg: watchdog feed register
48 * @pdev: back pointer to platform dev
49 */
50struct ts72xx_wdt {
51 struct mutex lock;
52 int regval;
53
54#define TS72XX_WDT_BUSY_FLAG 1
55#define TS72XX_WDT_EXPECT_CLOSE_FLAG 2
56 int flags;
57
58 void __iomem *control_reg;
59 void __iomem *feed_reg;
60
61 struct platform_device *pdev;
62};
63
64struct platform_device *ts72xx_wdt_pdev;
65
66/*
67 * TS-72xx Watchdog supports following timeouts (value written
68 * to control register):
69 * value description
70 * -------------------------
71 * 0x00 watchdog disabled
72 * 0x01 250ms
73 * 0x02 500ms
74 * 0x03 1s
75 * 0x04 reserved
76 * 0x05 2s
77 * 0x06 4s
78 * 0x07 8s
79 *
80 * Timeouts below 1s are not very usable so we don't
81 * allow them at all.
82 *
83 * We provide two functions that convert between these:
84 * timeout_to_regval() and regval_to_timeout().
85 */
86static const struct {
87 int timeout;
88 int regval;
89} ts72xx_wdt_map[] = {
90 { 1, 3 },
91 { 2, 5 },
92 { 4, 6 },
93 { 8, 7 },
94};
95
96/**
97 * timeout_to_regval() - converts given timeout to control register value
98 * @new_timeout: timeout in seconds to be converted
99 *
100 * Function converts given @new_timeout into valid value that can
101 * be programmed into watchdog control register. When conversion is
102 * not possible, function returns %-EINVAL.
103 */
104static int timeout_to_regval(int new_timeout)
105{
106 int i;
107
108 /* first limit it to 1 - 8 seconds */
109 new_timeout = clamp_val(new_timeout, 1, 8);
110
111 for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) {
112 if (ts72xx_wdt_map[i].timeout >= new_timeout)
113 return ts72xx_wdt_map[i].regval;
114 }
115
116 return -EINVAL;
117}
118
119/**
120 * regval_to_timeout() - converts control register value to timeout
121 * @regval: control register value to be converted
122 *
123 * Function converts given @regval to timeout in seconds (1, 2, 4 or 8).
124 * If @regval cannot be converted, function returns %-EINVAL.
125 */
126static int regval_to_timeout(int regval)
127{
128 int i;
129
130 for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) {
131 if (ts72xx_wdt_map[i].regval == regval)
132 return ts72xx_wdt_map[i].timeout;
133 }
134
135 return -EINVAL;
136}
137
138/**
139 * ts72xx_wdt_kick() - kick the watchdog
140 * @wdt: watchdog to be kicked
141 *
142 * Called with @wdt->lock held.
143 */
144static inline void ts72xx_wdt_kick(struct ts72xx_wdt *wdt)
145{
146 __raw_writeb(TS72XX_WDT_FEED_VAL, wdt->feed_reg);
147}
148
149/**
150 * ts72xx_wdt_start() - starts the watchdog timer
151 * @wdt: watchdog to be started
152 *
153 * This function programs timeout to watchdog timer
154 * and starts it.
155 *
156 * Called with @wdt->lock held.
157 */
158static void ts72xx_wdt_start(struct ts72xx_wdt *wdt)
159{
160 /*
161 * To program the wdt, it first must be "fed" and
162 * only after that (within 30 usecs) the configuration
163 * can be changed.
164 */
165 ts72xx_wdt_kick(wdt);
166 __raw_writeb((u8)wdt->regval, wdt->control_reg);
167}
168
169/**
170 * ts72xx_wdt_stop() - stops the watchdog timer
171 * @wdt: watchdog to be stopped
172 *
173 * Called with @wdt->lock held.
174 */
175static void ts72xx_wdt_stop(struct ts72xx_wdt *wdt)
176{
177 ts72xx_wdt_kick(wdt);
178 __raw_writeb(0, wdt->control_reg);
179}
180
181static int ts72xx_wdt_open(struct inode *inode, struct file *file)
182{
183 struct ts72xx_wdt *wdt = platform_get_drvdata(ts72xx_wdt_pdev);
184 int regval;
185
186 /*
187 * Try to convert default timeout to valid register
188 * value first.
189 */
190 regval = timeout_to_regval(timeout);
191 if (regval < 0) {
192 dev_err(&wdt->pdev->dev,
193 "failed to convert timeout (%d) to register value\n",
194 timeout);
195 return -EINVAL;
196 }
197
198 if (mutex_lock_interruptible(&wdt->lock))
199 return -ERESTARTSYS;
200
201 if ((wdt->flags & TS72XX_WDT_BUSY_FLAG) != 0) {
202 mutex_unlock(&wdt->lock);
203 return -EBUSY;
204 }
205
206 wdt->flags = TS72XX_WDT_BUSY_FLAG;
207 wdt->regval = regval;
208 file->private_data = wdt;
209
210 ts72xx_wdt_start(wdt);
211
212 mutex_unlock(&wdt->lock);
213 return nonseekable_open(inode, file);
214}
215
216static int ts72xx_wdt_release(struct inode *inode, struct file *file)
217{
218 struct ts72xx_wdt *wdt = file->private_data;
219
220 if (mutex_lock_interruptible(&wdt->lock))
221 return -ERESTARTSYS;
222
223 if ((wdt->flags & TS72XX_WDT_EXPECT_CLOSE_FLAG) != 0) {
224 ts72xx_wdt_stop(wdt);
225 } else {
226 dev_warn(&wdt->pdev->dev,
227 "TS-72XX WDT device closed unexpectly. "
228 "Watchdog timer will not stop!\n");
229 /*
230 * Kick it one more time, to give userland some time
231 * to recover (for example, respawning the kicker
232 * daemon).
233 */
234 ts72xx_wdt_kick(wdt);
235 }
236
237 wdt->flags = 0;
238
239 mutex_unlock(&wdt->lock);
240 return 0;
241}
242
243static ssize_t ts72xx_wdt_write(struct file *file,
244 const char __user *data,
245 size_t len,
246 loff_t *ppos)
247{
248 struct ts72xx_wdt *wdt = file->private_data;
249
250 if (!len)
251 return 0;
252
253 if (mutex_lock_interruptible(&wdt->lock))
254 return -ERESTARTSYS;
255
256 ts72xx_wdt_kick(wdt);
257
258 /*
259 * Support for magic character closing. User process
260 * writes 'V' into the device, just before it is closed.
261 * This means that we know that the wdt timer can be
262 * stopped after user closes the device.
263 */
264 if (!nowayout) {
265 int i;
266
267 for (i = 0; i < len; i++) {
268 char c;
269
270 /* In case it was set long ago */
271 wdt->flags &= ~TS72XX_WDT_EXPECT_CLOSE_FLAG;
272
273 if (get_user(c, data + i)) {
274 mutex_unlock(&wdt->lock);
275 return -EFAULT;
276 }
277 if (c == 'V') {
278 wdt->flags |= TS72XX_WDT_EXPECT_CLOSE_FLAG;
279 break;
280 }
281 }
282 }
283
284 mutex_unlock(&wdt->lock);
285 return len;
286}
287
288static const struct watchdog_info winfo = {
289 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
290 WDIOF_MAGICCLOSE,
291 .firmware_version = 1,
292 .identity = "TS-72XX WDT",
293};
294
295static long ts72xx_wdt_ioctl(struct file *file, unsigned int cmd,
296 unsigned long arg)
297{
298 struct ts72xx_wdt *wdt = file->private_data;
299 void __user *argp = (void __user *)arg;
300 int __user *p = (int __user *)argp;
301 int error = 0;
302
303 if (mutex_lock_interruptible(&wdt->lock))
304 return -ERESTARTSYS;
305
306 switch (cmd) {
307 case WDIOC_GETSUPPORT:
308 error = copy_to_user(argp, &winfo, sizeof(winfo));
309 break;
310
311 case WDIOC_GETSTATUS:
312 case WDIOC_GETBOOTSTATUS:
313 return put_user(0, p);
314
315 case WDIOC_KEEPALIVE:
316 ts72xx_wdt_kick(wdt);
317 break;
318
319 case WDIOC_SETOPTIONS: {
320 int options;
321
322 if (get_user(options, p)) {
323 error = -EFAULT;
324 break;
325 }
326
327 error = -EINVAL;
328
329 if ((options & WDIOS_DISABLECARD) != 0) {
330 ts72xx_wdt_stop(wdt);
331 error = 0;
332 }
333 if ((options & WDIOS_ENABLECARD) != 0) {
334 ts72xx_wdt_start(wdt);
335 error = 0;
336 }
337
338 break;
339 }
340
341 case WDIOC_SETTIMEOUT: {
342 int new_timeout;
343
344 if (get_user(new_timeout, p)) {
345 error = -EFAULT;
346 } else {
347 int regval;
348
349 regval = timeout_to_regval(new_timeout);
350 if (regval < 0) {
351 error = -EINVAL;
352 } else {
353 ts72xx_wdt_stop(wdt);
354 wdt->regval = regval;
355 ts72xx_wdt_start(wdt);
356 }
357 }
358 if (error)
359 break;
360
361 /*FALLTHROUGH*/
362 }
363
364 case WDIOC_GETTIMEOUT:
365 if (put_user(regval_to_timeout(wdt->regval), p))
366 error = -EFAULT;
367 break;
368
369 default:
370 error = -ENOTTY;
371 break;
372 }
373
374 mutex_unlock(&wdt->lock);
375 return error;
376}
377
378static const struct file_operations ts72xx_wdt_fops = {
379 .owner = THIS_MODULE,
380 .llseek = no_llseek,
381 .open = ts72xx_wdt_open,
382 .release = ts72xx_wdt_release,
383 .write = ts72xx_wdt_write,
384 .unlocked_ioctl = ts72xx_wdt_ioctl,
385};
386
387static struct miscdevice ts72xx_wdt_miscdev = {
388 .minor = WATCHDOG_MINOR,
389 .name = "watchdog",
390 .fops = &ts72xx_wdt_fops,
391};
392
393static __devinit int ts72xx_wdt_probe(struct platform_device *pdev)
394{
395 struct ts72xx_wdt *wdt;
396 struct resource *r1, *r2;
397 int error = 0;
398
399 wdt = kzalloc(sizeof(struct ts72xx_wdt), GFP_KERNEL);
400 if (!wdt) {
401 dev_err(&pdev->dev, "failed to allocate memory\n");
402 return -ENOMEM;
403 }
404
405 r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
406 if (!r1) {
407 dev_err(&pdev->dev, "failed to get memory resource\n");
408 error = -ENODEV;
409 goto fail;
410 }
411
412 r1 = request_mem_region(r1->start, resource_size(r1), pdev->name);
413 if (!r1) {
414 dev_err(&pdev->dev, "cannot request memory region\n");
415 error = -EBUSY;
416 goto fail;
417 }
418
419 wdt->control_reg = ioremap(r1->start, resource_size(r1));
420 if (!wdt->control_reg) {
421 dev_err(&pdev->dev, "failed to map memory\n");
422 error = -ENODEV;
423 goto fail_free_control;
424 }
425
426 r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
427 if (!r2) {
428 dev_err(&pdev->dev, "failed to get memory resource\n");
429 error = -ENODEV;
430 goto fail_unmap_control;
431 }
432
433 r2 = request_mem_region(r2->start, resource_size(r2), pdev->name);
434 if (!r2) {
435 dev_err(&pdev->dev, "cannot request memory region\n");
436 error = -EBUSY;
437 goto fail_unmap_control;
438 }
439
440 wdt->feed_reg = ioremap(r2->start, resource_size(r2));
441 if (!wdt->feed_reg) {
442 dev_err(&pdev->dev, "failed to map memory\n");
443 error = -ENODEV;
444 goto fail_free_feed;
445 }
446
447 platform_set_drvdata(pdev, wdt);
448 ts72xx_wdt_pdev = pdev;
449 wdt->pdev = pdev;
450 mutex_init(&wdt->lock);
451
452 error = misc_register(&ts72xx_wdt_miscdev);
453 if (error) {
454 dev_err(&pdev->dev, "failed to register miscdev\n");
455 goto fail_unmap_feed;
456 }
457
458 dev_info(&pdev->dev, "TS-72xx Watchdog driver\n");
459
460 return 0;
461
462fail_unmap_feed:
463 platform_set_drvdata(pdev, NULL);
464 iounmap(wdt->feed_reg);
465fail_free_feed:
466 release_mem_region(r2->start, resource_size(r2));
467fail_unmap_control:
468 iounmap(wdt->control_reg);
469fail_free_control:
470 release_mem_region(r1->start, resource_size(r1));
471fail:
472 kfree(wdt);
473 return error;
474}
475
476static __devexit int ts72xx_wdt_remove(struct platform_device *pdev)
477{
478 struct ts72xx_wdt *wdt = platform_get_drvdata(pdev);
479 struct resource *res;
480 int error;
481
482 error = misc_deregister(&ts72xx_wdt_miscdev);
483 platform_set_drvdata(pdev, NULL);
484
485 iounmap(wdt->feed_reg);
486 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
487 release_mem_region(res->start, resource_size(res));
488
489 iounmap(wdt->control_reg);
490 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
491 release_mem_region(res->start, resource_size(res));
492
493 kfree(wdt);
494 return error;
495}
496
497static struct platform_driver ts72xx_wdt_driver = {
498 .probe = ts72xx_wdt_probe,
499 .remove = __devexit_p(ts72xx_wdt_remove),
500 .driver = {
501 .name = "ts72xx-wdt",
502 .owner = THIS_MODULE,
503 },
504};
505
506static __init int ts72xx_wdt_init(void)
507{
508 return platform_driver_register(&ts72xx_wdt_driver);
509}
510module_init(ts72xx_wdt_init);
511
512static __exit void ts72xx_wdt_exit(void)
513{
514 platform_driver_unregister(&ts72xx_wdt_driver);
515}
516module_exit(ts72xx_wdt_exit);
517
518MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
519MODULE_DESCRIPTION("TS-72xx SBC Watchdog");
520MODULE_LICENSE("GPL");
521MODULE_ALIAS("platform:ts72xx-wdt");
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index cb46556f2973..dcabe77ad141 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -20,13 +20,14 @@
20 20
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/slab.h>
23#include <linux/kernel.h> 24#include <linux/kernel.h>
24#include <linux/fs.h> 25#include <linux/fs.h>
25#include <linux/watchdog.h> 26#include <linux/watchdog.h>
26#include <linux/platform_device.h> 27#include <linux/platform_device.h>
27#include <linux/miscdevice.h> 28#include <linux/miscdevice.h>
28#include <linux/uaccess.h> 29#include <linux/uaccess.h>
29#include <linux/i2c/twl4030.h> 30#include <linux/i2c/twl.h>
30 31
31#define TWL4030_WATCHDOG_CFG_REG_OFFS 0x3 32#define TWL4030_WATCHDOG_CFG_REG_OFFS 0x3
32 33
@@ -48,7 +49,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
48 49
49static int twl4030_wdt_write(unsigned char val) 50static int twl4030_wdt_write(unsigned char val)
50{ 51{
51 return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val, 52 return twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val,
52 TWL4030_WATCHDOG_CFG_REG_OFFS); 53 TWL4030_WATCHDOG_CFG_REG_OFFS);
53} 54}
54 55
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index 6adab77fbbb0..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;
@@ -214,22 +201,15 @@ static int __init txx9wdt_probe(struct platform_device *dev)
214 res = platform_get_resource(dev, IORESOURCE_MEM, 0); 201 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
215 if (!res) 202 if (!res)
216 goto exit_busy; 203 goto exit_busy;
217 if (!devm_request_mem_region(&dev->dev, 204 if (!devm_request_mem_region(&dev->dev, res->start, resource_size(res),
218 res->start, res->end - res->start + 1,
219 "txx9wdt")) 205 "txx9wdt"))
220 goto exit_busy; 206 goto exit_busy;
221 txx9wdt_reg = devm_ioremap(&dev->dev, 207 txx9wdt_reg = devm_ioremap(&dev->dev, res->start, resource_size(res));
222 res->start, res->end - res->start + 1);
223 if (!txx9wdt_reg) 208 if (!txx9wdt_reg)
224 goto exit_busy; 209 goto exit_busy;
225 210
226 ret = register_reboot_notifier(&txx9wdt_notifier);
227 if (ret)
228 goto exit;
229
230 ret = misc_register(&txx9wdt_miscdev); 211 ret = misc_register(&txx9wdt_miscdev);
231 if (ret) { 212 if (ret) {
232 unregister_reboot_notifier(&txx9wdt_notifier);
233 goto exit; 213 goto exit;
234 } 214 }
235 215
@@ -251,14 +231,19 @@ exit:
251static int __exit txx9wdt_remove(struct platform_device *dev) 231static int __exit txx9wdt_remove(struct platform_device *dev)
252{ 232{
253 misc_deregister(&txx9wdt_miscdev); 233 misc_deregister(&txx9wdt_miscdev);
254 unregister_reboot_notifier(&txx9wdt_notifier);
255 clk_disable(txx9_imclk); 234 clk_disable(txx9_imclk);
256 clk_put(txx9_imclk); 235 clk_put(txx9_imclk);
257 return 0; 236 return 0;
258} 237}
259 238
239static void txx9wdt_shutdown(struct platform_device *dev)
240{
241 txx9wdt_stop();
242}
243
260static struct platform_driver txx9wdt_driver = { 244static struct platform_driver txx9wdt_driver = {
261 .remove = __exit_p(txx9wdt_remove), 245 .remove = __exit_p(txx9wdt_remove),
246 .shutdown = txx9wdt_shutdown,
262 .driver = { 247 .driver = {
263 .name = "txx9wdt", 248 .name = "txx9wdt",
264 .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 3bde56bce63a..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",
@@ -542,7 +542,7 @@ static struct notifier_block wdrtas_notifier = {
542/** 542/**
543 * wdrtas_get_tokens - reads in RTAS tokens 543 * wdrtas_get_tokens - reads in RTAS tokens
544 * 544 *
545 * returns 0 on succes, <0 on failure 545 * returns 0 on success, <0 on failure
546 * 546 *
547 * wdrtas_get_tokens reads in the tokens for the RTAS calls used in 547 * wdrtas_get_tokens reads in the tokens for the RTAS calls used in
548 * this watchdog driver. It tolerates, if "get-sensor-state" and 548 * this watchdog driver. It tolerates, if "get-sensor-state" and
@@ -598,7 +598,7 @@ static void wdrtas_unregister_devs(void)
598/** 598/**
599 * wdrtas_register_devs - registers the misc dev handlers 599 * wdrtas_register_devs - registers the misc dev handlers
600 * 600 *
601 * returns 0 on succes, <0 on failure 601 * returns 0 on success, <0 on failure
602 * 602 *
603 * wdrtas_register_devs registers the watchdog and temperature watchdog 603 * wdrtas_register_devs registers the watchdog and temperature watchdog
604 * misc devs 604 * misc devs
@@ -630,7 +630,7 @@ static int wdrtas_register_devs(void)
630/** 630/**
631 * wdrtas_init - init function of the watchdog driver 631 * wdrtas_init - init function of the watchdog driver
632 * 632 *
633 * returns 0 on succes, <0 on failure 633 * returns 0 on success, <0 on failure
634 * 634 *
635 * registers the file handlers and the reboot notifier 635 * registers the file handlers and the reboot notifier
636 */ 636 */
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};