static int epx_c3_release(struct inode *inode, struct file *file) { if (!nowayout) epx_c3_stop(); epx_c3_alive = 0; return 0; }
static int epx_c3_release(struct inode *inode, struct file *file) { /* Shut off the timer. * Lock it in if it's a module and we defined ...NOWAYOUT */ if (!nowayout) epx_c3_stop(); /* Turn the WDT off */ epx_c3_alive = 0; return 0; }
static int epx_c3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int options, retval = -EINVAL; int __user *argp = (void __user *)arg; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .firmware_version = 0, .identity = "Winsystems EPX-C3 H/W Watchdog", }; switch (cmd) { case WDIOC_GETSUPPORT: if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; return 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, argp); case WDIOC_KEEPALIVE: epx_c3_pet(); return 0; case WDIOC_GETTIMEOUT: return put_user(WATCHDOG_TIMEOUT, argp); case WDIOC_SETOPTIONS: if (get_user(options, argp)) return -EFAULT; if (options & WDIOS_DISABLECARD) { epx_c3_stop(); retval = 0; } if (options & WDIOS_ENABLECARD) { epx_c3_start(); retval = 0; } return retval; default: return -ENOIOCTLCMD; } } static int epx_c3_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) epx_c3_stop(); /* Turn the WDT off */ return NOTIFY_DONE; } static struct file_operations epx_c3_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = epx_c3_write, .ioctl = epx_c3_ioctl, .open = epx_c3_open, .release = epx_c3_release, }; static struct miscdevice epx_c3_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &epx_c3_fops, }; static struct notifier_block epx_c3_notifier = { .notifier_call = epx_c3_notify_sys, }; static const char banner[] __initdata = KERN_INFO PFX "Hardware Watchdog Timer for Winsystems EPX-C3 SBC: 0.1\n"; static int __init watchdog_init(void) { int ret; if (!request_region(EPXC3_WATCHDOG_CTL_REG, 2, "epxc3_watchdog")) return -EBUSY; ret = register_reboot_notifier(&epx_c3_notifier); if (ret) { printk(KERN_ERR PFX "cannot register reboot notifier " "(err=%d)\n", ret); goto out; } ret = misc_register(&epx_c3_miscdev); if (ret) { printk(KERN_ERR PFX "cannot register miscdev on minor=%d " "(err=%d)\n", WATCHDOG_MINOR, ret); unregister_reboot_notifier(&epx_c3_notifier); goto out; } printk(banner); return 0; out: release_region(EPXC3_WATCHDOG_CTL_REG, 2); return ret; } static void __exit watchdog_exit(void) { misc_deregister(&epx_c3_miscdev); unregister_reboot_notifier(&epx_c3_notifier); release_region(EPXC3_WATCHDOG_CTL_REG, 2); }