static int ts72xx_wdt_open(struct inode *inode, struct file *file) { struct ts72xx_wdt *wdt = platform_get_drvdata(ts72xx_wdt_pdev); int regval; /* * Try to convert default timeout to valid register * value first. */ regval = timeout_to_regval(timeout); if (regval < 0) { dev_err(&wdt->pdev->dev, "failed to convert timeout (%d) to register value\n", timeout); return -EINVAL; } if (mutex_lock_interruptible(&wdt->lock)) return -ERESTARTSYS; if ((wdt->flags & TS72XX_WDT_BUSY_FLAG) != 0) { mutex_unlock(&wdt->lock); return -EBUSY; } wdt->flags = TS72XX_WDT_BUSY_FLAG; wdt->regval = regval; file->private_data = wdt; ts72xx_wdt_start(wdt); mutex_unlock(&wdt->lock); return nonseekable_open(inode, file); }
static int ts72xx_wdt_settimeout(struct watchdog_device *wdd, unsigned int to) { struct ts72xx_wdt_priv *priv = watchdog_get_drvdata(wdd); if (to == 1) { priv->regval = TS72XX_WDT_CTRL_1SEC; } else if (to == 2) { priv->regval = TS72XX_WDT_CTRL_2SEC; } else if (to <= 4) { priv->regval = TS72XX_WDT_CTRL_4SEC; to = 4; } else { priv->regval = TS72XX_WDT_CTRL_8SEC; if (to <= 8) to = 8; } wdd->timeout = to; if (watchdog_active(wdd)) { ts72xx_wdt_stop(wdd); ts72xx_wdt_start(wdd); } return 0; }
static long ts72xx_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct ts72xx_wdt *wdt = file->private_data; void __user *argp = (void __user *)arg; int __user *p = (int __user *)argp; int error = 0; if (mutex_lock_interruptible(&wdt->lock)) return -ERESTARTSYS; switch (cmd) { case WDIOC_GETSUPPORT: error = copy_to_user(argp, &winfo, sizeof(winfo)); break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: error = put_user(0, p); break; case WDIOC_KEEPALIVE: ts72xx_wdt_kick(wdt); break; case WDIOC_SETOPTIONS: { int options; if (get_user(options, p)) { error = -EFAULT; break; } error = -EINVAL; if ((options & WDIOS_DISABLECARD) != 0) { ts72xx_wdt_stop(wdt); error = 0; } if ((options & WDIOS_ENABLECARD) != 0) { ts72xx_wdt_start(wdt); error = 0; } break; } case WDIOC_SETTIMEOUT: { int new_timeout; if (get_user(new_timeout, p)) { error = -EFAULT; } else { int regval; regval = timeout_to_regval(new_timeout); if (regval < 0) { error = -EINVAL; } else { ts72xx_wdt_stop(wdt); wdt->regval = regval; ts72xx_wdt_start(wdt); } } if (error) break; /*FALLTHROUGH*/ } case WDIOC_GETTIMEOUT: if (put_user(regval_to_timeout(wdt->regval), p)) error = -EFAULT; break; default: error = -ENOTTY; break; } mutex_unlock(&wdt->lock); return error; }