summaryrefslogtreecommitdiff
path: root/arch/powerpc/sysdev/mpic_timer.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-01-15 07:22:35 +0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-01-15 07:22:35 +0400
commitfac515db45207718168cb55ca4d0a390e43b61af (patch)
tree7dd2fe9b94f769a2009ff6c7402c52ef3dd3b640 /arch/powerpc/sysdev/mpic_timer.c
parent3ac8ff1c475bda7174fce63230c0932454287cd5 (diff)
parentd064f30e5063ec54ab50af08c64fb5055e759bfd (diff)
downloadlinux-fac515db45207718168cb55ca4d0a390e43b61af.tar.xz
Merge remote-tracking branch 'scott/next' into next
Freescale updates from Scott: << Highlights include 32-bit booke relocatable support, e6500 hardware tablewalk support, various e500 SPE fixes, some new/revived boards, and e6500 deeper idle and altivec powerdown modes. >>
Diffstat (limited to 'arch/powerpc/sysdev/mpic_timer.c')
-rw-r--r--arch/powerpc/sysdev/mpic_timer.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c
index 22d7d57eead9..9d9b06217f8b 100644
--- a/arch/powerpc/sysdev/mpic_timer.c
+++ b/arch/powerpc/sysdev/mpic_timer.c
@@ -41,6 +41,7 @@
#define MPIC_TIMER_TCR_ROVR_OFFSET 24
#define TIMER_STOP 0x80000000
+#define GTCCR_TOG 0x80000000
#define TIMERS_PER_GROUP 4
#define MAX_TICKS (~0U >> 1)
#define MAX_TICKS_CASCADE (~0U)
@@ -96,8 +97,11 @@ static void convert_ticks_to_time(struct timer_group_priv *priv,
time->tv_sec = (__kernel_time_t)div_u64(ticks, priv->timerfreq);
tmp_sec = (u64)time->tv_sec * (u64)priv->timerfreq;
- time->tv_usec = (__kernel_suseconds_t)
- div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq);
+ time->tv_usec = 0;
+
+ if (tmp_sec <= ticks)
+ time->tv_usec = (__kernel_suseconds_t)
+ div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq);
return;
}
@@ -327,11 +331,13 @@ void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time)
casc_priv = priv->timer[handle->num].cascade_handle;
if (casc_priv) {
tmp_ticks = in_be32(&priv->regs[handle->num].gtccr);
+ tmp_ticks &= ~GTCCR_TOG;
ticks = ((u64)tmp_ticks & UINT_MAX) * (u64)MAX_TICKS_CASCADE;
tmp_ticks = in_be32(&priv->regs[handle->num - 1].gtccr);
ticks += tmp_ticks;
} else {
ticks = in_be32(&priv->regs[handle->num].gtccr);
+ ticks &= ~GTCCR_TOG;
}
convert_ticks_to_time(priv, ticks, time);