xref: /linux/drivers/watchdog/iTCO_wdt.c (revision 26b0d14106954ae46d2f4f7eec3481828a210f7d)
1 /*
2  *	intel TCO Watchdog Driver
3  *
4  *	(c) Copyright 2006-2011 Wim Van Sebroeck <wim@iguana.be>.
5  *
6  *	This program is free software; you can redistribute it and/or
7  *	modify it under the terms of the GNU General Public License
8  *	as published by the Free Software Foundation; either version
9  *	2 of the License, or (at your option) any later version.
10  *
11  *	Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor
12  *	provide warranty for any of this software. This material is
13  *	provided "AS-IS" and at no charge.
14  *
15  *	The TCO watchdog is implemented in the following I/O controller hubs:
16  *	(See the intel documentation on http://developer.intel.com.)
17  *	document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO)
18  *	document number 290687-002, 298242-027: 82801BA (ICH2)
19  *	document number 290733-003, 290739-013: 82801CA (ICH3-S)
20  *	document number 290716-001, 290718-007: 82801CAM (ICH3-M)
21  *	document number 290744-001, 290745-025: 82801DB (ICH4)
22  *	document number 252337-001, 252663-008: 82801DBM (ICH4-M)
23  *	document number 273599-001, 273645-002: 82801E (C-ICH)
24  *	document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R)
25  *	document number 300641-004, 300884-013: 6300ESB
26  *	document number 301473-002, 301474-026: 82801F (ICH6)
27  *	document number 313082-001, 313075-006: 631xESB, 632xESB
28  *	document number 307013-003, 307014-024: 82801G (ICH7)
29  *	document number 322896-001, 322897-001: NM10
30  *	document number 313056-003, 313057-017: 82801H (ICH8)
31  *	document number 316972-004, 316973-012: 82801I (ICH9)
32  *	document number 319973-002, 319974-002: 82801J (ICH10)
33  *	document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH)
34  *	document number 320066-003, 320257-008: EP80597 (IICH)
35  *	document number 324645-001, 324646-001: Cougar Point (CPT)
36  *	document number TBD                   : Patsburg (PBG)
37  *	document number TBD                   : DH89xxCC
38  *	document number TBD                   : Panther Point
39  *	document number TBD                   : Lynx Point
40  */
41 
42 /*
43  *	Includes, defines, variables, module parameters, ...
44  */
45 
46 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
47 
48 /* Module and version information */
49 #define DRV_NAME	"iTCO_wdt"
50 #define DRV_VERSION	"1.07"
51 
52 /* Includes */
53 #include <linux/module.h>		/* For module specific items */
54 #include <linux/moduleparam.h>		/* For new moduleparam's */
55 #include <linux/types.h>		/* For standard types (like size_t) */
56 #include <linux/errno.h>		/* For the -ENODEV/... values */
57 #include <linux/kernel.h>		/* For printk/panic/... */
58 #include <linux/miscdevice.h>		/* For MODULE_ALIAS_MISCDEV
59 							(WATCHDOG_MINOR) */
60 #include <linux/watchdog.h>		/* For the watchdog specific items */
61 #include <linux/init.h>			/* For __init/__exit/... */
62 #include <linux/fs.h>			/* For file operations */
63 #include <linux/platform_device.h>	/* For platform_driver framework */
64 #include <linux/pci.h>			/* For pci functions */
65 #include <linux/ioport.h>		/* For io-port access */
66 #include <linux/spinlock.h>		/* For spin_lock/spin_unlock/... */
67 #include <linux/uaccess.h>		/* For copy_to_user/put_user/... */
68 #include <linux/io.h>			/* For inb/outb/... */
69 #include <linux/mfd/core.h>
70 #include <linux/mfd/lpc_ich.h>
71 
72 #include "iTCO_vendor.h"
73 
74 /* Address definitions for the TCO */
75 /* TCO base address */
76 #define TCOBASE		(iTCO_wdt_private.tco_res->start)
77 /* SMI Control and Enable Register */
78 #define SMI_EN		(iTCO_wdt_private.smi_res->start)
79 
80 #define TCO_RLD		(TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */
81 #define TCOv1_TMR	(TCOBASE + 0x01) /* TCOv1 Timer Initial Value	*/
82 #define TCO_DAT_IN	(TCOBASE + 0x02) /* TCO Data In Register	*/
83 #define TCO_DAT_OUT	(TCOBASE + 0x03) /* TCO Data Out Register	*/
84 #define TCO1_STS	(TCOBASE + 0x04) /* TCO1 Status Register	*/
85 #define TCO2_STS	(TCOBASE + 0x06) /* TCO2 Status Register	*/
86 #define TCO1_CNT	(TCOBASE + 0x08) /* TCO1 Control Register	*/
87 #define TCO2_CNT	(TCOBASE + 0x0a) /* TCO2 Control Register	*/
88 #define TCOv2_TMR	(TCOBASE + 0x12) /* TCOv2 Timer Initial Value	*/
89 
90 /* internal variables */
91 static unsigned long is_active;
92 static char expect_release;
93 static struct {		/* this is private data for the iTCO_wdt device */
94 	/* TCO version/generation */
95 	unsigned int iTCO_version;
96 	struct resource *tco_res;
97 	struct resource *smi_res;
98 	struct resource *gcs_res;
99 	/* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/
100 	unsigned long __iomem *gcs;
101 	/* the lock for io operations */
102 	spinlock_t io_lock;
103 	struct platform_device *dev;
104 	/* the PCI-device */
105 	struct pci_dev *pdev;
106 } iTCO_wdt_private;
107 
108 /* module parameters */
109 #define WATCHDOG_HEARTBEAT 30	/* 30 sec default heartbeat */
110 static int heartbeat = WATCHDOG_HEARTBEAT;  /* in seconds */
111 module_param(heartbeat, int, 0);
112 MODULE_PARM_DESC(heartbeat, "Watchdog timeout in seconds. "
113 	"5..76 (TCO v1) or 3..614 (TCO v2), default="
114 				__MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
115 
116 static bool nowayout = WATCHDOG_NOWAYOUT;
117 module_param(nowayout, bool, 0);
118 MODULE_PARM_DESC(nowayout,
119 	"Watchdog cannot be stopped once started (default="
120 				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
121 
122 static int turn_SMI_watchdog_clear_off = 1;
123 module_param(turn_SMI_watchdog_clear_off, int, 0);
124 MODULE_PARM_DESC(turn_SMI_watchdog_clear_off,
125 	"Turn off SMI clearing watchdog (depends on TCO-version)(default=1)");
126 
127 /*
128  * Some TCO specific functions
129  */
130 
131 static inline unsigned int seconds_to_ticks(int seconds)
132 {
133 	/* the internal timer is stored as ticks which decrement
134 	 * every 0.6 seconds */
135 	return (seconds * 10) / 6;
136 }
137 
138 static void iTCO_wdt_set_NO_REBOOT_bit(void)
139 {
140 	u32 val32;
141 
142 	/* Set the NO_REBOOT bit: this disables reboots */
143 	if (iTCO_wdt_private.iTCO_version == 2) {
144 		val32 = readl(iTCO_wdt_private.gcs);
145 		val32 |= 0x00000020;
146 		writel(val32, iTCO_wdt_private.gcs);
147 	} else if (iTCO_wdt_private.iTCO_version == 1) {
148 		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
149 		val32 |= 0x00000002;
150 		pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
151 	}
152 }
153 
154 static int iTCO_wdt_unset_NO_REBOOT_bit(void)
155 {
156 	int ret = 0;
157 	u32 val32;
158 
159 	/* Unset the NO_REBOOT bit: this enables reboots */
160 	if (iTCO_wdt_private.iTCO_version == 2) {
161 		val32 = readl(iTCO_wdt_private.gcs);
162 		val32 &= 0xffffffdf;
163 		writel(val32, iTCO_wdt_private.gcs);
164 
165 		val32 = readl(iTCO_wdt_private.gcs);
166 		if (val32 & 0x00000020)
167 			ret = -EIO;
168 	} else if (iTCO_wdt_private.iTCO_version == 1) {
169 		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
170 		val32 &= 0xfffffffd;
171 		pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
172 
173 		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
174 		if (val32 & 0x00000002)
175 			ret = -EIO;
176 	}
177 
178 	return ret; /* returns: 0 = OK, -EIO = Error */
179 }
180 
181 static int iTCO_wdt_start(void)
182 {
183 	unsigned int val;
184 
185 	spin_lock(&iTCO_wdt_private.io_lock);
186 
187 	iTCO_vendor_pre_start(iTCO_wdt_private.smi_res, heartbeat);
188 
189 	/* disable chipset's NO_REBOOT bit */
190 	if (iTCO_wdt_unset_NO_REBOOT_bit()) {
191 		spin_unlock(&iTCO_wdt_private.io_lock);
192 		pr_err("failed to reset NO_REBOOT flag, reboot disabled by hardware/BIOS\n");
193 		return -EIO;
194 	}
195 
196 	/* Force the timer to its reload value by writing to the TCO_RLD
197 	   register */
198 	if (iTCO_wdt_private.iTCO_version == 2)
199 		outw(0x01, TCO_RLD);
200 	else if (iTCO_wdt_private.iTCO_version == 1)
201 		outb(0x01, TCO_RLD);
202 
203 	/* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */
204 	val = inw(TCO1_CNT);
205 	val &= 0xf7ff;
206 	outw(val, TCO1_CNT);
207 	val = inw(TCO1_CNT);
208 	spin_unlock(&iTCO_wdt_private.io_lock);
209 
210 	if (val & 0x0800)
211 		return -1;
212 	return 0;
213 }
214 
215 static int iTCO_wdt_stop(void)
216 {
217 	unsigned int val;
218 
219 	spin_lock(&iTCO_wdt_private.io_lock);
220 
221 	iTCO_vendor_pre_stop(iTCO_wdt_private.smi_res);
222 
223 	/* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */
224 	val = inw(TCO1_CNT);
225 	val |= 0x0800;
226 	outw(val, TCO1_CNT);
227 	val = inw(TCO1_CNT);
228 
229 	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
230 	iTCO_wdt_set_NO_REBOOT_bit();
231 
232 	spin_unlock(&iTCO_wdt_private.io_lock);
233 
234 	if ((val & 0x0800) == 0)
235 		return -1;
236 	return 0;
237 }
238 
239 static int iTCO_wdt_keepalive(void)
240 {
241 	spin_lock(&iTCO_wdt_private.io_lock);
242 
243 	iTCO_vendor_pre_keepalive(iTCO_wdt_private.smi_res, heartbeat);
244 
245 	/* Reload the timer by writing to the TCO Timer Counter register */
246 	if (iTCO_wdt_private.iTCO_version == 2)
247 		outw(0x01, TCO_RLD);
248 	else if (iTCO_wdt_private.iTCO_version == 1) {
249 		/* Reset the timeout status bit so that the timer
250 		 * needs to count down twice again before rebooting */
251 		outw(0x0008, TCO1_STS);	/* write 1 to clear bit */
252 
253 		outb(0x01, TCO_RLD);
254 	}
255 
256 	spin_unlock(&iTCO_wdt_private.io_lock);
257 	return 0;
258 }
259 
260 static int iTCO_wdt_set_heartbeat(int t)
261 {
262 	unsigned int val16;
263 	unsigned char val8;
264 	unsigned int tmrval;
265 
266 	tmrval = seconds_to_ticks(t);
267 
268 	/* For TCO v1 the timer counts down twice before rebooting */
269 	if (iTCO_wdt_private.iTCO_version == 1)
270 		tmrval /= 2;
271 
272 	/* from the specs: */
273 	/* "Values of 0h-3h are ignored and should not be attempted" */
274 	if (tmrval < 0x04)
275 		return -EINVAL;
276 	if (((iTCO_wdt_private.iTCO_version == 2) && (tmrval > 0x3ff)) ||
277 	    ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f)))
278 		return -EINVAL;
279 
280 	iTCO_vendor_pre_set_heartbeat(tmrval);
281 
282 	/* Write new heartbeat to watchdog */
283 	if (iTCO_wdt_private.iTCO_version == 2) {
284 		spin_lock(&iTCO_wdt_private.io_lock);
285 		val16 = inw(TCOv2_TMR);
286 		val16 &= 0xfc00;
287 		val16 |= tmrval;
288 		outw(val16, TCOv2_TMR);
289 		val16 = inw(TCOv2_TMR);
290 		spin_unlock(&iTCO_wdt_private.io_lock);
291 
292 		if ((val16 & 0x3ff) != tmrval)
293 			return -EINVAL;
294 	} else if (iTCO_wdt_private.iTCO_version == 1) {
295 		spin_lock(&iTCO_wdt_private.io_lock);
296 		val8 = inb(TCOv1_TMR);
297 		val8 &= 0xc0;
298 		val8 |= (tmrval & 0xff);
299 		outb(val8, TCOv1_TMR);
300 		val8 = inb(TCOv1_TMR);
301 		spin_unlock(&iTCO_wdt_private.io_lock);
302 
303 		if ((val8 & 0x3f) != tmrval)
304 			return -EINVAL;
305 	}
306 
307 	heartbeat = t;
308 	return 0;
309 }
310 
311 static int iTCO_wdt_get_timeleft(int *time_left)
312 {
313 	unsigned int val16;
314 	unsigned char val8;
315 
316 	/* read the TCO Timer */
317 	if (iTCO_wdt_private.iTCO_version == 2) {
318 		spin_lock(&iTCO_wdt_private.io_lock);
319 		val16 = inw(TCO_RLD);
320 		val16 &= 0x3ff;
321 		spin_unlock(&iTCO_wdt_private.io_lock);
322 
323 		*time_left = (val16 * 6) / 10;
324 	} else if (iTCO_wdt_private.iTCO_version == 1) {
325 		spin_lock(&iTCO_wdt_private.io_lock);
326 		val8 = inb(TCO_RLD);
327 		val8 &= 0x3f;
328 		if (!(inw(TCO1_STS) & 0x0008))
329 			val8 += (inb(TCOv1_TMR) & 0x3f);
330 		spin_unlock(&iTCO_wdt_private.io_lock);
331 
332 		*time_left = (val8 * 6) / 10;
333 	} else
334 		return -EINVAL;
335 	return 0;
336 }
337 
338 /*
339  *	/dev/watchdog handling
340  */
341 
342 static int iTCO_wdt_open(struct inode *inode, struct file *file)
343 {
344 	/* /dev/watchdog can only be opened once */
345 	if (test_and_set_bit(0, &is_active))
346 		return -EBUSY;
347 
348 	/*
349 	 *      Reload and activate timer
350 	 */
351 	iTCO_wdt_start();
352 	return nonseekable_open(inode, file);
353 }
354 
355 static int iTCO_wdt_release(struct inode *inode, struct file *file)
356 {
357 	/*
358 	 *      Shut off the timer.
359 	 */
360 	if (expect_release == 42) {
361 		iTCO_wdt_stop();
362 	} else {
363 		pr_crit("Unexpected close, not stopping watchdog!\n");
364 		iTCO_wdt_keepalive();
365 	}
366 	clear_bit(0, &is_active);
367 	expect_release = 0;
368 	return 0;
369 }
370 
371 static ssize_t iTCO_wdt_write(struct file *file, const char __user *data,
372 			      size_t len, loff_t *ppos)
373 {
374 	/* See if we got the magic character 'V' and reload the timer */
375 	if (len) {
376 		if (!nowayout) {
377 			size_t i;
378 
379 			/* note: just in case someone wrote the magic
380 			   character five months ago... */
381 			expect_release = 0;
382 
383 			/* scan to see whether or not we got the
384 			   magic character */
385 			for (i = 0; i != len; i++) {
386 				char c;
387 				if (get_user(c, data + i))
388 					return -EFAULT;
389 				if (c == 'V')
390 					expect_release = 42;
391 			}
392 		}
393 
394 		/* someone wrote to us, we should reload the timer */
395 		iTCO_wdt_keepalive();
396 	}
397 	return len;
398 }
399 
400 static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd,
401 							unsigned long arg)
402 {
403 	int new_options, retval = -EINVAL;
404 	int new_heartbeat;
405 	void __user *argp = (void __user *)arg;
406 	int __user *p = argp;
407 	static const struct watchdog_info ident = {
408 		.options =		WDIOF_SETTIMEOUT |
409 					WDIOF_KEEPALIVEPING |
410 					WDIOF_MAGICCLOSE,
411 		.firmware_version =	0,
412 		.identity =		DRV_NAME,
413 	};
414 
415 	switch (cmd) {
416 	case WDIOC_GETSUPPORT:
417 		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
418 	case WDIOC_GETSTATUS:
419 	case WDIOC_GETBOOTSTATUS:
420 		return put_user(0, p);
421 
422 	case WDIOC_SETOPTIONS:
423 	{
424 		if (get_user(new_options, p))
425 			return -EFAULT;
426 
427 		if (new_options & WDIOS_DISABLECARD) {
428 			iTCO_wdt_stop();
429 			retval = 0;
430 		}
431 		if (new_options & WDIOS_ENABLECARD) {
432 			iTCO_wdt_keepalive();
433 			iTCO_wdt_start();
434 			retval = 0;
435 		}
436 		return retval;
437 	}
438 	case WDIOC_KEEPALIVE:
439 		iTCO_wdt_keepalive();
440 		return 0;
441 
442 	case WDIOC_SETTIMEOUT:
443 	{
444 		if (get_user(new_heartbeat, p))
445 			return -EFAULT;
446 		if (iTCO_wdt_set_heartbeat(new_heartbeat))
447 			return -EINVAL;
448 		iTCO_wdt_keepalive();
449 		/* Fall */
450 	}
451 	case WDIOC_GETTIMEOUT:
452 		return put_user(heartbeat, p);
453 	case WDIOC_GETTIMELEFT:
454 	{
455 		int time_left;
456 		if (iTCO_wdt_get_timeleft(&time_left))
457 			return -EINVAL;
458 		return put_user(time_left, p);
459 	}
460 	default:
461 		return -ENOTTY;
462 	}
463 }
464 
465 /*
466  *	Kernel Interfaces
467  */
468 
469 static const struct file_operations iTCO_wdt_fops = {
470 	.owner =		THIS_MODULE,
471 	.llseek =		no_llseek,
472 	.write =		iTCO_wdt_write,
473 	.unlocked_ioctl =	iTCO_wdt_ioctl,
474 	.open =			iTCO_wdt_open,
475 	.release =		iTCO_wdt_release,
476 };
477 
478 static struct miscdevice iTCO_wdt_miscdev = {
479 	.minor =	WATCHDOG_MINOR,
480 	.name =		"watchdog",
481 	.fops =		&iTCO_wdt_fops,
482 };
483 
484 /*
485  *	Init & exit routines
486  */
487 
488 static void __devexit iTCO_wdt_cleanup(void)
489 {
490 	/* Stop the timer before we leave */
491 	if (!nowayout)
492 		iTCO_wdt_stop();
493 
494 	/* Deregister */
495 	misc_deregister(&iTCO_wdt_miscdev);
496 
497 	/* release resources */
498 	release_region(iTCO_wdt_private.tco_res->start,
499 			resource_size(iTCO_wdt_private.tco_res));
500 	release_region(iTCO_wdt_private.smi_res->start,
501 			resource_size(iTCO_wdt_private.smi_res));
502 	if (iTCO_wdt_private.iTCO_version == 2) {
503 		iounmap(iTCO_wdt_private.gcs);
504 		release_mem_region(iTCO_wdt_private.gcs_res->start,
505 				resource_size(iTCO_wdt_private.gcs_res));
506 	}
507 
508 	iTCO_wdt_private.tco_res = NULL;
509 	iTCO_wdt_private.smi_res = NULL;
510 	iTCO_wdt_private.gcs_res = NULL;
511 	iTCO_wdt_private.gcs = NULL;
512 }
513 
514 static int __devinit iTCO_wdt_probe(struct platform_device *dev)
515 {
516 	int ret = -ENODEV;
517 	unsigned long val32;
518 	struct lpc_ich_info *ich_info = dev->dev.platform_data;
519 
520 	if (!ich_info)
521 		goto out;
522 
523 	spin_lock_init(&iTCO_wdt_private.io_lock);
524 
525 	iTCO_wdt_private.tco_res =
526 		platform_get_resource(dev, IORESOURCE_IO, ICH_RES_IO_TCO);
527 	if (!iTCO_wdt_private.tco_res)
528 		goto out;
529 
530 	iTCO_wdt_private.smi_res =
531 		platform_get_resource(dev, IORESOURCE_IO, ICH_RES_IO_SMI);
532 	if (!iTCO_wdt_private.smi_res)
533 		goto out;
534 
535 	iTCO_wdt_private.iTCO_version = ich_info->iTCO_version;
536 	iTCO_wdt_private.dev = dev;
537 	iTCO_wdt_private.pdev = to_pci_dev(dev->dev.parent);
538 
539 	/*
540 	 * Get the Memory-Mapped GCS register, we need it for the
541 	 * NO_REBOOT flag (TCO v2).
542 	 */
543 	if (iTCO_wdt_private.iTCO_version == 2) {
544 		iTCO_wdt_private.gcs_res = platform_get_resource(dev,
545 							IORESOURCE_MEM,
546 							ICH_RES_MEM_GCS);
547 
548 		if (!iTCO_wdt_private.gcs_res)
549 			goto out;
550 
551 		if (!request_mem_region(iTCO_wdt_private.gcs_res->start,
552 			resource_size(iTCO_wdt_private.gcs_res), dev->name)) {
553 			ret = -EBUSY;
554 			goto out;
555 		}
556 		iTCO_wdt_private.gcs = ioremap(iTCO_wdt_private.gcs_res->start,
557 			resource_size(iTCO_wdt_private.gcs_res));
558 		if (!iTCO_wdt_private.gcs) {
559 			ret = -EIO;
560 			goto unreg_gcs;
561 		}
562 	}
563 
564 	/* Check chipset's NO_REBOOT bit */
565 	if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
566 		pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n");
567 		ret = -ENODEV;	/* Cannot reset NO_REBOOT bit */
568 		goto unmap_gcs;
569 	}
570 
571 	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
572 	iTCO_wdt_set_NO_REBOOT_bit();
573 
574 	/* The TCO logic uses the TCO_EN bit in the SMI_EN register */
575 	if (!request_region(iTCO_wdt_private.smi_res->start,
576 			resource_size(iTCO_wdt_private.smi_res), dev->name)) {
577 		pr_err("I/O address 0x%04llx already in use, device disabled\n",
578 		       (u64)SMI_EN);
579 		ret = -EBUSY;
580 		goto unmap_gcs;
581 	}
582 	if (turn_SMI_watchdog_clear_off >= iTCO_wdt_private.iTCO_version) {
583 		/*
584 		 * Bit 13: TCO_EN -> 0
585 		 * Disables TCO logic generating an SMI#
586 		 */
587 		val32 = inl(SMI_EN);
588 		val32 &= 0xffffdfff;	/* Turn off SMI clearing watchdog */
589 		outl(val32, SMI_EN);
590 	}
591 
592 	if (!request_region(iTCO_wdt_private.tco_res->start,
593 			resource_size(iTCO_wdt_private.tco_res), dev->name)) {
594 		pr_err("I/O address 0x%04llx already in use, device disabled\n",
595 		       (u64)TCOBASE);
596 		ret = -EBUSY;
597 		goto unreg_smi;
598 	}
599 
600 	pr_info("Found a %s TCO device (Version=%d, TCOBASE=0x%04llx)\n",
601 		ich_info->name, ich_info->iTCO_version, (u64)TCOBASE);
602 
603 	/* Clear out the (probably old) status */
604 	outw(0x0008, TCO1_STS);	/* Clear the Time Out Status bit */
605 	outw(0x0002, TCO2_STS);	/* Clear SECOND_TO_STS bit */
606 	outw(0x0004, TCO2_STS);	/* Clear BOOT_STS bit */
607 
608 	/* Make sure the watchdog is not running */
609 	iTCO_wdt_stop();
610 
611 	/* Check that the heartbeat value is within it's range;
612 	   if not reset to the default */
613 	if (iTCO_wdt_set_heartbeat(heartbeat)) {
614 		iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT);
615 		pr_info("timeout value out of range, using %d\n", heartbeat);
616 	}
617 
618 	ret = misc_register(&iTCO_wdt_miscdev);
619 	if (ret != 0) {
620 		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
621 		       WATCHDOG_MINOR, ret);
622 		goto unreg_tco;
623 	}
624 
625 	pr_info("initialized. heartbeat=%d sec (nowayout=%d)\n",
626 		heartbeat, nowayout);
627 
628 	return 0;
629 
630 unreg_tco:
631 	release_region(iTCO_wdt_private.tco_res->start,
632 			resource_size(iTCO_wdt_private.tco_res));
633 unreg_smi:
634 	release_region(iTCO_wdt_private.smi_res->start,
635 			resource_size(iTCO_wdt_private.smi_res));
636 unmap_gcs:
637 	if (iTCO_wdt_private.iTCO_version == 2)
638 		iounmap(iTCO_wdt_private.gcs);
639 unreg_gcs:
640 	if (iTCO_wdt_private.iTCO_version == 2)
641 		release_mem_region(iTCO_wdt_private.gcs_res->start,
642 				resource_size(iTCO_wdt_private.gcs_res));
643 out:
644 	iTCO_wdt_private.tco_res = NULL;
645 	iTCO_wdt_private.smi_res = NULL;
646 	iTCO_wdt_private.gcs_res = NULL;
647 	iTCO_wdt_private.gcs = NULL;
648 
649 	return ret;
650 }
651 
652 static int __devexit iTCO_wdt_remove(struct platform_device *dev)
653 {
654 	if (iTCO_wdt_private.tco_res || iTCO_wdt_private.smi_res)
655 		iTCO_wdt_cleanup();
656 
657 	return 0;
658 }
659 
660 static void iTCO_wdt_shutdown(struct platform_device *dev)
661 {
662 	iTCO_wdt_stop();
663 }
664 
665 static struct platform_driver iTCO_wdt_driver = {
666 	.probe          = iTCO_wdt_probe,
667 	.remove         = __devexit_p(iTCO_wdt_remove),
668 	.shutdown       = iTCO_wdt_shutdown,
669 	.driver         = {
670 		.owner  = THIS_MODULE,
671 		.name   = DRV_NAME,
672 	},
673 };
674 
675 static int __init iTCO_wdt_init_module(void)
676 {
677 	int err;
678 
679 	pr_info("Intel TCO WatchDog Timer Driver v%s\n", DRV_VERSION);
680 
681 	err = platform_driver_register(&iTCO_wdt_driver);
682 	if (err)
683 		return err;
684 
685 	return 0;
686 }
687 
688 static void __exit iTCO_wdt_cleanup_module(void)
689 {
690 	platform_driver_unregister(&iTCO_wdt_driver);
691 	pr_info("Watchdog Module Unloaded\n");
692 }
693 
694 module_init(iTCO_wdt_init_module);
695 module_exit(iTCO_wdt_cleanup_module);
696 
697 MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>");
698 MODULE_DESCRIPTION("Intel TCO WatchDog Timer Driver");
699 MODULE_VERSION(DRV_VERSION);
700 MODULE_LICENSE("GPL");
701 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
702 MODULE_ALIAS("platform:" DRV_NAME);
703