Loading drivers/watchdog/cpu5wdt.c +70 −74 Original line number Diff line number Diff line Loading @@ -30,16 +30,16 @@ #include <linux/timer.h> #include <linux/completion.h> #include <linux/jiffies.h> #include <asm/io.h> #include <asm/uaccess.h> #include <linux/io.h> #include <linux/uaccess.h> #include <linux/watchdog.h> /* adjustable parameters */ static int verbose = 0; static int verbose; static int port = 0x91; static int ticks = 10000; static spinlock_t cpu5wdt_lock; #define PFX "cpu5wdt: " Loading Loading @@ -76,6 +76,7 @@ static void cpu5wdt_trigger(unsigned long unused) if (cpu5wdt_device.running) ticks--; spin_lock(&cpu5wdt_lock); /* keep watchdog alive */ outb(1, port + CPU5WDT_TRIGGER_REG); Loading @@ -86,6 +87,7 @@ static void cpu5wdt_trigger(unsigned long unused) /* ticks doesn't matter anyway */ complete(&cpu5wdt_device.stop); } spin_unlock(&cpu5wdt_lock); } Loading @@ -100,6 +102,9 @@ static void cpu5wdt_reset(void) static void cpu5wdt_start(void) { unsigned long flags; spin_lock_irqsave(&cpu5wdt_lock, flags); if (!cpu5wdt_device.queue) { cpu5wdt_device.queue = 1; outb(0, port + CPU5WDT_TIME_A_REG); Loading @@ -111,18 +116,20 @@ static void cpu5wdt_start(void) } /* if process dies, counter is not decremented */ cpu5wdt_device.running++; spin_unlock_irqrestore(&cpu5wdt_lock, flags); } static int cpu5wdt_stop(void) { unsigned long flags; spin_lock_irqsave(&cpu5wdt_lock, flags); if (cpu5wdt_device.running) cpu5wdt_device.running = 0; ticks = cpu5wdt_device.default_ticks; spin_unlock_irqrestore(&cpu5wdt_lock, flags); if (verbose) printk(KERN_CRIT PFX "stop not possible\n"); return -EIO; } Loading @@ -132,7 +139,6 @@ static int cpu5wdt_open(struct inode *inode, struct file *file) { if (test_and_set_bit(0, &cpu5wdt_device.inuse)) return -EBUSY; return nonseekable_open(inode, file); } Loading @@ -142,12 +148,13 @@ static int cpu5wdt_release(struct inode *inode, struct file *file) return 0; } static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long cpu5wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; unsigned int value; static struct watchdog_info ident = { static struct watchdog_info ident = { .options = WDIOF_CARDRESET, .identity = "CPU5 WDT", }; Loading @@ -159,29 +166,20 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm case WDIOC_GETSTATUS: value = inb(port + CPU5WDT_STATUS_REG); value = (value >> 2) & 1; if ( copy_to_user(argp, &value, sizeof(int)) ) return -EFAULT; break; return put_user(value, p); case WDIOC_GETBOOTSTATUS: if ( copy_to_user(argp, &value, sizeof(int)) ) return -EFAULT; break; return put_user(0, p); case WDIOC_GETSUPPORT: if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; break; case WDIOC_SETOPTIONS: if ( copy_from_user(&value, argp, sizeof(int)) ) if (get_user(value, p)) return -EFAULT; switch(value) { case WDIOS_ENABLECARD: if (value & WDIOS_ENABLECARD) cpu5wdt_start(); break; case WDIOS_DISABLECARD: return cpu5wdt_stop(); default: return -EINVAL; } if (value & WDIOS_DISABLECARD) cpu5wdt_stop(); break; default: return -ENOTTY; Loading @@ -189,20 +187,19 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm return 0; } static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { if (!count) return -EIO; cpu5wdt_reset(); return count; } static const struct file_operations cpu5wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .ioctl = cpu5wdt_ioctl, .unlocked_ioctl = cpu5wdt_ioctl, .open = cpu5wdt_open, .write = cpu5wdt_write, .release = cpu5wdt_release, Loading @@ -222,7 +219,14 @@ static int __devinit cpu5wdt_init(void) int err; if (verbose) printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); init_completion(&cpu5wdt_device.stop); spin_lock_init(&cpu5wdt_lock); cpu5wdt_device.queue = 0; setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); cpu5wdt_device.default_ticks = ticks; if (!request_region(port, CPU5WDT_EXTENT, PFX)) { printk(KERN_ERR PFX "request_region failed\n"); Loading @@ -230,28 +234,20 @@ static int __devinit cpu5wdt_init(void) goto no_port; } if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) { printk(KERN_ERR PFX "misc_register failed\n"); goto no_misc; } /* watchdog reboot? */ val = inb(port + CPU5WDT_STATUS_REG); val = (val >> 2) & 1; if (!val) printk(KERN_INFO PFX "sorry, was my fault\n"); init_completion(&cpu5wdt_device.stop); cpu5wdt_device.queue = 0; clear_bit(0, &cpu5wdt_device.inuse); setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); err = misc_register(&cpu5wdt_misc); if (err < 0) { printk(KERN_ERR PFX "misc_register failed\n"); goto no_misc; } cpu5wdt_device.default_ticks = ticks; printk(KERN_INFO PFX "init success\n"); return 0; no_misc: Loading Loading
drivers/watchdog/cpu5wdt.c +70 −74 Original line number Diff line number Diff line Loading @@ -30,16 +30,16 @@ #include <linux/timer.h> #include <linux/completion.h> #include <linux/jiffies.h> #include <asm/io.h> #include <asm/uaccess.h> #include <linux/io.h> #include <linux/uaccess.h> #include <linux/watchdog.h> /* adjustable parameters */ static int verbose = 0; static int verbose; static int port = 0x91; static int ticks = 10000; static spinlock_t cpu5wdt_lock; #define PFX "cpu5wdt: " Loading Loading @@ -76,6 +76,7 @@ static void cpu5wdt_trigger(unsigned long unused) if (cpu5wdt_device.running) ticks--; spin_lock(&cpu5wdt_lock); /* keep watchdog alive */ outb(1, port + CPU5WDT_TRIGGER_REG); Loading @@ -86,6 +87,7 @@ static void cpu5wdt_trigger(unsigned long unused) /* ticks doesn't matter anyway */ complete(&cpu5wdt_device.stop); } spin_unlock(&cpu5wdt_lock); } Loading @@ -100,6 +102,9 @@ static void cpu5wdt_reset(void) static void cpu5wdt_start(void) { unsigned long flags; spin_lock_irqsave(&cpu5wdt_lock, flags); if (!cpu5wdt_device.queue) { cpu5wdt_device.queue = 1; outb(0, port + CPU5WDT_TIME_A_REG); Loading @@ -111,18 +116,20 @@ static void cpu5wdt_start(void) } /* if process dies, counter is not decremented */ cpu5wdt_device.running++; spin_unlock_irqrestore(&cpu5wdt_lock, flags); } static int cpu5wdt_stop(void) { unsigned long flags; spin_lock_irqsave(&cpu5wdt_lock, flags); if (cpu5wdt_device.running) cpu5wdt_device.running = 0; ticks = cpu5wdt_device.default_ticks; spin_unlock_irqrestore(&cpu5wdt_lock, flags); if (verbose) printk(KERN_CRIT PFX "stop not possible\n"); return -EIO; } Loading @@ -132,7 +139,6 @@ static int cpu5wdt_open(struct inode *inode, struct file *file) { if (test_and_set_bit(0, &cpu5wdt_device.inuse)) return -EBUSY; return nonseekable_open(inode, file); } Loading @@ -142,12 +148,13 @@ static int cpu5wdt_release(struct inode *inode, struct file *file) return 0; } static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long cpu5wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; unsigned int value; static struct watchdog_info ident = { static struct watchdog_info ident = { .options = WDIOF_CARDRESET, .identity = "CPU5 WDT", }; Loading @@ -159,29 +166,20 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm case WDIOC_GETSTATUS: value = inb(port + CPU5WDT_STATUS_REG); value = (value >> 2) & 1; if ( copy_to_user(argp, &value, sizeof(int)) ) return -EFAULT; break; return put_user(value, p); case WDIOC_GETBOOTSTATUS: if ( copy_to_user(argp, &value, sizeof(int)) ) return -EFAULT; break; return put_user(0, p); case WDIOC_GETSUPPORT: if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; break; case WDIOC_SETOPTIONS: if ( copy_from_user(&value, argp, sizeof(int)) ) if (get_user(value, p)) return -EFAULT; switch(value) { case WDIOS_ENABLECARD: if (value & WDIOS_ENABLECARD) cpu5wdt_start(); break; case WDIOS_DISABLECARD: return cpu5wdt_stop(); default: return -EINVAL; } if (value & WDIOS_DISABLECARD) cpu5wdt_stop(); break; default: return -ENOTTY; Loading @@ -189,20 +187,19 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm return 0; } static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { if (!count) return -EIO; cpu5wdt_reset(); return count; } static const struct file_operations cpu5wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .ioctl = cpu5wdt_ioctl, .unlocked_ioctl = cpu5wdt_ioctl, .open = cpu5wdt_open, .write = cpu5wdt_write, .release = cpu5wdt_release, Loading @@ -222,7 +219,14 @@ static int __devinit cpu5wdt_init(void) int err; if (verbose) printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); init_completion(&cpu5wdt_device.stop); spin_lock_init(&cpu5wdt_lock); cpu5wdt_device.queue = 0; setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); cpu5wdt_device.default_ticks = ticks; if (!request_region(port, CPU5WDT_EXTENT, PFX)) { printk(KERN_ERR PFX "request_region failed\n"); Loading @@ -230,28 +234,20 @@ static int __devinit cpu5wdt_init(void) goto no_port; } if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) { printk(KERN_ERR PFX "misc_register failed\n"); goto no_misc; } /* watchdog reboot? */ val = inb(port + CPU5WDT_STATUS_REG); val = (val >> 2) & 1; if (!val) printk(KERN_INFO PFX "sorry, was my fault\n"); init_completion(&cpu5wdt_device.stop); cpu5wdt_device.queue = 0; clear_bit(0, &cpu5wdt_device.inuse); setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0); err = misc_register(&cpu5wdt_misc); if (err < 0) { printk(KERN_ERR PFX "misc_register failed\n"); goto no_misc; } cpu5wdt_device.default_ticks = ticks; printk(KERN_INFO PFX "init success\n"); return 0; no_misc: Loading