X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fwatchdog%2Fsa1100_wdt.c;h=33c1137f17d6d3e8be5cbbc3abb2bf3099721cc1;hb=refs%2Fheads%2Fvserver;hp=862fb9ab344a93abf1de6b9cf4daffa7af7ea8ad;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c index 862fb9ab3..33c1137f1 100644 --- a/drivers/char/watchdog/sa1100_wdt.c +++ b/drivers/char/watchdog/sa1100_wdt.c @@ -1,5 +1,5 @@ /* - * Watchdog driver for the SA11x0 + * Watchdog driver for the SA11x0/PXA2xx * * (c) Copyright 2000 Oleg Drokin * Based on SoftDog driver by Alan Cox @@ -17,7 +17,6 @@ * * 27/11/2000 Initial release */ -#include #include #include #include @@ -27,28 +26,26 @@ #include #include +#ifdef CONFIG_ARCH_PXA +#include +#endif + #include #include #include -#define OSCR_FREQ 3686400 -#define SA1100_CLOSE_MAGIC (0x5afc4453) +#define OSCR_FREQ CLOCK_TICK_RATE static unsigned long sa1100wdt_users; -static int expect_close; static int pre_margin; static int boot_status; -#ifdef CONFIG_WATCHDOG_NOWAYOUT -static int nowayout = 1; -#else -static int nowayout = 0; -#endif /* * Allow only one person to hold it open */ static int sa1100dog_open(struct inode *inode, struct file *file) { + nonseekable_open(inode, file); if (test_and_set_bit(1,&sa1100wdt_users)) return -EBUSY; @@ -61,83 +58,59 @@ static int sa1100dog_open(struct inode *inode, struct file *file) } /* - * Shut off the timer. - * Lock it in if it's a module and we defined ...NOWAYOUT - * Oddly, the watchdog can only be enabled, but we can turn off - * the interrupt, which appears to prevent the watchdog timing out. + * The watchdog cannot be disabled. + * + * Previous comments suggested that turning off the interrupt by + * clearing OIER[E3] would prevent the watchdog timing out but this + * does not appear to be true (at least on the PXA255). */ static int sa1100dog_release(struct inode *inode, struct file *file) { - OSMR3 = OSCR + pre_margin; - - if (expect_close == SA1100_CLOSE_MAGIC) { - OIER &= ~OIER_E3; - } else { - printk(KERN_CRIT "WATCHDOG: WDT device closed unexpectedly. WDT will not stop!\n"); - } + printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n"); clear_bit(1, &sa1100wdt_users); - expect_close = 0; return 0; } -static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos) +static ssize_t sa1100dog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { - /* Can't seek (pwrite) on this device */ - if (ppos != &file->f_pos) - return -ESPIPE; - - if (len) { - if (!nowayout) { - size_t i; - - expect_close = 0; - - for (i = 0; i != len; i++) { - char c; - - if (get_user(c, data + i)) - return -EFAULT; - if (c == 'V') - expect_close = SA1100_CLOSE_MAGIC; - } - } + if (len) /* Refresh OSMR3 timer. */ OSMR3 = OSCR + pre_margin; - } return len; } static struct watchdog_info ident = { - .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | - WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, - .identity = "SA1100 Watchdog", + .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, + .identity = "SA1100/PXA255 Watchdog", }; static int sa1100dog_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int ret = -ENOIOCTLCMD; + int ret = -ENOTTY; int time; + void __user *argp = (void __user *)arg; + int __user *p = argp; switch (cmd) { case WDIOC_GETSUPPORT: - ret = copy_to_user((struct watchdog_info *)arg, &ident, + ret = copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; break; case WDIOC_GETSTATUS: - ret = put_user(0, (int *)arg); + ret = put_user(0, p); break; case WDIOC_GETBOOTSTATUS: - ret = put_user(boot_status, (int *)arg); + ret = put_user(boot_status, p); break; case WDIOC_SETTIMEOUT: - ret = get_user(time, (int *)arg); + ret = get_user(time, p); if (ret) break; @@ -151,7 +124,7 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file, /*fall through*/ case WDIOC_GETTIMEOUT: - ret = put_user(pre_margin / OSCR_FREQ, (int *)arg); + ret = put_user(pre_margin / OSCR_FREQ, p); break; case WDIOC_KEEPALIVE: @@ -162,9 +135,10 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file, return ret; } -static struct file_operations sa1100dog_fops = +static const struct file_operations sa1100dog_fops = { .owner = THIS_MODULE, + .llseek = no_llseek, .write = sa1100dog_write, .ioctl = sa1100dog_ioctl, .open = sa1100dog_open, @@ -174,7 +148,7 @@ static struct file_operations sa1100dog_fops = static struct miscdevice sa1100dog_miscdev = { .minor = WATCHDOG_MINOR, - .name = "SA1100 watchdog", + .name = "watchdog", .fops = &sa1100dog_fops, }; @@ -194,9 +168,8 @@ static int __init sa1100dog_init(void) ret = misc_register(&sa1100dog_miscdev); if (ret == 0) - printk("SA1100 Watchdog Timer: timer margin %d sec\n", + printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", margin); - return ret; } @@ -209,13 +182,10 @@ module_init(sa1100dog_init); module_exit(sa1100dog_exit); MODULE_AUTHOR("Oleg Drokin "); -MODULE_DESCRIPTION("SA1100 Watchdog"); +MODULE_DESCRIPTION("SA1100/PXA2xx Watchdog"); module_param(margin, int, 0); MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); -module_param(nowayout, int, 0); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); - MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);