diff options
author | David Brownell <david-b@pacbell.net> | 2007-05-08 03:33:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:18 -0400 |
commit | 7ca1d488ffe4817adaba61cc05b972782f7d3f91 (patch) | |
tree | 97fee4d2ddbc5be5265d99f5825e902f7a9262c1 /drivers/rtc/rtc-at91rm9200.c | |
parent | cd9662094edf4173e87f0452e57e4eacc228f8ff (diff) |
rtc: suspend()/resume() restores system clock
RTC class suspend/resume support, re-initializing the system clock on resume
from the clock used to initialize it at boot time.
- The reinit-on-resume is hooked to the existing RTC_HCTOSYS config
option, on the grounds that a clock good enough for init must also
be good enough for re-init.
- Inlining a version of the code used by ARM, to save and restore the
delta between a selected RTC and the current system wall-clock time.
- Removes calls to that ARM code from AT91, OMAP1, and S3C RTCs. This
means that systems using those RTCs across suspend/resume will likely
want to change their kernel configs to enable RTC_HCTOSYS.
If HCTOSYS isn't using a second RTC (with battery?), this changes the
system's initial date from Jan 1970 to the epoch this hardware uses:
1998 for AT91, 2000 for OMAP1 (assuming no split power mode), etc.
This goes on top of the patch series removing "struct class_device" usage
from the RTC framework. That's all needed for class suspend()/resume().
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-By: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc/rtc-at91rm9200.c')
-rw-r--r-- | drivers/rtc/rtc-at91rm9200.c | 30 |
1 files changed, 0 insertions, 30 deletions
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 2f06b5f9fb7b..33795e5a5595 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -348,21 +348,10 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) | |||
348 | 348 | ||
349 | /* AT91RM9200 RTC Power management control */ | 349 | /* AT91RM9200 RTC Power management control */ |
350 | 350 | ||
351 | static struct timespec at91_rtc_delta; | ||
352 | static u32 at91_rtc_imr; | 351 | static u32 at91_rtc_imr; |
353 | 352 | ||
354 | static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 353 | static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
355 | { | 354 | { |
356 | struct rtc_time tm; | ||
357 | struct timespec time; | ||
358 | |||
359 | time.tv_nsec = 0; | ||
360 | |||
361 | /* calculate time delta for suspend */ | ||
362 | at91_rtc_readtime(&pdev->dev, &tm); | ||
363 | rtc_tm_to_time(&tm, &time.tv_sec); | ||
364 | save_time_delta(&at91_rtc_delta, &time); | ||
365 | |||
366 | /* this IRQ is shared with DBGU and other hardware which isn't | 355 | /* this IRQ is shared with DBGU and other hardware which isn't |
367 | * necessarily doing PM like we are... | 356 | * necessarily doing PM like we are... |
368 | */ | 357 | */ |
@@ -374,36 +363,17 @@ static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
374 | else | 363 | else |
375 | at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); | 364 | at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); |
376 | } | 365 | } |
377 | |||
378 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, | ||
379 | 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday, | ||
380 | tm.tm_hour, tm.tm_min, tm.tm_sec); | ||
381 | |||
382 | return 0; | 366 | return 0; |
383 | } | 367 | } |
384 | 368 | ||
385 | static int at91_rtc_resume(struct platform_device *pdev) | 369 | static int at91_rtc_resume(struct platform_device *pdev) |
386 | { | 370 | { |
387 | struct rtc_time tm; | ||
388 | struct timespec time; | ||
389 | |||
390 | time.tv_nsec = 0; | ||
391 | |||
392 | at91_rtc_readtime(&pdev->dev, &tm); | ||
393 | rtc_tm_to_time(&tm, &time.tv_sec); | ||
394 | restore_time_delta(&at91_rtc_delta, &time); | ||
395 | |||
396 | if (at91_rtc_imr) { | 371 | if (at91_rtc_imr) { |
397 | if (device_may_wakeup(&pdev->dev)) | 372 | if (device_may_wakeup(&pdev->dev)) |
398 | disable_irq_wake(AT91_ID_SYS); | 373 | disable_irq_wake(AT91_ID_SYS); |
399 | else | 374 | else |
400 | at91_sys_write(AT91_RTC_IER, at91_rtc_imr); | 375 | at91_sys_write(AT91_RTC_IER, at91_rtc_imr); |
401 | } | 376 | } |
402 | |||
403 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, | ||
404 | 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday, | ||
405 | tm.tm_hour, tm.tm_min, tm.tm_sec); | ||
406 | |||
407 | return 0; | 377 | return 0; |
408 | } | 378 | } |
409 | #else | 379 | #else |