diff mbox

powerpc/mpic_timer: fix the time calculation is not accurate

Message ID 1387766025-46101-1-git-send-email-dongsheng.wang@freescale.com (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Dongsheng Wang Dec. 23, 2013, 2:33 a.m. UTC
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>

Comments

Scott Wood Dec. 27, 2013, 11:59 p.m. UTC | #1
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
Dongsheng Wang Dec. 30, 2013, 2:21 a.m. UTC | #2
> -----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 mbox

Patch

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);