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