static int __init imx2_wdt_probe()

in imx2_wdt.c [256:335]


static int __init imx2_wdt_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct imx2_wdt_device *wdev;
	struct watchdog_device *wdog;
	void __iomem *base;
	int ret;
	u32 val;

	wdev = devm_kzalloc(dev, sizeof(*wdev), GFP_KERNEL);
	if (!wdev)
		return -ENOMEM;

	base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(base))
		return PTR_ERR(base);

	wdev->regmap = devm_regmap_init_mmio_clk(dev, NULL, base,
						 &imx2_wdt_regmap_config);
	if (IS_ERR(wdev->regmap)) {
		dev_err(dev, "regmap init failed\n");
		return PTR_ERR(wdev->regmap);
	}

	wdev->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(wdev->clk)) {
		dev_err(dev, "can't get Watchdog clock\n");
		return PTR_ERR(wdev->clk);
	}

	wdog			= &wdev->wdog;
	wdog->info		= &imx2_wdt_info;
	wdog->ops		= &imx2_wdt_ops;
	wdog->min_timeout	= 1;
	wdog->timeout		= IMX2_WDT_DEFAULT_TIME;
	wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000;
	wdog->parent		= dev;

	ret = platform_get_irq(pdev, 0);
	if (ret > 0)
		if (!devm_request_irq(dev, ret, imx2_wdt_isr, 0,
				      dev_name(dev), wdog))
			wdog->info = &imx2_wdt_pretimeout_info;

	ret = clk_prepare_enable(wdev->clk);
	if (ret)
		return ret;

	ret = devm_add_action_or_reset(dev, imx2_wdt_action, wdev->clk);
	if (ret)
		return ret;

	wdev->clk_is_on = true;

	regmap_read(wdev->regmap, IMX2_WDT_WRSR, &val);
	wdog->bootstatus = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0;

	wdev->ext_reset = of_property_read_bool(dev->of_node,
						"fsl,ext-reset-output");
	platform_set_drvdata(pdev, wdog);
	watchdog_set_drvdata(wdog, wdev);
	watchdog_set_nowayout(wdog, nowayout);
	watchdog_set_restart_priority(wdog, 128);
	watchdog_init_timeout(wdog, timeout, dev);
	watchdog_stop_ping_on_suspend(wdog);

	if (imx2_wdt_is_running(wdev)) {
		imx2_wdt_set_timeout(wdog, wdog->timeout);
		set_bit(WDOG_HW_RUNNING, &wdog->status);
	}

	/*
	 * Disable the watchdog power down counter at boot. Otherwise the power
	 * down counter will pull down the #WDOG interrupt line for one clock
	 * cycle.
	 */
	regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0);

	return devm_watchdog_register_device(dev, wdog);
}