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 int ts72xx_wdt_release(struct inode *inode, struct file *file) { struct ts72xx_wdt *wdt = file->private_data; if (mutex_lock_interruptible(&wdt->lock)) return -ERESTARTSYS; if ((wdt->flags & TS72XX_WDT_EXPECT_CLOSE_FLAG) != 0) { ts72xx_wdt_stop(wdt); } else { dev_warn(&wdt->pdev->dev, "TS-72XX WDT device closed unexpectly. " "Watchdog timer will not stop!\n"); /* * Kick it one more time, to give userland some time * to recover (for example, respawning the kicker * daemon). */ ts72xx_wdt_kick(wdt); } wdt->flags = 0; mutex_unlock(&wdt->lock); return 0; }
static int ts72xx_wdt_probe(struct platform_device *pdev) { struct ts72xx_wdt *wdt; struct resource *r1, *r2; int error = 0; wdt = devm_kzalloc(&pdev->dev, sizeof(struct ts72xx_wdt), GFP_KERNEL); if (!wdt) { dev_err(&pdev->dev, "failed to allocate memory\n"); return -ENOMEM; } r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r1) { dev_err(&pdev->dev, "failed to get memory resource\n"); return -ENODEV; } wdt->control_reg = devm_ioremap_resource(&pdev->dev, r1); if (IS_ERR(wdt->control_reg)) return PTR_ERR(wdt->control_reg); r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!r2) { dev_err(&pdev->dev, "failed to get memory resource\n"); return -ENODEV; } wdt->feed_reg = devm_ioremap_resource(&pdev->dev, r2); if (IS_ERR(wdt->feed_reg)) return PTR_ERR(wdt->feed_reg); platform_set_drvdata(pdev, wdt); ts72xx_wdt_pdev = pdev; wdt->pdev = pdev; mutex_init(&wdt->lock); /* make sure that the watchdog is disabled */ ts72xx_wdt_stop(wdt); error = misc_register(&ts72xx_wdt_miscdev); if (error) { dev_err(&pdev->dev, "failed to register miscdev\n"); return error; } dev_info(&pdev->dev, "TS-72xx Watchdog driver\n"); return 0; }
static int ts72xx_wdt_probe(struct platform_device *pdev) { struct ts72xx_wdt *wdt; struct resource *r1, *r2; int error = 0; wdt = kzalloc(sizeof(struct ts72xx_wdt), GFP_KERNEL); if (!wdt) { dev_err(&pdev->dev, "failed to allocate memory\n"); return -ENOMEM; } r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r1) { dev_err(&pdev->dev, "failed to get memory resource\n"); error = -ENODEV; goto fail; } r1 = request_mem_region(r1->start, resource_size(r1), pdev->name); if (!r1) { dev_err(&pdev->dev, "cannot request memory region\n"); error = -EBUSY; goto fail; } wdt->control_reg = ioremap(r1->start, resource_size(r1)); if (!wdt->control_reg) { dev_err(&pdev->dev, "failed to map memory\n"); error = -ENODEV; goto fail_free_control; } r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!r2) { dev_err(&pdev->dev, "failed to get memory resource\n"); error = -ENODEV; goto fail_unmap_control; } r2 = request_mem_region(r2->start, resource_size(r2), pdev->name); if (!r2) { dev_err(&pdev->dev, "cannot request memory region\n"); error = -EBUSY; goto fail_unmap_control; } wdt->feed_reg = ioremap(r2->start, resource_size(r2)); if (!wdt->feed_reg) { dev_err(&pdev->dev, "failed to map memory\n"); error = -ENODEV; goto fail_free_feed; } platform_set_drvdata(pdev, wdt); ts72xx_wdt_pdev = pdev; wdt->pdev = pdev; mutex_init(&wdt->lock); /* make sure that the watchdog is disabled */ ts72xx_wdt_stop(wdt); error = misc_register(&ts72xx_wdt_miscdev); if (error) { dev_err(&pdev->dev, "failed to register miscdev\n"); goto fail_unmap_feed; } dev_info(&pdev->dev, "TS-72xx Watchdog driver\n"); return 0; fail_unmap_feed: platform_set_drvdata(pdev, NULL); iounmap(wdt->feed_reg); fail_free_feed: release_mem_region(r2->start, resource_size(r2)); fail_unmap_control: iounmap(wdt->control_reg); fail_free_control: release_mem_region(r1->start, resource_size(r1)); fail: kfree(wdt); return error; }
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; }