xref: /openbmc/linux/drivers/watchdog/iTCO_wdt.c (revision 9ac8d3fb)
1 /*
2  *	intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets)
3  *
4  *	(c) Copyright 2006-2007 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  *	82801AA  (ICH)       : document number 290655-003, 290677-014,
18  *	82801AB  (ICHO)      : document number 290655-003, 290677-014,
19  *	82801BA  (ICH2)      : document number 290687-002, 298242-027,
20  *	82801BAM (ICH2-M)    : document number 290687-002, 298242-027,
21  *	82801CA  (ICH3-S)    : document number 290733-003, 290739-013,
22  *	82801CAM (ICH3-M)    : document number 290716-001, 290718-007,
23  *	82801DB  (ICH4)      : document number 290744-001, 290745-020,
24  *	82801DBM (ICH4-M)    : document number 252337-001, 252663-005,
25  *	82801E   (C-ICH)     : document number 273599-001, 273645-002,
26  *	82801EB  (ICH5)      : document number 252516-001, 252517-003,
27  *	82801ER  (ICH5R)     : document number 252516-001, 252517-003,
28  *	82801FB  (ICH6)      : document number 301473-002, 301474-007,
29  *	82801FR  (ICH6R)     : document number 301473-002, 301474-007,
30  *	82801FBM (ICH6-M)    : document number 301473-002, 301474-007,
31  *	82801FW  (ICH6W)     : document number 301473-001, 301474-007,
32  *	82801FRW (ICH6RW)    : document number 301473-001, 301474-007,
33  *	82801GB  (ICH7)      : document number 307013-002, 307014-009,
34  *	82801GR  (ICH7R)     : document number 307013-002, 307014-009,
35  *	82801GDH (ICH7DH)    : document number 307013-002, 307014-009,
36  *	82801GBM (ICH7-M)    : document number 307013-002, 307014-009,
37  *	82801GHM (ICH7-M DH) : document number 307013-002, 307014-009,
38  *	82801HB  (ICH8)      : document number 313056-003, 313057-009,
39  *	82801HR  (ICH8R)     : document number 313056-003, 313057-009,
40  *	82801HBM (ICH8M)     : document number 313056-003, 313057-009,
41  *	82801HH  (ICH8DH)    : document number 313056-003, 313057-009,
42  *	82801HO  (ICH8DO)    : document number 313056-003, 313057-009,
43  *	82801HEM (ICH8M-E)   : document number 313056-003, 313057-009,
44  *	82801IB  (ICH9)      : document number 316972-001, 316973-006,
45  *	82801IR  (ICH9R)     : document number 316972-001, 316973-006,
46  *	82801IH  (ICH9DH)    : document number 316972-001, 316973-006,
47  *	82801IO  (ICH9DO)    : document number 316972-001, 316973-006,
48  *	6300ESB  (6300ESB)   : document number 300641-003, 300884-010,
49  *	631xESB  (631xESB)   : document number 313082-001, 313075-005,
50  *	632xESB  (632xESB)   : document number 313082-001, 313075-005
51  */
52 
53 /*
54  *	Includes, defines, variables, module parameters, ...
55  */
56 
57 /* Module and version information */
58 #define DRV_NAME	"iTCO_wdt"
59 #define DRV_VERSION	"1.03"
60 #define DRV_RELDATE	"30-Apr-2008"
61 #define PFX		DRV_NAME ": "
62 
63 /* Includes */
64 #include <linux/module.h>		/* For module specific items */
65 #include <linux/moduleparam.h>		/* For new moduleparam's */
66 #include <linux/types.h>		/* For standard types (like size_t) */
67 #include <linux/errno.h>		/* For the -ENODEV/... values */
68 #include <linux/kernel.h>		/* For printk/panic/... */
69 #include <linux/miscdevice.h>		/* For MODULE_ALIAS_MISCDEV
70 							(WATCHDOG_MINOR) */
71 #include <linux/watchdog.h>		/* For the watchdog specific items */
72 #include <linux/init.h>			/* For __init/__exit/... */
73 #include <linux/fs.h>			/* For file operations */
74 #include <linux/platform_device.h>	/* For platform_driver framework */
75 #include <linux/pci.h>			/* For pci functions */
76 #include <linux/ioport.h>		/* For io-port access */
77 #include <linux/spinlock.h>		/* For spin_lock/spin_unlock/... */
78 #include <linux/uaccess.h>		/* For copy_to_user/put_user/... */
79 #include <linux/io.h>			/* For inb/outb/... */
80 
81 #include "iTCO_vendor.h"
82 
83 /* TCO related info */
84 enum iTCO_chipsets {
85 	TCO_ICH = 0,	/* ICH */
86 	TCO_ICH0,	/* ICH0 */
87 	TCO_ICH2,	/* ICH2 */
88 	TCO_ICH2M,	/* ICH2-M */
89 	TCO_ICH3,	/* ICH3-S */
90 	TCO_ICH3M,	/* ICH3-M */
91 	TCO_ICH4,	/* ICH4 */
92 	TCO_ICH4M,	/* ICH4-M */
93 	TCO_CICH,	/* C-ICH */
94 	TCO_ICH5,	/* ICH5 & ICH5R */
95 	TCO_6300ESB,	/* 6300ESB */
96 	TCO_ICH6,	/* ICH6 & ICH6R */
97 	TCO_ICH6M,	/* ICH6-M */
98 	TCO_ICH6W,	/* ICH6W & ICH6RW */
99 	TCO_ICH7,	/* ICH7 & ICH7R */
100 	TCO_ICH7M,	/* ICH7-M */
101 	TCO_ICH7MDH,	/* ICH7-M DH */
102 	TCO_ICH8,	/* ICH8 & ICH8R */
103 	TCO_ICH8ME,	/* ICH8M-E */
104 	TCO_ICH8DH,	/* ICH8DH */
105 	TCO_ICH8DO,	/* ICH8DO */
106 	TCO_ICH8M,	/* ICH8M */
107 	TCO_ICH9,	/* ICH9 */
108 	TCO_ICH9R,	/* ICH9R */
109 	TCO_ICH9DH,	/* ICH9DH */
110 	TCO_ICH9DO,	/* ICH9DO */
111 	TCO_631XESB,	/* 631xESB/632xESB */
112 };
113 
114 static struct {
115 	char *name;
116 	unsigned int iTCO_version;
117 } iTCO_chipset_info[] __devinitdata = {
118 	{"ICH", 1},
119 	{"ICH0", 1},
120 	{"ICH2", 1},
121 	{"ICH2-M", 1},
122 	{"ICH3-S", 1},
123 	{"ICH3-M", 1},
124 	{"ICH4", 1},
125 	{"ICH4-M", 1},
126 	{"C-ICH", 1},
127 	{"ICH5 or ICH5R", 1},
128 	{"6300ESB", 1},
129 	{"ICH6 or ICH6R", 2},
130 	{"ICH6-M", 2},
131 	{"ICH6W or ICH6RW", 2},
132 	{"ICH7 or ICH7R", 2},
133 	{"ICH7-M", 2},
134 	{"ICH7-M DH", 2},
135 	{"ICH8 or ICH8R", 2},
136 	{"ICH8M-E", 2},
137 	{"ICH8DH", 2},
138 	{"ICH8DO", 2},
139 	{"ICH8M", 2},
140 	{"ICH9", 2},
141 	{"ICH9R", 2},
142 	{"ICH9DH", 2},
143 	{"ICH9DO", 2},
144 	{"631xESB/632xESB", 2},
145 	{NULL, 0}
146 };
147 
148 #define ITCO_PCI_DEVICE(dev, data) 	\
149 	.vendor = PCI_VENDOR_ID_INTEL,	\
150 	.device = dev,			\
151 	.subvendor = PCI_ANY_ID,	\
152 	.subdevice = PCI_ANY_ID,	\
153 	.class = 0,			\
154 	.class_mask = 0,		\
155 	.driver_data = data
156 
157 /*
158  * This data only exists for exporting the supported PCI ids
159  * via MODULE_DEVICE_TABLE.  We do not actually register a
160  * pci_driver, because the I/O Controller Hub has also other
161  * functions that probably will be registered by other drivers.
162  */
163 static struct pci_device_id iTCO_wdt_pci_tbl[] = {
164 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0,	TCO_ICH)},
165 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0,	TCO_ICH0)},
166 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0,	TCO_ICH2)},
167 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_10,	TCO_ICH2M)},
168 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_0,	TCO_ICH3)},
169 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_12,	TCO_ICH3M)},
170 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_0,	TCO_ICH4)},
171 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_12,	TCO_ICH4M)},
172 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801E_0,		TCO_CICH)},
173 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801EB_0,	TCO_ICH5)},
174 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB_1,		TCO_6300ESB)},
175 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0,		TCO_ICH6)},
176 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1,		TCO_ICH6M)},
177 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2,		TCO_ICH6W)},
178 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0,		TCO_ICH7)},
179 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1,		TCO_ICH7M)},
180 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31,		TCO_ICH7MDH)},
181 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0,		TCO_ICH8)},
182 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1,		TCO_ICH8ME)},
183 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2,		TCO_ICH8DH)},
184 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3,		TCO_ICH8DO)},
185 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4,		TCO_ICH8M)},
186 	{ ITCO_PCI_DEVICE(0x2918,				TCO_ICH9)},
187 	{ ITCO_PCI_DEVICE(0x2916,				TCO_ICH9R)},
188 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2,		TCO_ICH9DH)},
189 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4,		TCO_ICH9DO)},
190 	{ ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0,		TCO_631XESB)},
191 	{ ITCO_PCI_DEVICE(0x2671,				TCO_631XESB)},
192 	{ ITCO_PCI_DEVICE(0x2672,				TCO_631XESB)},
193 	{ ITCO_PCI_DEVICE(0x2673,				TCO_631XESB)},
194 	{ ITCO_PCI_DEVICE(0x2674,				TCO_631XESB)},
195 	{ ITCO_PCI_DEVICE(0x2675,				TCO_631XESB)},
196 	{ ITCO_PCI_DEVICE(0x2676,				TCO_631XESB)},
197 	{ ITCO_PCI_DEVICE(0x2677,				TCO_631XESB)},
198 	{ ITCO_PCI_DEVICE(0x2678,				TCO_631XESB)},
199 	{ ITCO_PCI_DEVICE(0x2679,				TCO_631XESB)},
200 	{ ITCO_PCI_DEVICE(0x267a,				TCO_631XESB)},
201 	{ ITCO_PCI_DEVICE(0x267b,				TCO_631XESB)},
202 	{ ITCO_PCI_DEVICE(0x267c,				TCO_631XESB)},
203 	{ ITCO_PCI_DEVICE(0x267d,				TCO_631XESB)},
204 	{ ITCO_PCI_DEVICE(0x267e,				TCO_631XESB)},
205 	{ ITCO_PCI_DEVICE(0x267f,				TCO_631XESB)},
206 	{ 0, },			/* End of list */
207 };
208 MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
209 
210 /* Address definitions for the TCO */
211 /* TCO base address */
212 #define	TCOBASE		iTCO_wdt_private.ACPIBASE + 0x60
213 /* SMI Control and Enable Register */
214 #define	SMI_EN		iTCO_wdt_private.ACPIBASE + 0x30
215 
216 #define TCO_RLD		TCOBASE + 0x00	/* TCO Timer Reload and Curr. Value */
217 #define TCOv1_TMR	TCOBASE + 0x01	/* TCOv1 Timer Initial Value	*/
218 #define	TCO_DAT_IN	TCOBASE + 0x02	/* TCO Data In Register		*/
219 #define	TCO_DAT_OUT	TCOBASE + 0x03	/* TCO Data Out Register	*/
220 #define	TCO1_STS	TCOBASE + 0x04	/* TCO1 Status Register		*/
221 #define	TCO2_STS	TCOBASE + 0x06	/* TCO2 Status Register		*/
222 #define TCO1_CNT	TCOBASE + 0x08	/* TCO1 Control Register	*/
223 #define TCO2_CNT	TCOBASE + 0x0a	/* TCO2 Control Register	*/
224 #define TCOv2_TMR	TCOBASE + 0x12	/* TCOv2 Timer Initial Value	*/
225 
226 /* internal variables */
227 static unsigned long is_active;
228 static char expect_release;
229 static struct {		/* this is private data for the iTCO_wdt device */
230 	/* TCO version/generation */
231 	unsigned int iTCO_version;
232 	/* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */
233 	unsigned long ACPIBASE;
234 	/* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/
235 	unsigned long __iomem *gcs;
236 	/* the lock for io operations */
237 	spinlock_t io_lock;
238 	/* the PCI-device */
239 	struct pci_dev *pdev;
240 } iTCO_wdt_private;
241 
242 /* the watchdog platform device */
243 static struct platform_device *iTCO_wdt_platform_device;
244 
245 /* module parameters */
246 #define WATCHDOG_HEARTBEAT 30	/* 30 sec default heartbeat */
247 static int heartbeat = WATCHDOG_HEARTBEAT;  /* in seconds */
248 module_param(heartbeat, int, 0);
249 MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO v1) or 613 (TCO v2), default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
250 
251 static int nowayout = WATCHDOG_NOWAYOUT;
252 module_param(nowayout, int, 0);
253 MODULE_PARM_DESC(nowayout,
254 	"Watchdog cannot be stopped once started (default="
255 				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
256 
257 /*
258  * Some TCO specific functions
259  */
260 
261 static inline unsigned int seconds_to_ticks(int seconds)
262 {
263 	/* the internal timer is stored as ticks which decrement
264 	 * every 0.6 seconds */
265 	return (seconds * 10) / 6;
266 }
267 
268 static void iTCO_wdt_set_NO_REBOOT_bit(void)
269 {
270 	u32 val32;
271 
272 	/* Set the NO_REBOOT bit: this disables reboots */
273 	if (iTCO_wdt_private.iTCO_version == 2) {
274 		val32 = readl(iTCO_wdt_private.gcs);
275 		val32 |= 0x00000020;
276 		writel(val32, iTCO_wdt_private.gcs);
277 	} else if (iTCO_wdt_private.iTCO_version == 1) {
278 		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
279 		val32 |= 0x00000002;
280 		pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
281 	}
282 }
283 
284 static int iTCO_wdt_unset_NO_REBOOT_bit(void)
285 {
286 	int ret = 0;
287 	u32 val32;
288 
289 	/* Unset the NO_REBOOT bit: this enables reboots */
290 	if (iTCO_wdt_private.iTCO_version == 2) {
291 		val32 = readl(iTCO_wdt_private.gcs);
292 		val32 &= 0xffffffdf;
293 		writel(val32, iTCO_wdt_private.gcs);
294 
295 		val32 = readl(iTCO_wdt_private.gcs);
296 		if (val32 & 0x00000020)
297 			ret = -EIO;
298 	} else if (iTCO_wdt_private.iTCO_version == 1) {
299 		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
300 		val32 &= 0xfffffffd;
301 		pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
302 
303 		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
304 		if (val32 & 0x00000002)
305 			ret = -EIO;
306 	}
307 
308 	return ret; /* returns: 0 = OK, -EIO = Error */
309 }
310 
311 static int iTCO_wdt_start(void)
312 {
313 	unsigned int val;
314 
315 	spin_lock(&iTCO_wdt_private.io_lock);
316 
317 	iTCO_vendor_pre_start(iTCO_wdt_private.ACPIBASE, heartbeat);
318 
319 	/* disable chipset's NO_REBOOT bit */
320 	if (iTCO_wdt_unset_NO_REBOOT_bit()) {
321 		spin_unlock(&iTCO_wdt_private.io_lock);
322 		printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
323 		return -EIO;
324 	}
325 
326 	/* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */
327 	val = inw(TCO1_CNT);
328 	val &= 0xf7ff;
329 	outw(val, TCO1_CNT);
330 	val = inw(TCO1_CNT);
331 	spin_unlock(&iTCO_wdt_private.io_lock);
332 
333 	if (val & 0x0800)
334 		return -1;
335 	return 0;
336 }
337 
338 static int iTCO_wdt_stop(void)
339 {
340 	unsigned int val;
341 
342 	spin_lock(&iTCO_wdt_private.io_lock);
343 
344 	iTCO_vendor_pre_stop(iTCO_wdt_private.ACPIBASE);
345 
346 	/* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */
347 	val = inw(TCO1_CNT);
348 	val |= 0x0800;
349 	outw(val, TCO1_CNT);
350 	val = inw(TCO1_CNT);
351 
352 	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
353 	iTCO_wdt_set_NO_REBOOT_bit();
354 
355 	spin_unlock(&iTCO_wdt_private.io_lock);
356 
357 	if ((val & 0x0800) == 0)
358 		return -1;
359 	return 0;
360 }
361 
362 static int iTCO_wdt_keepalive(void)
363 {
364 	spin_lock(&iTCO_wdt_private.io_lock);
365 
366 	iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat);
367 
368 	/* Reload the timer by writing to the TCO Timer Counter register */
369 	if (iTCO_wdt_private.iTCO_version == 2)
370 		outw(0x01, TCO_RLD);
371 	else if (iTCO_wdt_private.iTCO_version == 1)
372 		outb(0x01, TCO_RLD);
373 
374 	spin_unlock(&iTCO_wdt_private.io_lock);
375 	return 0;
376 }
377 
378 static int iTCO_wdt_set_heartbeat(int t)
379 {
380 	unsigned int val16;
381 	unsigned char val8;
382 	unsigned int tmrval;
383 
384 	tmrval = seconds_to_ticks(t);
385 	/* from the specs: */
386 	/* "Values of 0h-3h are ignored and should not be attempted" */
387 	if (tmrval < 0x04)
388 		return -EINVAL;
389 	if (((iTCO_wdt_private.iTCO_version == 2) && (tmrval > 0x3ff)) ||
390 	    ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f)))
391 		return -EINVAL;
392 
393 	iTCO_vendor_pre_set_heartbeat(tmrval);
394 
395 	/* Write new heartbeat to watchdog */
396 	if (iTCO_wdt_private.iTCO_version == 2) {
397 		spin_lock(&iTCO_wdt_private.io_lock);
398 		val16 = inw(TCOv2_TMR);
399 		val16 &= 0xfc00;
400 		val16 |= tmrval;
401 		outw(val16, TCOv2_TMR);
402 		val16 = inw(TCOv2_TMR);
403 		spin_unlock(&iTCO_wdt_private.io_lock);
404 
405 		if ((val16 & 0x3ff) != tmrval)
406 			return -EINVAL;
407 	} else if (iTCO_wdt_private.iTCO_version == 1) {
408 		spin_lock(&iTCO_wdt_private.io_lock);
409 		val8 = inb(TCOv1_TMR);
410 		val8 &= 0xc0;
411 		val8 |= (tmrval & 0xff);
412 		outb(val8, TCOv1_TMR);
413 		val8 = inb(TCOv1_TMR);
414 		spin_unlock(&iTCO_wdt_private.io_lock);
415 
416 		if ((val8 & 0x3f) != tmrval)
417 			return -EINVAL;
418 	}
419 
420 	heartbeat = t;
421 	return 0;
422 }
423 
424 static int iTCO_wdt_get_timeleft(int *time_left)
425 {
426 	unsigned int val16;
427 	unsigned char val8;
428 
429 	/* read the TCO Timer */
430 	if (iTCO_wdt_private.iTCO_version == 2) {
431 		spin_lock(&iTCO_wdt_private.io_lock);
432 		val16 = inw(TCO_RLD);
433 		val16 &= 0x3ff;
434 		spin_unlock(&iTCO_wdt_private.io_lock);
435 
436 		*time_left = (val16 * 6) / 10;
437 	} else if (iTCO_wdt_private.iTCO_version == 1) {
438 		spin_lock(&iTCO_wdt_private.io_lock);
439 		val8 = inb(TCO_RLD);
440 		val8 &= 0x3f;
441 		spin_unlock(&iTCO_wdt_private.io_lock);
442 
443 		*time_left = (val8 * 6) / 10;
444 	} else
445 		return -EINVAL;
446 	return 0;
447 }
448 
449 /*
450  *	/dev/watchdog handling
451  */
452 
453 static int iTCO_wdt_open(struct inode *inode, struct file *file)
454 {
455 	/* /dev/watchdog can only be opened once */
456 	if (test_and_set_bit(0, &is_active))
457 		return -EBUSY;
458 
459 	/*
460 	 *      Reload and activate timer
461 	 */
462 	iTCO_wdt_keepalive();
463 	iTCO_wdt_start();
464 	return nonseekable_open(inode, file);
465 }
466 
467 static int iTCO_wdt_release(struct inode *inode, struct file *file)
468 {
469 	/*
470 	 *      Shut off the timer.
471 	 */
472 	if (expect_release == 42) {
473 		iTCO_wdt_stop();
474 	} else {
475 		printk(KERN_CRIT PFX
476 			"Unexpected close, not stopping watchdog!\n");
477 		iTCO_wdt_keepalive();
478 	}
479 	clear_bit(0, &is_active);
480 	expect_release = 0;
481 	return 0;
482 }
483 
484 static ssize_t iTCO_wdt_write(struct file *file, const char __user *data,
485 			      size_t len, loff_t *ppos)
486 {
487 	/* See if we got the magic character 'V' and reload the timer */
488 	if (len) {
489 		if (!nowayout) {
490 			size_t i;
491 
492 			/* note: just in case someone wrote the magic
493 			   character five months ago... */
494 			expect_release = 0;
495 
496 			/* scan to see whether or not we got the
497 			   magic character */
498 			for (i = 0; i != len; i++) {
499 				char c;
500 				if (get_user(c, data + i))
501 					return -EFAULT;
502 				if (c == 'V')
503 					expect_release = 42;
504 			}
505 		}
506 
507 		/* someone wrote to us, we should reload the timer */
508 		iTCO_wdt_keepalive();
509 	}
510 	return len;
511 }
512 
513 static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd,
514 							unsigned long arg)
515 {
516 	int new_options, retval = -EINVAL;
517 	int new_heartbeat;
518 	void __user *argp = (void __user *)arg;
519 	int __user *p = argp;
520 	static struct watchdog_info ident = {
521 		.options =		WDIOF_SETTIMEOUT |
522 					WDIOF_KEEPALIVEPING |
523 					WDIOF_MAGICCLOSE,
524 		.firmware_version =	0,
525 		.identity =		DRV_NAME,
526 	};
527 
528 	switch (cmd) {
529 	case WDIOC_GETSUPPORT:
530 		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
531 	case WDIOC_GETSTATUS:
532 	case WDIOC_GETBOOTSTATUS:
533 		return put_user(0, p);
534 
535 	case WDIOC_SETOPTIONS:
536 	{
537 		if (get_user(new_options, p))
538 			return -EFAULT;
539 
540 		if (new_options & WDIOS_DISABLECARD) {
541 			iTCO_wdt_stop();
542 			retval = 0;
543 		}
544 		if (new_options & WDIOS_ENABLECARD) {
545 			iTCO_wdt_keepalive();
546 			iTCO_wdt_start();
547 			retval = 0;
548 		}
549 		return retval;
550 	}
551 	case WDIOC_KEEPALIVE:
552 		iTCO_wdt_keepalive();
553 		return 0;
554 
555 	case WDIOC_SETTIMEOUT:
556 	{
557 		if (get_user(new_heartbeat, p))
558 			return -EFAULT;
559 		if (iTCO_wdt_set_heartbeat(new_heartbeat))
560 			return -EINVAL;
561 		iTCO_wdt_keepalive();
562 		/* Fall */
563 	}
564 	case WDIOC_GETTIMEOUT:
565 		return put_user(heartbeat, p);
566 	case WDIOC_GETTIMELEFT:
567 	{
568 		int time_left;
569 		if (iTCO_wdt_get_timeleft(&time_left))
570 			return -EINVAL;
571 		return put_user(time_left, p);
572 	}
573 	default:
574 		return -ENOTTY;
575 	}
576 }
577 
578 /*
579  *	Kernel Interfaces
580  */
581 
582 static const struct file_operations iTCO_wdt_fops = {
583 	.owner =		THIS_MODULE,
584 	.llseek =		no_llseek,
585 	.write =		iTCO_wdt_write,
586 	.unlocked_ioctl =	iTCO_wdt_ioctl,
587 	.open =			iTCO_wdt_open,
588 	.release =		iTCO_wdt_release,
589 };
590 
591 static struct miscdevice iTCO_wdt_miscdev = {
592 	.minor =	WATCHDOG_MINOR,
593 	.name =		"watchdog",
594 	.fops =		&iTCO_wdt_fops,
595 };
596 
597 /*
598  *	Init & exit routines
599  */
600 
601 static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
602 		const struct pci_device_id *ent, struct platform_device *dev)
603 {
604 	int ret;
605 	u32 base_address;
606 	unsigned long RCBA;
607 	unsigned long val32;
608 
609 	/*
610 	 *      Find the ACPI/PM base I/O address which is the base
611 	 *      for the TCO registers (TCOBASE=ACPIBASE + 0x60)
612 	 *      ACPIBASE is bits [15:7] from 0x40-0x43
613 	 */
614 	pci_read_config_dword(pdev, 0x40, &base_address);
615 	base_address &= 0x0000ff80;
616 	if (base_address == 0x00000000) {
617 		/* Something's wrong here, ACPIBASE has to be set */
618 		printk(KERN_ERR PFX "failed to get TCOBASE address\n");
619 		pci_dev_put(pdev);
620 		return -ENODEV;
621 	}
622 	iTCO_wdt_private.iTCO_version =
623 			iTCO_chipset_info[ent->driver_data].iTCO_version;
624 	iTCO_wdt_private.ACPIBASE = base_address;
625 	iTCO_wdt_private.pdev = pdev;
626 
627 	/* Get the Memory-Mapped GCS register, we need it for the
628 	   NO_REBOOT flag (TCO v2). To get access to it you have to
629 	   read RCBA from PCI Config space 0xf0 and use it as base.
630 	   GCS = RCBA + ICH6_GCS(0x3410). */
631 	if (iTCO_wdt_private.iTCO_version == 2) {
632 		pci_read_config_dword(pdev, 0xf0, &base_address);
633 		RCBA = base_address & 0xffffc000;
634 		iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4);
635 	}
636 
637 	/* Check chipset's NO_REBOOT bit */
638 	if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
639 		printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
640 		ret = -ENODEV;	/* Cannot reset NO_REBOOT bit */
641 		goto out;
642 	}
643 
644 	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
645 	iTCO_wdt_set_NO_REBOOT_bit();
646 
647 	/* Set the TCO_EN bit in SMI_EN register */
648 	if (!request_region(SMI_EN, 4, "iTCO_wdt")) {
649 		printk(KERN_ERR PFX
650 			"I/O address 0x%04lx already in use\n", SMI_EN);
651 		ret = -EIO;
652 		goto out;
653 	}
654 	val32 = inl(SMI_EN);
655 	val32 &= 0xffffdfff;	/* Turn off SMI clearing watchdog */
656 	outl(val32, SMI_EN);
657 	release_region(SMI_EN, 4);
658 
659 	/* The TCO I/O registers reside in a 32-byte range pointed to
660 	   by the TCOBASE value */
661 	if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) {
662 		printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n",
663 			TCOBASE);
664 		ret = -EIO;
665 		goto out;
666 	}
667 
668 	printk(KERN_INFO PFX
669 		"Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n",
670 			iTCO_chipset_info[ent->driver_data].name,
671 			iTCO_chipset_info[ent->driver_data].iTCO_version,
672 			TCOBASE);
673 
674 	/* Clear out the (probably old) status */
675 	outb(0, TCO1_STS);
676 	outb(3, TCO2_STS);
677 
678 	/* Make sure the watchdog is not running */
679 	iTCO_wdt_stop();
680 
681 	/* Check that the heartbeat value is within it's range;
682 	   if not reset to the default */
683 	if (iTCO_wdt_set_heartbeat(heartbeat)) {
684 		iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT);
685 		printk(KERN_INFO PFX "heartbeat value must be 2 < heartbeat < 39 (TCO v1) or 613 (TCO v2), using %d\n",
686 							heartbeat);
687 	}
688 
689 	ret = misc_register(&iTCO_wdt_miscdev);
690 	if (ret != 0) {
691 		printk(KERN_ERR PFX
692 			"cannot register miscdev on minor=%d (err=%d)\n",
693 							WATCHDOG_MINOR, ret);
694 		goto unreg_region;
695 	}
696 
697 	printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
698 							heartbeat, nowayout);
699 
700 	return 0;
701 
702 unreg_region:
703 	release_region(TCOBASE, 0x20);
704 out:
705 	if (iTCO_wdt_private.iTCO_version == 2)
706 		iounmap(iTCO_wdt_private.gcs);
707 	pci_dev_put(iTCO_wdt_private.pdev);
708 	iTCO_wdt_private.ACPIBASE = 0;
709 	return ret;
710 }
711 
712 static void __devexit iTCO_wdt_cleanup(void)
713 {
714 	/* Stop the timer before we leave */
715 	if (!nowayout)
716 		iTCO_wdt_stop();
717 
718 	/* Deregister */
719 	misc_deregister(&iTCO_wdt_miscdev);
720 	release_region(TCOBASE, 0x20);
721 	if (iTCO_wdt_private.iTCO_version == 2)
722 		iounmap(iTCO_wdt_private.gcs);
723 	pci_dev_put(iTCO_wdt_private.pdev);
724 	iTCO_wdt_private.ACPIBASE = 0;
725 }
726 
727 static int __devinit iTCO_wdt_probe(struct platform_device *dev)
728 {
729 	int found = 0;
730 	struct pci_dev *pdev = NULL;
731 	const struct pci_device_id *ent;
732 
733 	spin_lock_init(&iTCO_wdt_private.io_lock);
734 
735 	for_each_pci_dev(pdev) {
736 		ent = pci_match_id(iTCO_wdt_pci_tbl, pdev);
737 		if (ent) {
738 			if (!(iTCO_wdt_init(pdev, ent, dev))) {
739 				found++;
740 				break;
741 			}
742 		}
743 	}
744 
745 	if (!found) {
746 		printk(KERN_INFO PFX "No card detected\n");
747 		return -ENODEV;
748 	}
749 
750 	return 0;
751 }
752 
753 static int __devexit iTCO_wdt_remove(struct platform_device *dev)
754 {
755 	if (iTCO_wdt_private.ACPIBASE)
756 		iTCO_wdt_cleanup();
757 
758 	return 0;
759 }
760 
761 static void iTCO_wdt_shutdown(struct platform_device *dev)
762 {
763 	iTCO_wdt_stop();
764 }
765 
766 #define iTCO_wdt_suspend NULL
767 #define iTCO_wdt_resume  NULL
768 
769 static struct platform_driver iTCO_wdt_driver = {
770 	.probe          = iTCO_wdt_probe,
771 	.remove         = __devexit_p(iTCO_wdt_remove),
772 	.shutdown       = iTCO_wdt_shutdown,
773 	.suspend        = iTCO_wdt_suspend,
774 	.resume         = iTCO_wdt_resume,
775 	.driver         = {
776 		.owner  = THIS_MODULE,
777 		.name   = DRV_NAME,
778 	},
779 };
780 
781 static int __init iTCO_wdt_init_module(void)
782 {
783 	int err;
784 
785 	printk(KERN_INFO PFX "Intel TCO WatchDog Timer Driver v%s (%s)\n",
786 		DRV_VERSION, DRV_RELDATE);
787 
788 	err = platform_driver_register(&iTCO_wdt_driver);
789 	if (err)
790 		return err;
791 
792 	iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME,
793 								-1, NULL, 0);
794 	if (IS_ERR(iTCO_wdt_platform_device)) {
795 		err = PTR_ERR(iTCO_wdt_platform_device);
796 		goto unreg_platform_driver;
797 	}
798 
799 	return 0;
800 
801 unreg_platform_driver:
802 	platform_driver_unregister(&iTCO_wdt_driver);
803 	return err;
804 }
805 
806 static void __exit iTCO_wdt_cleanup_module(void)
807 {
808 	platform_device_unregister(iTCO_wdt_platform_device);
809 	platform_driver_unregister(&iTCO_wdt_driver);
810 	printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
811 }
812 
813 module_init(iTCO_wdt_init_module);
814 module_exit(iTCO_wdt_cleanup_module);
815 
816 MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>");
817 MODULE_DESCRIPTION("Intel TCO WatchDog Timer Driver");
818 MODULE_VERSION(DRV_VERSION);
819 MODULE_LICENSE("GPL");
820 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
821