aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-bfin.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2010-09-09 19:37:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-09-09 21:57:22 -0400
commitb6de860651d5a9e56ba4f4e3edc1aa52ac2ac849 (patch)
tree59b41da9289132e7e494ebb49adef7bafdbac9cf /drivers/rtc/rtc-bfin.c
parent110b7e9698601b28f313c2c560d51a8b1c742002 (diff)
rtc-bfin: fix state restoration when resuming
Much (but not all) of the RTC state is kept in the RTC peripheral which has its own power domain. Periodically (1 HZ), that state is synced from one power domain to the other (peripheral->core). When we are resuming, we need to wait for the sync to occur so that we don't get a mismatch of reading undefined state in the rest of the driver. Further, once the externally maintained bits have been synced back into the core, we then need to restore the bits maintained in the core. In our particular case, that is just the write completion interrupt bit. If we don't do any of this, working with the RTC causes ~5 second delays from time to time after waking up due to the write completion interrupt never firing. Reported-by: Michael Dean <mdean@aeronix.com> Reported-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org> 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-bfin.c')
-rw-r--r--drivers/rtc/rtc-bfin.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c
index 65facfbe70f..d4fb82d85e9 100644
--- a/drivers/rtc/rtc-bfin.c
+++ b/drivers/rtc/rtc-bfin.c
@@ -435,8 +435,17 @@ static int bfin_rtc_resume(struct platform_device *pdev)
435{ 435{
436 if (device_may_wakeup(&pdev->dev)) 436 if (device_may_wakeup(&pdev->dev))
437 disable_irq_wake(IRQ_RTC); 437 disable_irq_wake(IRQ_RTC);
438 else 438
439 bfin_write_RTC_ISTAT(-1); 439 /*
440 * Since only some of the RTC bits are maintained externally in the
441 * Vbat domain, we need to wait for the RTC MMRs to be synced into
442 * the core after waking up. This happens every RTC 1HZ. Once that
443 * has happened, we can go ahead and re-enable the important write
444 * complete interrupt event.
445 */
446 while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_SEC))
447 continue;
448 bfin_rtc_int_set(RTC_ISTAT_WRITE_COMPLETE);
440 449
441 return 0; 450 return 0;
442} 451}