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
- Lines: 136
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/drivers/char/w83877f_wdt.c
- Orig date:
Thu Sep 13 15:21:32 2001
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)