Commit d92cfcbe authored by Kevin Hilman's avatar Kevin Hilman

OMAP: timekeeping: time should not stop during suspend

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: default avatarJon Hunter <jon-hunter@ti.com>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent dccaad89
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment