]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/char/watchdog/mixcomwd.c
[WATCHDOG] Mixcom Watchdog - checkcard
[mv-sheeva.git] / drivers / char / watchdog / mixcomwd.c
index ae943324d2511e2b5ab174b59d864fc055ca60a3..17c29cb78d099a159d7469873bee79b73d881742 100644 (file)
  *             - support for one more type board
  *
  * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com>
- *              - added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
+ *             - added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
+ *
+ * Version 0.6 (2002/04/12): Rob Radez <rob@osinvestor.com>
+ *             - make mixcomwd_opened unsigned,
+ *               removed lock_kernel/unlock_kernel from mixcomwd_release,
+ *               modified ioctl a bit to conform to API
  *
  */
 
-#define VERSION "0.5"
+#define VERSION "0.6"
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-static int mixcomwd_ioports[] = { 0x180, 0x280, 0x380, 0x000 };
-
-#define MIXCOM_WATCHDOG_OFFSET 0xc10
+/*
+ * We have two types of cards that can be probed:
+ * 1) The Mixcom cards: these cards can be found at addresses
+ *    0x180, 0x280, 0x380 with an additional offset of 0xc10.
+ *    (Or 0xd90, 0xe90, 0xf90).
+ * 2) The FlashCOM cards: these cards can be set up at
+ *    0x300 -> 0x378, in 0x8 jumps with an offset of 0x04.
+ *    (Or 0x304 -> 0x37c in 0x8 jumps).
+ *    Each card has it's own ID.
+ */
 #define MIXCOM_ID 0x11
-#define FLASHCOM_WATCHDOG_OFFSET 0x4
 #define FLASHCOM_ID 0x18
+static int mixcomwd_ioports[] = { 0xd90, 0xe90, 0xf90, 0x000 };
+
+static void mixcomwd_timerfun(unsigned long d);
 
 static unsigned long mixcomwd_opened; /* long req'd for setbit --RR */
 
 static int watchdog_port;
 static int mixcomwd_timer_alive;
-static DEFINE_TIMER(mixcomwd_timer, NULL, 0, 0);
+static DEFINE_TIMER(mixcomwd_timer, mixcomwd_timerfun, 0, 0);
 static char expect_close;
 
 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) ")");
 
 static void mixcomwd_ping(void)
 {
@@ -77,7 +91,7 @@ static void mixcomwd_timerfun(unsigned long d)
 {
        mixcomwd_ping();
 
-       mod_timer(&mixcomwd_timer,jiffies+ 5*HZ);
+       mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
 }
 
 /*
@@ -114,12 +128,8 @@ static int mixcomwd_release(struct inode *inode, struct file *file)
                        printk(KERN_ERR "mixcomwd: release called while internal timer alive");
                        return -EBUSY;
                }
-               init_timer(&mixcomwd_timer);
-               mixcomwd_timer.expires=jiffies + 5 * HZ;
-               mixcomwd_timer.function=mixcomwd_timerfun;
-               mixcomwd_timer.data=0;
                mixcomwd_timer_alive=1;
-               add_timer(&mixcomwd_timer);
+               mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
        } else {
                printk(KERN_CRIT "mixcomwd: WDT device closed unexpectedly.  WDT will not stop!\n");
        }
@@ -185,7 +195,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
                        mixcomwd_ping();
                        break;
                default:
-                       return -ENOIOCTLCMD;
+                       return -ENOTTY;
        }
        return 0;
 }
@@ -207,39 +217,24 @@ static struct miscdevice mixcomwd_miscdev=
        .fops   = &mixcomwd_fops,
 };
 
-static int __init mixcomwd_checkcard(int port)
-{
-       int id;
-
-       port += MIXCOM_WATCHDOG_OFFSET;
-       if (!request_region(port, 1, "MixCOM watchdog")) {
-               return 0;
-       }
-
-       id=inb_p(port) & 0x3f;
-       if(id!=MIXCOM_ID) {
-               release_region(port, 1);
-               return 0;
-       }
-       return port;
-}
-
-static int __init flashcom_checkcard(int port)
+static int __init checkcard(int port, int card_id)
 {
        int id;
 
-       port += FLASHCOM_WATCHDOG_OFFSET;
        if (!request_region(port, 1, "MixCOM watchdog")) {
                return 0;
        }
 
        id=inb_p(port);
-       if(id!=FLASHCOM_ID) {
+       if (card_id==MIXCOM_ID)
+               id &= 0x3f;
+
+       if (id!=card_id) {
                release_region(port, 1);
                return 0;
        }
-       return port;
- }
+       return 1;
+}
 
 static int __init mixcomwd_init(void)
 {
@@ -248,17 +243,17 @@ static int __init mixcomwd_init(void)
        int found=0;
 
        for (i = 0; !found && mixcomwd_ioports[i] != 0; i++) {
-               watchdog_port = mixcomwd_checkcard(mixcomwd_ioports[i]);
-               if (watchdog_port) {
+               if (checkcard(mixcomwd_ioports[i], MIXCOM_ID)) {
                        found = 1;
+                       watchdog_port = mixcomwd_ioports[i];
                }
        }
 
-       /* The FlashCOM card can be set up at 0x300 -> 0x378, in 0x8 jumps */
-       for (i = 0x300; !found && i < 0x380; i+=0x8) {
-               watchdog_port = flashcom_checkcard(i);
-               if (watchdog_port) {
+       /* The FlashCOM card can be set up at 0x304 -> 0x37c, in 0x8 jumps */
+       for (i = 0x304; !found && i < 0x380; i+=0x8) {
+               if (checkcard(i, FLASHCOM_ID)) {
                        found = 1;
+                       watchdog_port = i;
                }
        }
 
@@ -285,7 +280,7 @@ static void __exit mixcomwd_exit(void)
                if(mixcomwd_timer_alive) {
                        printk(KERN_WARNING "mixcomwd: I quit now, hardware will"
                               " probably reboot!\n");
-                       del_timer(&mixcomwd_timer);
+                       del_timer_sync(&mixcomwd_timer);
                        mixcomwd_timer_alive=0;
                }
        }