/*
 * This routine finds the most appropriate prescale and load value for input
 * timout value
 */
static void wdt_config(unsigned int timeout)
{
	wdt_default_init(timeout);

        spin_lock(&wdt->lock);

	/* unlock WDT register */
	writel(WDTLOCK_ALLWEN,wdt->base + WDTLOCK);

        writel(wdt->load_val,wdt->base + WDTLOAD);

	/* clear intr ok */
	writel(1,wdt->base + WDTINTCLR);

	/* relock WDT register */
	writel(0,wdt->base + WDTLOCK);

        spin_unlock(&wdt->lock);

}
static int __devinit hisik3_wdt_probe(struct platform_device *pdev)
{
        int ret = 0;
        struct resource *res;

        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                ret = -ENOENT;
                dev_warn(&pdev->dev, "WDT memory resource not defined\n");
                goto err;
        }

        if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
                dev_warn(&pdev->dev, "WDT failed to get memory region resource\n");
                ret = -ENOENT;
                goto err;
        }

        wdt = kzalloc(sizeof(*wdt), GFP_KERNEL);
        if (!wdt) {
                dev_warn(&pdev->dev, "WDT kzalloc failed\n");
                ret = -ENOMEM;
                goto err_kzalloc;
        }

        wdt->clk = clk_get(NULL,"clk_wd");
        if (IS_ERR(wdt->clk)) {
                dev_warn(&pdev->dev, "WDT clock not found\n");
                ret = PTR_ERR(wdt->clk);
                goto err_clk_get;
        }

        wdt->base = ioremap(res->start, resource_size(res));
        if (!wdt->base) {
                ret = -ENOMEM;
                dev_warn(&pdev->dev, "WDT ioremap fail\n");
                goto err_ioremap;
        }
        spin_lock_init(&wdt->lock);
        /* This checks if system booted after watchdog reset or not */
        ret = clk_enable(wdt->clk);
	if (ret) {
		dev_warn(&pdev->dev, "clock enable fail");
		goto err_clk_enable;
	}

	wdt->pdev = pdev;
	wdt_default_init(DEFAULT_TIMEOUT);
	wdt_default_config();

/* begin: add by wufan w00163571 for use kernel thread kick watchdog 20121201 */
	ret = k3_wdt_kick_start();
	if(ret)
		goto err_create_thread;
	register_cpu_notifier((struct notifier_block *)&k3wdt_cpu_nfb);
/* end: add by wufan w00163571 for use kernel thread kick watchdog 20121201 */

        ret = misc_register(&hisik3_wdt_miscdev);
        if (ret < 0) {
                dev_warn(&pdev->dev, "WDT cannot register misc device\n");
                goto err_misc_register;
        }

	wdt_enable();

        dev_warn(&pdev->dev,"WDT probing has been finished\n");
        return 0;

err_misc_register:
/* begin: add by wufan w00163571 for use kernel thread kick watchdog 20121201 */
	unregister_cpu_notifier((struct notifier_block *)&k3wdt_cpu_nfb);
err_create_thread:
	k3_wdt_kick_stop();
/* begin: add by wufan w00163571 for use kernel thread kick watchdog 20121201 */
	clk_disable(wdt->clk);
err_clk_enable:
        iounmap(wdt->base);
err_ioremap:
        clk_put(wdt->clk);
err_clk_get:
        kfree(wdt);
        wdt = NULL;
err_kzalloc:
        release_mem_region(res->start, resource_size(res));
err:
	dev_warn(&pdev->dev, "WDT probe failed!!!\n");
        return ret;
}
示例#3
0
static int __devinit hisik3_wdt_probe(struct platform_device *pdev)
{
        int ret = 0;
        struct resource *res;

        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                ret = -ENOENT;
                dev_warn(&pdev->dev, "WDT memory resource not defined\n");
                goto err;
        }

        if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
                dev_warn(&pdev->dev, "WDT failed to get memory region resource\n");
                ret = -ENOENT;
                goto err;
        }

        wdt = kzalloc(sizeof(*wdt), GFP_KERNEL);
        if (!wdt) {
                dev_warn(&pdev->dev, "WDT kzalloc failed\n");
                ret = -ENOMEM;
                goto err_kzalloc;
        }

        wdt->clk = clk_get(NULL,"clk_wd");
        if (IS_ERR(wdt->clk)) {
                dev_warn(&pdev->dev, "WDT clock not found\n");
                ret = PTR_ERR(wdt->clk);
                goto err_clk_get;
        }

        wdt->base = ioremap(res->start, resource_size(res));
        if (!wdt->base) {
                ret = -ENOMEM;
                dev_warn(&pdev->dev, "WDT ioremap fail\n");
                goto err_ioremap;
        }
        spin_lock_init(&wdt->lock);
        /* This checks if system booted after watchdog reset or not */
        ret = clk_enable(wdt->clk);
	if (ret) {
		dev_warn(&pdev->dev, "clock enable fail");
		goto err_clk_enable;
	}

	wdt->pdev = pdev;
	wdt_default_init(DEFAULT_TIMEOUT);
	wdt_default_config();

	INIT_DELAYED_WORK(&wdt->k3_wdt_delayed_work, wdt_mond);

	schedule_delayed_work(&wdt->k3_wdt_delayed_work, 0);

        ret = misc_register(&hisik3_wdt_miscdev);
        if (ret < 0) {
                dev_warn(&pdev->dev, "WDT cannot register misc device\n");
                goto err_misc_register;
        }

	wdt_enable();

        dev_warn(&pdev->dev,"WDT probing has been finished\n");
        return 0;

err_misc_register:
	clk_disable(wdt->clk);
err_clk_enable:
        iounmap(wdt->base);
err_ioremap:
        clk_put(wdt->clk);
err_clk_get:
        kfree(wdt);
        wdt = NULL;
err_kzalloc:
        release_mem_region(res->start, resource_size(res));
err:
	dev_warn(&pdev->dev, "WDT probe failed!!!\n");
        return ret;
}