diff options
-rw-r--r-- | drivers/char/watchdog/s3c2410_wdt.c | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c index f85ac898a49a..522435782e73 100644 --- a/drivers/char/watchdog/s3c2410_wdt.c +++ b/drivers/char/watchdog/s3c2410_wdt.c | |||
@@ -27,7 +27,9 @@ | |||
27 | * Fixed tmr_count / wdt_count confusion | 27 | * Fixed tmr_count / wdt_count confusion |
28 | * Added configurable debug | 28 | * Added configurable debug |
29 | * | 29 | * |
30 | * 11-Jan-2004 BJD Fixed divide-by-2 in timeout code | 30 | * 11-Jan-2005 BJD Fixed divide-by-2 in timeout code |
31 | * | ||
32 | * 25-Jan-2005 DA Added suspend/resume support | ||
31 | * | 33 | * |
32 | * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA | 34 | * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA |
33 | */ | 35 | */ |
@@ -479,15 +481,57 @@ static int s3c2410wdt_remove(struct device *dev) | |||
479 | return 0; | 481 | return 0; |
480 | } | 482 | } |
481 | 483 | ||
484 | #ifdef CONFIG_PM | ||
485 | |||
486 | static unsigned long wtcon_save; | ||
487 | static unsigned long wtdat_save; | ||
488 | |||
489 | static int s3c2410wdt_suspend(struct device *dev, u32 state, u32 level) | ||
490 | { | ||
491 | if (level == SUSPEND_POWER_DOWN) { | ||
492 | /* Save watchdog state, and turn it off. */ | ||
493 | wtcon_save = readl(wdt_base + S3C2410_WTCON); | ||
494 | wtdat_save = readl(wdt_base + S3C2410_WTDAT); | ||
495 | |||
496 | /* Note that WTCNT doesn't need to be saved. */ | ||
497 | s3c2410wdt_stop(); | ||
498 | } | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | static int s3c2410wdt_resume(struct device *dev, u32 level) | ||
504 | { | ||
505 | if (level == RESUME_POWER_ON) { | ||
506 | /* Restore watchdog state. */ | ||
507 | |||
508 | writel(wtdat_save, wdt_base + S3C2410_WTDAT); | ||
509 | writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */ | ||
510 | writel(wtcon_save, wdt_base + S3C2410_WTCON); | ||
511 | |||
512 | printk(KERN_INFO PFX "watchdog %sabled\n", | ||
513 | (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis"); | ||
514 | } | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | #else | ||
520 | #define s3c2410wdt_suspend NULL | ||
521 | #define s3c2410wdt_resume NULL | ||
522 | #endif /* CONFIG_PM */ | ||
523 | |||
524 | |||
482 | static struct device_driver s3c2410wdt_driver = { | 525 | static struct device_driver s3c2410wdt_driver = { |
483 | .name = "s3c2410-wdt", | 526 | .name = "s3c2410-wdt", |
484 | .bus = &platform_bus_type, | 527 | .bus = &platform_bus_type, |
485 | .probe = s3c2410wdt_probe, | 528 | .probe = s3c2410wdt_probe, |
486 | .remove = s3c2410wdt_remove, | 529 | .remove = s3c2410wdt_remove, |
530 | .suspend = s3c2410wdt_suspend, | ||
531 | .resume = s3c2410wdt_resume, | ||
487 | }; | 532 | }; |
488 | 533 | ||
489 | 534 | ||
490 | |||
491 | static char banner[] __initdata = KERN_INFO "S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics\n"; | 535 | static char banner[] __initdata = KERN_INFO "S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics\n"; |
492 | 536 | ||
493 | static int __init watchdog_init(void) | 537 | static int __init watchdog_init(void) |
@@ -505,7 +549,8 @@ static void __exit watchdog_exit(void) | |||
505 | module_init(watchdog_init); | 549 | module_init(watchdog_init); |
506 | module_exit(watchdog_exit); | 550 | module_exit(watchdog_exit); |
507 | 551 | ||
508 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | 552 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, " |
553 | "Dimitry Andric <dimitry.andric@tomtom.com>"); | ||
509 | MODULE_DESCRIPTION("S3C2410 Watchdog Device Driver"); | 554 | MODULE_DESCRIPTION("S3C2410 Watchdog Device Driver"); |
510 | MODULE_LICENSE("GPL"); | 555 | MODULE_LICENSE("GPL"); |
511 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 556 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |