Patchwork [2/4] rtc-bfin: fix state restoration when resuming

login
register
mail settings
Submitter Mike Frysinger
Date Aug. 17, 2010, 4:44 a.m.
Message ID <1282020249-8807-2-git-send-email-vapier@gentoo.org>
Download mbox | patch
Permalink /patch/61854/
State New
Headers show

Comments

Mike Frysinger - Aug. 17, 2010, 4:44 a.m.
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>
---
 drivers/rtc/rtc-bfin.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)
Alessandro Zummo - Aug. 17, 2010, 10:20 a.m.
On Tue, 17 Aug 2010 00:44:07 -0400
Mike Frysinger <vapier@gentoo.org> wrote:

> 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>

Patch

diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c
index 65facfb..d4fb82d 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)
 {
 	if (device_may_wakeup(&pdev->dev))
 		disable_irq_wake(IRQ_RTC);
-	else
-		bfin_write_RTC_ISTAT(-1);
+
+	/*
+	 * Since only some of the RTC bits are maintained externally in the
+	 * Vbat domain, we need to wait for the RTC MMRs to be synced into
+	 * the core after waking up.  This happens every RTC 1HZ.  Once that
+	 * has happened, we can go ahead and re-enable the important write
+	 * complete interrupt event.
+	 */
+	while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_SEC))
+		continue;
+	bfin_rtc_int_set(RTC_ISTAT_WRITE_COMPLETE);
 
 	return 0;
 }