ehea: Whitespace cleanup
[safe/jmp/linux-2.6] / drivers / char / watchdog / pcwd_pci.c
index d9ef55b..61a89e9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     Berkshire PCI-PC Watchdog Card Driver
  *
- *     (c) Copyright 2003-2005 Wim Van Sebroeck <wim@iguana.be>.
+ *     (c) Copyright 2003-2007 Wim Van Sebroeck <wim@iguana.be>.
  *
  *     Based on source code of the following authors:
  *       Ken Hollis <kenji@bitgate.com>,
@@ -21,7 +21,7 @@
  */
 
 /*
- *     A bells and whistles driver is available from: 
+ *     A bells and whistles driver is available from:
  *     http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/
  *
  *     More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/
@@ -31,7 +31,6 @@
  *     Includes, defines, variables, module parameters, ...
  */
 
-#include <linux/config.h>      /* For CONFIG_WATCHDOG_NOWAYOUT/... */
 #include <linux/module.h>      /* For module specific items */
 #include <linux/moduleparam.h> /* For new moduleparam's */
 #include <linux/types.h>       /* For standard types (like size_t) */
@@ -52,8 +51,8 @@
 #include <asm/io.h>            /* For inb/outb/... */
 
 /* Module and version information */
-#define WATCHDOG_VERSION "1.02"
-#define WATCHDOG_DATE "03 Sep 2005"
+#define WATCHDOG_VERSION "1.03"
+#define WATCHDOG_DATE "21 Jan 2007"
 #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
 #define WATCHDOG_NAME "pcwd_pci"
 #define PFX WATCHDOG_NAME ": "
 #define CMD_WRITE_WATCHDOG_TIMEOUT             0x19
 #define CMD_GET_CLEAR_RESET_COUNT              0x84
 
+/* Watchdog's Dip Switch heartbeat values */
+static const int heartbeat_tbl [] = {
+       5,      /* OFF-OFF-OFF  =  5 Sec  */
+       10,     /* OFF-OFF-ON   = 10 Sec  */
+       30,     /* OFF-ON-OFF   = 30 Sec  */
+       60,     /* OFF-ON-ON    =  1 Min  */
+       300,    /* ON-OFF-OFF   =  5 Min  */
+       600,    /* ON-OFF-ON    = 10 Min  */
+       1800,   /* ON-ON-OFF    = 30 Min  */
+       3600,   /* ON-ON-ON     =  1 hour */
+};
+
 /* We can only use 1 card due to the /dev/watchdog restriction */
 static int cards_found;
 
@@ -120,14 +131,14 @@ static int debug = QUIET;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
 
-#define WATCHDOG_HEARTBEAT 2   /* 2 sec default heartbeat */
+#define WATCHDOG_HEARTBEAT 0   /* default heartbeat = delay-time from dip-switches */
 static int heartbeat = WATCHDOG_HEARTBEAT;
 module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  *     Internal functions
@@ -287,7 +298,9 @@ static int pcipcwd_stop(void)
 static int pcipcwd_keepalive(void)
 {
        /* Re-trigger watchdog by writing to port 0 */
+       spin_lock(&pcipcwd_private.io_lock);
        outb_p(0x42, pcipcwd_private.io_addr);  /* send out any data */
+       spin_unlock(&pcipcwd_private.io_lock);
 
        if (debug >= DEBUG)
                printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n");
@@ -374,7 +387,9 @@ static int pcipcwd_get_temperature(int *temperature)
        if (!pcipcwd_private.supports_temp)
                return -ENODEV;
 
+       spin_lock(&pcipcwd_private.io_lock);
        *temperature = inb_p(pcipcwd_private.io_addr);
+       spin_unlock(&pcipcwd_private.io_lock);
 
        /*
         * Convert celsius to fahrenheit, since this was
@@ -390,6 +405,24 @@ static int pcipcwd_get_temperature(int *temperature)
        return 0;
 }
 
+static int pcipcwd_get_timeleft(int *time_left)
+{
+       int msb;
+       int lsb;
+
+       /* Read the time that's left before rebooting */
+       /* Note: if the board is not yet armed then we will read 0xFFFF */
+       send_command(CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb);
+
+       *time_left = (msb << 8) + lsb;
+
+       if (debug >= VERBOSE)
+               printk(KERN_DEBUG PFX "Time left before next reboot: %d\n",
+                      *time_left);
+
+       return 0;
+}
+
 /*
  *     /dev/watchdog handling
  */
@@ -512,8 +545,18 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
                case WDIOC_GETTIMEOUT:
                        return put_user(heartbeat, p);
 
+               case WDIOC_GETTIMELEFT:
+               {
+                       int time_left;
+
+                       if (pcipcwd_get_timeleft(&time_left))
+                               return -EFAULT;
+
+                       return put_user(time_left, p);
+               }
+
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
 }
 
@@ -597,7 +640,7 @@ static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, v
  *     Kernel Interfaces
  */
 
-static struct file_operations pcipcwd_fops = {
+static const struct file_operations pcipcwd_fops = {
        .owner =        THIS_MODULE,
        .llseek =       no_llseek,
        .write =        pcipcwd_write,
@@ -612,7 +655,7 @@ static struct miscdevice pcipcwd_miscdev = {
        .fops =         &pcipcwd_fops,
 };
 
-static struct file_operations pcipcwd_temp_fops = {
+static const struct file_operations pcipcwd_temp_fops = {
        .owner =        THIS_MODULE,
        .llseek =       no_llseek,
        .read =         pcipcwd_temp_read,
@@ -684,6 +727,10 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
        /* Show info about the card itself */
        pcipcwd_show_card_info();
 
+       /* If heartbeat = 0 then we use the heartbeat from the dip-switches */
+       if (heartbeat == 0)
+               heartbeat = heartbeat_tbl[(pcipcwd_get_option_switches() & 0x07)];
+
        /* Check that the heartbeat value is within it's range ; if not reset to the default */
        if (pcipcwd_set_heartbeat(heartbeat)) {
                pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
@@ -755,7 +802,6 @@ static struct pci_device_id pcipcwd_pci_tbl[] = {
 MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl);
 
 static struct pci_driver pcipcwd_driver = {
-       .owner          = THIS_MODULE,
        .name           = WATCHDOG_NAME,
        .id_table       = pcipcwd_pci_tbl,
        .probe          = pcipcwd_card_init,
@@ -772,6 +818,8 @@ static int __init pcipcwd_init_module(void)
 static void __exit pcipcwd_cleanup_module(void)
 {
        pci_unregister_driver(&pcipcwd_driver);
+
+       printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
 }
 
 module_init(pcipcwd_init_module);