static int dw_wdt_open(struct inode *inode, struct file *filp) { if (test_and_set_bit(0, &dw_wdt.in_use)) return -EBUSY; /* Make sure we don't get unloaded. */ __module_get(THIS_MODULE); spin_lock(&dw_wdt.lock); if (!dw_wdt_is_enabled()) { /* * The watchdog is not currently enabled. Set the timeout to * the maximum and then start it. */ dw_wdt_set_top(DW_WDT_MAX_TOP); writel(WDOG_CONTROL_REG_WDT_EN_MASK, dw_wdt.regs + WDOG_CONTROL_REG_OFFSET); } dw_wdt_set_next_heartbeat(); spin_unlock(&dw_wdt.lock); return nonseekable_open(inode, filp); }
static int dw_wdt_restart(struct watchdog_device *wdd, unsigned long action, void *data) { struct dw_wdt *dw_wdt = to_dw_wdt(wdd); writel(0, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET); if (dw_wdt_is_enabled(dw_wdt)) writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt->regs + WDOG_COUNTER_RESTART_REG_OFFSET); else dw_wdt_arm_system_reset(dw_wdt); /* wait for reset to assert... */ mdelay(500); return 0; }
static int dw_wdt_open(struct inode *inode, struct file *filp) { if (test_and_set_bit(0, &dw_wdt.in_use)) return -EBUSY; __module_get(THIS_MODULE); spin_lock(&dw_wdt.lock); if (!dw_wdt_is_enabled()) { dw_wdt_set_top(DW_WDT_MAX_TOP); writel(WDOG_CONTROL_REG_WDT_EN_MASK, dw_wdt.regs + WDOG_CONTROL_REG_OFFSET); } dw_wdt_set_next_heartbeat(); spin_unlock(&dw_wdt.lock); return nonseekable_open(inode, filp); }
static int dw_wdt_drv_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct watchdog_device *wdd; struct dw_wdt *dw_wdt; struct resource *mem; int ret; dw_wdt = devm_kzalloc(dev, sizeof(*dw_wdt), GFP_KERNEL); if (!dw_wdt) return -ENOMEM; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); dw_wdt->regs = devm_ioremap_resource(dev, mem); if (IS_ERR(dw_wdt->regs)) return PTR_ERR(dw_wdt->regs); dw_wdt->clk = devm_clk_get(dev, NULL); if (IS_ERR(dw_wdt->clk)) return PTR_ERR(dw_wdt->clk); ret = clk_prepare_enable(dw_wdt->clk); if (ret) return ret; dw_wdt->rate = clk_get_rate(dw_wdt->clk); if (dw_wdt->rate == 0) { ret = -EINVAL; goto out_disable_clk; } dw_wdt->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL); if (IS_ERR(dw_wdt->rst)) { ret = PTR_ERR(dw_wdt->rst); goto out_disable_clk; } reset_control_deassert(dw_wdt->rst); wdd = &dw_wdt->wdd; wdd->info = &dw_wdt_ident; wdd->ops = &dw_wdt_ops; wdd->min_timeout = 1; wdd->max_hw_heartbeat_ms = dw_wdt_top_in_seconds(dw_wdt, DW_WDT_MAX_TOP) * 1000; wdd->parent = dev; watchdog_set_drvdata(wdd, dw_wdt); watchdog_set_nowayout(wdd, nowayout); watchdog_init_timeout(wdd, 0, dev); /* * If the watchdog is already running, use its already configured * timeout. Otherwise use the default or the value provided through * devicetree. */ if (dw_wdt_is_enabled(dw_wdt)) { wdd->timeout = dw_wdt_get_top(dw_wdt); set_bit(WDOG_HW_RUNNING, &wdd->status); } else { wdd->timeout = DW_WDT_DEFAULT_SECONDS; watchdog_init_timeout(wdd, 0, dev); } platform_set_drvdata(pdev, dw_wdt); watchdog_set_restart_priority(wdd, 128); ret = watchdog_register_device(wdd); if (ret) goto out_disable_clk; return 0; out_disable_clk: clk_disable_unprepare(dw_wdt->clk); return ret; }