projects
/
linux-block.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-block.git]
/
drivers
/
watchdog
/
iop_wdt.c
diff --git
a/drivers/watchdog/iop_wdt.c
b/drivers/watchdog/iop_wdt.c
index bbbd91af754dc4696e21be327b9884378f771449..96eb2cbe5874dd887ba9ec072cdba9031fd2244c 100644
(file)
--- a/
drivers/watchdog/iop_wdt.c
+++ b/
drivers/watchdog/iop_wdt.c
@@
-32,11
+32,12
@@
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/uaccess.h>
-#include <
asm
/hardware.h>
+#include <
mach
/hardware.h>
static int nowayout = WATCHDOG_NOWAYOUT;
static unsigned long wdt_status;
static unsigned long boot_status;
static int nowayout = WATCHDOG_NOWAYOUT;
static unsigned long wdt_status;
static unsigned long boot_status;
+static spinlock_t wdt_lock;
#define WDT_IN_USE 0
#define WDT_OK_TO_CLOSE 1
#define WDT_IN_USE 0
#define WDT_OK_TO_CLOSE 1
@@
-68,8
+69,10
@@
static void wdt_enable(void)
/* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF
* Takes approx. 10.7s to timeout
*/
/* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF
* Takes approx. 10.7s to timeout
*/
+ spin_lock(&wdt_lock);
write_wdtcr(IOP_WDTCR_EN_ARM);
write_wdtcr(IOP_WDTCR_EN);
write_wdtcr(IOP_WDTCR_EN_ARM);
write_wdtcr(IOP_WDTCR_EN);
+ spin_unlock(&wdt_lock);
}
/* returns 0 if the timer was successfully disabled */
}
/* returns 0 if the timer was successfully disabled */
@@
-77,9
+80,11
@@
static int wdt_disable(void)
{
/* Stop Counting */
if (wdt_supports_disable()) {
{
/* Stop Counting */
if (wdt_supports_disable()) {
+ spin_lock(&wdt_lock);
write_wdtcr(IOP_WDTCR_DIS_ARM);
write_wdtcr(IOP_WDTCR_DIS);
clear_bit(WDT_ENABLED, &wdt_status);
write_wdtcr(IOP_WDTCR_DIS_ARM);
write_wdtcr(IOP_WDTCR_DIS);
clear_bit(WDT_ENABLED, &wdt_status);
+ spin_unlock(&wdt_lock);
printk(KERN_INFO "WATCHDOG: Disabled\n");
return 0;
} else
printk(KERN_INFO "WATCHDOG: Disabled\n");
return 0;
} else
@@
-92,16
+97,12
@@
static int iop_wdt_open(struct inode *inode, struct file *file)
return -EBUSY;
clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
return -EBUSY;
clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
-
wdt_enable();
wdt_enable();
-
set_bit(WDT_ENABLED, &wdt_status);
set_bit(WDT_ENABLED, &wdt_status);
-
return nonseekable_open(inode, file);
}
return nonseekable_open(inode, file);
}
-static ssize_t
-iop_wdt_write(struct file *file, const char *data, size_t len,
+static ssize_t iop_wdt_write(struct file *file, const char *data, size_t len,
loff_t *ppos)
{
if (len) {
loff_t *ppos)
{
if (len) {
@@
-121,46
+122,35
@@
iop_wdt_write(struct file *file, const char *data, size_t len,
}
wdt_enable();
}
}
wdt_enable();
}
-
return len;
}
return len;
}
-static struct watchdog_info ident = {
+static
const
struct watchdog_info ident = {
.options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
.identity = "iop watchdog",
};
.options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
.identity = "iop watchdog",
};
-static int
-iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
+static long iop_wdt_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
{
int options;
int ret = -ENOTTY;
{
int options;
int ret = -ENOTTY;
+ int __user *argp = (int __user *)arg;
switch (cmd) {
case WDIOC_GETSUPPORT:
switch (cmd) {
case WDIOC_GETSUPPORT:
- if (copy_to_user
- ((struct watchdog_info *)arg, &ident, sizeof ident))
+ if (copy_to_user(argp, &ident, sizeof ident))
ret = -EFAULT;
else
ret = 0;
break;
case WDIOC_GETSTATUS:
ret = -EFAULT;
else
ret = 0;
break;
case WDIOC_GETSTATUS:
- ret = put_user(0,
(int *)arg
);
+ ret = put_user(0,
argp
);
break;
case WDIOC_GETBOOTSTATUS:
break;
case WDIOC_GETBOOTSTATUS:
- ret = put_user(boot_status, (int *)arg);
- break;
-
- case WDIOC_GETTIMEOUT:
- ret = put_user(iop_watchdog_timeout(), (int *)arg);
- break;
-
- case WDIOC_KEEPALIVE:
- wdt_enable();
- ret = 0;
+ ret = put_user(boot_status, argp);
break;
case WDIOC_SETOPTIONS:
break;
case WDIOC_SETOPTIONS:
@@
-177,14
+167,21
@@
iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
} else
ret = 0;
}
} else
ret = 0;
}
-
if (options & WDIOS_ENABLECARD) {
wdt_enable();
ret = 0;
}
break;
if (options & WDIOS_ENABLECARD) {
wdt_enable();
ret = 0;
}
break;
- }
+ case WDIOC_KEEPALIVE:
+ wdt_enable();
+ ret = 0;
+ break;
+
+ case WDIOC_GETTIMEOUT:
+ ret = put_user(iop_watchdog_timeout(), argp);
+ break;
+ }
return ret;
}
return ret;
}
@@
-214,7
+211,7
@@
static const struct file_operations iop_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = iop_wdt_write,
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = iop_wdt_write,
- .ioctl = iop_wdt_ioctl,
+ .
unlocked_
ioctl = iop_wdt_ioctl,
.open = iop_wdt_open,
.release = iop_wdt_release,
};
.open = iop_wdt_open,
.release = iop_wdt_release,
};
@@
-229,10
+226,8
@@
static int __init iop_wdt_init(void)
{
int ret;
{
int ret;
- ret = misc_register(&iop_wdt_miscdev);
- if (ret == 0)
- printk("iop watchdog timer: timeout %lu sec\n",
- iop_watchdog_timeout());
+ spin_lock_init(&wdt_lock);
+
/* check if the reset was caused by the watchdog timer */
boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0;
/* check if the reset was caused by the watchdog timer */
boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0;
@@
-242,6
+237,13
@@
static int __init iop_wdt_init(void)
*/
write_wdtsr(IOP13XX_WDTCR_IB_RESET);
*/
write_wdtsr(IOP13XX_WDTCR_IB_RESET);
+ /* Register after we have the device set up so we cannot race
+ with an open */
+ ret = misc_register(&iop_wdt_miscdev);
+ if (ret == 0)
+ printk(KERN_INFO "iop watchdog timer: timeout %lu sec\n",
+ iop_watchdog_timeout());
+
return ret;
}
return ret;
}