Skip to content

Commit

Permalink
OMAP: timekeeping: time should not stop during suspend
Browse files Browse the repository at this point in the history
During suspend, the kernel timekeeping subsystem is shut down.  Before
suspend and upon resume, it uses a weak function
read_persistent_clock() to determine the amount of time that elapsed
during suspend.

This function was not implemented on OMAP, so from the timekeeping
subsystem perspective (and thus userspace as well) it appeared that no
time elapsed during suspend.

This patch uses the 32k sync timer as a the persistent clock.

NOTE: This does *NOT* fully handle wrapping of the 32k sync timer, so
      more than one wrapping of the 32k sync timer during suspend may
      cause problems.  Also note there are not interrupts when the 32k
      sync timer wraps, so something else has to be done.

Reported-by: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
  • Loading branch information
Kevin Hilman committed Jan 21, 2010
1 parent dccaad8 commit d92cfcb
Showing 1 changed file with 26 additions and 0 deletions.
26 changes: 26 additions & 0 deletions arch/arm/plat-omap/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,32 @@ unsigned long long sched_clock(void)
clocksource_32k.mult, clocksource_32k.shift);
}

/**
* read_persistent_clock - Return time from a persistent clock.
*
* Reads the time from a source which isn't disabled during PM, the
* 32k sync timer. Convert the cycles elapsed since last read into
* nsecs and adds to a monotonically increasing timespec.
*/
static struct timespec persistent_ts;
static cycles_t cycles, last_cycles;
void read_persistent_clock(struct timespec *ts)
{
unsigned long long nsecs;
cycles_t delta;
struct timespec *tsp = &persistent_ts;

last_cycles = cycles;
cycles = clocksource_32k.read(&clocksource_32k);
delta = cycles - last_cycles;

nsecs = clocksource_cyc2ns(delta,
clocksource_32k.mult, clocksource_32k.shift);

timespec_add_ns(tsp, nsecs);
*ts = *tsp;
}

static int __init omap_init_clocksource_32k(void)
{
static char err[] __initdata = KERN_ERR
Expand Down

0 comments on commit d92cfcb

Please sign in to comment.