• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/watchdog/
1/*
2 *	HP WatchDog Driver
3 *	based on
4 *
5 *	SoftDog	0.05:	A Software Watchdog Device
6 *
7 *	(c) Copyright 2007 Hewlett-Packard Development Company, L.P.
8 *	Thomas Mingarelli <thomas.mingarelli@hp.com>
9 *
10 *	This program is free software; you can redistribute it and/or
11 *	modify it under the terms of the GNU General Public License
12 *	version 2 as published by the Free Software Foundation
13 *
14 */
15
16#include <linux/device.h>
17#include <linux/fs.h>
18#include <linux/init.h>
19#include <linux/io.h>
20#include <linux/bitops.h>
21#include <linux/kernel.h>
22#include <linux/miscdevice.h>
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/pci.h>
26#include <linux/pci_ids.h>
27#include <linux/types.h>
28#include <linux/uaccess.h>
29#include <linux/watchdog.h>
30#ifdef CONFIG_HPWDT_NMI_DECODING
31#include <linux/dmi.h>
32#include <linux/spinlock.h>
33#include <linux/nmi.h>
34#include <linux/kdebug.h>
35#include <linux/notifier.h>
36#include <asm/cacheflush.h>
37#endif /* CONFIG_HPWDT_NMI_DECODING */
38
39#define HPWDT_VERSION			"1.2.0"
40#define SECS_TO_TICKS(secs)		((secs) * 1000 / 128)
41#define TICKS_TO_SECS(ticks)		((ticks) * 128 / 1000)
42#define HPWDT_MAX_TIMER			TICKS_TO_SECS(65535)
43#define DEFAULT_MARGIN			30
44
45static unsigned int soft_margin = DEFAULT_MARGIN;	/* in seconds */
46static unsigned int reload;			/* the computed soft_margin */
47static int nowayout = WATCHDOG_NOWAYOUT;
48static char expect_release;
49static unsigned long hpwdt_is_open;
50
51static void __iomem *pci_mem_addr;		/* the PCI-memory address */
52static unsigned long __iomem *hpwdt_timer_reg;
53static unsigned long __iomem *hpwdt_timer_con;
54
55static struct pci_device_id hpwdt_devices[] = {
56	{ PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB203) },	/* iLO2 */
57	{ PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3306) },	/* iLO3 */
58	{0},			/* terminate list */
59};
60MODULE_DEVICE_TABLE(pci, hpwdt_devices);
61
62#ifdef CONFIG_HPWDT_NMI_DECODING
63#define PCI_BIOS32_SD_VALUE		0x5F32335F	/* "_32_" */
64#define CRU_BIOS_SIGNATURE_VALUE	0x55524324
65#define PCI_BIOS32_PARAGRAPH_LEN	16
66#define PCI_ROM_BASE1			0x000F0000
67#define ROM_SIZE			0x10000
68
69struct bios32_service_dir {
70	u32 signature;
71	u32 entry_point;
72	u8 revision;
73	u8 length;
74	u8 checksum;
75	u8 reserved[5];
76};
77
78/* type 212 */
79struct smbios_cru64_info {
80	u8 type;
81	u8 byte_length;
82	u16 handle;
83	u32 signature;
84	u64 physical_address;
85	u32 double_length;
86	u32 double_offset;
87};
88#define SMBIOS_CRU64_INFORMATION	212
89
90struct cmn_registers {
91	union {
92		struct {
93			u8 ral;
94			u8 rah;
95			u16 rea2;
96		};
97		u32 reax;
98	} u1;
99	union {
100		struct {
101			u8 rbl;
102			u8 rbh;
103			u8 reb2l;
104			u8 reb2h;
105		};
106		u32 rebx;
107	} u2;
108	union {
109		struct {
110			u8 rcl;
111			u8 rch;
112			u16 rec2;
113		};
114		u32 recx;
115	} u3;
116	union {
117		struct {
118			u8 rdl;
119			u8 rdh;
120			u16 red2;
121		};
122		u32 redx;
123	} u4;
124
125	u32 resi;
126	u32 redi;
127	u16 rds;
128	u16 res;
129	u32 reflags;
130}  __attribute__((packed));
131
132static unsigned int hpwdt_nmi_decoding;
133static unsigned int allow_kdump;
134static unsigned int priority;		/* hpwdt at end of die_notify list */
135static DEFINE_SPINLOCK(rom_lock);
136static void *cru_rom_addr;
137static struct cmn_registers cmn_regs;
138
139extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
140						unsigned long *pRomEntry);
141
142#ifdef CONFIG_X86_32
143/* --32 Bit Bios------------------------------------------------------------ */
144
145#define HPWDT_ARCH	32
146
147asm(".text                          \n\t"
148    ".align 4                       \n"
149    "asminline_call:                \n\t"
150    "pushl       %ebp               \n\t"
151    "movl        %esp, %ebp         \n\t"
152    "pusha                          \n\t"
153    "pushf                          \n\t"
154    "push        %es                \n\t"
155    "push        %ds                \n\t"
156    "pop         %es                \n\t"
157    "movl        8(%ebp),%eax       \n\t"
158    "movl        4(%eax),%ebx       \n\t"
159    "movl        8(%eax),%ecx       \n\t"
160    "movl        12(%eax),%edx      \n\t"
161    "movl        16(%eax),%esi      \n\t"
162    "movl        20(%eax),%edi      \n\t"
163    "movl        (%eax),%eax        \n\t"
164    "push        %cs                \n\t"
165    "call        *12(%ebp)          \n\t"
166    "pushf                          \n\t"
167    "pushl       %eax               \n\t"
168    "movl        8(%ebp),%eax       \n\t"
169    "movl        %ebx,4(%eax)       \n\t"
170    "movl        %ecx,8(%eax)       \n\t"
171    "movl        %edx,12(%eax)      \n\t"
172    "movl        %esi,16(%eax)      \n\t"
173    "movl        %edi,20(%eax)      \n\t"
174    "movw        %ds,24(%eax)       \n\t"
175    "movw        %es,26(%eax)       \n\t"
176    "popl        %ebx               \n\t"
177    "movl        %ebx,(%eax)        \n\t"
178    "popl        %ebx               \n\t"
179    "movl        %ebx,28(%eax)      \n\t"
180    "pop         %es                \n\t"
181    "popf                           \n\t"
182    "popa                           \n\t"
183    "leave                          \n\t"
184    "ret                            \n\t"
185    ".previous");
186
187
188/*
189 *	cru_detect
190 *
191 *	Routine Description:
192 *	This function uses the 32-bit BIOS Service Directory record to
193 *	search for a $CRU record.
194 *
195 *	Return Value:
196 *	0        :  SUCCESS
197 *	<0       :  FAILURE
198 */
199static int __devinit cru_detect(unsigned long map_entry,
200	unsigned long map_offset)
201{
202	void *bios32_map;
203	unsigned long *bios32_entrypoint;
204	unsigned long cru_physical_address;
205	unsigned long cru_length;
206	unsigned long physical_bios_base = 0;
207	unsigned long physical_bios_offset = 0;
208	int retval = -ENODEV;
209
210	bios32_map = ioremap(map_entry, (2 * PAGE_SIZE));
211
212	if (bios32_map == NULL)
213		return -ENODEV;
214
215	bios32_entrypoint = bios32_map + map_offset;
216
217	cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;
218
219	asminline_call(&cmn_regs, bios32_entrypoint);
220
221	if (cmn_regs.u1.ral != 0) {
222		printk(KERN_WARNING
223			"hpwdt: Call succeeded but with an error: 0x%x\n",
224			cmn_regs.u1.ral);
225	} else {
226		physical_bios_base = cmn_regs.u2.rebx;
227		physical_bios_offset = cmn_regs.u4.redx;
228		cru_length = cmn_regs.u3.recx;
229		cru_physical_address =
230			physical_bios_base + physical_bios_offset;
231
232		/* If the values look OK, then map it in. */
233		if ((physical_bios_base + physical_bios_offset)) {
234			cru_rom_addr =
235				ioremap(cru_physical_address, cru_length);
236			if (cru_rom_addr)
237				retval = 0;
238		}
239
240		printk(KERN_DEBUG "hpwdt: CRU Base Address:   0x%lx\n",
241			physical_bios_base);
242		printk(KERN_DEBUG "hpwdt: CRU Offset Address: 0x%lx\n",
243			physical_bios_offset);
244		printk(KERN_DEBUG "hpwdt: CRU Length:         0x%lx\n",
245			cru_length);
246		printk(KERN_DEBUG "hpwdt: CRU Mapped Address: %p\n",
247			&cru_rom_addr);
248	}
249	iounmap(bios32_map);
250	return retval;
251}
252
253/*
254 *	bios_checksum
255 */
256static int __devinit bios_checksum(const char __iomem *ptr, int len)
257{
258	char sum = 0;
259	int i;
260
261	/*
262	 * calculate checksum of size bytes. This should add up
263	 * to zero if we have a valid header.
264	 */
265	for (i = 0; i < len; i++)
266		sum += ptr[i];
267
268	return ((sum == 0) && (len > 0));
269}
270
271/*
272 *	bios32_present
273 *
274 *	Routine Description:
275 *	This function finds the 32-bit BIOS Service Directory
276 *
277 *	Return Value:
278 *	0        :  SUCCESS
279 *	<0       :  FAILURE
280 */
281static int __devinit bios32_present(const char __iomem *p)
282{
283	struct bios32_service_dir *bios_32_ptr;
284	int length;
285	unsigned long map_entry, map_offset;
286
287	bios_32_ptr = (struct bios32_service_dir *) p;
288
289	/*
290	 * Search for signature by checking equal to the swizzled value
291	 * instead of calling another routine to perform a strcmp.
292	 */
293	if (bios_32_ptr->signature == PCI_BIOS32_SD_VALUE) {
294		length = bios_32_ptr->length * PCI_BIOS32_PARAGRAPH_LEN;
295		if (bios_checksum(p, length)) {
296			/*
297			 * According to the spec, we're looking for the
298			 * first 4KB-aligned address below the entrypoint
299			 * listed in the header. The Service Directory code
300			 * is guaranteed to occupy no more than 2 4KB pages.
301			 */
302			map_entry = bios_32_ptr->entry_point & ~(PAGE_SIZE - 1);
303			map_offset = bios_32_ptr->entry_point - map_entry;
304
305			return cru_detect(map_entry, map_offset);
306		}
307	}
308	return -ENODEV;
309}
310
311static int __devinit detect_cru_service(void)
312{
313	char __iomem *p, *q;
314	int rc = -1;
315
316	/*
317	 * Search from 0x0f0000 through 0x0fffff, inclusive.
318	 */
319	p = ioremap(PCI_ROM_BASE1, ROM_SIZE);
320	if (p == NULL)
321		return -ENOMEM;
322
323	for (q = p; q < p + ROM_SIZE; q += 16) {
324		rc = bios32_present(q);
325		if (!rc)
326			break;
327	}
328	iounmap(p);
329	return rc;
330}
331/* ------------------------------------------------------------------------- */
332#endif /* CONFIG_X86_32 */
333#ifdef CONFIG_X86_64
334/* --64 Bit Bios------------------------------------------------------------ */
335
336#define HPWDT_ARCH	64
337
338asm(".text                      \n\t"
339    ".align 4                   \n"
340    "asminline_call:            \n\t"
341    "pushq      %rbp            \n\t"
342    "movq       %rsp, %rbp      \n\t"
343    "pushq      %rax            \n\t"
344    "pushq      %rbx            \n\t"
345    "pushq      %rdx            \n\t"
346    "pushq      %r12            \n\t"
347    "pushq      %r9             \n\t"
348    "movq       %rsi, %r12      \n\t"
349    "movq       %rdi, %r9       \n\t"
350    "movl       4(%r9),%ebx     \n\t"
351    "movl       8(%r9),%ecx     \n\t"
352    "movl       12(%r9),%edx    \n\t"
353    "movl       16(%r9),%esi    \n\t"
354    "movl       20(%r9),%edi    \n\t"
355    "movl       (%r9),%eax      \n\t"
356    "call       *%r12           \n\t"
357    "pushfq                     \n\t"
358    "popq        %r12           \n\t"
359    "movl       %eax, (%r9)     \n\t"
360    "movl       %ebx, 4(%r9)    \n\t"
361    "movl       %ecx, 8(%r9)    \n\t"
362    "movl       %edx, 12(%r9)   \n\t"
363    "movl       %esi, 16(%r9)   \n\t"
364    "movl       %edi, 20(%r9)   \n\t"
365    "movq       %r12, %rax      \n\t"
366    "movl       %eax, 28(%r9)   \n\t"
367    "popq       %r9             \n\t"
368    "popq       %r12            \n\t"
369    "popq       %rdx            \n\t"
370    "popq       %rbx            \n\t"
371    "popq       %rax            \n\t"
372    "leave                      \n\t"
373    "ret                        \n\t"
374    ".previous");
375
376/*
377 *	dmi_find_cru
378 *
379 *	Routine Description:
380 *	This function checks whether or not a SMBIOS/DMI record is
381 *	the 64bit CRU info or not
382 */
383static void __devinit dmi_find_cru(const struct dmi_header *dm, void *dummy)
384{
385	struct smbios_cru64_info *smbios_cru64_ptr;
386	unsigned long cru_physical_address;
387
388	if (dm->type == SMBIOS_CRU64_INFORMATION) {
389		smbios_cru64_ptr = (struct smbios_cru64_info *) dm;
390		if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) {
391			cru_physical_address =
392				smbios_cru64_ptr->physical_address +
393				smbios_cru64_ptr->double_offset;
394			cru_rom_addr = ioremap(cru_physical_address,
395				smbios_cru64_ptr->double_length);
396			set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK,
397				smbios_cru64_ptr->double_length >> PAGE_SHIFT);
398		}
399	}
400}
401
402static int __devinit detect_cru_service(void)
403{
404	cru_rom_addr = NULL;
405
406	dmi_walk(dmi_find_cru, NULL);
407
408	/* if cru_rom_addr has been set then we found a CRU service */
409	return ((cru_rom_addr != NULL) ? 0 : -ENODEV);
410}
411/* ------------------------------------------------------------------------- */
412#endif /* CONFIG_X86_64 */
413#endif /* CONFIG_HPWDT_NMI_DECODING */
414
415/*
416 *	Watchdog operations
417 */
418static void hpwdt_start(void)
419{
420	reload = SECS_TO_TICKS(soft_margin);
421	iowrite16(reload, hpwdt_timer_reg);
422	iowrite16(0x85, hpwdt_timer_con);
423}
424
425static void hpwdt_stop(void)
426{
427	unsigned long data;
428
429	data = ioread16(hpwdt_timer_con);
430	data &= 0xFE;
431	iowrite16(data, hpwdt_timer_con);
432}
433
434static void hpwdt_ping(void)
435{
436	iowrite16(reload, hpwdt_timer_reg);
437}
438
439static int hpwdt_change_timer(int new_margin)
440{
441	if (new_margin < 1 || new_margin > HPWDT_MAX_TIMER) {
442		printk(KERN_WARNING
443			"hpwdt: New value passed in is invalid: %d seconds.\n",
444			new_margin);
445		return -EINVAL;
446	}
447
448	soft_margin = new_margin;
449	printk(KERN_DEBUG
450		"hpwdt: New timer passed in is %d seconds.\n",
451		new_margin);
452	reload = SECS_TO_TICKS(soft_margin);
453
454	return 0;
455}
456
457static int hpwdt_time_left(void)
458{
459	return TICKS_TO_SECS(ioread16(hpwdt_timer_reg));
460}
461
462#ifdef CONFIG_HPWDT_NMI_DECODING
463/*
464 *	NMI Handler
465 */
466static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
467				void *data)
468{
469	unsigned long rom_pl;
470	static int die_nmi_called;
471
472	if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI)
473		goto out;
474
475	if (!hpwdt_nmi_decoding)
476		goto out;
477
478	spin_lock_irqsave(&rom_lock, rom_pl);
479	if (!die_nmi_called)
480		asminline_call(&cmn_regs, cru_rom_addr);
481	die_nmi_called = 1;
482	spin_unlock_irqrestore(&rom_lock, rom_pl);
483	if (cmn_regs.u1.ral == 0) {
484		printk(KERN_WARNING "hpwdt: An NMI occurred, "
485			"but unable to determine source.\n");
486	} else {
487		if (allow_kdump)
488			hpwdt_stop();
489		panic("An NMI occurred, please see the Integrated "
490			"Management Log for details.\n");
491	}
492out:
493	return NOTIFY_OK;
494}
495#endif /* CONFIG_HPWDT_NMI_DECODING */
496
497/*
498 *	/dev/watchdog handling
499 */
500static int hpwdt_open(struct inode *inode, struct file *file)
501{
502	/* /dev/watchdog can only be opened once */
503	if (test_and_set_bit(0, &hpwdt_is_open))
504		return -EBUSY;
505
506	/* Start the watchdog */
507	hpwdt_start();
508	hpwdt_ping();
509
510	return nonseekable_open(inode, file);
511}
512
513static int hpwdt_release(struct inode *inode, struct file *file)
514{
515	/* Stop the watchdog */
516	if (expect_release == 42) {
517		hpwdt_stop();
518	} else {
519		printk(KERN_CRIT
520			"hpwdt: Unexpected close, not stopping watchdog!\n");
521		hpwdt_ping();
522	}
523
524	expect_release = 0;
525
526	/* /dev/watchdog is being closed, make sure it can be re-opened */
527	clear_bit(0, &hpwdt_is_open);
528
529	return 0;
530}
531
532static ssize_t hpwdt_write(struct file *file, const char __user *data,
533	size_t len, loff_t *ppos)
534{
535	/* See if we got the magic character 'V' and reload the timer */
536	if (len) {
537		if (!nowayout) {
538			size_t i;
539
540			/* note: just in case someone wrote the magic character
541			 * five months ago... */
542			expect_release = 0;
543
544			/* scan to see whether or not we got the magic char. */
545			for (i = 0; i != len; i++) {
546				char c;
547				if (get_user(c, data + i))
548					return -EFAULT;
549				if (c == 'V')
550					expect_release = 42;
551			}
552		}
553
554		/* someone wrote to us, we should reload the timer */
555		hpwdt_ping();
556	}
557
558	return len;
559}
560
561static const struct watchdog_info ident = {
562	.options = WDIOF_SETTIMEOUT |
563		   WDIOF_KEEPALIVEPING |
564		   WDIOF_MAGICCLOSE,
565	.identity = "HP iLO2+ HW Watchdog Timer",
566};
567
568static long hpwdt_ioctl(struct file *file, unsigned int cmd,
569	unsigned long arg)
570{
571	void __user *argp = (void __user *)arg;
572	int __user *p = argp;
573	int new_margin;
574	int ret = -ENOTTY;
575
576	switch (cmd) {
577	case WDIOC_GETSUPPORT:
578		ret = 0;
579		if (copy_to_user(argp, &ident, sizeof(ident)))
580			ret = -EFAULT;
581		break;
582
583	case WDIOC_GETSTATUS:
584	case WDIOC_GETBOOTSTATUS:
585		ret = put_user(0, p);
586		break;
587
588	case WDIOC_KEEPALIVE:
589		hpwdt_ping();
590		ret = 0;
591		break;
592
593	case WDIOC_SETTIMEOUT:
594		ret = get_user(new_margin, p);
595		if (ret)
596			break;
597
598		ret = hpwdt_change_timer(new_margin);
599		if (ret)
600			break;
601
602		hpwdt_ping();
603		/* Fall */
604	case WDIOC_GETTIMEOUT:
605		ret = put_user(soft_margin, p);
606		break;
607
608	case WDIOC_GETTIMELEFT:
609		ret = put_user(hpwdt_time_left(), p);
610		break;
611	}
612	return ret;
613}
614
615/*
616 *	Kernel interfaces
617 */
618static const struct file_operations hpwdt_fops = {
619	.owner = THIS_MODULE,
620	.llseek = no_llseek,
621	.write = hpwdt_write,
622	.unlocked_ioctl = hpwdt_ioctl,
623	.open = hpwdt_open,
624	.release = hpwdt_release,
625};
626
627static struct miscdevice hpwdt_miscdev = {
628	.minor = WATCHDOG_MINOR,
629	.name = "watchdog",
630	.fops = &hpwdt_fops,
631};
632
633#ifdef CONFIG_HPWDT_NMI_DECODING
634static struct notifier_block die_notifier = {
635	.notifier_call = hpwdt_pretimeout,
636	.priority = 0,
637};
638#endif /* CONFIG_HPWDT_NMI_DECODING */
639
640/*
641 *	Init & Exit
642 */
643
644#ifdef CONFIG_HPWDT_NMI_DECODING
645#ifdef ARCH_HAS_NMI_WATCHDOG
646static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev)
647{
648	/*
649	 * If nmi_watchdog is turned off then we can turn on
650	 * our nmi decoding capability.
651	 */
652	if (!nmi_watchdog_active())
653		hpwdt_nmi_decoding = 1;
654	else
655		dev_warn(&dev->dev, "NMI decoding is disabled. To enable this "
656			"functionality you must reboot with nmi_watchdog=0 "
657			"and load the hpwdt driver with priority=1.\n");
658}
659#else
660static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev)
661{
662	dev_warn(&dev->dev, "NMI decoding is disabled. "
663		"Your kernel does not support a NMI Watchdog.\n");
664}
665#endif /* ARCH_HAS_NMI_WATCHDOG */
666
667static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev)
668{
669	int retval;
670
671	/*
672	 * We need to map the ROM to get the CRU service.
673	 * For 32 bit Operating Systems we need to go through the 32 Bit
674	 * BIOS Service Directory
675	 * For 64 bit Operating Systems we get that service through SMBIOS.
676	 */
677	retval = detect_cru_service();
678	if (retval < 0) {
679		dev_warn(&dev->dev,
680			"Unable to detect the %d Bit CRU Service.\n",
681			HPWDT_ARCH);
682		return retval;
683	}
684
685	/*
686	 * We know this is the only CRU call we need to make so lets keep as
687	 * few instructions as possible once the NMI comes in.
688	 */
689	cmn_regs.u1.rah = 0x0D;
690	cmn_regs.u1.ral = 0x02;
691
692	/*
693	 * If the priority is set to 1, then we will be put first on the
694	 * die notify list to handle a critical NMI. The default is to
695	 * be last so other users of the NMI signal can function.
696	 */
697	if (priority)
698		die_notifier.priority = 0x7FFFFFFF;
699
700	retval = register_die_notifier(&die_notifier);
701	if (retval != 0) {
702		dev_warn(&dev->dev,
703			"Unable to register a die notifier (err=%d).\n",
704			retval);
705		if (cru_rom_addr)
706			iounmap(cru_rom_addr);
707	}
708
709	dev_info(&dev->dev,
710			"HP Watchdog Timer Driver: NMI decoding initialized"
711			", allow kernel dump: %s (default = 0/OFF)"
712			", priority: %s (default = 0/LAST).\n",
713			(allow_kdump == 0) ? "OFF" : "ON",
714			(priority == 0) ? "LAST" : "FIRST");
715	return 0;
716}
717
718static void __devexit hpwdt_exit_nmi_decoding(void)
719{
720	unregister_die_notifier(&die_notifier);
721	if (cru_rom_addr)
722		iounmap(cru_rom_addr);
723}
724#else /* !CONFIG_HPWDT_NMI_DECODING */
725static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev)
726{
727}
728
729static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev)
730{
731	return 0;
732}
733
734static void __devexit hpwdt_exit_nmi_decoding(void)
735{
736}
737#endif /* CONFIG_HPWDT_NMI_DECODING */
738
739static int __devinit hpwdt_init_one(struct pci_dev *dev,
740					const struct pci_device_id *ent)
741{
742	int retval;
743
744	/*
745	 * Check if we can do NMI decoding or not
746	 */
747	hpwdt_check_nmi_decoding(dev);
748
749	/*
750	 * First let's find out if we are on an iLO2+ server. We will
751	 * not run on a legacy ASM box.
752	 * So we only support the G5 ProLiant servers and higher.
753	 */
754	if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) {
755		dev_warn(&dev->dev,
756			"This server does not have an iLO2+ ASIC.\n");
757		return -ENODEV;
758	}
759
760	if (pci_enable_device(dev)) {
761		dev_warn(&dev->dev,
762			"Not possible to enable PCI Device: 0x%x:0x%x.\n",
763			ent->vendor, ent->device);
764		return -ENODEV;
765	}
766
767	pci_mem_addr = pci_iomap(dev, 1, 0x80);
768	if (!pci_mem_addr) {
769		dev_warn(&dev->dev,
770			"Unable to detect the iLO2+ server memory.\n");
771		retval = -ENOMEM;
772		goto error_pci_iomap;
773	}
774	hpwdt_timer_reg = pci_mem_addr + 0x70;
775	hpwdt_timer_con = pci_mem_addr + 0x72;
776
777	/* Make sure that we have a valid soft_margin */
778	if (hpwdt_change_timer(soft_margin))
779		hpwdt_change_timer(DEFAULT_MARGIN);
780
781	/* Initialize NMI Decoding functionality */
782	retval = hpwdt_init_nmi_decoding(dev);
783	if (retval != 0)
784		goto error_init_nmi_decoding;
785
786	retval = misc_register(&hpwdt_miscdev);
787	if (retval < 0) {
788		dev_warn(&dev->dev,
789			"Unable to register miscdev on minor=%d (err=%d).\n",
790			WATCHDOG_MINOR, retval);
791		goto error_misc_register;
792	}
793
794	dev_info(&dev->dev, "HP Watchdog Timer Driver: %s"
795			", timer margin: %d seconds (nowayout=%d).\n",
796			HPWDT_VERSION, soft_margin, nowayout);
797	return 0;
798
799error_misc_register:
800	hpwdt_exit_nmi_decoding();
801error_init_nmi_decoding:
802	pci_iounmap(dev, pci_mem_addr);
803error_pci_iomap:
804	pci_disable_device(dev);
805	return retval;
806}
807
808static void __devexit hpwdt_exit(struct pci_dev *dev)
809{
810	if (!nowayout)
811		hpwdt_stop();
812
813	misc_deregister(&hpwdt_miscdev);
814	hpwdt_exit_nmi_decoding();
815	pci_iounmap(dev, pci_mem_addr);
816	pci_disable_device(dev);
817}
818
819static struct pci_driver hpwdt_driver = {
820	.name = "hpwdt",
821	.id_table = hpwdt_devices,
822	.probe = hpwdt_init_one,
823	.remove = __devexit_p(hpwdt_exit),
824};
825
826static void __exit hpwdt_cleanup(void)
827{
828	pci_unregister_driver(&hpwdt_driver);
829}
830
831static int __init hpwdt_init(void)
832{
833	return pci_register_driver(&hpwdt_driver);
834}
835
836MODULE_AUTHOR("Tom Mingarelli");
837MODULE_DESCRIPTION("hp watchdog driver");
838MODULE_LICENSE("GPL");
839MODULE_VERSION(HPWDT_VERSION);
840MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
841
842module_param(soft_margin, int, 0);
843MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds");
844
845module_param(nowayout, int, 0);
846MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
847		__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
848
849#ifdef CONFIG_HPWDT_NMI_DECODING
850module_param(allow_kdump, int, 0);
851MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs");
852
853module_param(priority, int, 0);
854MODULE_PARM_DESC(priority, "The hpwdt driver handles NMIs first or last"
855		" (default = 0/Last)\n");
856#endif /* !CONFIG_HPWDT_NMI_DECODING */
857
858module_init(hpwdt_init);
859module_exit(hpwdt_cleanup);
860