Commit bd5490e4 authored by Dave Jones's avatar Dave Jones Committed by Dave Jones

[WATCHDOG] Final 2.4 changes for wdt_pci.c

parent cbe6ef3a
......@@ -30,7 +30,9 @@
* Alan Cox : Split ISA and PCI cards into two drivers
* Jeff Garzik : PCI cleanups
* Tigran Aivazian : Restructured wdtpci_init_one() to handle failures
* Matt Domsch : added nowayout and timeout module options
* Joel Becker : Added WDIOC_GET/SETTIMEOUT
* Zwane Mwaikambo : Magic char closing, locking changes, cleanups
* Matt Domsch : nowayout module option
*/
#include <linux/config.h>
......@@ -67,23 +69,18 @@
#define PCI_DEVICE_ID_WDG_CSM 0x22c0
#endif
static unsigned long wdt_is_open;
static struct semaphore open_sem;
static spinlock_t wdtpci_lock;
static int expect_close = 0;
/*
* You must set these - there is no sane way to probe for this board.
* You can use wdt=x,y to set these now.
*/
static int io=0x240;
static int irq=11;
static int io;
static int irq;
/* Default timeout */
#define WD_TIMO (100*60) /* 1 minute */
#define WD_TIMO_MAX (WD_TIMO*60) /* 1 hour(?) */
static int timeout_val = WD_TIMO; /* value passed to card */
static int timeout = 60; /* in seconds */
MODULE_PARM(timeout,"i");
MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=60)");
static int wd_margin = WD_TIMO;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1;
......@@ -94,43 +91,6 @@ static int nowayout = 0;
MODULE_PARM(nowayout,"i");
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
static void __init
wdtpci_validate_timeout(void)
{
timeout_val = timeout * 100;
}
#ifndef MODULE
/**
* wdtpci_setup:
* @str: command line string
*
* Setup options. The board isn't really probe-able so we have to
* get the user to tell us the configuration. Sane people build it
* modular but the others come here.
*/
static int __init wdtpci_setup(char *str)
{
int ints[4];
str = get_options (str, ARRAY_SIZE(ints), ints);
if (ints[0] > 0)
{
io = ints[1];
if(ints[0] > 1)
irq = ints[2];
}
return 1;
}
__setup("wdt=", wdtpci_setup);
#endif /* !MODULE */
/*
* Programming support
*/
......@@ -246,11 +206,15 @@ static void wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static void wdtpci_ping(void)
{
unsigned long flags;
/* Write a watchdog value */
spin_lock_irqsave(&wdtpci_lock, flags);
inb_p(WDT_DC);
wdtpci_ctr_mode(1,2);
wdtpci_ctr_load(1,timeout_val); /* Timeout */
wdtpci_ctr_load(1,wd_margin); /* Timeout */
outb_p(0, WDT_DC);
spin_unlock_irqrestore(&wdtpci_lock, flags);
}
/**
......@@ -270,10 +234,12 @@ static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, lo
if (ppos != &file->f_pos)
return -ESPIPE;
if(count)
{
if (count) {
if (!nowayout) {
size_t i;
expect_close = 0;
for (i = 0; i != count; i++) {
char c;
if(get_user(c, buf+i))
......@@ -283,9 +249,9 @@ static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, lo
}
}
wdtpci_ping();
return 1;
}
return 0;
return count;
}
/**
......@@ -337,6 +303,7 @@ static ssize_t wdtpci_read(struct file *file, char *buf, size_t count, loff_t *p
static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
int new_margin;
static struct watchdog_info ident = {
.options = WDIOF_OVERHEAT | WDIOF_POWERUNDER |
WDIOF_POWEROVER | WDIOF_EXTERN1 |
......@@ -361,6 +328,18 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
case WDIOC_KEEPALIVE:
wdtpci_ping();
return 0;
case WDIOC_SETTIMEOUT:
if (get_user(new_margin, (int *)arg))
return -EFAULT;
/* Arbitrary, can't find the card's limits */
new_margin *= 100;
if ((new_margin < 0) || (new_margin > WD_TIMO_MAX))
return -EINVAL;
wd_margin = new_margin;
wdtpci_ping();
/* Fall */
case WDIOC_GETTIMEOUT:
return put_user(wd_margin / 100, (int *)arg);
}
}
......@@ -378,20 +357,22 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
static int wdtpci_open(struct inode *inode, struct file *file)
{
unsigned long flags;
switch(minor(inode->i_rdev))
{
case WATCHDOG_MINOR:
if( test_and_set_bit(0,&wdt_is_open) )
{
if (down_trylock(&open_sem))
return -EBUSY;
}
if (nowayout) {
MOD_INC_USE_COUNT;
}
/*
* Activate
*/
spin_lock_irqsave(&wdtpci_lock, flags);
inb_p(WDT_DC); /* Disable */
/*
......@@ -413,9 +394,10 @@ static int wdtpci_open(struct inode *inode, struct file *file)
wdtpci_ctr_mode(1,2);
wdtpci_ctr_mode(2,1);
wdtpci_ctr_load(0,20833); /* count at 100Hz */
wdtpci_ctr_load(1,timeout_val); /* Timeout */
wdtpci_ctr_load(1,wd_margin);/* Timeout 60 seconds */
/* DO NOT LOAD CTR2 on PCI card! -- JPN */
outb_p(0, WDT_DC); /* Enable */
spin_unlock_irqrestore(&wdtpci_lock, flags);
return 0;
case TEMP_MINOR:
return 0;
......@@ -438,13 +420,19 @@ static int wdtpci_open(struct inode *inode, struct file *file)
static int wdtpci_release(struct inode *inode, struct file *file)
{
if(minor(inode->i_rdev)==WATCHDOG_MINOR)
{
if (!nowayout) {
if (minor(inode->i_rdev)==WATCHDOG_MINOR) {
unsigned long flags;
if (expect_close) {
spin_lock_irqsave(&wdtpci_lock, flags);
inb_p(WDT_DC); /* Disable counters */
wdtpci_ctr_load(2,0); /* 0 length reset pulses now */
spin_unlock_irqrestore(&wdtpci_lock, flags);
} else {
printk(KERN_CRIT PFX "Unexpected close, not stopping timer!");
wdtpci_ping();
}
clear_bit(0, &wdt_is_open );
up(&open_sem);
}
return 0;
}
......@@ -464,11 +452,14 @@ static int wdtpci_release(struct inode *inode, struct file *file)
static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
void *unused)
{
if(code==SYS_DOWN || code==SYS_HALT)
{
unsigned long flags;
if (code==SYS_DOWN || code==SYS_HALT) {
/* Turn the card off */
spin_lock_irqsave(&wdtpci_lock, flags);
inb_p(WDT_DC);
wdtpci_ctr_load(2,0);
spin_unlock_irqrestore(&wdtpci_lock, flags);
}
return NOTIFY_DONE;
}
......@@ -528,6 +519,9 @@ static int __init wdtpci_init_one (struct pci_dev *dev,
if (pci_enable_device (dev))
goto out;
sema_init(&open_sem, 1);
spin_lock_init(&wdtpci_lock);
irq = dev->irq;
io = pci_resource_start (dev, 2);
printk ("WDT501-P(PCI-WDG-CSM) driver 0.07 at %X "
......@@ -645,8 +639,6 @@ static int __init wdtpci_init(void)
if (rc < 1)
return -ENODEV;
wdtpci_validate_timeout();
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment