Commit fbd47149 authored by Alan Cox's avatar Alan Cox Committed by Wim Van Sebroeck

[WATCHDOG 04/57] AR7 watchdog

Fix locking
Use unlocked_ioctl
Remove semaphores
Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarWim Van Sebroeck <wim@iguana.be>
parent 173d95bc
...@@ -69,7 +69,8 @@ struct ar7_wdt { ...@@ -69,7 +69,8 @@ struct ar7_wdt {
u32 prescale; u32 prescale;
}; };
static struct semaphore open_semaphore; static unsigned long wdt_is_open;
static spinlock_t wdt_lock;
static unsigned expect_close; static unsigned expect_close;
/* XXX currently fixed, allows max margin ~68.72 secs */ /* XXX currently fixed, allows max margin ~68.72 secs */
...@@ -154,8 +155,10 @@ static void ar7_wdt_update_margin(int new_margin) ...@@ -154,8 +155,10 @@ static void ar7_wdt_update_margin(int new_margin)
u32 change; u32 change;
change = new_margin * (ar7_vbus_freq() / prescale_value); change = new_margin * (ar7_vbus_freq() / prescale_value);
if (change < 1) change = 1; if (change < 1)
if (change > 0xffff) change = 0xffff; change = 1;
if (change > 0xffff)
change = 0xffff;
ar7_wdt_change(change); ar7_wdt_change(change);
margin = change * prescale_value / ar7_vbus_freq(); margin = change * prescale_value / ar7_vbus_freq();
printk(KERN_INFO DRVNAME printk(KERN_INFO DRVNAME
...@@ -179,7 +182,7 @@ static void ar7_wdt_disable_wdt(void) ...@@ -179,7 +182,7 @@ static void ar7_wdt_disable_wdt(void)
static int ar7_wdt_open(struct inode *inode, struct file *file) static int ar7_wdt_open(struct inode *inode, struct file *file)
{ {
/* only allow one at a time */ /* only allow one at a time */
if (down_trylock(&open_semaphore)) if (test_and_set_bit(0, &wdt_is_open))
return -EBUSY; return -EBUSY;
ar7_wdt_enable_wdt(); ar7_wdt_enable_wdt();
expect_close = 0; expect_close = 0;
...@@ -195,9 +198,7 @@ static int ar7_wdt_release(struct inode *inode, struct file *file) ...@@ -195,9 +198,7 @@ static int ar7_wdt_release(struct inode *inode, struct file *file)
"will not disable the watchdog timer\n"); "will not disable the watchdog timer\n");
else if (!nowayout) else if (!nowayout)
ar7_wdt_disable_wdt(); ar7_wdt_disable_wdt();
clear_bit(0, &wdt_is_open);
up(&open_semaphore);
return 0; return 0;
} }
...@@ -222,7 +223,9 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data, ...@@ -222,7 +223,9 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data,
if (len) { if (len) {
size_t i; size_t i;
spin_lock(&wdt_lock);
ar7_wdt_kick(1); ar7_wdt_kick(1);
spin_unlock(&wdt_lock);
expect_close = 0; expect_close = 0;
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
...@@ -237,7 +240,7 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data, ...@@ -237,7 +240,7 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data,
return len; return len;
} }
static int ar7_wdt_ioctl(struct inode *inode, struct file *file, static long ar7_wdt_ioctl(struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
static struct watchdog_info ident = { static struct watchdog_info ident = {
...@@ -269,8 +272,10 @@ static int ar7_wdt_ioctl(struct inode *inode, struct file *file, ...@@ -269,8 +272,10 @@ static int ar7_wdt_ioctl(struct inode *inode, struct file *file,
if (new_margin < 1) if (new_margin < 1)
return -EINVAL; return -EINVAL;
spin_lock(&wdt_lock);
ar7_wdt_update_margin(new_margin); ar7_wdt_update_margin(new_margin);
ar7_wdt_kick(1); ar7_wdt_kick(1);
spin_unlock(&wdt_lock);
case WDIOC_GETTIMEOUT: case WDIOC_GETTIMEOUT:
if (put_user(margin, (int *)arg)) if (put_user(margin, (int *)arg))
...@@ -282,7 +287,7 @@ static int ar7_wdt_ioctl(struct inode *inode, struct file *file, ...@@ -282,7 +287,7 @@ static int ar7_wdt_ioctl(struct inode *inode, struct file *file,
static const struct file_operations ar7_wdt_fops = { static const struct file_operations ar7_wdt_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.write = ar7_wdt_write, .write = ar7_wdt_write,
.ioctl = ar7_wdt_ioctl, .unlocked_ioctl = ar7_wdt_ioctl,
.open = ar7_wdt_open, .open = ar7_wdt_open,
.release = ar7_wdt_release, .release = ar7_wdt_release,
}; };
...@@ -297,6 +302,8 @@ static int __init ar7_wdt_init(void) ...@@ -297,6 +302,8 @@ static int __init ar7_wdt_init(void)
{ {
int rc; int rc;
spin_lock_init(&wdt_lock);
ar7_wdt_get_regs(); ar7_wdt_get_regs();
if (!request_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt), if (!request_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt),
...@@ -312,8 +319,6 @@ static int __init ar7_wdt_init(void) ...@@ -312,8 +319,6 @@ static int __init ar7_wdt_init(void)
ar7_wdt_prescale(prescale_value); ar7_wdt_prescale(prescale_value);
ar7_wdt_update_margin(margin); ar7_wdt_update_margin(margin);
sema_init(&open_semaphore, 1);
rc = register_reboot_notifier(&ar7_wdt_notifier); rc = register_reboot_notifier(&ar7_wdt_notifier);
if (rc) { if (rc) {
printk(KERN_ERR DRVNAME printk(KERN_ERR DRVNAME
......
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