static int sirfsoc_wdt_probe(struct platform_device *pdev) { struct resource *res; int ret; void __iomem *base; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); watchdog_set_drvdata(&sirfsoc_wdd, base); watchdog_init_timeout(&sirfsoc_wdd, timeout, &pdev->dev); watchdog_set_nowayout(&sirfsoc_wdd, nowayout); sirfsoc_wdd.parent = &pdev->dev; ret = watchdog_register_device(&sirfsoc_wdd); if (ret) return ret; platform_set_drvdata(pdev, &sirfsoc_wdd); return 0; }
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 moxart_wdt_probe(struct platform_device *pdev) { struct moxart_wdt_dev *moxart_wdt; struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; struct resource *res; struct clk *clk; int err; unsigned int max_timeout; bool nowayout = WATCHDOG_NOWAYOUT; moxart_wdt = devm_kzalloc(dev, sizeof(*moxart_wdt), GFP_KERNEL); if (!moxart_wdt) return -ENOMEM; platform_set_drvdata(pdev, moxart_wdt); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); moxart_wdt->base = devm_ioremap_resource(dev, res); if (IS_ERR(moxart_wdt->base)) return PTR_ERR(moxart_wdt->base); clk = of_clk_get(node, 0); if (IS_ERR(clk)) { pr_err("%s: of_clk_get failed\n", __func__); return PTR_ERR(clk); } moxart_wdt->clock_frequency = clk_get_rate(clk); if (moxart_wdt->clock_frequency == 0) { pr_err("%s: incorrect clock frequency\n", __func__); return -EINVAL; } max_timeout = UINT_MAX / moxart_wdt->clock_frequency; moxart_wdt->dev.info = &moxart_wdt_info; moxart_wdt->dev.ops = &moxart_wdt_ops; moxart_wdt->dev.timeout = max_timeout; moxart_wdt->dev.min_timeout = 1; moxart_wdt->dev.max_timeout = max_timeout; moxart_wdt->dev.parent = dev; watchdog_init_timeout(&moxart_wdt->dev, heartbeat, dev); watchdog_set_nowayout(&moxart_wdt->dev, nowayout); watchdog_set_drvdata(&moxart_wdt->dev, moxart_wdt); err = watchdog_register_device(&moxart_wdt->dev); if (err) return err; moxart_restart_ctx = moxart_wdt; arm_pm_restart = moxart_wdt_restart; dev_dbg(dev, "Watchdog enabled (heartbeat=%d sec, nowayout=%d)\n", moxart_wdt->dev.timeout, nowayout); return 0; }
static int rn5t618_wdt_probe(struct platform_device *pdev) { struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent); struct rn5t618_wdt *wdt; int min_timeout, max_timeout; wdt = devm_kzalloc(&pdev->dev, sizeof(struct rn5t618_wdt), GFP_KERNEL); if (!wdt) return -ENOMEM; min_timeout = rn5t618_wdt_map[0].time; max_timeout = rn5t618_wdt_map[ARRAY_SIZE(rn5t618_wdt_map) - 1].time; wdt->rn5t618 = rn5t618; wdt->wdt_dev.info = &rn5t618_wdt_info; wdt->wdt_dev.ops = &rn5t618_wdt_ops; wdt->wdt_dev.min_timeout = min_timeout; wdt->wdt_dev.max_timeout = max_timeout; wdt->wdt_dev.timeout = max_timeout; wdt->wdt_dev.parent = &pdev->dev; watchdog_set_drvdata(&wdt->wdt_dev, wdt); watchdog_init_timeout(&wdt->wdt_dev, timeout, &pdev->dev); watchdog_set_nowayout(&wdt->wdt_dev, nowayout); platform_set_drvdata(pdev, wdt); return watchdog_register_device(&wdt->wdt_dev); }
static int rza_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rza_wdt *priv; unsigned long rate; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); priv->clk = devm_clk_get(dev, NULL); if (IS_ERR(priv->clk)) return PTR_ERR(priv->clk); rate = clk_get_rate(priv->clk); if (rate < 16384) { dev_err(dev, "invalid clock rate (%ld)\n", rate); return -ENOENT; } priv->wdev.info = &rza_wdt_ident, priv->wdev.ops = &rza_wdt_ops, priv->wdev.parent = dev; priv->cks = (u8)(uintptr_t) of_device_get_match_data(dev); if (priv->cks == CKS_4BIT) { /* Assume slowest clock rate possible (CKS=0xF) */ priv->wdev.max_timeout = (DIVIDER_4BIT * U8_MAX) / rate; } else if (priv->cks == CKS_3BIT) { /* Assume slowest clock rate possible (CKS=7) */ rate /= DIVIDER_3BIT; /* * Since the max possible timeout of our 8-bit count * register is less than a second, we must use * max_hw_heartbeat_ms. */ priv->wdev.max_hw_heartbeat_ms = (1000 * U8_MAX) / rate; dev_dbg(dev, "max hw timeout of %dms\n", priv->wdev.max_hw_heartbeat_ms); } priv->wdev.min_timeout = 1; priv->wdev.timeout = DEFAULT_TIMEOUT; watchdog_init_timeout(&priv->wdev, 0, dev); watchdog_set_drvdata(&priv->wdev, priv); ret = devm_watchdog_register_device(dev, &priv->wdev); if (ret) dev_err(dev, "Cannot register watchdog device\n"); return ret; }
static int rt288x_wdt_probe(struct platform_device *pdev) { struct resource *res; int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rt288x_wdt_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(rt288x_wdt_base)) return PTR_ERR(rt288x_wdt_base); rt288x_wdt_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(rt288x_wdt_clk)) return PTR_ERR(rt288x_wdt_clk); rt288x_wdt_reset = devm_reset_control_get(&pdev->dev, NULL); if (!IS_ERR(rt288x_wdt_reset)) reset_control_deassert(rt288x_wdt_reset); rt288x_wdt_freq = clk_get_rate(rt288x_wdt_clk) / RALINK_WDT_PRESCALE; rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause(); rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq); rt288x_wdt_dev.parent = &pdev->dev; watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout, &pdev->dev); watchdog_set_nowayout(&rt288x_wdt_dev, nowayout); ret = watchdog_register_device(&rt288x_wdt_dev); if (!ret) dev_info(&pdev->dev, "Initialized\n"); return 0; }
static int __init wdt_init(void) { int ret; int chip; static const char * const chip_name[] = { "W83627HF", "W83627S", "W83697HF", "W83697UG", "W83637HF", "W83627THF", "W83687THF", "W83627EHF", "W83627DHG", "W83627UHG", "W83667HG", "W83667DHG-P", "W83667HG-B", "NCT6775", "NCT6776", "NCT6779", "NCT6791", "NCT6792", "NCT6793", "NCT6795", "NCT6102", }; wdt_io = 0x2e; chip = wdt_find(0x2e); if (chip < 0) { wdt_io = 0x4e; chip = wdt_find(0x4e); if (chip < 0) return chip; } pr_info("WDT driver for %s Super I/O chip initialising\n", chip_name[chip]); watchdog_init_timeout(&wdt_dev, timeout, NULL); watchdog_set_nowayout(&wdt_dev, nowayout); watchdog_stop_on_reboot(&wdt_dev); ret = w83627hf_init(&wdt_dev, chip); if (ret) { pr_err("failed to initialize watchdog (err=%d)\n", ret); return ret; } ret = watchdog_register_device(&wdt_dev); if (ret) return ret; pr_info("initialized. timeout=%d sec (nowayout=%d)\n", wdt_dev.timeout, nowayout); return ret; }
static int ltq_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ltq_wdt_priv *priv; struct watchdog_device *wdt; struct clk *clk; const struct ltq_wdt_hw *ltq_wdt_hw; int ret; u32 status; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->membase = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->membase)) return PTR_ERR(priv->membase); /* we do not need to enable the clock as it is always running */ clk = clk_get_io(); priv->clk_rate = clk_get_rate(clk) / LTQ_WDT_DIVIDER; if (!priv->clk_rate) { dev_err(dev, "clock rate less than divider %i\n", LTQ_WDT_DIVIDER); return -EINVAL; } wdt = &priv->wdt; wdt->info = <q_wdt_info; wdt->ops = <q_wdt_ops; wdt->min_timeout = 1; wdt->max_timeout = LTQ_WDT_CR_MAX_TIMEOUT / priv->clk_rate; wdt->timeout = wdt->max_timeout; wdt->parent = dev; ltq_wdt_hw = of_device_get_match_data(dev); if (ltq_wdt_hw && ltq_wdt_hw->bootstatus_get) { ret = ltq_wdt_hw->bootstatus_get(dev); if (ret >= 0) wdt->bootstatus = ret; } watchdog_set_nowayout(wdt, nowayout); watchdog_init_timeout(wdt, 0, dev); status = ltq_wdt_r32(priv, LTQ_WDT_SR); if (status & LTQ_WDT_SR_EN) { /* * If the watchdog is already running overwrite it with our * new settings. Stop is not needed as the start call will * replace all settings anyway. */ ltq_wdt_start(wdt); set_bit(WDOG_HW_RUNNING, &wdt->status); } return devm_watchdog_register_device(dev, wdt); }
static int atlas7_wdt_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct atlas7_wdog *wdt; struct resource *res; struct clk *clk; int ret; wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); if (!wdt) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(wdt->base)) return PTR_ERR(wdt->base); clk = of_clk_get(np, 0); if (IS_ERR(clk)) return PTR_ERR(clk); ret = clk_prepare_enable(clk); if (ret) { dev_err(&pdev->dev, "clk enable failed\n"); goto err; } /* disable watchdog hardware */ writel(0, wdt->base + ATLAS7_WDT_CNT_CTRL); wdt->tick_rate = clk_get_rate(clk); if (!wdt->tick_rate) { ret = -EINVAL; goto err1; } wdt->clk = clk; atlas7_wdd.min_timeout = 1; atlas7_wdd.max_timeout = UINT_MAX / wdt->tick_rate; watchdog_init_timeout(&atlas7_wdd, 0, &pdev->dev); watchdog_set_nowayout(&atlas7_wdd, nowayout); watchdog_set_drvdata(&atlas7_wdd, wdt); platform_set_drvdata(pdev, &atlas7_wdd); ret = watchdog_register_device(&atlas7_wdd); if (ret) goto err1; return 0; err1: clk_disable_unprepare(clk); err: clk_put(clk); return ret; }
static int __init at91wdt_probe(struct platform_device *pdev) { struct at91wdt_drvdata *driver_data; struct resource *r; int ret; driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), GFP_KERNEL); if (!driver_data) { dev_err(&pdev->dev, "Unable to alloacate watchdog device\n"); return -ENOMEM; } watchdog_set_drvdata(&at91wdt_wdd, driver_data); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) return -ENODEV; driver_data->phybase = ioremap(r->start, resource_size(r)); if (!driver_data->phybase) { dev_err(&pdev->dev, "failed to map registers, aborting.\n"); return -ENOMEM; } ret = watchdog_register_device(&at91wdt_wdd); if (ret) { dev_err(&pdev->dev, "cannot register watchdog (%d)\n", ret); return ret; } watchdog_set_nowayout(&at91wdt_wdd, nowayout); watchdog_init_timeout(&at91wdt_wdd, heartbeat, pdev->dev.of_node); ret = at91wdt_enable(&at91wdt_wdd, ms_to_ticks(WDT_HW_TIMEOUT * 1000)); if (ret) { pr_info("the watchdog has been disabled\n"); return 0; } driver_data->next_heartbeat = jiffies + at91wdt_wdd.timeout * HZ; setup_timer(&driver_data->timer, at91wdt_timer_tick, (unsigned long)&at91wdt_wdd); mod_timer(&driver_data->timer, jiffies + WDT_TIMEOUT); pr_info("enabled (heartbeat=%d sec, nowayout=%d)\n", at91wdt_wdd.timeout, nowayout); 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 menf21bmc_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; int ret, bmc_timeout; struct menf21bmc_wdt *drv_data; struct i2c_client *i2c_client = to_i2c_client(dev->parent); drv_data = devm_kzalloc(dev, sizeof(struct menf21bmc_wdt), GFP_KERNEL); if (!drv_data) return -ENOMEM; drv_data->wdt.ops = &menf21bmc_wdt_ops; drv_data->wdt.info = &menf21bmc_wdt_info; drv_data->wdt.min_timeout = BMC_WD_TIMEOUT_MIN; drv_data->wdt.max_timeout = BMC_WD_TIMEOUT_MAX; drv_data->wdt.parent = dev; drv_data->i2c_client = i2c_client; /* * Get the current wdt timeout value from the BMC because * the BMC will save the value set before if the system restarts. */ bmc_timeout = i2c_smbus_read_word_data(drv_data->i2c_client, BMC_CMD_WD_TIME); if (bmc_timeout < 0) { dev_err(dev, "failed to get current WDT timeout\n"); return bmc_timeout; } watchdog_init_timeout(&drv_data->wdt, bmc_timeout / 10, dev); watchdog_set_nowayout(&drv_data->wdt, nowayout); watchdog_set_drvdata(&drv_data->wdt, drv_data); platform_set_drvdata(pdev, drv_data); ret = menf21bmc_wdt_set_bootstatus(drv_data); if (ret < 0) { dev_err(dev, "failed to set Watchdog bootstatus\n"); return ret; } ret = devm_watchdog_register_device(dev, &drv_data->wdt); if (ret) { dev_err(dev, "failed to register Watchdog device\n"); return ret; } dev_info(dev, "MEN 14F021P00 BMC Watchdog device enabled\n"); return 0; }
static int uniphier_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct uniphier_wdt_dev *wdev; struct regmap *regmap; struct device_node *parent; int ret; wdev = devm_kzalloc(dev, sizeof(*wdev), GFP_KERNEL); if (!wdev) return -ENOMEM; platform_set_drvdata(pdev, wdev); parent = of_get_parent(dev->of_node); /* parent should be syscon node */ regmap = syscon_node_to_regmap(parent); of_node_put(parent); if (IS_ERR(regmap)) return PTR_ERR(regmap); wdev->regmap = regmap; wdev->wdt_dev.info = &uniphier_wdt_info; wdev->wdt_dev.ops = &uniphier_wdt_ops; wdev->wdt_dev.max_timeout = WDT_PERIOD_MAX; wdev->wdt_dev.min_timeout = WDT_PERIOD_MIN; wdev->wdt_dev.parent = dev; if (watchdog_init_timeout(&wdev->wdt_dev, timeout, dev) < 0) { wdev->wdt_dev.timeout = WDT_DEFAULT_TIMEOUT; } watchdog_set_nowayout(&wdev->wdt_dev, nowayout); watchdog_stop_on_reboot(&wdev->wdt_dev); watchdog_set_drvdata(&wdev->wdt_dev, wdev); uniphier_watchdog_stop(&wdev->wdt_dev); ret = regmap_write(wdev->regmap, WDTRSTSEL, WDTRSTSEL_RSTSEL_BOTH); if (ret) return ret; ret = devm_watchdog_register_device(dev, &wdev->wdt_dev); if (ret) return ret; dev_info(dev, "watchdog driver (timeout=%d sec, nowayout=%d)\n", wdev->wdt_dev.timeout, nowayout); return 0; }
static int __init softdog_init(void) { int ret; watchdog_init_timeout(&softdog_dev, soft_margin, NULL); watchdog_set_nowayout(&softdog_dev, nowayout); watchdog_stop_on_reboot(&softdog_dev); ret = watchdog_register_device(&softdog_dev); if (ret) return ret; pr_info("initialized. soft_noboot=%d soft_margin=%d sec soft_panic=%d (nowayout=%d)\n", soft_noboot, softdog_dev.timeout, soft_panic, nowayout); 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 ts72xx_wdt_probe(struct platform_device *pdev) { struct ts72xx_wdt_priv *priv; struct watchdog_device *wdd; struct resource *res; int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->control_reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->control_reg)) return PTR_ERR(priv->control_reg); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); priv->feed_reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->feed_reg)) return PTR_ERR(priv->feed_reg); wdd = &priv->wdd; wdd->info = &ts72xx_wdt_ident; wdd->ops = &ts72xx_wdt_ops; wdd->min_timeout = 1; wdd->max_hw_heartbeat_ms = 8000; wdd->parent = &pdev->dev; watchdog_set_nowayout(wdd, nowayout); wdd->timeout = TS72XX_WDT_DEFAULT_TIMEOUT; watchdog_init_timeout(wdd, timeout, &pdev->dev); watchdog_set_drvdata(wdd, priv); ret = devm_watchdog_register_device(&pdev->dev, wdd); if (ret) return ret; dev_info(&pdev->dev, "TS-72xx Watchdog driver\n"); return 0; }
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 pmic_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; int ret; struct stpmic1 *pmic; struct stpmic1_wdt *wdt; if (!dev->parent) return -EINVAL; pmic = dev_get_drvdata(dev->parent); if (!pmic) return -EINVAL; wdt = devm_kzalloc(dev, sizeof(struct stpmic1_wdt), GFP_KERNEL); if (!wdt) return -ENOMEM; wdt->pmic = pmic; wdt->wdtdev.info = &pmic_watchdog_info; wdt->wdtdev.ops = &pmic_watchdog_ops; wdt->wdtdev.min_timeout = PMIC_WDT_MIN_TIMEOUT; wdt->wdtdev.max_timeout = PMIC_WDT_MAX_TIMEOUT; wdt->wdtdev.parent = dev; wdt->wdtdev.timeout = PMIC_WDT_DEFAULT_TIMEOUT; watchdog_init_timeout(&wdt->wdtdev, 0, dev); watchdog_set_nowayout(&wdt->wdtdev, nowayout); watchdog_set_drvdata(&wdt->wdtdev, wdt); ret = devm_watchdog_register_device(dev, &wdt->wdtdev); if (ret) return ret; dev_dbg(wdt->pmic->dev, "PMIC Watchdog driver probed\n"); return 0; }
static int orion_wdt_probe(struct platform_device *pdev) { struct resource *res; int ret; clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { dev_err(&pdev->dev, "Orion Watchdog missing clock\n"); return -ENODEV; } clk_prepare_enable(clk); wdt_tclk = clk_get_rate(clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; wdt_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!wdt_reg) return -ENOMEM; wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk; orion_wdt.timeout = wdt_max_duration; orion_wdt.max_timeout = wdt_max_duration; watchdog_init_timeout(&orion_wdt, heartbeat, &pdev->dev); watchdog_set_nowayout(&orion_wdt, nowayout); ret = watchdog_register_device(&orion_wdt); if (ret) { clk_disable_unprepare(clk); return ret; } pr_info("Initial timeout %d sec%s\n", orion_wdt.timeout, nowayout ? ", nowayout" : ""); return 0; }
static int mt7621_wdt_probe(struct platform_device *pdev) { struct resource *res; int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mt7621_wdt_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(mt7621_wdt_base)) return PTR_ERR(mt7621_wdt_base); mt7621_wdt_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(mt7621_wdt_reset)) reset_control_deassert(mt7621_wdt_reset); mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause(); watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout, &pdev->dev); watchdog_set_nowayout(&mt7621_wdt_dev, nowayout); ret = watchdog_register_device(&mt7621_wdt_dev); return 0; }
static int s3c2410wdt_probe(struct platform_device *pdev) { struct device *dev; unsigned int wtcon; int started = 0; int ret; struct s3c_watchdog_platdata *pdata; DBG("%s: probe=%p\n", __func__, pdev); dev = &pdev->dev; wdt_dev = &pdev->dev; if (s3c2410wdt_get_platdata(pdev)) { dev_err(dev, "failed to get platdata\n"); return -EINVAL; } pdata = dev_get_platdata(&pdev->dev); wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (wdt_mem == NULL) { dev_err(dev, "no memory resource specified\n"); return -ENOENT; } wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (wdt_irq == NULL) { dev_err(dev, "no irq resource specified\n"); ret = -ENOENT; goto err; } /* get the memory region for the watchdog timer */ wdt_base = devm_ioremap_resource(dev, wdt_mem); if (IS_ERR(wdt_base)) { ret = PTR_ERR(wdt_base); goto err; } DBG("probe: mapped wdt_base=%p\n", wdt_base); rate_wdt_clock = devm_clk_get(dev, "rate_watchdog"); if (IS_ERR(rate_wdt_clock)) { dev_err(dev, "failed to find watchdog rate clock source\n"); ret = PTR_ERR(rate_wdt_clock); goto err; } wdt_clock = devm_clk_get(dev, "gate_watchdog"); if (IS_ERR(wdt_clock)) { dev_err(dev, "failed to find watchdog clock source\n"); ret = PTR_ERR(wdt_clock); goto err; } clk_prepare_enable(wdt_clock); /* Enable pmu watchdog reset control */ if (pdata != NULL && pdata->pmu_wdt_control != NULL) { s3c2410wdt_int_clear(&s3c2410_wdd); pdata->pmu_wdt_control(1, pdata->pmu_wdt_reset_type); } /* see if we can actually set the requested timer margin, and if * not, try the default value */ ret = s3c2410wdt_set_min_max_timeout(&s3c2410_wdd); if (ret != 0) { dev_err(dev, "clock rate is 0\n"); goto err_clk; } watchdog_init_timeout(&s3c2410_wdd, tmr_margin, &pdev->dev); if (s3c2410wdt_set_heartbeat(&s3c2410_wdd, s3c2410_wdd.timeout)) { started = s3c2410wdt_set_heartbeat(&s3c2410_wdd, CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); if (started == 0) dev_info(dev, "tmr_margin value out of range, default %d used\n", CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); else dev_info(dev, "default timer value is out of range, " "cannot start\n"); } ret = devm_request_irq(dev, wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev); if (ret != 0) { dev_err(dev, "failed to install irq (%d)\n", ret); goto err_clk; } watchdog_set_nowayout(&s3c2410_wdd, nowayout); ret = watchdog_register_device(&s3c2410_wdd); if (ret) { dev_err(dev, "cannot register watchdog (%d)\n", ret); goto err_clk; } if (tmr_atboot && started == 0) { dev_info(dev, "starting watchdog timer\n"); s3c2410wdt_start(&s3c2410_wdd); } else if (!tmr_atboot) { /* if we're not enabling the watchdog, then ensure it is * disabled if it has been left running from the bootloader * or other source */ s3c2410wdt_stop(&s3c2410_wdd); } /* print out a statement of readiness */ wtcon = readl(wdt_base + S3C2410_WTCON); dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n", (wtcon & S3C2410_WTCON_ENABLE) ? "" : "in", (wtcon & S3C2410_WTCON_RSTEN) ? "en" : "dis", (wtcon & S3C2410_WTCON_INTEN) ? "en" : "dis"); return 0; err_clk: clk_disable_unprepare(wdt_clock); wdt_clock = NULL; rate_wdt_clock = NULL; err: wdt_irq = NULL; wdt_mem = NULL; 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_timeout = (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_ACTIVE, &dev->wdt.status); tangox_wdt_start(&dev->wdt); } err = watchdog_register_device(&dev->wdt); if (err) goto err; platform_set_drvdata(pdev, dev); dev->restart.notifier_call = tangox_wdt_restart; dev->restart.priority = 128; err = register_restart_handler(&dev->restart); if (err) dev_warn(&pdev->dev, "failed to register restart handler\n"); dev_info(&pdev->dev, "SMP86xx/SMP87xx watchdog registered\n"); return 0; err: clk_disable_unprepare(dev->clk); return err; }
static int omap_wdt_probe(struct platform_device *pdev) { struct omap_wd_timer_platform_data *pdata = dev_get_platdata(&pdev->dev); struct resource *res; struct omap_wdt_dev *wdev; int ret; wdev = devm_kzalloc(&pdev->dev, sizeof(*wdev), GFP_KERNEL); if (!wdev) return -ENOMEM; wdev->omap_wdt_users = false; wdev->dev = &pdev->dev; wdev->wdt_trgr_pattern = 0x1234; mutex_init(&wdev->lock); /* reserve static register mappings */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdev->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(wdev->base)) return PTR_ERR(wdev->base); wdev->wdog.info = &omap_wdt_info; wdev->wdog.ops = &omap_wdt_ops; wdev->wdog.min_timeout = TIMER_MARGIN_MIN; wdev->wdog.max_timeout = TIMER_MARGIN_MAX; wdev->wdog.parent = &pdev->dev; if (watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev) < 0) wdev->wdog.timeout = TIMER_MARGIN_DEFAULT; watchdog_set_nowayout(&wdev->wdog, nowayout); platform_set_drvdata(pdev, wdev); pm_runtime_enable(wdev->dev); pm_runtime_get_sync(wdev->dev); if (pdata && pdata->read_reset_sources) { u32 rs = pdata->read_reset_sources(); if (rs & (1 << OMAP_MPU_WD_RST_SRC_ID_SHIFT)) wdev->wdog.bootstatus = WDIOF_CARDRESET; } omap_wdt_disable(wdev); ret = watchdog_register_device(&wdev->wdog); if (ret) { pm_runtime_disable(wdev->dev); return ret; } pr_info("OMAP Watchdog Timer Rev 0x%02x: initial timeout %d sec\n", readl_relaxed(wdev->base + OMAP_WATCHDOG_REV) & 0xFF, wdev->wdog.timeout); pm_runtime_put_sync(wdev->dev); if (early_enable) omap_wdt_start(&wdev->wdog); return 0; }
static int at91_wdt_init(struct platform_device *pdev, struct at91wdt *wdt) { u32 tmp; u32 delta; u32 value; int err; u32 mask = wdt->mr_mask; unsigned long min_heartbeat = 1; unsigned long max_heartbeat; struct device *dev = &pdev->dev; tmp = wdt_read(wdt, AT91_WDT_MR); if ((tmp & mask) != (wdt->mr & mask)) { if (tmp == WDT_MR_RESET) { wdt_write(wdt, AT91_WDT_MR, wdt->mr); tmp = wdt_read(wdt, AT91_WDT_MR); } } if (tmp & AT91_WDT_WDDIS) { if (wdt->mr & AT91_WDT_WDDIS) return 0; dev_err(dev, "watchdog is disabled\n"); return -EINVAL; } value = tmp & AT91_WDT_WDV; delta = (tmp & AT91_WDT_WDD) >> 16; if (delta < value) min_heartbeat = ticks_to_hz_roundup(value - delta); max_heartbeat = ticks_to_hz_rounddown(value); if (!max_heartbeat) { dev_err(dev, "heartbeat is too small for the system to handle it correctly\n"); return -EINVAL; } /* * Try to reset the watchdog counter 4 or 2 times more often than * actually requested, to avoid spurious watchdog reset. * If this is not possible because of the min_heartbeat value, reset * it at the min_heartbeat period. */ if ((max_heartbeat / 4) >= min_heartbeat) wdt->heartbeat = max_heartbeat / 4; else if ((max_heartbeat / 2) >= min_heartbeat) wdt->heartbeat = max_heartbeat / 2; else wdt->heartbeat = min_heartbeat; if (max_heartbeat < min_heartbeat + 4) dev_warn(dev, "min heartbeat and max heartbeat might be too close for the system to handle it correctly\n"); if ((tmp & AT91_WDT_WDFIEN) && wdt->irq) { err = request_irq(wdt->irq, wdt_interrupt, IRQF_SHARED | IRQF_IRQPOLL | IRQF_NO_SUSPEND, pdev->name, wdt); if (err) return err; } if ((tmp & wdt->mr_mask) != (wdt->mr & wdt->mr_mask)) dev_warn(dev, "watchdog already configured differently (mr = %x expecting %x)\n", tmp & wdt->mr_mask, wdt->mr & wdt->mr_mask); timer_setup(&wdt->timer, at91_ping, 0); /* * Use min_heartbeat the first time to avoid spurious watchdog reset: * we don't know for how long the watchdog counter is running, and * - resetting it right now might trigger a watchdog fault reset * - waiting for heartbeat time might lead to a watchdog timeout * reset */ mod_timer(&wdt->timer, jiffies + min_heartbeat); /* Try to set timeout from device tree first */ if (watchdog_init_timeout(&wdt->wdd, 0, dev)) watchdog_init_timeout(&wdt->wdd, heartbeat, dev); watchdog_set_nowayout(&wdt->wdd, wdt->nowayout); err = watchdog_register_device(&wdt->wdd); if (err) goto out_stop_timer; wdt->next_heartbeat = jiffies + wdt->wdd.timeout * HZ; return 0; out_stop_timer: del_timer(&wdt->timer); return err; }
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; }
/** * cdns_wdt_probe - Probe call for the device. * * @pdev: handle to the platform device structure. * Return: 0 on success, negative error otherwise. * * It does all the memory allocation and registration for the device. */ static int cdns_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; int ret, irq; unsigned long clock_f; struct cdns_wdt *wdt; struct watchdog_device *cdns_wdt_device; wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); if (!wdt) return -ENOMEM; cdns_wdt_device = &wdt->cdns_wdt_device; cdns_wdt_device->info = &cdns_wdt_info; cdns_wdt_device->ops = &cdns_wdt_ops; cdns_wdt_device->timeout = CDNS_WDT_DEFAULT_TIMEOUT; cdns_wdt_device->min_timeout = CDNS_WDT_MIN_TIMEOUT; cdns_wdt_device->max_timeout = CDNS_WDT_MAX_TIMEOUT; wdt->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(wdt->regs)) return PTR_ERR(wdt->regs); /* Register the interrupt */ wdt->rst = of_property_read_bool(dev->of_node, "reset-on-timeout"); irq = platform_get_irq(pdev, 0); if (!wdt->rst && irq >= 0) { ret = devm_request_irq(dev, irq, cdns_wdt_irq_handler, 0, pdev->name, pdev); if (ret) { dev_err(dev, "cannot register interrupt handler err=%d\n", ret); return ret; } } /* Initialize the members of cdns_wdt structure */ cdns_wdt_device->parent = dev; watchdog_init_timeout(cdns_wdt_device, wdt_timeout, dev); watchdog_set_nowayout(cdns_wdt_device, nowayout); watchdog_stop_on_reboot(cdns_wdt_device); watchdog_set_drvdata(cdns_wdt_device, wdt); wdt->clk = devm_clk_get(dev, NULL); if (IS_ERR(wdt->clk)) { dev_err(dev, "input clock not found\n"); return PTR_ERR(wdt->clk); } ret = clk_prepare_enable(wdt->clk); if (ret) { dev_err(dev, "unable to enable clock\n"); return ret; } ret = devm_add_action_or_reset(dev, cdns_clk_disable_unprepare, wdt->clk); if (ret) return ret; clock_f = clk_get_rate(wdt->clk); if (clock_f <= CDNS_WDT_CLK_75MHZ) { wdt->prescaler = CDNS_WDT_PRESCALE_512; wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512; } else { wdt->prescaler = CDNS_WDT_PRESCALE_4096; wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_4096; } spin_lock_init(&wdt->io_lock); watchdog_stop_on_reboot(cdns_wdt_device); watchdog_stop_on_unregister(cdns_wdt_device); ret = devm_watchdog_register_device(dev, cdns_wdt_device); if (ret) { dev_err(dev, "Failed to register wdt device\n"); return ret; } platform_set_drvdata(pdev, wdt); dev_info(dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n", wdt->regs, cdns_wdt_device->timeout, nowayout ? ", nowayout" : ""); 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 pdc_wdt_probe(struct platform_device *pdev) { int ret, val; unsigned long clk_rate; struct resource *res; struct pdc_wdt_dev *pdc_wdt; pdc_wdt = devm_kzalloc(&pdev->dev, sizeof(*pdc_wdt), GFP_KERNEL); if (!pdc_wdt) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); pdc_wdt->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(pdc_wdt->base)) return PTR_ERR(pdc_wdt->base); pdc_wdt->sys_clk = devm_clk_get(&pdev->dev, "sys"); if (IS_ERR(pdc_wdt->sys_clk)) { dev_err(&pdev->dev, "failed to get the sys clock\n"); return PTR_ERR(pdc_wdt->sys_clk); } pdc_wdt->wdt_clk = devm_clk_get(&pdev->dev, "wdt"); if (IS_ERR(pdc_wdt->wdt_clk)) { dev_err(&pdev->dev, "failed to get the wdt clock\n"); return PTR_ERR(pdc_wdt->wdt_clk); } ret = clk_prepare_enable(pdc_wdt->sys_clk); if (ret) { dev_err(&pdev->dev, "could not prepare or enable sys clock\n"); return ret; } ret = clk_prepare_enable(pdc_wdt->wdt_clk); if (ret) { dev_err(&pdev->dev, "could not prepare or enable wdt clock\n"); goto disable_sys_clk; } /* We use the clock rate to calculate the max timeout */ clk_rate = clk_get_rate(pdc_wdt->wdt_clk); if (clk_rate == 0) { dev_err(&pdev->dev, "failed to get clock rate\n"); ret = -EINVAL; goto disable_wdt_clk; } if (order_base_2(clk_rate) > PDC_WDT_CONFIG_DELAY_MASK + 1) { dev_err(&pdev->dev, "invalid clock rate\n"); ret = -EINVAL; goto disable_wdt_clk; } if (order_base_2(clk_rate) == 0) pdc_wdt->wdt_dev.min_timeout = PDC_WDT_MIN_TIMEOUT + 1; else pdc_wdt->wdt_dev.min_timeout = PDC_WDT_MIN_TIMEOUT; pdc_wdt->wdt_dev.info = &pdc_wdt_info; pdc_wdt->wdt_dev.ops = &pdc_wdt_ops; pdc_wdt->wdt_dev.max_timeout = 1 << PDC_WDT_CONFIG_DELAY_MASK; pdc_wdt->wdt_dev.parent = &pdev->dev; ret = watchdog_init_timeout(&pdc_wdt->wdt_dev, heartbeat, &pdev->dev); if (ret < 0) { pdc_wdt->wdt_dev.timeout = pdc_wdt->wdt_dev.max_timeout; dev_warn(&pdev->dev, "Initial timeout out of range! setting max timeout\n"); } pdc_wdt_stop(&pdc_wdt->wdt_dev); /* Find what caused the last reset */ val = readl(pdc_wdt->base + PDC_WDT_TICKLE1); val = (val & PDC_WDT_TICKLE_STATUS_MASK) >> PDC_WDT_TICKLE_STATUS_SHIFT; switch (val) { case PDC_WDT_TICKLE_STATUS_TICKLE: case PDC_WDT_TICKLE_STATUS_TIMEOUT: pdc_wdt->wdt_dev.bootstatus |= WDIOF_CARDRESET; dev_info(&pdev->dev, "watchdog module last reset due to timeout\n"); break; case PDC_WDT_TICKLE_STATUS_HRESET: dev_info(&pdev->dev, "watchdog module last reset due to hard reset\n"); break; case PDC_WDT_TICKLE_STATUS_SRESET: dev_info(&pdev->dev, "watchdog module last reset due to soft reset\n"); break; case PDC_WDT_TICKLE_STATUS_USER: dev_info(&pdev->dev, "watchdog module last reset due to user reset\n"); break; default: dev_info(&pdev->dev, "contains an illegal status code (%08x)\n", val); break; } watchdog_set_nowayout(&pdc_wdt->wdt_dev, nowayout); platform_set_drvdata(pdev, pdc_wdt); watchdog_set_drvdata(&pdc_wdt->wdt_dev, pdc_wdt); ret = watchdog_register_device(&pdc_wdt->wdt_dev); if (ret) goto disable_wdt_clk; return 0; disable_wdt_clk: clk_disable_unprepare(pdc_wdt->wdt_clk); disable_sys_clk: clk_disable_unprepare(pdc_wdt->sys_clk); return ret; }
static int stm32_iwdg_probe(struct platform_device *pdev) { struct watchdog_device *wdd; struct stm32_iwdg *wdt; struct resource *res; void __iomem *regs; struct clk *clk; int ret; /* This is the timer base. */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(regs)) { dev_err(&pdev->dev, "Could not get resource\n"); return PTR_ERR(regs); } clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { dev_err(&pdev->dev, "Unable to get clock\n"); return PTR_ERR(clk); } ret = clk_prepare_enable(clk); if (ret) { dev_err(&pdev->dev, "Unable to prepare clock %p\n", clk); return ret; } /* * Allocate our watchdog driver data, which has the * struct watchdog_device nested within it. */ wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); if (!wdt) { ret = -ENOMEM; goto err; } /* Initialize struct stm32_iwdg. */ wdt->regs = regs; wdt->clk = clk; wdt->rate = clk_get_rate(clk); /* Initialize struct watchdog_device. */ wdd = &wdt->wdd; wdd->info = &stm32_iwdg_info; wdd->ops = &stm32_iwdg_ops; wdd->min_timeout = ((RLR_MIN + 1) * 256) / wdt->rate; wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * 256 * 1000) / wdt->rate; wdd->parent = &pdev->dev; watchdog_set_drvdata(wdd, wdt); watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT); ret = watchdog_init_timeout(wdd, 0, &pdev->dev); if (ret) dev_warn(&pdev->dev, "unable to set timeout value, using default\n"); ret = watchdog_register_device(wdd); if (ret) { dev_err(&pdev->dev, "failed to register watchdog device\n"); goto err; } platform_set_drvdata(pdev, wdt); return 0; err: clk_disable_unprepare(clk); return ret; }