aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-10 17:33:03 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-10 17:33:03 -0400
commita9deecba19b8f384d97f82c75379da48bccb2588 (patch)
treeed909c58167b93304e74e67d1e8fcbcc37f4de92 /drivers/char
parentd9de2622bd4fd29cab4ef7db66a9f916cb38e032 (diff)
parent04bf3b4f5fc033adf921f2e57d034ddbebef5fe7 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
* master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog: [WATCHDOG] MTX-1 Watchdog driver [WATCHDOG] s3c2410_wdt - initialize watchdog irq resource [WATCHDOG] Kconfig menuconfig patch [WATCHDOG] pcwd.c: Port to the new device driver model [WATCHDOG] use mutex instead of semaphore in Berkshire USB-PC Watchdog driver [WATCHDOG] the scheduled removal of the i8xx_tco watchdog driver [WATCHDOG] Semi-typical watchdog bug re early misc_register() [WATCHDOG] add support for the w83627thf chipset.
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/watchdog/Kconfig150
-rw-r--r--drivers/char/watchdog/Makefile2
-rw-r--r--drivers/char/watchdog/cpu5wdt.c14
-rw-r--r--drivers/char/watchdog/eurotechwdt.c22
-rw-r--r--drivers/char/watchdog/i8xx_tco.c571
-rw-r--r--drivers/char/watchdog/i8xx_tco.h42
-rw-r--r--drivers/char/watchdog/ibmasr.c11
-rw-r--r--drivers/char/watchdog/machzwd.c18
-rw-r--r--drivers/char/watchdog/mtx-1_wdt.c238
-rw-r--r--drivers/char/watchdog/pcwd.c242
-rw-r--r--drivers/char/watchdog/pcwd_usb.c8
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c6
-rw-r--r--drivers/char/watchdog/sbc8360.c28
-rw-r--r--drivers/char/watchdog/w83627hf_wdt.c23
14 files changed, 496 insertions, 879 deletions
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 60198a78974c..1cad32c62ed3 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -2,9 +2,7 @@
2# Watchdog device configuration 2# Watchdog device configuration
3# 3#
4 4
5menu "Watchdog Cards" 5menuconfig WATCHDOG
6
7config WATCHDOG
8 bool "Watchdog Timer Support" 6 bool "Watchdog Timer Support"
9 ---help--- 7 ---help---
10 If you say Y here (and to one of the following options) and create a 8 If you say Y here (and to one of the following options) and create a
@@ -28,9 +26,10 @@ config WATCHDOG
28 26
29 If unsure, say N. 27 If unsure, say N.
30 28
29if WATCHDOG
30
31config WATCHDOG_NOWAYOUT 31config WATCHDOG_NOWAYOUT
32 bool "Disable watchdog shutdown on close" 32 bool "Disable watchdog shutdown on close"
33 depends on WATCHDOG
34 help 33 help
35 The default watchdog behaviour (which you get if you say N here) is 34 The default watchdog behaviour (which you get if you say N here) is
36 to stop the timer if the process managing it closes the file 35 to stop the timer if the process managing it closes the file
@@ -43,13 +42,11 @@ config WATCHDOG_NOWAYOUT
43# 42#
44 43
45comment "Watchdog Device Drivers" 44comment "Watchdog Device Drivers"
46 depends on WATCHDOG
47 45
48# Architecture Independent 46# Architecture Independent
49 47
50config SOFT_WATCHDOG 48config SOFT_WATCHDOG
51 tristate "Software watchdog" 49 tristate "Software watchdog"
52 depends on WATCHDOG
53 help 50 help
54 A software monitoring watchdog. This will fail to reboot your system 51 A software monitoring watchdog. This will fail to reboot your system
55 from some situations that the hardware watchdog will recover 52 from some situations that the hardware watchdog will recover
@@ -62,14 +59,14 @@ config SOFT_WATCHDOG
62 59
63config AT91RM9200_WATCHDOG 60config AT91RM9200_WATCHDOG
64 tristate "AT91RM9200 watchdog" 61 tristate "AT91RM9200 watchdog"
65 depends on WATCHDOG && ARCH_AT91RM9200 62 depends on ARCH_AT91RM9200
66 help 63 help
67 Watchdog timer embedded into AT91RM9200 chips. This will reboot your 64 Watchdog timer embedded into AT91RM9200 chips. This will reboot your
68 system when the timeout is reached. 65 system when the timeout is reached.
69 66
70config 21285_WATCHDOG 67config 21285_WATCHDOG
71 tristate "DC21285 watchdog" 68 tristate "DC21285 watchdog"
72 depends on WATCHDOG && FOOTBRIDGE 69 depends on FOOTBRIDGE
73 help 70 help
74 The Intel Footbridge chip contains a built-in watchdog circuit. Say Y 71 The Intel Footbridge chip contains a built-in watchdog circuit. Say Y
75 here if you wish to use this. Alternatively say M to compile the 72 here if you wish to use this. Alternatively say M to compile the
@@ -83,7 +80,7 @@ config 21285_WATCHDOG
83 80
84config 977_WATCHDOG 81config 977_WATCHDOG
85 tristate "NetWinder WB83C977 watchdog" 82 tristate "NetWinder WB83C977 watchdog"
86 depends on WATCHDOG && FOOTBRIDGE && ARCH_NETWINDER 83 depends on FOOTBRIDGE && ARCH_NETWINDER
87 help 84 help
88 Say Y here to include support for the WB977 watchdog included in 85 Say Y here to include support for the WB977 watchdog included in
89 NetWinder machines. Alternatively say M to compile the driver as 86 NetWinder machines. Alternatively say M to compile the driver as
@@ -93,7 +90,7 @@ config 977_WATCHDOG
93 90
94config IXP2000_WATCHDOG 91config IXP2000_WATCHDOG
95 tristate "IXP2000 Watchdog" 92 tristate "IXP2000 Watchdog"
96 depends on WATCHDOG && ARCH_IXP2000 93 depends on ARCH_IXP2000
97 help 94 help
98 Say Y here if to include support for the watchdog timer 95 Say Y here if to include support for the watchdog timer
99 in the Intel IXP2000(2400, 2800, 2850) network processors. 96 in the Intel IXP2000(2400, 2800, 2850) network processors.
@@ -104,7 +101,7 @@ config IXP2000_WATCHDOG
104 101
105config IXP4XX_WATCHDOG 102config IXP4XX_WATCHDOG
106 tristate "IXP4xx Watchdog" 103 tristate "IXP4xx Watchdog"
107 depends on WATCHDOG && ARCH_IXP4XX 104 depends on ARCH_IXP4XX
108 help 105 help
109 Say Y here if to include support for the watchdog timer 106 Say Y here if to include support for the watchdog timer
110 in the Intel IXP4xx network processors. This driver can 107 in the Intel IXP4xx network processors. This driver can
@@ -120,7 +117,7 @@ config IXP4XX_WATCHDOG
120 117
121config S3C2410_WATCHDOG 118config S3C2410_WATCHDOG
122 tristate "S3C2410 Watchdog" 119 tristate "S3C2410 Watchdog"
123 depends on WATCHDOG && ARCH_S3C2410 120 depends on ARCH_S3C2410
124 help 121 help
125 Watchdog timer block in the Samsung S3C2410 chips. This will 122 Watchdog timer block in the Samsung S3C2410 chips. This will
126 reboot the system when the timer expires with the watchdog 123 reboot the system when the timer expires with the watchdog
@@ -136,7 +133,7 @@ config S3C2410_WATCHDOG
136 133
137config SA1100_WATCHDOG 134config SA1100_WATCHDOG
138 tristate "SA1100/PXA2xx watchdog" 135 tristate "SA1100/PXA2xx watchdog"
139 depends on WATCHDOG && ( ARCH_SA1100 || ARCH_PXA ) 136 depends on ARCH_SA1100 || ARCH_PXA
140 help 137 help
141 Watchdog timer embedded into SA11x0 and PXA2xx chips. This will 138 Watchdog timer embedded into SA11x0 and PXA2xx chips. This will
142 reboot your system when timeout is reached. 139 reboot your system when timeout is reached.
@@ -148,7 +145,7 @@ config SA1100_WATCHDOG
148 145
149config MPCORE_WATCHDOG 146config MPCORE_WATCHDOG
150 tristate "MPcore watchdog" 147 tristate "MPcore watchdog"
151 depends on WATCHDOG && ARM_MPCORE_PLATFORM && LOCAL_TIMERS 148 depends on ARM_MPCORE_PLATFORM && LOCAL_TIMERS
152 help 149 help
153 Watchdog timer embedded into the MPcore system. 150 Watchdog timer embedded into the MPcore system.
154 151
@@ -157,7 +154,7 @@ config MPCORE_WATCHDOG
157 154
158config EP93XX_WATCHDOG 155config EP93XX_WATCHDOG
159 tristate "EP93xx Watchdog" 156 tristate "EP93xx Watchdog"
160 depends on WATCHDOG && ARCH_EP93XX 157 depends on ARCH_EP93XX
161 help 158 help
162 Say Y here if to include support for the watchdog timer 159 Say Y here if to include support for the watchdog timer
163 embedded in the Cirrus Logic EP93xx family of devices. 160 embedded in the Cirrus Logic EP93xx family of devices.
@@ -167,14 +164,14 @@ config EP93XX_WATCHDOG
167 164
168config OMAP_WATCHDOG 165config OMAP_WATCHDOG
169 tristate "OMAP Watchdog" 166 tristate "OMAP Watchdog"
170 depends on WATCHDOG && (ARCH_OMAP16XX || ARCH_OMAP24XX) 167 depends on ARCH_OMAP16XX || ARCH_OMAP24XX
171 help 168 help
172 Support for TI OMAP1610/OMAP1710/OMAP2420 watchdog. Say 'Y' here to 169 Support for TI OMAP1610/OMAP1710/OMAP2420 watchdog. Say 'Y' here to
173 enable the OMAP1610/OMAP1710 watchdog timer. 170 enable the OMAP1610/OMAP1710 watchdog timer.
174 171
175config PNX4008_WATCHDOG 172config PNX4008_WATCHDOG
176 tristate "PNX4008 Watchdog" 173 tristate "PNX4008 Watchdog"
177 depends on WATCHDOG && ARCH_PNX4008 174 depends on ARCH_PNX4008
178 help 175 help
179 Say Y here if to include support for the watchdog timer 176 Say Y here if to include support for the watchdog timer
180 in the PNX4008 processor. 177 in the PNX4008 processor.
@@ -187,7 +184,7 @@ config PNX4008_WATCHDOG
187 184
188config ACQUIRE_WDT 185config ACQUIRE_WDT
189 tristate "Acquire SBC Watchdog Timer" 186 tristate "Acquire SBC Watchdog Timer"
190 depends on WATCHDOG && X86 187 depends on X86
191 ---help--- 188 ---help---
192 This is the driver for the hardware watchdog on Single Board 189 This is the driver for the hardware watchdog on Single Board
193 Computers produced by Acquire Inc (and others). This watchdog 190 Computers produced by Acquire Inc (and others). This watchdog
@@ -201,7 +198,7 @@ config ACQUIRE_WDT
201 198
202config ADVANTECH_WDT 199config ADVANTECH_WDT
203 tristate "Advantech SBC Watchdog Timer" 200 tristate "Advantech SBC Watchdog Timer"
204 depends on WATCHDOG && X86 201 depends on X86
205 help 202 help
206 If you are configuring a Linux kernel for the Advantech single-board 203 If you are configuring a Linux kernel for the Advantech single-board
207 computer, say `Y' here to support its built-in watchdog timer 204 computer, say `Y' here to support its built-in watchdog timer
@@ -210,7 +207,7 @@ config ADVANTECH_WDT
210 207
211config ALIM1535_WDT 208config ALIM1535_WDT
212 tristate "ALi M1535 PMU Watchdog Timer" 209 tristate "ALi M1535 PMU Watchdog Timer"
213 depends on WATCHDOG && X86 && PCI 210 depends on X86 && PCI
214 ---help--- 211 ---help---
215 This is the driver for the hardware watchdog on the ALi M1535 PMU. 212 This is the driver for the hardware watchdog on the ALi M1535 PMU.
216 213
@@ -221,7 +218,7 @@ config ALIM1535_WDT
221 218
222config ALIM7101_WDT 219config ALIM7101_WDT
223 tristate "ALi M7101 PMU Computer Watchdog" 220 tristate "ALi M7101 PMU Computer Watchdog"
224 depends on WATCHDOG && X86 && PCI 221 depends on X86 && PCI
225 help 222 help
226 This is the driver for the hardware watchdog on the ALi M7101 PMU 223 This is the driver for the hardware watchdog on the ALi M7101 PMU
227 as used in the x86 Cobalt servers. 224 as used in the x86 Cobalt servers.
@@ -233,7 +230,7 @@ config ALIM7101_WDT
233 230
234config SC520_WDT 231config SC520_WDT
235 tristate "AMD Elan SC520 processor Watchdog" 232 tristate "AMD Elan SC520 processor Watchdog"
236 depends on WATCHDOG && X86 233 depends on X86
237 help 234 help
238 This is the driver for the hardware watchdog built in to the 235 This is the driver for the hardware watchdog built in to the
239 AMD "Elan" SC520 microcomputer commonly used in embedded systems. 236 AMD "Elan" SC520 microcomputer commonly used in embedded systems.
@@ -246,7 +243,7 @@ config SC520_WDT
246 243
247config EUROTECH_WDT 244config EUROTECH_WDT
248 tristate "Eurotech CPU-1220/1410 Watchdog Timer" 245 tristate "Eurotech CPU-1220/1410 Watchdog Timer"
249 depends on WATCHDOG && X86 246 depends on X86
250 help 247 help
251 Enable support for the watchdog timer on the Eurotech CPU-1220 and 248 Enable support for the watchdog timer on the Eurotech CPU-1220 and
252 CPU-1410 cards. These are PC/104 SBCs. Spec sheets and product 249 CPU-1410 cards. These are PC/104 SBCs. Spec sheets and product
@@ -254,7 +251,7 @@ config EUROTECH_WDT
254 251
255config IB700_WDT 252config IB700_WDT
256 tristate "IB700 SBC Watchdog Timer" 253 tristate "IB700 SBC Watchdog Timer"
257 depends on WATCHDOG && X86 254 depends on X86
258 ---help--- 255 ---help---
259 This is the driver for the hardware watchdog on the IB700 Single 256 This is the driver for the hardware watchdog on the IB700 Single
260 Board Computer produced by TMC Technology (www.tmc-uk.com). This watchdog 257 Board Computer produced by TMC Technology (www.tmc-uk.com). This watchdog
@@ -270,7 +267,7 @@ config IB700_WDT
270 267
271config IBMASR 268config IBMASR
272 tristate "IBM Automatic Server Restart" 269 tristate "IBM Automatic Server Restart"
273 depends on WATCHDOG && X86 270 depends on X86
274 help 271 help
275 This is the driver for the IBM Automatic Server Restart watchdog 272 This is the driver for the IBM Automatic Server Restart watchdog
276 timer built-in into some eServer xSeries machines. 273 timer built-in into some eServer xSeries machines.
@@ -280,7 +277,7 @@ config IBMASR
280 277
281config WAFER_WDT 278config WAFER_WDT
282 tristate "ICP Wafer 5823 Single Board Computer Watchdog" 279 tristate "ICP Wafer 5823 Single Board Computer Watchdog"
283 depends on WATCHDOG && X86 280 depends on X86
284 help 281 help
285 This is a driver for the hardware watchdog on the ICP Wafer 5823 282 This is a driver for the hardware watchdog on the ICP Wafer 5823
286 Single Board Computer (and probably other similar models). 283 Single Board Computer (and probably other similar models).
@@ -290,7 +287,7 @@ config WAFER_WDT
290 287
291config I6300ESB_WDT 288config I6300ESB_WDT
292 tristate "Intel 6300ESB Timer/Watchdog" 289 tristate "Intel 6300ESB Timer/Watchdog"
293 depends on WATCHDOG && X86 && PCI 290 depends on X86 && PCI
294 ---help--- 291 ---help---
295 Hardware driver for the watchdog timer built into the Intel 292 Hardware driver for the watchdog timer built into the Intel
296 6300ESB controller hub. 293 6300ESB controller hub.
@@ -298,31 +295,9 @@ config I6300ESB_WDT
298 To compile this driver as a module, choose M here: the 295 To compile this driver as a module, choose M here: the
299 module will be called i6300esb. 296 module will be called i6300esb.
300 297
301config I8XX_TCO
302 tristate "Intel i8xx TCO Timer/Watchdog"
303 depends on WATCHDOG && (X86 || IA64) && PCI
304 default n
305 ---help---
306 Hardware driver for the TCO timer built into the Intel 82801
307 I/O Controller Hub family. The TCO (Total Cost of Ownership)
308 timer is a watchdog timer that will reboot the machine after
309 its second expiration. The expiration time can be configured
310 with the "heartbeat" parameter.
311
312 On some motherboards the driver may fail to reset the chipset's
313 NO_REBOOT flag which prevents the watchdog from rebooting the
314 machine. If this is the case you will get a kernel message like
315 "failed to reset NO_REBOOT flag, reboot disabled by hardware".
316
317 To compile this driver as a module, choose M here: the
318 module will be called i8xx_tco.
319
320 Note: This driver will be removed in the near future. Please
321 use the Intel TCO Timer/Watchdog driver.
322
323config ITCO_WDT 298config ITCO_WDT
324 tristate "Intel TCO Timer/Watchdog" 299 tristate "Intel TCO Timer/Watchdog"
325 depends on WATCHDOG && (X86 || IA64) && PCI 300 depends on (X86 || IA64) && PCI
326 ---help--- 301 ---help---
327 Hardware driver for the intel TCO timer based watchdog devices. 302 Hardware driver for the intel TCO timer based watchdog devices.
328 These drivers are included in the Intel 82801 I/O Controller 303 These drivers are included in the Intel 82801 I/O Controller
@@ -351,7 +326,7 @@ config ITCO_VENDOR_SUPPORT
351 326
352config SC1200_WDT 327config SC1200_WDT
353 tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog" 328 tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
354 depends on WATCHDOG && X86 329 depends on X86
355 help 330 help
356 This is a driver for National Semiconductor PC87307/PC97307 hardware 331 This is a driver for National Semiconductor PC87307/PC97307 hardware
357 watchdog cards as found on the SC1200. This watchdog is mainly used 332 watchdog cards as found on the SC1200. This watchdog is mainly used
@@ -365,7 +340,7 @@ config SC1200_WDT
365 340
366config SCx200_WDT 341config SCx200_WDT
367 tristate "National Semiconductor SCx200 Watchdog" 342 tristate "National Semiconductor SCx200 Watchdog"
368 depends on WATCHDOG && SCx200 && PCI 343 depends on SCx200 && PCI
369 help 344 help
370 Enable the built-in watchdog timer support on the National 345 Enable the built-in watchdog timer support on the National
371 Semiconductor SCx200 processors. 346 Semiconductor SCx200 processors.
@@ -374,7 +349,7 @@ config SCx200_WDT
374 349
375config PC87413_WDT 350config PC87413_WDT
376 tristate "NS PC87413 watchdog" 351 tristate "NS PC87413 watchdog"
377 depends on WATCHDOG && X86 352 depends on X86
378 ---help--- 353 ---help---
379 This is the driver for the hardware watchdog on the PC87413 chipset 354 This is the driver for the hardware watchdog on the PC87413 chipset
380 This watchdog simply watches your kernel to make sure it doesn't 355 This watchdog simply watches your kernel to make sure it doesn't
@@ -388,7 +363,7 @@ config PC87413_WDT
388 363
389config 60XX_WDT 364config 60XX_WDT
390 tristate "SBC-60XX Watchdog Timer" 365 tristate "SBC-60XX Watchdog Timer"
391 depends on WATCHDOG && X86 366 depends on X86
392 help 367 help
393 This driver can be used with the watchdog timer found on some 368 This driver can be used with the watchdog timer found on some
394 single board computers, namely the 6010 PII based computer. 369 single board computers, namely the 6010 PII based computer.
@@ -402,7 +377,7 @@ config 60XX_WDT
402 377
403config SBC8360_WDT 378config SBC8360_WDT
404 tristate "SBC8360 Watchdog Timer" 379 tristate "SBC8360 Watchdog Timer"
405 depends on WATCHDOG && X86 380 depends on X86
406 ---help--- 381 ---help---
407 382
408 This is the driver for the hardware watchdog on the SBC8360 Single 383 This is the driver for the hardware watchdog on the SBC8360 Single
@@ -415,7 +390,7 @@ config SBC8360_WDT
415 390
416config CPU5_WDT 391config CPU5_WDT
417 tristate "SMA CPU5 Watchdog" 392 tristate "SMA CPU5 Watchdog"
418 depends on WATCHDOG && X86 393 depends on X86
419 ---help--- 394 ---help---
420 TBD. 395 TBD.
421 To compile this driver as a module, choose M here: the 396 To compile this driver as a module, choose M here: the
@@ -423,7 +398,7 @@ config CPU5_WDT
423 398
424config SMSC37B787_WDT 399config SMSC37B787_WDT
425 tristate "Winbond SMsC37B787 Watchdog Timer" 400 tristate "Winbond SMsC37B787 Watchdog Timer"
426 depends on WATCHDOG && X86 401 depends on X86
427 ---help--- 402 ---help---
428 This is the driver for the hardware watchdog component on the 403 This is the driver for the hardware watchdog component on the
429 Winbond SMsC37B787 chipset as used on the NetRunner Mainboard 404 Winbond SMsC37B787 chipset as used on the NetRunner Mainboard
@@ -443,7 +418,7 @@ config SMSC37B787_WDT
443 418
444config W83627HF_WDT 419config W83627HF_WDT
445 tristate "W83627HF Watchdog Timer" 420 tristate "W83627HF Watchdog Timer"
446 depends on WATCHDOG && X86 421 depends on X86
447 ---help--- 422 ---help---
448 This is the driver for the hardware watchdog on the W83627HF chipset 423 This is the driver for the hardware watchdog on the W83627HF chipset
449 as used in Advantech PC-9578 and Tyan S2721-533 motherboards 424 as used in Advantech PC-9578 and Tyan S2721-533 motherboards
@@ -458,7 +433,7 @@ config W83627HF_WDT
458 433
459config W83697HF_WDT 434config W83697HF_WDT
460 tristate "W83697HF/W83697HG Watchdog Timer" 435 tristate "W83697HF/W83697HG Watchdog Timer"
461 depends on WATCHDOG && X86 436 depends on X86
462 ---help--- 437 ---help---
463 This is the driver for the hardware watchdog on the W83697HF/HG 438 This is the driver for the hardware watchdog on the W83697HF/HG
464 chipset as used in Dedibox/VIA motherboards (and likely others). 439 chipset as used in Dedibox/VIA motherboards (and likely others).
@@ -473,7 +448,7 @@ config W83697HF_WDT
473 448
474config W83877F_WDT 449config W83877F_WDT
475 tristate "W83877F (EMACS) Watchdog Timer" 450 tristate "W83877F (EMACS) Watchdog Timer"
476 depends on WATCHDOG && X86 451 depends on X86
477 ---help--- 452 ---help---
478 This is the driver for the hardware watchdog on the W83877F chipset 453 This is the driver for the hardware watchdog on the W83877F chipset
479 as used in EMACS PC-104 motherboards (and likely others). This 454 as used in EMACS PC-104 motherboards (and likely others). This
@@ -488,7 +463,7 @@ config W83877F_WDT
488 463
489config W83977F_WDT 464config W83977F_WDT
490 tristate "W83977F (PCM-5335) Watchdog Timer" 465 tristate "W83977F (PCM-5335) Watchdog Timer"
491 depends on WATCHDOG && X86 466 depends on X86
492 ---help--- 467 ---help---
493 This is the driver for the hardware watchdog on the W83977F I/O chip 468 This is the driver for the hardware watchdog on the W83977F I/O chip
494 as used in AAEON's PCM-5335 SBC (and likely others). This 469 as used in AAEON's PCM-5335 SBC (and likely others). This
@@ -501,7 +476,7 @@ config W83977F_WDT
501 476
502config MACHZ_WDT 477config MACHZ_WDT
503 tristate "ZF MachZ Watchdog" 478 tristate "ZF MachZ Watchdog"
504 depends on WATCHDOG && X86 479 depends on X86
505 ---help--- 480 ---help---
506 If you are using a ZF Micro MachZ processor, say Y here, otherwise 481 If you are using a ZF Micro MachZ processor, say Y here, otherwise
507 N. This is the driver for the watchdog timer built-in on that 482 N. This is the driver for the watchdog timer built-in on that
@@ -514,7 +489,7 @@ config MACHZ_WDT
514 489
515config SBC_EPX_C3_WATCHDOG 490config SBC_EPX_C3_WATCHDOG
516 tristate "Winsystems SBC EPX-C3 watchdog" 491 tristate "Winsystems SBC EPX-C3 watchdog"
517 depends on WATCHDOG && X86 492 depends on X86
518 ---help--- 493 ---help---
519 This is the driver for the built-in watchdog timer on the EPX-C3 494 This is the driver for the built-in watchdog timer on the EPX-C3
520 Single-board computer made by Winsystems, Inc. 495 Single-board computer made by Winsystems, Inc.
@@ -537,19 +512,19 @@ config SBC_EPX_C3_WATCHDOG
537 512
538config 8xx_WDT 513config 8xx_WDT
539 tristate "MPC8xx Watchdog Timer" 514 tristate "MPC8xx Watchdog Timer"
540 depends on WATCHDOG && 8xx 515 depends on 8xx
541 516
542config 83xx_WDT 517config 83xx_WDT
543 tristate "MPC83xx Watchdog Timer" 518 tristate "MPC83xx Watchdog Timer"
544 depends on WATCHDOG && PPC_83xx 519 depends on PPC_83xx
545 520
546config MV64X60_WDT 521config MV64X60_WDT
547 tristate "MV64X60 (Marvell Discovery) Watchdog Timer" 522 tristate "MV64X60 (Marvell Discovery) Watchdog Timer"
548 depends on WATCHDOG && MV64X60 523 depends on MV64X60
549 524
550config BOOKE_WDT 525config BOOKE_WDT
551 bool "PowerPC Book-E Watchdog Timer" 526 bool "PowerPC Book-E Watchdog Timer"
552 depends on WATCHDOG && (BOOKE || 4xx) 527 depends on BOOKE || 4xx
553 ---help--- 528 ---help---
554 Please see Documentation/watchdog/watchdog-api.txt for 529 Please see Documentation/watchdog/watchdog-api.txt for
555 more information. 530 more information.
@@ -558,7 +533,7 @@ config BOOKE_WDT
558 533
559config WATCHDOG_RTAS 534config WATCHDOG_RTAS
560 tristate "RTAS watchdog" 535 tristate "RTAS watchdog"
561 depends on WATCHDOG && PPC_RTAS 536 depends on PPC_RTAS
562 help 537 help
563 This driver adds watchdog support for the RTAS watchdog. 538 This driver adds watchdog support for the RTAS watchdog.
564 539
@@ -569,16 +544,23 @@ config WATCHDOG_RTAS
569 544
570config INDYDOG 545config INDYDOG
571 tristate "Indy/I2 Hardware Watchdog" 546 tristate "Indy/I2 Hardware Watchdog"
572 depends on WATCHDOG && SGI_IP22 547 depends on SGI_IP22
573 help 548 help
574 Hardware driver for the Indy's/I2's watchdog. This is a 549 Hardware driver for the Indy's/I2's watchdog. This is a
575 watchdog timer that will reboot the machine after a 60 second 550 watchdog timer that will reboot the machine after a 60 second
576 timer expired and no process has written to /dev/watchdog during 551 timer expired and no process has written to /dev/watchdog during
577 that time. 552 that time.
578 553
554config WDT_MTX1
555 tristate "MTX-1 Hardware Watchdog"
556 depends on MIPS_MTX1
557 help
558 Hardware driver for the MTX-1 boards. This is a watchdog timer that
559 will reboot the machine after a 100 seconds timer expired.
560
579config WDT_RM9K_GPI 561config WDT_RM9K_GPI
580 tristate "RM9000/GPI hardware watchdog" 562 tristate "RM9000/GPI hardware watchdog"
581 depends on WATCHDOG && CPU_RM9000 563 depends on CPU_RM9000
582 help 564 help
583 Watchdog implementation using the GPI hardware found on 565 Watchdog implementation using the GPI hardware found on
584 PMC-Sierra RM9xxx CPUs. 566 PMC-Sierra RM9xxx CPUs.
@@ -590,7 +572,7 @@ config WDT_RM9K_GPI
590 572
591config ZVM_WATCHDOG 573config ZVM_WATCHDOG
592 tristate "z/VM Watchdog Timer" 574 tristate "z/VM Watchdog Timer"
593 depends on WATCHDOG && S390 575 depends on S390
594 help 576 help
595 IBM s/390 and zSeries machines running under z/VM 5.1 or later 577 IBM s/390 and zSeries machines running under z/VM 5.1 or later
596 provide a virtual watchdog timer to their guest that cause a 578 provide a virtual watchdog timer to their guest that cause a
@@ -604,7 +586,7 @@ config ZVM_WATCHDOG
604 586
605config SH_WDT 587config SH_WDT
606 tristate "SuperH Watchdog" 588 tristate "SuperH Watchdog"
607 depends on WATCHDOG && SUPERH 589 depends on SUPERH
608 help 590 help
609 This driver adds watchdog support for the integrated watchdog in the 591 This driver adds watchdog support for the integrated watchdog in the
610 SuperH processors. If you have one of these processors and wish 592 SuperH processors. If you have one of these processors and wish
@@ -631,7 +613,7 @@ config SH_WDT_MMAP
631 613
632config WATCHDOG_CP1XXX 614config WATCHDOG_CP1XXX
633 tristate "CP1XXX Hardware Watchdog support" 615 tristate "CP1XXX Hardware Watchdog support"
634 depends on WATCHDOG && SPARC64 && PCI 616 depends on SPARC64 && PCI
635 ---help--- 617 ---help---
636 This is the driver for the hardware watchdog timers present on 618 This is the driver for the hardware watchdog timers present on
637 Sun Microsystems CompactPCI models CP1400 and CP1500. 619 Sun Microsystems CompactPCI models CP1400 and CP1500.
@@ -645,7 +627,7 @@ config WATCHDOG_CP1XXX
645 627
646config WATCHDOG_RIO 628config WATCHDOG_RIO
647 tristate "RIO Hardware Watchdog support" 629 tristate "RIO Hardware Watchdog support"
648 depends on WATCHDOG && SPARC64 && PCI 630 depends on SPARC64 && PCI
649 help 631 help
650 Say Y here to support the hardware watchdog capability on Sun RIO 632 Say Y here to support the hardware watchdog capability on Sun RIO
651 machines. The watchdog timeout period is normally one minute but 633 machines. The watchdog timeout period is normally one minute but
@@ -656,11 +638,11 @@ config WATCHDOG_RIO
656# 638#
657 639
658comment "ISA-based Watchdog Cards" 640comment "ISA-based Watchdog Cards"
659 depends on WATCHDOG && ISA 641 depends on ISA
660 642
661config PCWATCHDOG 643config PCWATCHDOG
662 tristate "Berkshire Products ISA-PC Watchdog" 644 tristate "Berkshire Products ISA-PC Watchdog"
663 depends on WATCHDOG && ISA 645 depends on ISA
664 ---help--- 646 ---help---
665 This is the driver for the Berkshire Products ISA-PC Watchdog card. 647 This is the driver for the Berkshire Products ISA-PC Watchdog card.
666 This card simply watches your kernel to make sure it doesn't freeze, 648 This card simply watches your kernel to make sure it doesn't freeze,
@@ -676,7 +658,7 @@ config PCWATCHDOG
676 658
677config MIXCOMWD 659config MIXCOMWD
678 tristate "Mixcom Watchdog" 660 tristate "Mixcom Watchdog"
679 depends on WATCHDOG && ISA 661 depends on ISA
680 ---help--- 662 ---help---
681 This is a driver for the Mixcom hardware watchdog cards. This 663 This is a driver for the Mixcom hardware watchdog cards. This
682 watchdog simply watches your kernel to make sure it doesn't freeze, 664 watchdog simply watches your kernel to make sure it doesn't freeze,
@@ -690,7 +672,7 @@ config MIXCOMWD
690 672
691config WDT 673config WDT
692 tristate "WDT Watchdog timer" 674 tristate "WDT Watchdog timer"
693 depends on WATCHDOG && ISA 675 depends on ISA
694 ---help--- 676 ---help---
695 If you have a WDT500P or WDT501P watchdog board, say Y here, 677 If you have a WDT500P or WDT501P watchdog board, say Y here,
696 otherwise N. It is not possible to probe for this board, which means 678 otherwise N. It is not possible to probe for this board, which means
@@ -720,11 +702,11 @@ config WDT_501
720# 702#
721 703
722comment "PCI-based Watchdog Cards" 704comment "PCI-based Watchdog Cards"
723 depends on WATCHDOG && PCI 705 depends on PCI
724 706
725config PCIPCWATCHDOG 707config PCIPCWATCHDOG
726 tristate "Berkshire Products PCI-PC Watchdog" 708 tristate "Berkshire Products PCI-PC Watchdog"
727 depends on WATCHDOG && PCI 709 depends on PCI
728 ---help--- 710 ---help---
729 This is the driver for the Berkshire Products PCI-PC Watchdog card. 711 This is the driver for the Berkshire Products PCI-PC Watchdog card.
730 This card simply watches your kernel to make sure it doesn't freeze, 712 This card simply watches your kernel to make sure it doesn't freeze,
@@ -739,7 +721,7 @@ config PCIPCWATCHDOG
739 721
740config WDTPCI 722config WDTPCI
741 tristate "PCI-WDT500/501 Watchdog timer" 723 tristate "PCI-WDT500/501 Watchdog timer"
742 depends on WATCHDOG && PCI 724 depends on PCI
743 ---help--- 725 ---help---
744 If you have a PCI-WDT500/501 watchdog board, say Y here, otherwise N. 726 If you have a PCI-WDT500/501 watchdog board, say Y here, otherwise N.
745 727
@@ -766,11 +748,11 @@ config WDT_501_PCI
766# 748#
767 749
768comment "USB-based Watchdog Cards" 750comment "USB-based Watchdog Cards"
769 depends on WATCHDOG && USB 751 depends on USB
770 752
771config USBPCWATCHDOG 753config USBPCWATCHDOG
772 tristate "Berkshire Products USB-PC Watchdog" 754 tristate "Berkshire Products USB-PC Watchdog"
773 depends on WATCHDOG && USB 755 depends on USB
774 ---help--- 756 ---help---
775 This is the driver for the Berkshire Products USB-PC Watchdog card. 757 This is the driver for the Berkshire Products USB-PC Watchdog card.
776 This card simply watches your kernel to make sure it doesn't freeze, 758 This card simply watches your kernel to make sure it doesn't freeze,
@@ -783,4 +765,4 @@ config USBPCWATCHDOG
783 765
784 Most people will say N. 766 Most people will say N.
785 767
786endmenu 768endif # WATCHDOG
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 2cd8ff8d10ac..8bfc00cc7c2b 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -46,7 +46,6 @@ obj-$(CONFIG_IB700_WDT) += ib700wdt.o
46obj-$(CONFIG_IBMASR) += ibmasr.o 46obj-$(CONFIG_IBMASR) += ibmasr.o
47obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o 47obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
48obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o 48obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
49obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o
50obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o 49obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o
51obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o 50obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
52obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o 51obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
@@ -73,6 +72,7 @@ obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
73 72
74# MIPS Architecture 73# MIPS Architecture
75obj-$(CONFIG_INDYDOG) += indydog.o 74obj-$(CONFIG_INDYDOG) += indydog.o
75obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
76obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o 76obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
77 77
78# S390 Architecture 78# S390 Architecture
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
index bcd7e36ca0aa..d0d45a8b09f0 100644
--- a/drivers/char/watchdog/cpu5wdt.c
+++ b/drivers/char/watchdog/cpu5wdt.c
@@ -220,17 +220,17 @@ static int __devinit cpu5wdt_init(void)
220 if ( verbose ) 220 if ( verbose )
221 printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); 221 printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose);
222 222
223 if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) {
224 printk(KERN_ERR PFX "misc_register failed\n");
225 goto no_misc;
226 }
227
228 if ( !request_region(port, CPU5WDT_EXTENT, PFX) ) { 223 if ( !request_region(port, CPU5WDT_EXTENT, PFX) ) {
229 printk(KERN_ERR PFX "request_region failed\n"); 224 printk(KERN_ERR PFX "request_region failed\n");
230 err = -EBUSY; 225 err = -EBUSY;
231 goto no_port; 226 goto no_port;
232 } 227 }
233 228
229 if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) {
230 printk(KERN_ERR PFX "misc_register failed\n");
231 goto no_misc;
232 }
233
234 /* watchdog reboot? */ 234 /* watchdog reboot? */
235 val = inb(port + CPU5WDT_STATUS_REG); 235 val = inb(port + CPU5WDT_STATUS_REG);
236 val = (val >> 2) & 1; 236 val = (val >> 2) & 1;
@@ -250,9 +250,9 @@ static int __devinit cpu5wdt_init(void)
250 250
251 return 0; 251 return 0;
252 252
253no_port:
254 misc_deregister(&cpu5wdt_misc);
255no_misc: 253no_misc:
254 release_region(port, CPU5WDT_EXTENT);
255no_port:
256 return err; 256 return err;
257} 257}
258 258
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c
index f70387f01b2b..b070324e27a6 100644
--- a/drivers/char/watchdog/eurotechwdt.c
+++ b/drivers/char/watchdog/eurotechwdt.c
@@ -413,17 +413,10 @@ static int __init eurwdt_init(void)
413{ 413{
414 int ret; 414 int ret;
415 415
416 ret = misc_register(&eurwdt_miscdev);
417 if (ret) {
418 printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
419 WATCHDOG_MINOR);
420 goto out;
421 }
422
423 ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL); 416 ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL);
424 if(ret) { 417 if(ret) {
425 printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq); 418 printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq);
426 goto outmisc; 419 goto out;
427 } 420 }
428 421
429 if (!request_region(io, 2, "eurwdt")) { 422 if (!request_region(io, 2, "eurwdt")) {
@@ -438,6 +431,13 @@ static int __init eurwdt_init(void)
438 goto outreg; 431 goto outreg;
439 } 432 }
440 433
434 ret = misc_register(&eurwdt_miscdev);
435 if (ret) {
436 printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
437 WATCHDOG_MINOR);
438 goto outreboot;
439 }
440
441 eurwdt_unlock_chip(); 441 eurwdt_unlock_chip();
442 442
443 ret = 0; 443 ret = 0;
@@ -448,14 +448,14 @@ static int __init eurwdt_init(void)
448out: 448out:
449 return ret; 449 return ret;
450 450
451outreboot:
452 unregister_reboot_notifier(&eurwdt_notifier);
453
451outreg: 454outreg:
452 release_region(io, 2); 455 release_region(io, 2);
453 456
454outirq: 457outirq:
455 free_irq(irq, NULL); 458 free_irq(irq, NULL);
456
457outmisc:
458 misc_deregister(&eurwdt_miscdev);
459 goto out; 459 goto out;
460} 460}
461 461
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
deleted file mode 100644
index a62ef48a15ae..000000000000
--- a/drivers/char/watchdog/i8xx_tco.c
+++ /dev/null
@@ -1,571 +0,0 @@
1/*
2 * i8xx_tco: TCO timer driver for i8xx chipsets
3 *
4 * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
5 * http://www.kernelconcepts.de
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 * Neither kernel concepts nor Nils Faerber admit liability nor provide
13 * warranty for any of this software. This material is provided
14 * "AS-IS" and at no charge.
15 *
16 * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>
17 * developed for
18 * Jentro AG, Haar/Munich (Germany)
19 *
20 * TCO timer driver for i8xx chipsets
21 * based on softdog.c by Alan Cox <alan@redhat.com>
22 *
23 * The TCO timer is implemented in the following I/O controller hubs:
24 * (See the intel documentation on http://developer.intel.com.)
25 * 82801AA (ICH) : document number 290655-003, 290677-014,
26 * 82801AB (ICHO) : document number 290655-003, 290677-014,
27 * 82801BA (ICH2) : document number 290687-002, 298242-027,
28 * 82801BAM (ICH2-M) : document number 290687-002, 298242-027,
29 * 82801CA (ICH3-S) : document number 290733-003, 290739-013,
30 * 82801CAM (ICH3-M) : document number 290716-001, 290718-007,
31 * 82801DB (ICH4) : document number 290744-001, 290745-020,
32 * 82801DBM (ICH4-M) : document number 252337-001, 252663-005,
33 * 82801E (C-ICH) : document number 273599-001, 273645-002,
34 * 82801EB (ICH5) : document number 252516-001, 252517-003,
35 * 82801ER (ICH5R) : document number 252516-001, 252517-003,
36 *
37 * 20000710 Nils Faerber
38 * Initial Version 0.01
39 * 20000728 Nils Faerber
40 * 0.02 Fix for SMI_EN->TCO_EN bit, some cleanups
41 * 20011214 Matt Domsch <Matt_Domsch@dell.com>
42 * 0.03 Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
43 * Didn't add timeout option as i810_margin already exists.
44 * 20020224 Joel Becker, Wim Van Sebroeck
45 * 0.04 Support for 82801CA(M) chipset, timer margin needs to be > 3,
46 * add support for WDIOC_SETTIMEOUT and WDIOC_GETTIMEOUT.
47 * 20020412 Rob Radez <rob@osinvestor.com>, Wim Van Sebroeck
48 * 0.05 Fix possible timer_alive race, add expect close support,
49 * clean up ioctls (WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS and
50 * WDIOC_SETOPTIONS), made i810tco_getdevice __init,
51 * removed boot_status, removed tco_timer_read,
52 * added support for 82801DB and 82801E chipset,
53 * added support for 82801EB and 8280ER chipset,
54 * general cleanup.
55 * 20030921 Wim Van Sebroeck <wim@iguana.be>
56 * 0.06 change i810_margin to heartbeat, use module_param,
57 * added notify system support, renamed module to i8xx_tco.
58 * 20050128 Wim Van Sebroeck <wim@iguana.be>
59 * 0.07 Added support for the ICH4-M, ICH6, ICH6R, ICH6-M, ICH6W and ICH6RW
60 * chipsets. Also added support for the "undocumented" ICH7 chipset.
61 * 20050807 Wim Van Sebroeck <wim@iguana.be>
62 * 0.08 Make sure that the watchdog is only "armed" when started.
63 * (Kernel Bug 4251)
64 * 20060416 Wim Van Sebroeck <wim@iguana.be>
65 * 0.09 Remove support for the ICH6, ICH6R, ICH6-M, ICH6W and ICH6RW and
66 * ICH7 chipsets. (See Kernel Bug 6031 - other code will support these
67 * chipsets)
68 */
69
70/*
71 * Includes, defines, variables, module parameters, ...
72 */
73
74#include <linux/module.h>
75#include <linux/moduleparam.h>
76#include <linux/types.h>
77#include <linux/miscdevice.h>
78#include <linux/watchdog.h>
79#include <linux/notifier.h>
80#include <linux/reboot.h>
81#include <linux/init.h>
82#include <linux/fs.h>
83#include <linux/pci.h>
84#include <linux/ioport.h>
85
86#include <asm/uaccess.h>
87#include <asm/io.h>
88
89#include "i8xx_tco.h"
90
91/* Module and version information */
92#define TCO_VERSION "0.09"
93#define TCO_MODULE_NAME "i8xx TCO timer"
94#define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION
95#define PFX TCO_MODULE_NAME ": "
96
97/* internal variables */
98static unsigned int ACPIBASE;
99static spinlock_t tco_lock; /* Guards the hardware */
100static unsigned long timer_alive;
101static char tco_expect_close;
102static struct pci_dev *i8xx_tco_pci;
103
104/* module parameters */
105#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat (2<heartbeat<39) */
106static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
107module_param(heartbeat, int, 0);
108MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
109
110static int nowayout = WATCHDOG_NOWAYOUT;
111module_param(nowayout, int, 0);
112MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
113
114/*
115 * Some TCO specific functions
116 */
117
118static inline unsigned char seconds_to_ticks(int seconds)
119{
120 /* the internal timer is stored as ticks which decrement
121 * every 0.6 seconds */
122 return (seconds * 10) / 6;
123}
124
125static int tco_timer_start (void)
126{
127 unsigned char val;
128
129 spin_lock(&tco_lock);
130
131 /* disable chipset's NO_REBOOT bit */
132 pci_read_config_byte (i8xx_tco_pci, 0xd4, &val);
133 val &= 0xfd;
134 pci_write_config_byte (i8xx_tco_pci, 0xd4, val);
135
136 /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */
137 val = inb (TCO1_CNT + 1);
138 val &= 0xf7;
139 outb (val, TCO1_CNT + 1);
140 val = inb (TCO1_CNT + 1);
141
142 spin_unlock(&tco_lock);
143
144 if (val & 0x08)
145 return -1;
146 return 0;
147}
148
149static int tco_timer_stop (void)
150{
151 unsigned char val, val1;
152
153 spin_lock(&tco_lock);
154 /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */
155 val = inb (TCO1_CNT + 1);
156 val |= 0x08;
157 outb (val, TCO1_CNT + 1);
158 val = inb (TCO1_CNT + 1);
159
160 /* Set the NO_REBOOT bit to prevent later reboots, just for sure */
161 pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1);
162 val1 |= 0x02;
163 pci_write_config_byte (i8xx_tco_pci, 0xd4, val1);
164
165 spin_unlock(&tco_lock);
166
167 if ((val & 0x08) == 0)
168 return -1;
169 return 0;
170}
171
172static int tco_timer_keepalive (void)
173{
174 spin_lock(&tco_lock);
175 /* Reload the timer by writing to the TCO Timer Reload register */
176 outb (0x01, TCO1_RLD);
177 spin_unlock(&tco_lock);
178 return 0;
179}
180
181static int tco_timer_set_heartbeat (int t)
182{
183 unsigned char val;
184 unsigned char tmrval;
185
186 tmrval = seconds_to_ticks(t);
187 /* from the specs: */
188 /* "Values of 0h-3h are ignored and should not be attempted" */
189 if (tmrval > 0x3f || tmrval < 0x04)
190 return -EINVAL;
191
192 /* Write new heartbeat to watchdog */
193 spin_lock(&tco_lock);
194 val = inb (TCO1_TMR);
195 val &= 0xc0;
196 val |= tmrval;
197 outb (val, TCO1_TMR);
198 val = inb (TCO1_TMR);
199 spin_unlock(&tco_lock);
200
201 if ((val & 0x3f) != tmrval)
202 return -EINVAL;
203
204 heartbeat = t;
205 return 0;
206}
207
208static int tco_timer_get_timeleft (int *time_left)
209{
210 unsigned char val;
211
212 spin_lock(&tco_lock);
213
214 /* read the TCO Timer */
215 val = inb (TCO1_RLD);
216 val &= 0x3f;
217
218 spin_unlock(&tco_lock);
219
220 *time_left = (int)((val * 6) / 10);
221
222 return 0;
223}
224
225/*
226 * /dev/watchdog handling
227 */
228
229static int i8xx_tco_open (struct inode *inode, struct file *file)
230{
231 /* /dev/watchdog can only be opened once */
232 if (test_and_set_bit(0, &timer_alive))
233 return -EBUSY;
234
235 /*
236 * Reload and activate timer
237 */
238 tco_timer_keepalive ();
239 tco_timer_start ();
240 return nonseekable_open(inode, file);
241}
242
243static int i8xx_tco_release (struct inode *inode, struct file *file)
244{
245 /*
246 * Shut off the timer.
247 */
248 if (tco_expect_close == 42) {
249 tco_timer_stop ();
250 } else {
251 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
252 tco_timer_keepalive ();
253 }
254 clear_bit(0, &timer_alive);
255 tco_expect_close = 0;
256 return 0;
257}
258
259static ssize_t i8xx_tco_write (struct file *file, const char __user *data,
260 size_t len, loff_t * ppos)
261{
262 /* See if we got the magic character 'V' and reload the timer */
263 if (len) {
264 if (!nowayout) {
265 size_t i;
266
267 /* note: just in case someone wrote the magic character
268 * five months ago... */
269 tco_expect_close = 0;
270
271 /* scan to see whether or not we got the magic character */
272 for (i = 0; i != len; i++) {
273 char c;
274 if(get_user(c, data+i))
275 return -EFAULT;
276 if (c == 'V')
277 tco_expect_close = 42;
278 }
279 }
280
281 /* someone wrote to us, we should reload the timer */
282 tco_timer_keepalive ();
283 }
284 return len;
285}
286
287static int i8xx_tco_ioctl (struct inode *inode, struct file *file,
288 unsigned int cmd, unsigned long arg)
289{
290 int new_options, retval = -EINVAL;
291 int new_heartbeat;
292 int time_left;
293 void __user *argp = (void __user *)arg;
294 int __user *p = argp;
295 static struct watchdog_info ident = {
296 .options = WDIOF_SETTIMEOUT |
297 WDIOF_KEEPALIVEPING |
298 WDIOF_MAGICCLOSE,
299 .firmware_version = 0,
300 .identity = TCO_MODULE_NAME,
301 };
302
303 switch (cmd) {
304 case WDIOC_GETSUPPORT:
305 return copy_to_user(argp, &ident,
306 sizeof (ident)) ? -EFAULT : 0;
307
308 case WDIOC_GETSTATUS:
309 case WDIOC_GETBOOTSTATUS:
310 return put_user (0, p);
311
312 case WDIOC_KEEPALIVE:
313 tco_timer_keepalive ();
314 return 0;
315
316 case WDIOC_SETOPTIONS:
317 {
318 if (get_user (new_options, p))
319 return -EFAULT;
320
321 if (new_options & WDIOS_DISABLECARD) {
322 tco_timer_stop ();
323 retval = 0;
324 }
325
326 if (new_options & WDIOS_ENABLECARD) {
327 tco_timer_keepalive ();
328 tco_timer_start ();
329 retval = 0;
330 }
331
332 return retval;
333 }
334
335 case WDIOC_SETTIMEOUT:
336 {
337 if (get_user(new_heartbeat, p))
338 return -EFAULT;
339
340 if (tco_timer_set_heartbeat(new_heartbeat))
341 return -EINVAL;
342
343 tco_timer_keepalive ();
344 /* Fall */
345 }
346
347 case WDIOC_GETTIMEOUT:
348 return put_user(heartbeat, p);
349
350 case WDIOC_GETTIMELEFT:
351 {
352 if (tco_timer_get_timeleft(&time_left))
353 return -EINVAL;
354
355 return put_user(time_left, p);
356 }
357
358 default:
359 return -ENOTTY;
360 }
361}
362
363/*
364 * Notify system
365 */
366
367static int i8xx_tco_notify_sys (struct notifier_block *this, unsigned long code, void *unused)
368{
369 if (code==SYS_DOWN || code==SYS_HALT) {
370 /* Turn the WDT off */
371 tco_timer_stop ();
372 }
373
374 return NOTIFY_DONE;
375}
376
377/*
378 * Kernel Interfaces
379 */
380
381static const struct file_operations i8xx_tco_fops = {
382 .owner = THIS_MODULE,
383 .llseek = no_llseek,
384 .write = i8xx_tco_write,
385 .ioctl = i8xx_tco_ioctl,
386 .open = i8xx_tco_open,
387 .release = i8xx_tco_release,
388};
389
390static struct miscdevice i8xx_tco_miscdev = {
391 .minor = WATCHDOG_MINOR,
392 .name = "watchdog",
393 .fops = &i8xx_tco_fops,
394};
395
396static struct notifier_block i8xx_tco_notifier = {
397 .notifier_call = i8xx_tco_notify_sys,
398};
399
400/*
401 * Data for PCI driver interface
402 *
403 * This data only exists for exporting the supported
404 * PCI ids via MODULE_DEVICE_TABLE. We do not actually
405 * register a pci_driver, because someone else might one day
406 * want to register another driver on the same PCI id.
407 */
408static struct pci_device_id i8xx_tco_pci_tbl[] = {
409 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0) },
410 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0) },
411 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0) },
412 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10) },
413 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0) },
414 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12) },
415 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0) },
416 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12) },
417 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0) },
418 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0) },
419 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1) },
420 { }, /* End of list */
421};
422MODULE_DEVICE_TABLE (pci, i8xx_tco_pci_tbl);
423
424/*
425 * Init & exit routines
426 */
427
428static unsigned char __init i8xx_tco_getdevice (void)
429{
430 struct pci_dev *dev = NULL;
431 u8 val1, val2;
432 u16 badr;
433 /*
434 * Find the PCI device
435 */
436
437 for_each_pci_dev(dev)
438 if (pci_match_id(i8xx_tco_pci_tbl, dev)) {
439 i8xx_tco_pci = dev;
440 break;
441 }
442
443 if (i8xx_tco_pci) {
444 /*
445 * Find the ACPI base I/O address which is the base
446 * for the TCO registers (TCOBASE=ACPIBASE + 0x60)
447 * ACPIBASE is bits [15:7] from 0x40-0x43
448 */
449 pci_read_config_byte (i8xx_tco_pci, 0x40, &val1);
450 pci_read_config_byte (i8xx_tco_pci, 0x41, &val2);
451 badr = ((val2 << 1) | (val1 >> 7)) << 7;
452 ACPIBASE = badr;
453 /* Something's wrong here, ACPIBASE has to be set */
454 if (badr == 0x0001 || badr == 0x0000) {
455 printk (KERN_ERR PFX "failed to get TCOBASE address\n");
456 pci_dev_put(i8xx_tco_pci);
457 return 0;
458 }
459
460 /* Check chipset's NO_REBOOT bit */
461 pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1);
462 if (val1 & 0x02) {
463 val1 &= 0xfd;
464 pci_write_config_byte (i8xx_tco_pci, 0xd4, val1);
465 pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1);
466 if (val1 & 0x02) {
467 printk (KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
468 pci_dev_put(i8xx_tco_pci);
469 return 0; /* Cannot reset NO_REBOOT bit */
470 }
471 }
472 /* Disable reboots untill the watchdog starts */
473 val1 |= 0x02;
474 pci_write_config_byte (i8xx_tco_pci, 0xd4, val1);
475
476 /* Set the TCO_EN bit in SMI_EN register */
477 if (!request_region (SMI_EN + 1, 1, "i8xx TCO")) {
478 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
479 SMI_EN + 1);
480 pci_dev_put(i8xx_tco_pci);
481 return 0;
482 }
483 val1 = inb (SMI_EN + 1);
484 val1 &= 0xdf;
485 outb (val1, SMI_EN + 1);
486 release_region (SMI_EN + 1, 1);
487 return 1;
488 }
489 return 0;
490}
491
492static int __init watchdog_init (void)
493{
494 int ret;
495
496 spin_lock_init(&tco_lock);
497
498 /* Check whether or not the hardware watchdog is there */
499 if (!i8xx_tco_getdevice () || i8xx_tco_pci == NULL)
500 return -ENODEV;
501
502 if (!request_region (TCOBASE, 0x10, "i8xx TCO")) {
503 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
504 TCOBASE);
505 ret = -EIO;
506 goto out;
507 }
508
509 /* Clear out the (probably old) status */
510 outb (0, TCO1_STS);
511 outb (3, TCO2_STS);
512
513 /* Check that the heartbeat value is within it's range ; if not reset to the default */
514 if (tco_timer_set_heartbeat (heartbeat)) {
515 heartbeat = WATCHDOG_HEARTBEAT;
516 tco_timer_set_heartbeat (heartbeat);
517 printk(KERN_INFO PFX "heartbeat value must be 2<heartbeat<39, using %d\n",
518 heartbeat);
519 }
520
521 ret = register_reboot_notifier(&i8xx_tco_notifier);
522 if (ret != 0) {
523 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
524 ret);
525 goto unreg_region;
526 }
527
528 ret = misc_register(&i8xx_tco_miscdev);
529 if (ret != 0) {
530 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
531 WATCHDOG_MINOR, ret);
532 goto unreg_notifier;
533 }
534
535 tco_timer_stop ();
536
537 printk (KERN_INFO PFX "initialized (0x%04x). heartbeat=%d sec (nowayout=%d)\n",
538 TCOBASE, heartbeat, nowayout);
539
540 return 0;
541
542unreg_notifier:
543 unregister_reboot_notifier(&i8xx_tco_notifier);
544unreg_region:
545 release_region (TCOBASE, 0x10);
546out:
547 pci_dev_put(i8xx_tco_pci);
548 return ret;
549}
550
551static void __exit watchdog_cleanup (void)
552{
553 /* Stop the timer before we leave */
554 if (!nowayout)
555 tco_timer_stop ();
556
557 /* Deregister */
558 misc_deregister (&i8xx_tco_miscdev);
559 unregister_reboot_notifier(&i8xx_tco_notifier);
560 release_region (TCOBASE, 0x10);
561
562 pci_dev_put(i8xx_tco_pci);
563}
564
565module_init(watchdog_init);
566module_exit(watchdog_cleanup);
567
568MODULE_AUTHOR("Nils Faerber");
569MODULE_DESCRIPTION("TCO timer driver for i8xx chipsets");
570MODULE_LICENSE("GPL");
571MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/i8xx_tco.h b/drivers/char/watchdog/i8xx_tco.h
deleted file mode 100644
index cc14eb8ac3d6..000000000000
--- a/drivers/char/watchdog/i8xx_tco.h
+++ /dev/null
@@ -1,42 +0,0 @@
1/*
2 * i8xx_tco: TCO timer driver for i8xx chipsets
3 *
4 * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
5 * http://www.kernelconcepts.de
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 * Neither kernel concepts nor Nils Faerber admit liability nor provide
13 * warranty for any of this software. This material is provided
14 * "AS-IS" and at no charge.
15 *
16 * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>
17 * developed for
18 * Jentro AG, Haar/Munich (Germany)
19 *
20 * TCO timer driver for i8xx chipsets
21 * based on softdog.c by Alan Cox <alan@redhat.com>
22 *
23 * For history and the complete list of supported I/O Controller Hub's
24 * see i8xx_tco.c
25 */
26
27
28/*
29 * Some address definitions for the TCO
30 */
31
32#define TCOBASE ACPIBASE + 0x60 /* TCO base address */
33#define TCO1_RLD TCOBASE + 0x00 /* TCO Timer Reload and Current Value */
34#define TCO1_TMR TCOBASE + 0x01 /* TCO Timer Initial Value */
35#define TCO1_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */
36#define TCO1_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */
37#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
38#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */
39#define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */
40#define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */
41
42#define SMI_EN ACPIBASE + 0x30 /* SMI Control and Enable Register */
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/char/watchdog/ibmasr.c
index 8195f5023d85..94155f6136c2 100644
--- a/drivers/char/watchdog/ibmasr.c
+++ b/drivers/char/watchdog/ibmasr.c
@@ -367,18 +367,17 @@ static int __init ibmasr_init(void)
367 if (!asr_type) 367 if (!asr_type)
368 return -ENODEV; 368 return -ENODEV;
369 369
370 rc = asr_get_base_address();
371 if (rc)
372 return rc;
373
370 rc = misc_register(&asr_miscdev); 374 rc = misc_register(&asr_miscdev);
371 if (rc < 0) { 375 if (rc < 0) {
376 release_region(asr_base, asr_length);
372 printk(KERN_ERR PFX "failed to register misc device\n"); 377 printk(KERN_ERR PFX "failed to register misc device\n");
373 return rc; 378 return rc;
374 } 379 }
375 380
376 rc = asr_get_base_address();
377 if (rc) {
378 misc_deregister(&asr_miscdev);
379 return rc;
380 }
381
382 return 0; 381 return 0;
383} 382}
384 383
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
index 76c7fa37fa6c..a0d27160c80e 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -440,13 +440,6 @@ static int __init zf_init(void)
440 spin_lock_init(&zf_lock); 440 spin_lock_init(&zf_lock);
441 spin_lock_init(&zf_port_lock); 441 spin_lock_init(&zf_port_lock);
442 442
443 ret = misc_register(&zf_miscdev);
444 if (ret){
445 printk(KERN_ERR "can't misc_register on minor=%d\n",
446 WATCHDOG_MINOR);
447 goto out;
448 }
449
450 if(!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")){ 443 if(!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")){
451 printk(KERN_ERR "cannot reserve I/O ports at %d\n", 444 printk(KERN_ERR "cannot reserve I/O ports at %d\n",
452 ZF_IOBASE); 445 ZF_IOBASE);
@@ -461,16 +454,23 @@ static int __init zf_init(void)
461 goto no_reboot; 454 goto no_reboot;
462 } 455 }
463 456
457 ret = misc_register(&zf_miscdev);
458 if (ret){
459 printk(KERN_ERR "can't misc_register on minor=%d\n",
460 WATCHDOG_MINOR);
461 goto no_misc;
462 }
463
464 zf_set_status(0); 464 zf_set_status(0);
465 zf_set_control(0); 465 zf_set_control(0);
466 466
467 return 0; 467 return 0;
468 468
469no_misc:
470 unregister_reboot_notifier(&zf_notifier);
469no_reboot: 471no_reboot:
470 release_region(ZF_IOBASE, 3); 472 release_region(ZF_IOBASE, 3);
471no_region: 473no_region:
472 misc_deregister(&zf_miscdev);
473out:
474 return ret; 474 return ret;
475} 475}
476 476
diff --git a/drivers/char/watchdog/mtx-1_wdt.c b/drivers/char/watchdog/mtx-1_wdt.c
new file mode 100644
index 000000000000..419ab445c944
--- /dev/null
+++ b/drivers/char/watchdog/mtx-1_wdt.c
@@ -0,0 +1,238 @@
1/*
2 * Driver for the MTX-1 Watchdog.
3 *
4 * (C) Copyright 2005 4G Systems <info@4g-systems.biz>, All Rights Reserved.
5 * http://www.4g-systems.biz
6 *
7 * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 *
14 * Neither Michael Stickel nor 4G Systems admit liability nor provide
15 * warranty for any of this software. This material is provided
16 * "AS-IS" and at no charge.
17 *
18 * (c) Copyright 2005 4G Systems <info@4g-systems.biz>
19 *
20 * Release 0.01.
21 * Author: Michael Stickel michael.stickel@4g-systems.biz
22 *
23 * Release 0.02.
24 * Author: Florian Fainelli florian@openwrt.org
25 * use the Linux watchdog/timer APIs
26 *
27 * The Watchdog is configured to reset the MTX-1
28 * if it is not triggered for 100 seconds.
29 * It should not be triggered more often than 1.6 seconds.
30 *
31 * A timer triggers the watchdog every 5 seconds, until
32 * it is opened for the first time. After the first open
33 * it MUST be triggered every 2..95 seconds.
34 */
35
36#include <linux/module.h>
37#include <linux/moduleparam.h>
38#include <linux/types.h>
39#include <linux/errno.h>
40#include <linux/miscdevice.h>
41#include <linux/fs.h>
42#include <linux/init.h>
43#include <linux/ioport.h>
44#include <linux/timer.h>
45#include <linux/completion.h>
46#include <linux/jiffies.h>
47#include <linux/watchdog.h>
48#include <asm/io.h>
49#include <asm/uaccess.h>
50
51#include <asm/mach-au1x00/au1000.h>
52
53#define MTX1_WDT_INTERVAL (5 * HZ)
54
55static int ticks = 100 * HZ;
56
57static struct {
58 struct completion stop;
59 volatile int running;
60 struct timer_list timer;
61 volatile int queue;
62 int default_ticks;
63 unsigned long inuse;
64} mtx1_wdt_device;
65
66static void mtx1_wdt_trigger(unsigned long unused)
67{
68 u32 tmp;
69
70 if (mtx1_wdt_device.running)
71 ticks--;
72 /*
73 * toggle GPIO2_15
74 */
75 tmp = au_readl(GPIO2_DIR);
76 tmp = (tmp & ~(1<<15)) | ((~tmp) & (1<<15));
77 au_writel (tmp, GPIO2_DIR);
78
79 if (mtx1_wdt_device.queue && ticks)
80 mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
81 else {
82 complete(&mtx1_wdt_device.stop);
83 }
84}
85
86static void mtx1_wdt_reset(void)
87{
88 ticks = mtx1_wdt_device.default_ticks;
89}
90
91
92static void mtx1_wdt_start(void)
93{
94 if (!mtx1_wdt_device.queue) {
95 mtx1_wdt_device.queue = 1;
96 au_writel (au_readl(GPIO2_DIR) | (u32)(1<<15), GPIO2_DIR);
97 mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
98 }
99 mtx1_wdt_device.running++;
100}
101
102static int mtx1_wdt_stop(void)
103{
104 if (mtx1_wdt_device.queue) {
105 mtx1_wdt_device.queue = 0;
106 au_writel (au_readl(GPIO2_DIR) & ~((u32)(1<<15)), GPIO2_DIR);
107 }
108
109 ticks = mtx1_wdt_device.default_ticks;
110
111 return 0;
112}
113
114/* Filesystem functions */
115
116static int mtx1_wdt_open(struct inode *inode, struct file *file)
117{
118 if (test_and_set_bit(0, &mtx1_wdt_device.inuse))
119 return -EBUSY;
120
121 return nonseekable_open(inode, file);
122}
123
124
125static int mtx1_wdt_release(struct inode *inode, struct file *file)
126{
127 clear_bit(0, &mtx1_wdt_device.inuse);
128 return 0;
129}
130
131static int mtx1_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
132{
133 void __user *argp = (void __user *)arg;
134 unsigned int value;
135 static struct watchdog_info ident =
136 {
137 .options = WDIOF_CARDRESET,
138 .identity = "MTX-1 WDT",
139 };
140
141 switch(cmd) {
142 case WDIOC_KEEPALIVE:
143 mtx1_wdt_reset();
144 break;
145 case WDIOC_GETSTATUS:
146 if ( copy_to_user(argp, &value, sizeof(int)) )
147 return -EFAULT;
148 break;
149 case WDIOC_GETSUPPORT:
150 if ( copy_to_user(argp, &ident, sizeof(ident)) )
151 return -EFAULT;
152 break;
153 case WDIOC_SETOPTIONS:
154 if ( copy_from_user(&value, argp, sizeof(int)) )
155 return -EFAULT;
156 switch(value) {
157 case WDIOS_ENABLECARD:
158 mtx1_wdt_start();
159 break;
160 case WDIOS_DISABLECARD:
161 return mtx1_wdt_stop();
162 default:
163 return -EINVAL;
164 }
165 break;
166 default:
167 return -ENOTTY;
168 }
169 return 0;
170}
171
172
173static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
174{
175 if (!count)
176 return -EIO;
177
178 mtx1_wdt_reset();
179 return count;
180}
181
182static struct file_operations mtx1_wdt_fops = {
183 .owner = THIS_MODULE,
184 .llseek = no_llseek,
185 .ioctl = mtx1_wdt_ioctl,
186 .open = mtx1_wdt_open,
187 .write = mtx1_wdt_write,
188 .release = mtx1_wdt_release
189};
190
191
192static struct miscdevice mtx1_wdt_misc = {
193 .minor = WATCHDOG_MINOR,
194 .name = "watchdog",
195 .fops = &mtx1_wdt_fops
196};
197
198
199static int __init mtx1_wdt_init(void)
200{
201 int ret;
202
203 if ((ret = misc_register(&mtx1_wdt_misc)) < 0) {
204 printk(KERN_ERR " mtx-1_wdt : failed to register\n");
205 return ret;
206 }
207
208 init_completion(&mtx1_wdt_device.stop);
209 mtx1_wdt_device.queue = 0;
210
211 clear_bit(0, &mtx1_wdt_device.inuse);
212
213 setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L);
214
215 mtx1_wdt_device.default_ticks = ticks;
216
217 mtx1_wdt_start();
218
219 printk(KERN_INFO "MTX-1 Watchdog driver\n");
220
221 return 0;
222}
223
224static void __exit mtx1_wdt_exit(void)
225{
226 if (mtx1_wdt_device.queue) {
227 mtx1_wdt_device.queue = 0;
228 wait_for_completion(&mtx1_wdt_device.stop);
229 }
230 misc_deregister(&mtx1_wdt_misc);
231}
232
233module_init(mtx1_wdt_init);
234module_exit(mtx1_wdt_exit);
235
236MODULE_AUTHOR("Michael Stickel, Florian Fainelli");
237MODULE_DESCRIPTION("Driver for the MTX-1 watchdog");
238MODULE_LICENSE("GPL");
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index 6e8b5705b5b7..7b41434fac8c 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -59,10 +59,10 @@
59#include <linux/jiffies.h> /* For jiffies stuff */ 59#include <linux/jiffies.h> /* For jiffies stuff */
60#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ 60#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
61#include <linux/watchdog.h> /* For the watchdog specific items */ 61#include <linux/watchdog.h> /* For the watchdog specific items */
62#include <linux/notifier.h> /* For notifier support */ 62#include <linux/reboot.h> /* For kernel_power_off() */
63#include <linux/reboot.h> /* For reboot_notifier stuff */
64#include <linux/init.h> /* For __init/__exit/... */ 63#include <linux/init.h> /* For __init/__exit/... */
65#include <linux/fs.h> /* For file operations */ 64#include <linux/fs.h> /* For file operations */
65#include <linux/isa.h> /* For isa devices */
66#include <linux/ioport.h> /* For io-port access */ 66#include <linux/ioport.h> /* For io-port access */
67#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 67#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
68 68
@@ -70,8 +70,8 @@
70#include <asm/io.h> /* For inb/outb/... */ 70#include <asm/io.h> /* For inb/outb/... */
71 71
72/* Module and version information */ 72/* Module and version information */
73#define WATCHDOG_VERSION "1.18" 73#define WATCHDOG_VERSION "1.20"
74#define WATCHDOG_DATE "21 Jan 2007" 74#define WATCHDOG_DATE "18 Feb 2007"
75#define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog" 75#define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog"
76#define WATCHDOG_NAME "pcwd" 76#define WATCHDOG_NAME "pcwd"
77#define PFX WATCHDOG_NAME ": " 77#define PFX WATCHDOG_NAME ": "
@@ -89,6 +89,15 @@
89#define PCWD_REVISION_C 2 89#define PCWD_REVISION_C 2
90 90
91/* 91/*
92 * These are the auto-probe addresses available.
93 *
94 * Revision A only uses ports 0x270 and 0x370. Revision C introduced 0x350.
95 * Revision A has an address range of 2 addresses, while Revision C has 4.
96 */
97#define PCWD_ISA_NR_CARDS 3
98static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 };
99
100/*
92 * These are the defines that describe the control status bits for the 101 * These are the defines that describe the control status bits for the
93 * PCI-PC Watchdog card. 102 * PCI-PC Watchdog card.
94*/ 103*/
@@ -485,7 +494,7 @@ static int pcwd_get_status(int *status)
485 if (control_status & WD_T110) { 494 if (control_status & WD_T110) {
486 *status |= WDIOF_OVERHEAT; 495 *status |= WDIOF_OVERHEAT;
487 if (temp_panic) { 496 if (temp_panic) {
488 printk (KERN_INFO PFX "Temperature overheat trip!\n"); 497 printk(KERN_INFO PFX "Temperature overheat trip!\n");
489 kernel_power_off(); 498 kernel_power_off();
490 /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */ 499 /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */
491 } 500 }
@@ -497,7 +506,7 @@ static int pcwd_get_status(int *status)
497 if (control_status & WD_REVC_TTRP) { 506 if (control_status & WD_REVC_TTRP) {
498 *status |= WDIOF_OVERHEAT; 507 *status |= WDIOF_OVERHEAT;
499 if (temp_panic) { 508 if (temp_panic) {
500 printk (KERN_INFO PFX "Temperature overheat trip!\n"); 509 printk(KERN_INFO PFX "Temperature overheat trip!\n");
501 kernel_power_off(); 510 kernel_power_off();
502 /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */ 511 /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */
503 } 512 }
@@ -734,20 +743,6 @@ static int pcwd_temp_close(struct inode *inode, struct file *file)
734} 743}
735 744
736/* 745/*
737 * Notify system
738 */
739
740static int pcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
741{
742 if (code==SYS_DOWN || code==SYS_HALT) {
743 /* Turn the WDT off */
744 pcwd_stop();
745 }
746
747 return NOTIFY_DONE;
748}
749
750/*
751 * Kernel Interfaces 746 * Kernel Interfaces
752 */ 747 */
753 748
@@ -780,10 +775,6 @@ static struct miscdevice temp_miscdev = {
780 .fops = &pcwd_temp_fops, 775 .fops = &pcwd_temp_fops,
781}; 776};
782 777
783static struct notifier_block pcwd_notifier = {
784 .notifier_call = pcwd_notify_sys,
785};
786
787/* 778/*
788 * Init & exit routines 779 * Init & exit routines
789 */ 780 */
@@ -803,10 +794,67 @@ static inline int get_revision(void)
803 return r; 794 return r;
804} 795}
805 796
806static int __devinit pcwatchdog_init(int base_addr) 797/*
798 * The ISA cards have a heartbeat bit in one of the registers, which
799 * register is card dependent. The heartbeat bit is monitored, and if
800 * found, is considered proof that a Berkshire card has been found.
801 * The initial rate is once per second at board start up, then twice
802 * per second for normal operation.
803 */
804static int __devinit pcwd_isa_match(struct device *dev, unsigned int id)
805{
806 int base_addr=pcwd_ioports[id];
807 int port0, last_port0; /* Reg 0, in case it's REV A */
808 int port1, last_port1; /* Register 1 for REV C cards */
809 int i;
810 int retval;
811
812 if (debug >= DEBUG)
813 printk(KERN_DEBUG PFX "pcwd_isa_match id=%d\n",
814 id);
815
816 if (!request_region (base_addr, 4, "PCWD")) {
817 printk(KERN_INFO PFX "Port 0x%04x unavailable\n", base_addr);
818 return 0;
819 }
820
821 retval = 0;
822
823 port0 = inb_p(base_addr); /* For REV A boards */
824 port1 = inb_p(base_addr + 1); /* For REV C boards */
825 if (port0 != 0xff || port1 != 0xff) {
826 /* Not an 'ff' from a floating bus, so must be a card! */
827 for (i = 0; i < 4; ++i) {
828
829 msleep(500);
830
831 last_port0 = port0;
832 last_port1 = port1;
833
834 port0 = inb_p(base_addr);
835 port1 = inb_p(base_addr + 1);
836
837 /* Has either hearbeat bit changed? */
838 if ((port0 ^ last_port0) & WD_HRTBT ||
839 (port1 ^ last_port1) & WD_REVC_HRBT) {
840 retval = 1;
841 break;
842 }
843 }
844 }
845 release_region (base_addr, 4);
846
847 return retval;
848}
849
850static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id)
807{ 851{
808 int ret; 852 int ret;
809 853
854 if (debug >= DEBUG)
855 printk(KERN_DEBUG PFX "pcwd_isa_probe id=%d\n",
856 id);
857
810 cards_found++; 858 cards_found++;
811 if (cards_found == 1) 859 if (cards_found == 1)
812 printk(KERN_INFO PFX "v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER); 860 printk(KERN_INFO PFX "v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER);
@@ -816,11 +864,13 @@ static int __devinit pcwatchdog_init(int base_addr)
816 return -ENODEV; 864 return -ENODEV;
817 } 865 }
818 866
819 if (base_addr == 0x0000) { 867 if (pcwd_ioports[id] == 0x0000) {
820 printk(KERN_ERR PFX "No I/O-Address for card detected\n"); 868 printk(KERN_ERR PFX "No I/O-Address for card detected\n");
821 return -ENODEV; 869 return -ENODEV;
822 } 870 }
823 pcwd_private.io_addr = base_addr; 871 pcwd_private.io_addr = pcwd_ioports[id];
872
873 spin_lock_init(&pcwd_private.io_lock);
824 874
825 /* Check card's revision */ 875 /* Check card's revision */
826 pcwd_private.revision = get_revision(); 876 pcwd_private.revision = get_revision();
@@ -828,8 +878,8 @@ static int __devinit pcwatchdog_init(int base_addr)
828 if (!request_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { 878 if (!request_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) {
829 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 879 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
830 pcwd_private.io_addr); 880 pcwd_private.io_addr);
831 pcwd_private.io_addr = 0x0000; 881 ret=-EIO;
832 return -EIO; 882 goto error_request_region;
833 } 883 }
834 884
835 /* Initial variables */ 885 /* Initial variables */
@@ -865,24 +915,12 @@ static int __devinit pcwatchdog_init(int base_addr)
865 WATCHDOG_HEARTBEAT); 915 WATCHDOG_HEARTBEAT);
866 } 916 }
867 917
868 ret = register_reboot_notifier(&pcwd_notifier);
869 if (ret) {
870 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
871 ret);
872 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
873 pcwd_private.io_addr = 0x0000;
874 return ret;
875 }
876
877 if (pcwd_private.supports_temp) { 918 if (pcwd_private.supports_temp) {
878 ret = misc_register(&temp_miscdev); 919 ret = misc_register(&temp_miscdev);
879 if (ret) { 920 if (ret) {
880 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 921 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
881 TEMP_MINOR, ret); 922 TEMP_MINOR, ret);
882 unregister_reboot_notifier(&pcwd_notifier); 923 goto error_misc_register_temp;
883 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
884 pcwd_private.io_addr = 0x0000;
885 return ret;
886 } 924 }
887 } 925 }
888 926
@@ -890,22 +928,34 @@ static int __devinit pcwatchdog_init(int base_addr)
890 if (ret) { 928 if (ret) {
891 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 929 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
892 WATCHDOG_MINOR, ret); 930 WATCHDOG_MINOR, ret);
893 if (pcwd_private.supports_temp) 931 goto error_misc_register_watchdog;
894 misc_deregister(&temp_miscdev);
895 unregister_reboot_notifier(&pcwd_notifier);
896 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
897 pcwd_private.io_addr = 0x0000;
898 return ret;
899 } 932 }
900 933
901 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", 934 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
902 heartbeat, nowayout); 935 heartbeat, nowayout);
903 936
904 return 0; 937 return 0;
938
939error_misc_register_watchdog:
940 if (pcwd_private.supports_temp)
941 misc_deregister(&temp_miscdev);
942error_misc_register_temp:
943 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
944error_request_region:
945 pcwd_private.io_addr = 0x0000;
946 cards_found--;
947 return ret;
905} 948}
906 949
907static void __devexit pcwatchdog_exit(void) 950static int __devexit pcwd_isa_remove(struct device *dev, unsigned int id)
908{ 951{
952 if (debug >= DEBUG)
953 printk(KERN_DEBUG PFX "pcwd_isa_remove id=%d\n",
954 id);
955
956 if (!pcwd_private.io_addr)
957 return 1;
958
909 /* Disable the board */ 959 /* Disable the board */
910 if (!nowayout) 960 if (!nowayout)
911 pcwd_stop(); 961 pcwd_stop();
@@ -914,102 +964,50 @@ static void __devexit pcwatchdog_exit(void)
914 misc_deregister(&pcwd_miscdev); 964 misc_deregister(&pcwd_miscdev);
915 if (pcwd_private.supports_temp) 965 if (pcwd_private.supports_temp)
916 misc_deregister(&temp_miscdev); 966 misc_deregister(&temp_miscdev);
917 unregister_reboot_notifier(&pcwd_notifier);
918 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); 967 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
919 pcwd_private.io_addr = 0x0000; 968 pcwd_private.io_addr = 0x0000;
920 cards_found--; 969 cards_found--;
970
971 return 0;
921} 972}
922 973
923/* 974static void pcwd_isa_shutdown(struct device *dev, unsigned int id)
924 * The ISA cards have a heartbeat bit in one of the registers, which
925 * register is card dependent. The heartbeat bit is monitored, and if
926 * found, is considered proof that a Berkshire card has been found.
927 * The initial rate is once per second at board start up, then twice
928 * per second for normal operation.
929 */
930static int __init pcwd_checkcard(int base_addr)
931{ 975{
932 int port0, last_port0; /* Reg 0, in case it's REV A */ 976 if (debug >= DEBUG)
933 int port1, last_port1; /* Register 1 for REV C cards */ 977 printk(KERN_DEBUG PFX "pcwd_isa_shutdown id=%d\n",
934 int i; 978 id);
935 int retval;
936
937 if (!request_region (base_addr, 4, "PCWD")) {
938 printk (KERN_INFO PFX "Port 0x%04x unavailable\n", base_addr);
939 return 0;
940 }
941
942 retval = 0;
943
944 port0 = inb_p(base_addr); /* For REV A boards */
945 port1 = inb_p(base_addr + 1); /* For REV C boards */
946 if (port0 != 0xff || port1 != 0xff) {
947 /* Not an 'ff' from a floating bus, so must be a card! */
948 for (i = 0; i < 4; ++i) {
949
950 msleep(500);
951
952 last_port0 = port0;
953 last_port1 = port1;
954
955 port0 = inb_p(base_addr);
956 port1 = inb_p(base_addr + 1);
957
958 /* Has either hearbeat bit changed? */
959 if ((port0 ^ last_port0) & WD_HRTBT ||
960 (port1 ^ last_port1) & WD_REVC_HRBT) {
961 retval = 1;
962 break;
963 }
964 }
965 }
966 release_region (base_addr, 4);
967 979
968 return retval; 980 pcwd_stop();
969} 981}
970 982
971/* 983static struct isa_driver pcwd_isa_driver = {
972 * These are the auto-probe addresses available. 984 .match = pcwd_isa_match,
973 * 985 .probe = pcwd_isa_probe,
974 * Revision A only uses ports 0x270 and 0x370. Revision C introduced 0x350. 986 .remove = __devexit_p(pcwd_isa_remove),
975 * Revision A has an address range of 2 addresses, while Revision C has 4. 987 .shutdown = pcwd_isa_shutdown,
976 */ 988 .driver = {
977static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 }; 989 .owner = THIS_MODULE,
990 .name = WATCHDOG_NAME,
991 },
992};
978 993
979static int __init pcwd_init_module(void) 994static int __init pcwd_init_module(void)
980{ 995{
981 int i, found = 0; 996 return isa_register_driver(&pcwd_isa_driver, PCWD_ISA_NR_CARDS);
982
983 spin_lock_init(&pcwd_private.io_lock);
984
985 for (i = 0; pcwd_ioports[i] != 0; i++) {
986 if (pcwd_checkcard(pcwd_ioports[i])) {
987 if (!(pcwatchdog_init(pcwd_ioports[i])))
988 found++;
989 }
990 }
991
992 if (!found) {
993 printk (KERN_INFO PFX "No card detected, or port not available\n");
994 return -ENODEV;
995 }
996
997 return 0;
998} 997}
999 998
1000static void __exit pcwd_cleanup_module(void) 999static void __exit pcwd_cleanup_module(void)
1001{ 1000{
1002 if (pcwd_private.io_addr) 1001 isa_unregister_driver(&pcwd_isa_driver);
1003 pcwatchdog_exit();
1004
1005 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); 1002 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
1006} 1003}
1007 1004
1008module_init(pcwd_init_module); 1005module_init(pcwd_init_module);
1009module_exit(pcwd_cleanup_module); 1006module_exit(pcwd_cleanup_module);
1010 1007
1011MODULE_AUTHOR("Ken Hollis <kenji@bitgate.com>"); 1008MODULE_AUTHOR("Ken Hollis <kenji@bitgate.com>, Wim Van Sebroeck <wim@iguana.be>");
1012MODULE_DESCRIPTION("Berkshire ISA-PC Watchdog driver"); 1009MODULE_DESCRIPTION("Berkshire ISA-PC Watchdog driver");
1010MODULE_VERSION(WATCHDOG_VERSION);
1013MODULE_LICENSE("GPL"); 1011MODULE_LICENSE("GPL");
1014MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 1012MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
1015MODULE_ALIAS_MISCDEV(TEMP_MINOR); 1013MODULE_ALIAS_MISCDEV(TEMP_MINOR);
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index 31037f9c9ffe..1e7a6719d5ba 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -146,7 +146,7 @@ struct usb_pcwd_private {
146 atomic_t cmd_received; /* true if we received a report after a command */ 146 atomic_t cmd_received; /* true if we received a report after a command */
147 147
148 int exists; /* Wether or not the device exists */ 148 int exists; /* Wether or not the device exists */
149 struct semaphore sem; /* locks this structure */ 149 struct mutex mtx; /* locks this structure */
150}; 150};
151static struct usb_pcwd_private *usb_pcwd_device; 151static struct usb_pcwd_private *usb_pcwd_device;
152 152
@@ -635,7 +635,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
635 635
636 usb_pcwd_device = usb_pcwd; 636 usb_pcwd_device = usb_pcwd;
637 637
638 init_MUTEX (&usb_pcwd->sem); 638 mutex_init(&usb_pcwd->mtx);
639 usb_pcwd->udev = udev; 639 usb_pcwd->udev = udev;
640 usb_pcwd->interface = interface; 640 usb_pcwd->interface = interface;
641 usb_pcwd->interface_number = iface_desc->desc.bInterfaceNumber; 641 usb_pcwd->interface_number = iface_desc->desc.bInterfaceNumber;
@@ -763,7 +763,7 @@ static void usb_pcwd_disconnect(struct usb_interface *interface)
763 usb_pcwd = usb_get_intfdata (interface); 763 usb_pcwd = usb_get_intfdata (interface);
764 usb_set_intfdata (interface, NULL); 764 usb_set_intfdata (interface, NULL);
765 765
766 down (&usb_pcwd->sem); 766 mutex_lock(&usb_pcwd->mtx);
767 767
768 /* Stop the timer before we leave */ 768 /* Stop the timer before we leave */
769 if (!nowayout) 769 if (!nowayout)
@@ -777,7 +777,7 @@ static void usb_pcwd_disconnect(struct usb_interface *interface)
777 misc_deregister(&usb_pcwd_temperature_miscdev); 777 misc_deregister(&usb_pcwd_temperature_miscdev);
778 unregister_reboot_notifier(&usb_pcwd_notifier); 778 unregister_reboot_notifier(&usb_pcwd_notifier);
779 779
780 up (&usb_pcwd->sem); 780 mutex_unlock(&usb_pcwd->mtx);
781 781
782 /* Delete the USB PCWD device */ 782 /* Delete the USB PCWD device */
783 usb_pcwd_delete(usb_pcwd); 783 usb_pcwd_delete(usb_pcwd);
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index dff6cb5dc9a7..20fa29ca7404 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -379,14 +379,14 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
379 379
380 DBG("probe: mapped wdt_base=%p\n", wdt_base); 380 DBG("probe: mapped wdt_base=%p\n", wdt_base);
381 381
382 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 382 wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
383 if (res == NULL) { 383 if (wdt_irq == NULL) {
384 printk(KERN_INFO PFX "failed to get irq resource\n"); 384 printk(KERN_INFO PFX "failed to get irq resource\n");
385 ret = -ENOENT; 385 ret = -ENOENT;
386 goto err_map; 386 goto err_map;
387 } 387 }
388 388
389 ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev); 389 ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
390 if (ret != 0) { 390 if (ret != 0) {
391 printk(KERN_INFO PFX "failed to install irq (%d)\n", ret); 391 printk(KERN_INFO PFX "failed to install irq (%d)\n", ret);
392 goto err_map; 392 goto err_map;
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/char/watchdog/sbc8360.c
index 67ae42685e75..285d85289532 100644
--- a/drivers/char/watchdog/sbc8360.c
+++ b/drivers/char/watchdog/sbc8360.c
@@ -333,18 +333,17 @@ static int __init sbc8360_init(void)
333 int res; 333 int res;
334 unsigned long int mseconds = 60000; 334 unsigned long int mseconds = 60000;
335 335
336 spin_lock_init(&sbc8360_lock); 336 if (timeout < 0 || timeout > 63) {
337 res = misc_register(&sbc8360_miscdev); 337 printk(KERN_ERR PFX "Invalid timeout index (must be 0-63).\n");
338 if (res) { 338 res = -EINVAL;
339 printk(KERN_ERR PFX "failed to register misc device\n"); 339 goto out;
340 goto out_nomisc;
341 } 340 }
342 341
343 if (!request_region(SBC8360_ENABLE, 1, "SBC8360")) { 342 if (!request_region(SBC8360_ENABLE, 1, "SBC8360")) {
344 printk(KERN_ERR PFX "ENABLE method I/O %X is not available.\n", 343 printk(KERN_ERR PFX "ENABLE method I/O %X is not available.\n",
345 SBC8360_ENABLE); 344 SBC8360_ENABLE);
346 res = -EIO; 345 res = -EIO;
347 goto out_noenablereg; 346 goto out;
348 } 347 }
349 if (!request_region(SBC8360_BASETIME, 1, "SBC8360")) { 348 if (!request_region(SBC8360_BASETIME, 1, "SBC8360")) {
350 printk(KERN_ERR PFX 349 printk(KERN_ERR PFX
@@ -360,10 +359,11 @@ static int __init sbc8360_init(void)
360 goto out_noreboot; 359 goto out_noreboot;
361 } 360 }
362 361
363 if (timeout < 0 || timeout > 63) { 362 spin_lock_init(&sbc8360_lock);
364 printk(KERN_ERR PFX "Invalid timeout index (must be 0-63).\n"); 363 res = misc_register(&sbc8360_miscdev);
365 res = -EINVAL; 364 if (res) {
366 goto out_noreboot; 365 printk(KERN_ERR PFX "failed to register misc device\n");
366 goto out_nomisc;
367 } 367 }
368 368
369 wd_margin = wd_times[timeout][0]; 369 wd_margin = wd_times[timeout][0];
@@ -383,13 +383,13 @@ static int __init sbc8360_init(void)
383 383
384 return 0; 384 return 0;
385 385
386 out_nomisc:
387 unregister_reboot_notifier(&sbc8360_notifier);
386 out_noreboot: 388 out_noreboot:
387 release_region(SBC8360_ENABLE, 1);
388 release_region(SBC8360_BASETIME, 1); 389 release_region(SBC8360_BASETIME, 1);
389 out_noenablereg:
390 out_nobasetimereg: 390 out_nobasetimereg:
391 misc_deregister(&sbc8360_miscdev); 391 release_region(SBC8360_ENABLE, 1);
392 out_nomisc: 392 out:
393 return res; 393 return res;
394} 394}
395 395
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
index 337ee42c90dd..b46e7f47d705 100644
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/char/watchdog/w83627hf_wdt.c
@@ -1,5 +1,8 @@
1/* 1/*
2 * w83627hf WDT driver 2 * w83627hf/thf WDT driver
3 *
4 * (c) Copyright 2007 Vlad Drukker <vlad@storewiz.com>
5 * added support for W83627THF.
3 * 6 *
4 * (c) Copyright 2003 Pádraig Brady <P@draigBrady.com> 7 * (c) Copyright 2003 Pádraig Brady <P@draigBrady.com>
5 * 8 *
@@ -39,7 +42,7 @@
39#include <asm/uaccess.h> 42#include <asm/uaccess.h>
40#include <asm/system.h> 43#include <asm/system.h>
41 44
42#define WATCHDOG_NAME "w83627hf WDT" 45#define WATCHDOG_NAME "w83627hf/thf WDT"
43#define PFX WATCHDOG_NAME ": " 46#define PFX WATCHDOG_NAME ": "
44#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ 47#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */
45 48
@@ -50,7 +53,7 @@ static spinlock_t io_lock;
50/* You must set this - there is no sane way to probe for this board. */ 53/* You must set this - there is no sane way to probe for this board. */
51static int wdt_io = 0x2E; 54static int wdt_io = 0x2E;
52module_param(wdt_io, int, 0); 55module_param(wdt_io, int, 0);
53MODULE_PARM_DESC(wdt_io, "w83627hf WDT io port (default 0x2E)"); 56MODULE_PARM_DESC(wdt_io, "w83627hf/thf WDT io port (default 0x2E)");
54 57
55static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 58static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
56module_param(timeout, int, 0); 59module_param(timeout, int, 0);
@@ -71,9 +74,19 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" _
71static void 74static void
72w83627hf_select_wd_register(void) 75w83627hf_select_wd_register(void)
73{ 76{
77 unsigned char c;
74 outb_p(0x87, WDT_EFER); /* Enter extended function mode */ 78 outb_p(0x87, WDT_EFER); /* Enter extended function mode */
75 outb_p(0x87, WDT_EFER); /* Again according to manual */ 79 outb_p(0x87, WDT_EFER); /* Again according to manual */
76 80
81 outb(0x20, WDT_EFER); /* check chip version */
82 c = inb(WDT_EFDR);
83 if (c == 0x82) { /* W83627THF */
84 outb_p(0x2b, WDT_EFER); /* select GPIO3 */
85 c = ((inb_p(WDT_EFDR) & 0xf7) | 0x04); /* select WDT0 */
86 outb_p(0x2b, WDT_EFER);
87 outb_p(c, WDT_EFDR); /* set GPIO3 to WDT0 */
88 }
89
77 outb_p(0x07, WDT_EFER); /* point to logical device number reg */ 90 outb_p(0x07, WDT_EFER); /* point to logical device number reg */
78 outb_p(0x08, WDT_EFDR); /* select logical device 8 (GPIO2) */ 91 outb_p(0x08, WDT_EFDR); /* select logical device 8 (GPIO2) */
79 outb_p(0x30, WDT_EFER); /* select CR30 */ 92 outb_p(0x30, WDT_EFER); /* select CR30 */
@@ -311,7 +324,7 @@ wdt_init(void)
311 324
312 spin_lock_init(&io_lock); 325 spin_lock_init(&io_lock);
313 326
314 printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF Super I/O chip initialising.\n"); 327 printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF/THF Super I/O chip initialising.\n");
315 328
316 if (wdt_set_heartbeat(timeout)) { 329 if (wdt_set_heartbeat(timeout)) {
317 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 330 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
@@ -367,5 +380,5 @@ module_exit(wdt_exit);
367 380
368MODULE_LICENSE("GPL"); 381MODULE_LICENSE("GPL");
369MODULE_AUTHOR("Pádraig Brady <P@draigBrady.com>"); 382MODULE_AUTHOR("Pádraig Brady <P@draigBrady.com>");
370MODULE_DESCRIPTION("w83627hf WDT driver"); 383MODULE_DESCRIPTION("w83627hf/thf WDT driver");
371MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 384MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);