patch-2.4.19 linux-2.4.19/drivers/char/w83877f_wdt.c

Next file: linux-2.4.19/drivers/char/wafer5823wdt.c
Previous file: linux-2.4.19/drivers/char/vme_scc.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/drivers/char/w83877f_wdt.c linux-2.4.19/drivers/char/w83877f_wdt.c
@@ -13,9 +13,10 @@
  *	any of this software. This material is provided "AS-IS" in 
  *      the hope that it may be useful for others.
  *
- *	(c) Copyright 2001    Scott Jennings <management@oro.net>
+ *	(c) Copyright 2001    Scott Jennings <linuxdrivers@oro.net>
  *
  *           4/19 - 2001      [Initial revision]
+ *           9/27 - 2001      Added spinlocking
  *
  *
  *  Theory of operation:
@@ -88,8 +89,9 @@
 static void wdt_timer_ping(unsigned long);
 static struct timer_list timer;
 static unsigned long next_heartbeat;
-static int wdt_is_open;
+static unsigned long wdt_is_open;
 static int wdt_expect_close;
+static spinlock_t wdt_spinlock;
 
 /*
  *	Whack the dog
@@ -102,11 +104,18 @@
 	 */
 	if(time_before(jiffies, next_heartbeat)) 
 	{
+		/* Ping the WDT */
+		spin_lock(&wdt_spinlock);
+
 		/* Ping the WDT by reading from WDT_PING */
 		inb_p(WDT_PING);
+
 		/* Re-set the timer interval */
 		timer.expires = jiffies + WDT_INTERVAL;
 		add_timer(&timer);
+
+		spin_unlock(&wdt_spinlock);
+
 	} else {
 		printk(OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n");
 	}
@@ -118,19 +127,24 @@
 
 static void wdt_change(int writeval)
 {
+	unsigned long flags;
+	spin_lock_irqsave(&wdt_spinlock, flags);
+
 	/* buy some time */
 	inb_p(WDT_PING);
 
 	/* make W83877F available */
-	outb_p(ENABLE_W83877F,ENABLE_W83877F_PORT);
-	outb_p(ENABLE_W83877F,ENABLE_W83877F_PORT);
+	outb_p(ENABLE_W83877F,  ENABLE_W83877F_PORT);
+	outb_p(ENABLE_W83877F,  ENABLE_W83877F_PORT);
 
 	/* enable watchdog */
-	outb_p(WDT_REGISTER,ENABLE_W83877F_PORT);
-	outb_p(writeval,ENABLE_W83877F_PORT+1);
+	outb_p(WDT_REGISTER,    ENABLE_W83877F_PORT);
+	outb_p(writeval,        ENABLE_W83877F_PORT+1);
 
 	/* lock the W8387FF away */
-	outb_p(DISABLE_W83877F,ENABLE_W83877F_PORT);
+	outb_p(DISABLE_W83877F, ENABLE_W83877F_PORT);
+
+	spin_unlock_irqrestore(&wdt_spinlock, flags);
 }
 
 static void wdt_startup(void)
@@ -178,7 +192,7 @@
 
 		/* now scan */
 		for(ofs = 0; ofs != count; ofs++)
-		  if(buf[ofs] == 'V')
+			if(buf[ofs] == 'V')
 				wdt_expect_close = 1;
 
 		/* someone wrote to us, we should restart timer */
@@ -200,10 +214,11 @@
 	{
 		case WATCHDOG_MINOR:
 			/* Just in case we're already talking to someone... */
-			if(wdt_is_open)
+			if(test_and_set_bit(0, &wdt_is_open)) {
+				spin_unlock(&wdt_spinlock);
 				return -EBUSY;
+			}
 			/* Good, fire up the show */
-			wdt_is_open = 1;
 			wdt_startup();
 			return 0;
 
@@ -214,7 +229,6 @@
 
 static int fop_close(struct inode * inode, struct file * file)
 {
-	lock_kernel();
 	if(MINOR(inode->i_rdev) == WATCHDOG_MINOR) 
 	{
 		if(wdt_expect_close)
@@ -224,13 +238,11 @@
 			printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n");
 		}
 	}
-	wdt_is_open = 0;
-	unlock_kernel();
+	clear_bit(0, &wdt_is_open);
 	return 0;
 }
 
-static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-	unsigned long arg)
+static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	static struct watchdog_info ident=
 	{
@@ -307,6 +319,8 @@
 {
 	int rc = -EBUSY;
 
+	spin_lock_init(&wdt_spinlock);
+
 	if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT"))
 		goto err_out;
 	if (!request_region(WDT_PING, 1, "W8387FF WDT"))
@@ -341,4 +355,7 @@
 module_init(w83877f_wdt_init);
 module_exit(w83877f_wdt_unload);
 
+MODULE_AUTHOR("Scott and Bill Jennings");
+MODULE_DESCRIPTION("Driver for watchdog timer in w83877f chip");
 MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)