aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/watchdog/s3c2410_wdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/watchdog/s3c2410_wdt.c')
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c62
1 files changed, 36 insertions, 26 deletions
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index 18cb050c3862..dff6cb5dc9a7 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -78,7 +78,7 @@ MODULE_PARM_DESC(tmr_margin, "Watchdog tmr_margin in seconds. default=" __MODULE
78 78
79MODULE_PARM_DESC(tmr_atboot, "Watchdog is started at boot time if set to 1, default=" __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT)); 79MODULE_PARM_DESC(tmr_atboot, "Watchdog is started at boot time if set to 1, default=" __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT));
80 80
81MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 81MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
82 82
83MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)"); 83MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)");
84 84
@@ -366,13 +366,15 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
366 wdt_mem = request_mem_region(res->start, size, pdev->name); 366 wdt_mem = request_mem_region(res->start, size, pdev->name);
367 if (wdt_mem == NULL) { 367 if (wdt_mem == NULL) {
368 printk(KERN_INFO PFX "failed to get memory region\n"); 368 printk(KERN_INFO PFX "failed to get memory region\n");
369 return -ENOENT; 369 ret = -ENOENT;
370 goto err_req;
370 } 371 }
371 372
372 wdt_base = ioremap(res->start, size); 373 wdt_base = ioremap(res->start, size);
373 if (wdt_base == 0) { 374 if (wdt_base == 0) {
374 printk(KERN_INFO PFX "failed to ioremap() region\n"); 375 printk(KERN_INFO PFX "failed to ioremap() region\n");
375 return -EINVAL; 376 ret = -EINVAL;
377 goto err_req;
376 } 378 }
377 379
378 DBG("probe: mapped wdt_base=%p\n", wdt_base); 380 DBG("probe: mapped wdt_base=%p\n", wdt_base);
@@ -380,22 +382,21 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
380 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 382 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
381 if (res == NULL) { 383 if (res == NULL) {
382 printk(KERN_INFO PFX "failed to get irq resource\n"); 384 printk(KERN_INFO PFX "failed to get irq resource\n");
383 iounmap(wdt_base); 385 ret = -ENOENT;
384 return -ENOENT; 386 goto err_map;
385 } 387 }
386 388
387 ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev); 389 ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev);
388 if (ret != 0) { 390 if (ret != 0) {
389 printk(KERN_INFO PFX "failed to install irq (%d)\n", ret); 391 printk(KERN_INFO PFX "failed to install irq (%d)\n", ret);
390 iounmap(wdt_base); 392 goto err_map;
391 return ret;
392 } 393 }
393 394
394 wdt_clock = clk_get(&pdev->dev, "watchdog"); 395 wdt_clock = clk_get(&pdev->dev, "watchdog");
395 if (wdt_clock == NULL) { 396 if (IS_ERR(wdt_clock)) {
396 printk(KERN_INFO PFX "failed to find watchdog clock source\n"); 397 printk(KERN_INFO PFX "failed to find watchdog clock source\n");
397 iounmap(wdt_base); 398 ret = PTR_ERR(wdt_clock);
398 return -ENOENT; 399 goto err_irq;
399 } 400 }
400 401
401 clk_enable(wdt_clock); 402 clk_enable(wdt_clock);
@@ -418,8 +419,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
418 if (ret) { 419 if (ret) {
419 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n", 420 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n",
420 WATCHDOG_MINOR, ret); 421 WATCHDOG_MINOR, ret);
421 iounmap(wdt_base); 422 goto err_clk;
422 return ret;
423 } 423 }
424 424
425 if (tmr_atboot && started == 0) { 425 if (tmr_atboot && started == 0) {
@@ -434,26 +434,36 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
434 } 434 }
435 435
436 return 0; 436 return 0;
437
438 err_clk:
439 clk_disable(wdt_clock);
440 clk_put(wdt_clock);
441
442 err_irq:
443 free_irq(wdt_irq->start, pdev);
444
445 err_map:
446 iounmap(wdt_base);
447
448 err_req:
449 release_resource(wdt_mem);
450 kfree(wdt_mem);
451
452 return ret;
437} 453}
438 454
439static int s3c2410wdt_remove(struct platform_device *dev) 455static int s3c2410wdt_remove(struct platform_device *dev)
440{ 456{
441 if (wdt_mem != NULL) { 457 release_resource(wdt_mem);
442 release_resource(wdt_mem); 458 kfree(wdt_mem);
443 kfree(wdt_mem); 459 wdt_mem = NULL;
444 wdt_mem = NULL;
445 }
446 460
447 if (wdt_irq != NULL) { 461 free_irq(wdt_irq->start, dev);
448 free_irq(wdt_irq->start, dev); 462 wdt_irq = NULL;
449 wdt_irq = NULL;
450 }
451 463
452 if (wdt_clock != NULL) { 464 clk_disable(wdt_clock);
453 clk_disable(wdt_clock); 465 clk_put(wdt_clock);
454 clk_put(wdt_clock); 466 wdt_clock = NULL;
455 wdt_clock = NULL;
456 }
457 467
458 iounmap(wdt_base); 468 iounmap(wdt_base);
459 misc_deregister(&s3c2410wdt_miscdev); 469 misc_deregister(&s3c2410wdt_miscdev);