Message ID | 1387766025-46101-1-git-send-email-dongsheng.wang@freescale.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
On Mon, 2013-12-23 at 10:33 +0800, Dongsheng Wang wrote: > From: Wang Dongsheng <dongsheng.wang@freescale.com> > > When the timer GTCCR toggle bit is inverted, we calculated the rest > of the time is not accurate. So we need to ignore this bit. > > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com> > > diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c > index 22d7d57..0fb70c9 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,15 @@ 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; > + > + /* > + * In some cases tmp_sec may be greater than ticks, because in the > + * process of calculation ticks and tmp_sec will be rounded. > + */ > + if (tmp_sec <= ticks) > + time->tv_usec = (__kernel_suseconds_t) > + div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq); I don't see how this part of the patch relates to the patch description. -Scott
> -----Original Message----- > From: Wood Scott-B07421 > Sent: Saturday, December 28, 2013 8:00 AM > To: Wang Dongsheng-B40534 > Cc: galak@kernel.crashing.org; linuxppc-dev@lists.ozlabs.org > Subject: Re: [PATCH] powerpc/mpic_timer: fix the time calculation is not > accurate > > On Mon, 2013-12-23 at 10:33 +0800, Dongsheng Wang wrote: > > From: Wang Dongsheng <dongsheng.wang@freescale.com> > > > > When the timer GTCCR toggle bit is inverted, we calculated the rest of > > the time is not accurate. So we need to ignore this bit. > > > > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com> > > > > diff --git a/arch/powerpc/sysdev/mpic_timer.c > > b/arch/powerpc/sysdev/mpic_timer.c > > index 22d7d57..0fb70c9 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,15 @@ 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; > > + > > + /* > > + * In some cases tmp_sec may be greater than ticks, because in the > > + * process of calculation ticks and tmp_sec will be rounded. > > + */ > > + if (tmp_sec <= ticks) > > + time->tv_usec = (__kernel_suseconds_t) > > + div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq); > > I don't see how this part of the patch relates to the patch description. > Thanks, I miss this description, :(. I should split the patch. -Dongsheng > -Scott >
diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c index 22d7d57..0fb70c9 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,15 @@ 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; + + /* + * In some cases tmp_sec may be greater than ticks, because in the + * process of calculation ticks and tmp_sec will be rounded. + */ + if (tmp_sec <= ticks) + time->tv_usec = (__kernel_suseconds_t) + div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq); return; } @@ -327,11 +335,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);