Skip to content

Commit

Permalink
watchdog: fix error in probe() of s3c2410_wdt (reset at booting)
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: MyungJoo Ham <[email protected]>
Signed-off-by: Kyungmin Park <[email protected]>
Signed-off-by: Wim Van Sebroeck <[email protected]>
  • Loading branch information
myungjoo authored and Wim Van Sebroeck committed Feb 28, 2012
1 parent 97d2a10 commit 78d3e00
Showing 1 changed file with 31 additions and 26 deletions.
57 changes: 31 additions & 26 deletions drivers/watchdog/s3c2410_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}
Expand All @@ -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) {
Expand All @@ -408,42 +410,45 @@ 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;
}

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;
}
Expand Down

0 comments on commit 78d3e00

Please sign in to comment.