watchdog: fix error in probe() of s3c2410_wdt (reset at booting)

Probe function of s3c2410 watchdog calls request_irq before initializing
required value (wdt_count). This incurs resetting watchdog counter value
and watchdog-reboot during booting up.

This patch addresses such an issue by calling request_irq later.

Error handling in probe function and calling oder in remove function are
also revised accordingly.

Reported-by: Chanwoo Park <cw00.choi@samsung.com>
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
This commit is contained in:
MyungJoo Ham 2012-01-13 14:14:23 +09:00 committed by Wim Van Sebroeck
parent 97d2a10d58
commit 78d3e00bb0

View file

@ -312,18 +312,26 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
dev = &pdev->dev;
wdt_dev = &pdev->dev;
/* get the memory region for the watchdog timer */
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 */
size = resource_size(wdt_mem);
if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
dev_err(dev, "failed to get memory region\n");
return -EBUSY;
ret = -EBUSY;
goto err;
}
wdt_base = ioremap(wdt_mem->start, size);
@ -335,29 +343,17 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
DBG("probe: mapped wdt_base=%p\n", wdt_base);
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_map;
}
ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
if (ret != 0) {
dev_err(dev, "failed to install irq (%d)\n", ret);
goto err_map;
}
wdt_clock = clk_get(&pdev->dev, "watchdog");
if (IS_ERR(wdt_clock)) {
dev_err(dev, "failed to find watchdog clock source\n");
ret = PTR_ERR(wdt_clock);
goto err_irq;
goto err_map;
}
clk_enable(wdt_clock);
if (s3c2410wdt_cpufreq_register() < 0) {
ret = s3c2410wdt_cpufreq_register();
if (ret < 0) {
printk(KERN_ERR PFX "failed to register cpufreq\n");
goto err_clk;
}
@ -378,12 +374,18 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
"cannot start\n");
}
ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
if (ret != 0) {
dev_err(dev, "failed to install irq (%d)\n", ret);
goto err_cpufreq;
}
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_cpufreq;
goto err_irq;
}
if (tmr_atboot && started == 0) {
@ -408,23 +410,26 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
return 0;
err_irq:
free_irq(wdt_irq->start, pdev);
err_cpufreq:
s3c2410wdt_cpufreq_deregister();
err_clk:
clk_disable(wdt_clock);
clk_put(wdt_clock);
err_irq:
free_irq(wdt_irq->start, pdev);
wdt_clock = NULL;
err_map:
iounmap(wdt_base);
err_req:
release_mem_region(wdt_mem->start, size);
wdt_mem = NULL;
err:
wdt_irq = NULL;
wdt_mem = NULL;
return ret;
}
@ -432,18 +437,18 @@ static int __devexit s3c2410wdt_remove(struct platform_device *dev)
{
watchdog_unregister_device(&s3c2410_wdd);
free_irq(wdt_irq->start, dev);
s3c2410wdt_cpufreq_deregister();
clk_disable(wdt_clock);
clk_put(wdt_clock);
wdt_clock = NULL;
free_irq(wdt_irq->start, dev);
wdt_irq = NULL;
iounmap(wdt_base);
release_mem_region(wdt_mem->start, resource_size(wdt_mem));
wdt_irq = NULL;
wdt_mem = NULL;
return 0;
}