aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/Kconfig18
-rw-r--r--drivers/watchdog/wdt_pci.c122
2 files changed, 66 insertions, 74 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index e8d45b6ccef8..b1ccc04f3c9a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1007,24 +1007,16 @@ config WDTPCI
1007 ---help--- 1007 ---help---
1008 If you have a PCI-WDT500/501 watchdog board, say Y here, otherwise N. 1008 If you have a PCI-WDT500/501 watchdog board, say Y here, otherwise N.
1009 1009
1010 To compile this driver as a module, choose M here: the 1010 If you have a PCI-WDT501 watchdog board then you can enable the
1011 module will be called wdt_pci. 1011 temperature sensor by setting the type parameter to 501.
1012
1013config WDT_501_PCI
1014 bool "PCI-WDT501 features"
1015 depends on WDTPCI
1016 help
1017 Saying Y here and creating a character special file /dev/temperature
1018 with major number 10 and minor number 131 ("man mknod") will give
1019 you a thermometer inside your computer: reading from
1020 /dev/temperature yields one byte, the temperature in degrees
1021 Fahrenheit. This works only if you have a PCI-WDT501 watchdog board
1022 installed.
1023 1012
1024 If you want to enable the Fan Tachometer on the PCI-WDT501, then you 1013 If you want to enable the Fan Tachometer on the PCI-WDT501, then you
1025 can do this via the tachometer parameter. Only do this if you have a 1014 can do this via the tachometer parameter. Only do this if you have a
1026 fan tachometer actually set up. 1015 fan tachometer actually set up.
1027 1016
1017 To compile this driver as a module, choose M here: the
1018 module will be called wdt_pci.
1019
1028# 1020#
1029# USB-based Watchdog Cards 1021# USB-based Watchdog Cards
1030# 1022#
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index c45839a4a34d..7a1bdc7c95a9 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -2,7 +2,7 @@
2 * Industrial Computer Source PCI-WDT500/501 driver 2 * Industrial Computer Source PCI-WDT500/501 driver
3 * 3 *
4 * (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>, 4 * (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -99,14 +99,16 @@ MODULE_PARM_DESC(nowayout,
99 "Watchdog cannot be stopped once started (default=" 99 "Watchdog cannot be stopped once started (default="
100 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 100 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
101 101
102#ifdef CONFIG_WDT_501_PCI
103/* Support for the Fan Tachometer on the PCI-WDT501 */ 102/* Support for the Fan Tachometer on the PCI-WDT501 */
104static int tachometer; 103static int tachometer;
105
106module_param(tachometer, int, 0); 104module_param(tachometer, int, 0);
107MODULE_PARM_DESC(tachometer, 105MODULE_PARM_DESC(tachometer,
108 "PCI-WDT501 Fan Tachometer support (0=disable, default=0)"); 106 "PCI-WDT501 Fan Tachometer support (0=disable, default=0)");
109#endif /* CONFIG_WDT_501_PCI */ 107
108static int type = 500;
109module_param(type, int, 0);
110MODULE_PARM_DESC(type,
111 "PCI-WDT501 Card type (500 or 501 , default=500)");
110 112
111/* 113/*
112 * Programming support 114 * Programming support
@@ -266,22 +268,21 @@ static int wdtpci_get_status(int *status)
266 *status |= WDIOF_EXTERN1; 268 *status |= WDIOF_EXTERN1;
267 if (new_status & WDC_SR_ISII1) 269 if (new_status & WDC_SR_ISII1)
268 *status |= WDIOF_EXTERN2; 270 *status |= WDIOF_EXTERN2;
269#ifdef CONFIG_WDT_501_PCI 271 if (type == 501) {
270 if (!(new_status & WDC_SR_TGOOD)) 272 if (!(new_status & WDC_SR_TGOOD))
271 *status |= WDIOF_OVERHEAT; 273 *status |= WDIOF_OVERHEAT;
272 if (!(new_status & WDC_SR_PSUOVER)) 274 if (!(new_status & WDC_SR_PSUOVER))
273 *status |= WDIOF_POWEROVER; 275 *status |= WDIOF_POWEROVER;
274 if (!(new_status & WDC_SR_PSUUNDR)) 276 if (!(new_status & WDC_SR_PSUUNDR))
275 *status |= WDIOF_POWERUNDER; 277 *status |= WDIOF_POWERUNDER;
276 if (tachometer) { 278 if (tachometer) {
277 if (!(new_status & WDC_SR_FANGOOD)) 279 if (!(new_status & WDC_SR_FANGOOD))
278 *status |= WDIOF_FANFAULT; 280 *status |= WDIOF_FANFAULT;
281 }
279 } 282 }
280#endif /* CONFIG_WDT_501_PCI */
281 return 0; 283 return 0;
282} 284}
283 285
284#ifdef CONFIG_WDT_501_PCI
285/** 286/**
286 * wdtpci_get_temperature: 287 * wdtpci_get_temperature:
287 * 288 *
@@ -300,7 +301,6 @@ static int wdtpci_get_temperature(int *temperature)
300 *temperature = (c * 11 / 15) + 7; 301 *temperature = (c * 11 / 15) + 7;
301 return 0; 302 return 0;
302} 303}
303#endif /* CONFIG_WDT_501_PCI */
304 304
305/** 305/**
306 * wdtpci_interrupt: 306 * wdtpci_interrupt:
@@ -327,22 +327,22 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id)
327 327
328 printk(KERN_CRIT PFX "status %d\n", status); 328 printk(KERN_CRIT PFX "status %d\n", status);
329 329
330#ifdef CONFIG_WDT_501_PCI 330 if (type == 501) {
331 if (!(status & WDC_SR_TGOOD)) { 331 if (!(status & WDC_SR_TGOOD)) {
332 u8 alarm = inb(WDT_RT); 332 printk(KERN_CRIT PFX "Overheat alarm.(%d)\n",
333 printk(KERN_CRIT PFX "Overheat alarm.(%d)\n", alarm); 333 inb(WDT_RT));
334 udelay(8); 334 udelay(8);
335 } 335 }
336 if (!(status & WDC_SR_PSUOVER)) 336 if (!(status & WDC_SR_PSUOVER))
337 printk(KERN_CRIT PFX "PSU over voltage.\n"); 337 printk(KERN_CRIT PFX "PSU over voltage.\n");
338 if (!(status & WDC_SR_PSUUNDR)) 338 if (!(status & WDC_SR_PSUUNDR))
339 printk(KERN_CRIT PFX "PSU under voltage.\n"); 339 printk(KERN_CRIT PFX "PSU under voltage.\n");
340 if (tachometer) { 340 if (tachometer) {
341 if (!(status & WDC_SR_FANGOOD)) 341 if (!(status & WDC_SR_FANGOOD))
342 printk(KERN_CRIT PFX "Possible fan fault.\n"); 342 printk(KERN_CRIT PFX "Possible fan fault.\n");
343 }
343 } 344 }
344#endif /* CONFIG_WDT_501_PCI */ 345 if (!(status & WDC_SR_WCCR)) {
345 if (!(status&WDC_SR_WCCR)) {
346#ifdef SOFTWARE_REBOOT 346#ifdef SOFTWARE_REBOOT
347#ifdef ONLY_TESTING 347#ifdef ONLY_TESTING
348 printk(KERN_CRIT PFX "Would Reboot.\n"); 348 printk(KERN_CRIT PFX "Would Reboot.\n");
@@ -371,12 +371,13 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id)
371 */ 371 */
372 372
373static ssize_t wdtpci_write(struct file *file, const char __user *buf, 373static ssize_t wdtpci_write(struct file *file, const char __user *buf,
374 size_t count, loff_t *ppos) 374 size_t count, loff_t *ppos)
375{ 375{
376 if (count) { 376 if (count) {
377 if (!nowayout) { 377 if (!nowayout) {
378 size_t i; 378 size_t i;
379 379
380 /* In case it was set long ago */
380 expect_close = 0; 381 expect_close = 0;
381 382
382 for (i = 0; i != count; i++) { 383 for (i = 0; i != count; i++) {
@@ -406,10 +407,10 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf,
406static long wdtpci_ioctl(struct file *file, unsigned int cmd, 407static long wdtpci_ioctl(struct file *file, unsigned int cmd,
407 unsigned long arg) 408 unsigned long arg)
408{ 409{
409 int new_heartbeat;
410 int status;
411 void __user *argp = (void __user *)arg; 410 void __user *argp = (void __user *)arg;
412 int __user *p = argp; 411 int __user *p = argp;
412 int new_heartbeat;
413 int status;
413 414
414 static struct watchdog_info ident = { 415 static struct watchdog_info ident = {
415 .options = WDIOF_SETTIMEOUT| 416 .options = WDIOF_SETTIMEOUT|
@@ -421,11 +422,12 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd,
421 422
422 /* Add options according to the card we have */ 423 /* Add options according to the card we have */
423 ident.options |= (WDIOF_EXTERN1|WDIOF_EXTERN2); 424 ident.options |= (WDIOF_EXTERN1|WDIOF_EXTERN2);
424#ifdef CONFIG_WDT_501_PCI 425 if (type == 501) {
425 ident.options |= (WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER); 426 ident.options |= (WDIOF_OVERHEAT|WDIOF_POWERUNDER|
426 if (tachometer) 427 WDIOF_POWEROVER);
427 ident.options |= WDIOF_FANFAULT; 428 if (tachometer)
428#endif /* CONFIG_WDT_501_PCI */ 429 ident.options |= WDIOF_FANFAULT;
430 }
429 431
430 switch (cmd) { 432 switch (cmd) {
431 case WDIOC_GETSUPPORT: 433 case WDIOC_GETSUPPORT:
@@ -503,7 +505,6 @@ static int wdtpci_release(struct inode *inode, struct file *file)
503 return 0; 505 return 0;
504} 506}
505 507
506#ifdef CONFIG_WDT_501_PCI
507/** 508/**
508 * wdtpci_temp_read: 509 * wdtpci_temp_read:
509 * @file: file handle to the watchdog board 510 * @file: file handle to the watchdog board
@@ -554,7 +555,6 @@ static int wdtpci_temp_release(struct inode *inode, struct file *file)
554{ 555{
555 return 0; 556 return 0;
556} 557}
557#endif /* CONFIG_WDT_501_PCI */
558 558
559/** 559/**
560 * notify_sys: 560 * notify_sys:
@@ -596,7 +596,6 @@ static struct miscdevice wdtpci_miscdev = {
596 .fops = &wdtpci_fops, 596 .fops = &wdtpci_fops,
597}; 597};
598 598
599#ifdef CONFIG_WDT_501_PCI
600static const struct file_operations wdtpci_temp_fops = { 599static const struct file_operations wdtpci_temp_fops = {
601 .owner = THIS_MODULE, 600 .owner = THIS_MODULE,
602 .llseek = no_llseek, 601 .llseek = no_llseek,
@@ -610,7 +609,6 @@ static struct miscdevice temp_miscdev = {
610 .name = "temperature", 609 .name = "temperature",
611 .fops = &wdtpci_temp_fops, 610 .fops = &wdtpci_temp_fops,
612}; 611};
613#endif /* CONFIG_WDT_501_PCI */
614 612
615/* 613/*
616 * The WDT card needs to learn about soft shutdowns in order to 614 * The WDT card needs to learn about soft shutdowns in order to
@@ -633,6 +631,11 @@ static int __devinit wdtpci_init_one(struct pci_dev *dev,
633 return -ENODEV; 631 return -ENODEV;
634 } 632 }
635 633
634 if (type != 500 && type != 501) {
635 printk(KERN_ERR PFX "unknown card type '%d'.\n", type);
636 return -ENODEV;
637 }
638
636 if (pci_enable_device(dev)) { 639 if (pci_enable_device(dev)) {
637 printk(KERN_ERR PFX "Not possible to enable PCI Device\n"); 640 printk(KERN_ERR PFX "Not possible to enable PCI Device\n");
638 return -ENODEV; 641 return -ENODEV;
@@ -678,15 +681,15 @@ static int __devinit wdtpci_init_one(struct pci_dev *dev,
678 goto out_irq; 681 goto out_irq;
679 } 682 }
680 683
681#ifdef CONFIG_WDT_501_PCI 684 if (type == 501) {
682 ret = misc_register(&temp_miscdev); 685 ret = misc_register(&temp_miscdev);
683 if (ret) { 686 if (ret) {
684 printk(KERN_ERR PFX 687 printk(KERN_ERR PFX
685 "cannot register miscdev on minor=%d (err=%d)\n", 688 "cannot register miscdev on minor=%d (err=%d)\n",
686 TEMP_MINOR, ret); 689 TEMP_MINOR, ret);
687 goto out_rbt; 690 goto out_rbt;
691 }
688 } 692 }
689#endif /* CONFIG_WDT_501_PCI */
690 693
691 ret = misc_register(&wdtpci_miscdev); 694 ret = misc_register(&wdtpci_miscdev);
692 if (ret) { 695 if (ret) {
@@ -698,20 +701,18 @@ static int __devinit wdtpci_init_one(struct pci_dev *dev,
698 701
699 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", 702 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
700 heartbeat, nowayout); 703 heartbeat, nowayout);
701#ifdef CONFIG_WDT_501_PCI 704 if (type == 501)
702 printk(KERN_INFO "wdt: Fan Tachometer is %s\n", 705 printk(KERN_INFO "wdt: Fan Tachometer is %s\n",
703 (tachometer ? "Enabled" : "Disabled")); 706 (tachometer ? "Enabled" : "Disabled"));
704#endif /* CONFIG_WDT_501_PCI */
705 707
706 ret = 0; 708 ret = 0;
707out: 709out:
708 return ret; 710 return ret;
709 711
710out_misc: 712out_misc:
711#ifdef CONFIG_WDT_501_PCI 713 if (type == 501)
712 misc_deregister(&temp_miscdev); 714 misc_deregister(&temp_miscdev);
713out_rbt: 715out_rbt:
714#endif /* CONFIG_WDT_501_PCI */
715 unregister_reboot_notifier(&wdtpci_notifier); 716 unregister_reboot_notifier(&wdtpci_notifier);
716out_irq: 717out_irq:
717 free_irq(irq, &wdtpci_miscdev); 718 free_irq(irq, &wdtpci_miscdev);
@@ -728,9 +729,8 @@ static void __devexit wdtpci_remove_one(struct pci_dev *pdev)
728 /* here we assume only one device will ever have 729 /* here we assume only one device will ever have
729 * been picked up and registered by probe function */ 730 * been picked up and registered by probe function */
730 misc_deregister(&wdtpci_miscdev); 731 misc_deregister(&wdtpci_miscdev);
731#ifdef CONFIG_WDT_501_PCI 732 if (type == 501)
732 misc_deregister(&temp_miscdev); 733 misc_deregister(&temp_miscdev);
733#endif /* CONFIG_WDT_501_PCI */
734 unregister_reboot_notifier(&wdtpci_notifier); 734 unregister_reboot_notifier(&wdtpci_notifier);
735 free_irq(irq, &wdtpci_miscdev); 735 free_irq(irq, &wdtpci_miscdev);
736 release_region(io, 16); 736 release_region(io, 16);