aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Bunk <bunk@stusta.de>2007-04-06 06:22:17 -0400
committerWim Van Sebroeck <wim@iguana.be>2007-05-01 03:35:35 -0400
commitdbf379ea9ae878bf88d2b3cf8f74ce4536e25d19 (patch)
tree96d846142debb428b424e88891e3e39dcbe1355e
parent48a7afe314bfc4d7f50e1608632f503dbba7e013 (diff)
[WATCHDOG] the scheduled removal of the i8xx_tco watchdog driver
This patch contains the scheduled removal of the i8xx_tco watchdog driver. Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
-rw-r--r--Documentation/feature-removal-schedule.txt8
-rw-r--r--MAINTAINERS6
-rw-r--r--drivers/char/watchdog/Kconfig22
-rw-r--r--drivers/char/watchdog/Makefile1
-rw-r--r--drivers/char/watchdog/i8xx_tco.c571
-rw-r--r--drivers/char/watchdog/i8xx_tco.h42
6 files changed, 0 insertions, 650 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 5c88ba1ea262..d6d183f24cc9 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -288,14 +288,6 @@ Who: Richard Purdie <rpurdie@rpsys.net>
288 288
289--------------------------- 289---------------------------
290 290
291What: i8xx_tco watchdog driver
292When: in 2.6.22
293Why: the i8xx_tco watchdog driver has been replaced by the iTCO_wdt
294 watchdog driver.
295Who: Wim Van Sebroeck <wim@iguana.be>
296
297---------------------------
298
299What: Multipath cached routing support in ipv4 291What: Multipath cached routing support in ipv4
300When: in 2.6.23 292When: in 2.6.23
301Why: Code was merged, then submitter immediately disappeared leaving 293Why: Code was merged, then submitter immediately disappeared leaving
diff --git a/MAINTAINERS b/MAINTAINERS
index af1c7926c153..6fd435dbea0e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1644,12 +1644,6 @@ P: H. Peter Anvin
1644M: hpa@zytor.com 1644M: hpa@zytor.com
1645S: Maintained 1645S: Maintained
1646 1646
1647i810 TCO TIMER WATCHDOG
1648P: Nils Faerber
1649M: nils@kernelconcepts.de
1650W: http://www.kernelconcepts.de/
1651S: Maintained
1652
1653IA64 (Itanium) PLATFORM 1647IA64 (Itanium) PLATFORM
1654P: Tony Luck 1648P: Tony Luck
1655M: tony.luck@intel.com 1649M: tony.luck@intel.com
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 60198a78974c..684812f32d1d 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -298,28 +298,6 @@ config I6300ESB_WDT
298 To compile this driver as a module, choose M here: the 298 To compile this driver as a module, choose M here: the
299 module will be called i6300esb. 299 module will be called i6300esb.
300 300
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 301config ITCO_WDT
324 tristate "Intel TCO Timer/Watchdog" 302 tristate "Intel TCO Timer/Watchdog"
325 depends on WATCHDOG && (X86 || IA64) && PCI 303 depends on WATCHDOG && (X86 || IA64) && PCI
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 2cd8ff8d10ac..387eb80b404f 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
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 */