Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #4
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);
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
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;
}
Beispiel #8
0
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		= &ltq_wdt_info;
	wdt->ops		= &ltq_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);
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
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;
}
Beispiel #14
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;
}
Beispiel #15
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;
}
Beispiel #16
0
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;
}
Beispiel #17
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;
}
Beispiel #18
0
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;
}
Beispiel #19
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;
}
Beispiel #21
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;
}
Beispiel #23
0
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;
}
Beispiel #24
0
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;
}
Beispiel #25
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;
}
Beispiel #27
0
/**
 * 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;
}
Beispiel #28
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;
}
Beispiel #29
0
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;
}
Beispiel #30
0
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;
}