From 4ae7806f8b4bf9a1e74c82f3bd4e91d59bd3d697 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 12 Nov 2007 22:48:12 +0000 Subject: [PATCH] [ARM] pxa: Don't wind OSCR backwards over suspend/resume OSCR is supposed to monotonically increment; however restoring it to a time prior to OSMR0 may result in it being wound backwards. Instead, if OSMR0 is within the minimum expiry time, wind OSMR0 forwards. Signed-off-by: Russell King --- arch/arm/mach-pxa/time.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 3c4abbf31803..ac0bbad35238 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -181,7 +181,7 @@ static void __init pxa_timer_init(void) } #ifdef CONFIG_PM -static unsigned long osmr[4], oier; +static unsigned long osmr[4], oier, oscr; static void pxa_timer_suspend(void) { @@ -190,23 +190,26 @@ static void pxa_timer_suspend(void) osmr[2] = OSMR2; osmr[3] = OSMR3; oier = OIER; + oscr = OSCR; } static void pxa_timer_resume(void) { + /* + * Ensure that we have at least MIN_OSCR_DELTA between match + * register 0 and the OSCR, to guarantee that we will receive + * the one-shot timer interrupt. We adjust OSMR0 in preference + * to OSCR to guarantee that OSCR is monotonically incrementing. + */ + if (osmr[0] - oscr < MIN_OSCR_DELTA) + osmr[0] += MIN_OSCR_DELTA; + OSMR0 = osmr[0]; OSMR1 = osmr[1]; OSMR2 = osmr[2]; OSMR3 = osmr[3]; OIER = oier; - - /* - * OSCR0 is the system timer, which has to increase - * monotonically until it rolls over in hardware. The value - * (OSMR0 - LATCH) is OSCR0 at the most recent system tick, - * which is a handy value to restore to OSCR0. - */ - OSCR = OSMR0 - LATCH; + OSCR = oscr; } #else #define pxa_timer_suspend NULL -- 2.20.1