static int dc_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct dc_wdt *wdt; int ret; wdt = devm_kzalloc(dev, sizeof(struct dc_wdt), GFP_KERNEL); if (!wdt) return -ENOMEM; wdt->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(wdt->base)) return PTR_ERR(wdt->base); wdt->clk = devm_clk_get(dev, NULL); if (IS_ERR(wdt->clk)) return PTR_ERR(wdt->clk); dc_wdt_wdd.max_timeout = U32_MAX / clk_get_rate(wdt->clk); dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout; dc_wdt_wdd.parent = dev; spin_lock_init(&wdt->lock); watchdog_set_drvdata(&dc_wdt_wdd, wdt); watchdog_set_restart_priority(&dc_wdt_wdd, 128); watchdog_init_timeout(&dc_wdt_wdd, timeout, dev); watchdog_stop_on_reboot(&dc_wdt_wdd); ret = devm_watchdog_register_device(dev, &dc_wdt_wdd); if (ret) { dev_err(dev, "Failed to register watchdog device"); return ret; } return 0; }
static int bcm2835_wdt_probe(struct platform_device *pdev) { struct resource *res; struct device *dev = &pdev->dev; struct bcm2835_wdt *wdt; int err; wdt = devm_kzalloc(dev, sizeof(struct bcm2835_wdt), GFP_KERNEL); if (!wdt) return -ENOMEM; platform_set_drvdata(pdev, wdt); spin_lock_init(&wdt->lock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_ioremap_resource(dev, res); if (IS_ERR(wdt->base)) return PTR_ERR(wdt->base); watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt); watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev); watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout); bcm2835_wdt_wdd.parent = dev; if (bcm2835_wdt_is_running(wdt)) { /* * The currently active timeout value (set by the * bootloader) may be different from the module * heartbeat parameter or the value in device * tree. But we just need to set WDOG_HW_RUNNING, * because then the framework will "immediately" ping * the device, updating the timeout. */ set_bit(WDOG_HW_RUNNING, &bcm2835_wdt_wdd.status); } watchdog_set_restart_priority(&bcm2835_wdt_wdd, 128); watchdog_stop_on_reboot(&bcm2835_wdt_wdd); err = devm_watchdog_register_device(dev, &bcm2835_wdt_wdd); if (err) { dev_err(dev, "Failed to register watchdog device"); return err; } if (pm_power_off == NULL) pm_power_off = bcm2835_power_off; dev_info(dev, "Broadcom BCM2835 watchdog timer"); return 0; }
static int dc_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct dc_wdt *wdt; int ret; wdt = devm_kzalloc(dev, sizeof(struct dc_wdt), GFP_KERNEL); if (!wdt) return -ENOMEM; platform_set_drvdata(pdev, wdt); wdt->base = of_iomap(np, 0); if (!wdt->base) { dev_err(dev, "Failed to remap watchdog regs"); return -ENODEV; } wdt->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(wdt->clk)) { ret = PTR_ERR(wdt->clk); goto err_iounmap; } dc_wdt_wdd.max_timeout = U32_MAX / clk_get_rate(wdt->clk); dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout; dc_wdt_wdd.parent = &pdev->dev; spin_lock_init(&wdt->lock); watchdog_set_drvdata(&dc_wdt_wdd, wdt); watchdog_set_restart_priority(&dc_wdt_wdd, 128); watchdog_init_timeout(&dc_wdt_wdd, timeout, dev); ret = watchdog_register_device(&dc_wdt_wdd); if (ret) { dev_err(dev, "Failed to register watchdog device"); goto err_iounmap; } return 0; err_iounmap: iounmap(wdt->base); return ret; }
static int pnx4008_wdt_probe(struct platform_device *pdev) { struct resource *r; int ret = 0; watchdog_init_timeout(&pnx4008_wdd, heartbeat, &pdev->dev); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt_base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(wdt_base)) return PTR_ERR(wdt_base); wdt_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(wdt_clk)) return PTR_ERR(wdt_clk); ret = clk_prepare_enable(wdt_clk); if (ret) return ret; pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? WDIOF_CARDRESET : 0; pnx4008_wdd.parent = &pdev->dev; watchdog_set_nowayout(&pnx4008_wdd, nowayout); watchdog_set_restart_priority(&pnx4008_wdd, 128); pnx4008_wdt_stop(&pnx4008_wdd); /* disable for now */ ret = watchdog_register_device(&pnx4008_wdd); if (ret < 0) { dev_err(&pdev->dev, "cannot register watchdog device\n"); goto disable_clk; } dev_info(&pdev->dev, "heartbeat %d sec\n", pnx4008_wdd.timeout); return 0; disable_clk: clk_disable_unprepare(wdt_clk); return ret; }
static int mtk_wdt_probe(struct platform_device *pdev) { struct mtk_wdt_dev *mtk_wdt; struct resource *res; int err; mtk_wdt = devm_kzalloc(&pdev->dev, sizeof(*mtk_wdt), GFP_KERNEL); if (!mtk_wdt) return -ENOMEM; platform_set_drvdata(pdev, mtk_wdt); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mtk_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(mtk_wdt->wdt_base)) return PTR_ERR(mtk_wdt->wdt_base); mtk_wdt->wdt_dev.info = &mtk_wdt_info; mtk_wdt->wdt_dev.ops = &mtk_wdt_ops; mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT; mtk_wdt->wdt_dev.max_timeout = WDT_MAX_TIMEOUT; mtk_wdt->wdt_dev.min_timeout = WDT_MIN_TIMEOUT; mtk_wdt->wdt_dev.parent = &pdev->dev; watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, &pdev->dev); watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout); watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128); watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt); mtk_wdt_stop(&mtk_wdt->wdt_dev); err = watchdog_register_device(&mtk_wdt->wdt_dev); if (unlikely(err)) return err; dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n", mtk_wdt->wdt_dev.timeout, nowayout); return 0; }
static int da9063_wdt_probe(struct platform_device *pdev) { int ret; struct da9063 *da9063; struct da9063_watchdog *wdt; if (!pdev->dev.parent) return -EINVAL; da9063 = dev_get_drvdata(pdev->dev.parent); if (!da9063) return -EINVAL; wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); if (!wdt) return -ENOMEM; wdt->da9063 = da9063; wdt->wdtdev.info = &da9063_watchdog_info; wdt->wdtdev.ops = &da9063_watchdog_ops; wdt->wdtdev.min_timeout = DA9063_WDT_MIN_TIMEOUT; wdt->wdtdev.max_timeout = DA9063_WDT_MAX_TIMEOUT; wdt->wdtdev.timeout = DA9063_WDG_TIMEOUT; wdt->wdtdev.parent = &pdev->dev; wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS; watchdog_set_restart_priority(&wdt->wdtdev, 128); watchdog_set_drvdata(&wdt->wdtdev, wdt); dev_set_drvdata(&pdev->dev, wdt); ret = watchdog_register_device(&wdt->wdtdev); if (ret) return ret; return 0; }
static int lpc18xx_wdt_probe(struct platform_device *pdev) { struct lpc18xx_wdt_dev *lpc18xx_wdt; struct device *dev = &pdev->dev; struct resource *res; int ret; lpc18xx_wdt = devm_kzalloc(dev, sizeof(*lpc18xx_wdt), GFP_KERNEL); if (!lpc18xx_wdt) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); lpc18xx_wdt->base = devm_ioremap_resource(dev, res); if (IS_ERR(lpc18xx_wdt->base)) return PTR_ERR(lpc18xx_wdt->base); lpc18xx_wdt->reg_clk = devm_clk_get(dev, "reg"); if (IS_ERR(lpc18xx_wdt->reg_clk)) { dev_err(dev, "failed to get the reg clock\n"); return PTR_ERR(lpc18xx_wdt->reg_clk); } lpc18xx_wdt->wdt_clk = devm_clk_get(dev, "wdtclk"); if (IS_ERR(lpc18xx_wdt->wdt_clk)) { dev_err(dev, "failed to get the wdt clock\n"); return PTR_ERR(lpc18xx_wdt->wdt_clk); } ret = clk_prepare_enable(lpc18xx_wdt->reg_clk); if (ret) { dev_err(dev, "could not prepare or enable sys clock\n"); return ret; } ret = clk_prepare_enable(lpc18xx_wdt->wdt_clk); if (ret) { dev_err(dev, "could not prepare or enable wdt clock\n"); goto disable_reg_clk; } /* We use the clock rate to calculate timeouts */ lpc18xx_wdt->clk_rate = clk_get_rate(lpc18xx_wdt->wdt_clk); if (lpc18xx_wdt->clk_rate == 0) { dev_err(dev, "failed to get clock rate\n"); ret = -EINVAL; goto disable_wdt_clk; } lpc18xx_wdt->wdt_dev.info = &lpc18xx_wdt_info; lpc18xx_wdt->wdt_dev.ops = &lpc18xx_wdt_ops; lpc18xx_wdt->wdt_dev.min_timeout = DIV_ROUND_UP(LPC18XX_WDT_TC_MIN * LPC18XX_WDT_CLK_DIV, lpc18xx_wdt->clk_rate); lpc18xx_wdt->wdt_dev.max_timeout = (LPC18XX_WDT_TC_MAX * LPC18XX_WDT_CLK_DIV) / lpc18xx_wdt->clk_rate; lpc18xx_wdt->wdt_dev.timeout = min(lpc18xx_wdt->wdt_dev.max_timeout, LPC18XX_WDT_DEF_TIMEOUT); spin_lock_init(&lpc18xx_wdt->lock); lpc18xx_wdt->wdt_dev.parent = dev; watchdog_set_drvdata(&lpc18xx_wdt->wdt_dev, lpc18xx_wdt); ret = watchdog_init_timeout(&lpc18xx_wdt->wdt_dev, heartbeat, dev); __lpc18xx_wdt_set_timeout(lpc18xx_wdt); setup_timer(&lpc18xx_wdt->timer, lpc18xx_wdt_timer_feed, (unsigned long)&lpc18xx_wdt->wdt_dev); watchdog_set_nowayout(&lpc18xx_wdt->wdt_dev, nowayout); watchdog_set_restart_priority(&lpc18xx_wdt->wdt_dev, 128); platform_set_drvdata(pdev, lpc18xx_wdt); ret = watchdog_register_device(&lpc18xx_wdt->wdt_dev); if (ret) goto disable_wdt_clk; return 0; disable_wdt_clk: clk_disable_unprepare(lpc18xx_wdt->wdt_clk); disable_reg_clk: clk_disable_unprepare(lpc18xx_wdt->reg_clk); return ret; }
static int rwdt_probe(struct platform_device *pdev) { struct rwdt_priv *priv; struct resource *res; struct clk *clk; unsigned long clks_per_sec; int ret, i; if (rwdt_blacklisted(&pdev->dev)) return -ENODEV; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) return PTR_ERR(clk); pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); priv->clk_rate = clk_get_rate(clk); priv->wdev.bootstatus = (readb_relaxed(priv->base + RWTCSRA) & RWTCSRA_WOVF) ? WDIOF_CARDRESET : 0; pm_runtime_put(&pdev->dev); if (!priv->clk_rate) { ret = -ENOENT; goto out_pm_disable; } for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) { clks_per_sec = priv->clk_rate / clk_divs[i]; if (clks_per_sec && clks_per_sec < 65536) { priv->cks = i; break; } } if (i < 0) { dev_err(&pdev->dev, "Can't find suitable clock divider\n"); ret = -ERANGE; goto out_pm_disable; } priv->wdev.info = &rwdt_ident, priv->wdev.ops = &rwdt_ops, priv->wdev.parent = &pdev->dev; priv->wdev.min_timeout = 1; priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536); priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT); platform_set_drvdata(pdev, priv); watchdog_set_drvdata(&priv->wdev, priv); watchdog_set_nowayout(&priv->wdev, nowayout); watchdog_set_restart_priority(&priv->wdev, 0); /* This overrides the default timeout only if DT configuration was found */ ret = watchdog_init_timeout(&priv->wdev, 0, &pdev->dev); if (ret) dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n"); ret = watchdog_register_device(&priv->wdev); if (ret < 0) goto out_pm_disable; return 0; out_pm_disable: pm_runtime_disable(&pdev->dev); return ret; }
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; }
static int tangox_wdt_probe(struct platform_device *pdev) { struct tangox_wdt_device *dev; struct resource *res; u32 config; int err; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dev->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dev->base)) return PTR_ERR(dev->base); dev->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(dev->clk)) return PTR_ERR(dev->clk); err = clk_prepare_enable(dev->clk); if (err) return err; dev->clk_rate = clk_get_rate(dev->clk); if (!dev->clk_rate) { err = -EINVAL; goto err; } dev->wdt.parent = &pdev->dev; dev->wdt.info = &tangox_wdt_info; dev->wdt.ops = &tangox_wdt_ops; dev->wdt.timeout = DEFAULT_TIMEOUT; dev->wdt.min_timeout = 1; dev->wdt.max_hw_heartbeat_ms = (U32_MAX - 1) / dev->clk_rate; watchdog_init_timeout(&dev->wdt, timeout, &pdev->dev); watchdog_set_nowayout(&dev->wdt, nowayout); watchdog_set_drvdata(&dev->wdt, dev); /* * Deactivate counter if disable bit is set to avoid * accidental reset. */ config = readl(dev->base + WD_CONFIG); if (config & WD_CONFIG_DISABLE) writel(0, dev->base + WD_COUNTER); writel(WD_CONFIG_XTAL_IN, dev->base + WD_CONFIG); /* * Mark as active and restart with configured timeout if * already running. */ if (readl(dev->base + WD_COUNTER)) { set_bit(WDOG_HW_RUNNING, &dev->wdt.status); tangox_wdt_start(&dev->wdt); } watchdog_set_restart_priority(&dev->wdt, 128); err = watchdog_register_device(&dev->wdt); if (err) goto err; platform_set_drvdata(pdev, dev); dev_info(&pdev->dev, "SMP86xx/SMP87xx watchdog registered\n"); return 0; err: clk_disable_unprepare(dev->clk); return err; }