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: Jon Hunter <jon-hunter@ti.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
This commit is contained in:
parent
dccaad8950
commit
d92cfcbe39
1 changed files with 26 additions and 0 deletions
|
@ -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
|
||||
|
|
Reference in a new issue