X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fwatchdog%2Fixp2000_wdt.c;h=4f4b35a20d84ed6642fb789b49e6c601b8742d86;hb=184d68b2b0b836587f92887b14baea41033ffeef;hp=884c2b435bea24a6d0bd8234ea0dea57a44affec;hpb=a1b81a84fff05dbfef45b7012c26e1fee9973e5d;p=linux-2.6-omap-h63xx.git diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c index 884c2b435be..4f4b35a20d8 100644 --- a/drivers/watchdog/ixp2000_wdt.c +++ b/drivers/watchdog/ixp2000_wdt.c @@ -25,42 +25,44 @@ #include #include #include - -#include -#include +#include +#include static int nowayout = WATCHDOG_NOWAYOUT; static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ static unsigned long wdt_status; +static spinlock_t wdt_lock; #define WDT_IN_USE 0 #define WDT_OK_TO_CLOSE 1 static unsigned long wdt_tick_rate; -static void -wdt_enable(void) +static void wdt_enable(void) { + spin_lock(&wdt_lock); ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE); ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE); ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE); + spin_unlock(&wdt_lock); } -static void -wdt_disable(void) +static void wdt_disable(void) { + spin_lock(&wdt_lock); ixp2000_reg_write(IXP2000_T4_CTL, 0); + spin_unlock(&wdt_lock); } -static void -wdt_keepalive(void) +static void wdt_keepalive(void) { + spin_lock(&wdt_lock); ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); + spin_unlock(&wdt_lock); } -static int -ixp2000_wdt_open(struct inode *inode, struct file *file) +static int ixp2000_wdt_open(struct inode *inode, struct file *file) { if (test_and_set_bit(WDT_IN_USE, &wdt_status)) return -EBUSY; @@ -72,8 +74,8 @@ ixp2000_wdt_open(struct inode *inode, struct file *file) return nonseekable_open(inode, file); } -static ssize_t -ixp2000_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) +static ssize_t ixp2000_wdt_write(struct file *file, const char *data, + size_t len, loff_t *ppos) { if (len) { if (!nowayout) { @@ -103,9 +105,8 @@ static struct watchdog_info ident = { .identity = "IXP2000 Watchdog", }; -static int -ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static long ixp2000_wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { int ret = -ENOTTY; int time; @@ -124,6 +125,11 @@ ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ret = put_user(0, (int *)arg); break; + case WDIOC_KEEPALIVE: + wdt_enable(); + ret = 0; + break; + case WDIOC_SETTIMEOUT: ret = get_user(time, (int *)arg); if (ret) @@ -141,26 +147,18 @@ ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, case WDIOC_GETTIMEOUT: ret = put_user(heartbeat, (int *)arg); break; - - case WDIOC_KEEPALIVE: - wdt_enable(); - ret = 0; - break; } return ret; } -static int -ixp2000_wdt_release(struct inode *inode, struct file *file) +static int ixp2000_wdt_release(struct inode *inode, struct file *file) { - if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { + if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) wdt_disable(); - } else { + else printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " "timer will not stop\n"); - } - clear_bit(WDT_IN_USE, &wdt_status); clear_bit(WDT_OK_TO_CLOSE, &wdt_status); @@ -168,18 +166,16 @@ ixp2000_wdt_release(struct inode *inode, struct file *file) } -static const struct file_operations ixp2000_wdt_fops = -{ +static const struct file_operations ixp2000_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = ixp2000_wdt_write, - .ioctl = ixp2000_wdt_ioctl, + .unlocked_ioctl = ixp2000_wdt_ioctl, .open = ixp2000_wdt_open, .release = ixp2000_wdt_release, }; -static struct miscdevice ixp2000_wdt_miscdev = -{ +static struct miscdevice ixp2000_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &ixp2000_wdt_fops, @@ -191,9 +187,8 @@ static int __init ixp2000_wdt_init(void) printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n"); return -EIO; } - wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; - + spin_lock_init(&wdt_lock); return misc_register(&ixp2000_wdt_miscdev); }