From patchwork Mon Dec 23 02:33:45 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dongsheng Wang X-Patchwork-Id: 304637 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [IPv6:::1]) by ozlabs.org (Postfix) with ESMTP id A75A22C014F for ; Mon, 23 Dec 2013 13:37:07 +1100 (EST) Received: from co1outboundpool.messaging.microsoft.com (co1ehsobe004.messaging.microsoft.com [216.32.180.187]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 366D12C0084 for ; Mon, 23 Dec 2013 13:36:40 +1100 (EST) Received: from mail219-co1-R.bigfish.com (10.243.78.237) by CO1EHSOBE031.bigfish.com (10.243.66.96) with Microsoft SMTP Server id 14.1.225.22; Mon, 23 Dec 2013 02:36:34 +0000 Received: from mail219-co1 (localhost [127.0.0.1]) by mail219-co1-R.bigfish.com (Postfix) with ESMTP id B3D4E100491; Mon, 23 Dec 2013 02:36:34 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1f42h2148h208ch1ee6h1de0h1fdah2073h2146h1202h1e76h2189h1d1ah1d2ah1fc6hzz1de098h8275bh1de097hz2dh2a8h839hd24he5bhf0ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1b2fh2222h224fh1fb3h1d0ch1d2eh1d3fh1dc1h1dfeh1dffh1e23h1fe8h1ff5h2218h2216h226dh22d0h2327h2336h1155h) Received: from mail219-co1 (localhost.localdomain [127.0.0.1]) by mail219-co1 (MessageSwitch) id 1387766192807372_18380; Mon, 23 Dec 2013 02:36:32 +0000 (UTC) Received: from CO1EHSMHS003.bigfish.com (unknown [10.243.78.250]) by mail219-co1.bigfish.com (Postfix) with ESMTP id C10794C0049; Mon, 23 Dec 2013 02:36:32 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CO1EHSMHS003.bigfish.com (10.243.66.13) with Microsoft SMTP Server (TLS) id 14.16.227.3; Mon, 23 Dec 2013 02:36:32 +0000 Received: from tx30smr01.am.freescale.net (10.81.153.31) by 039-SN1MMR1-004.039d.mgd.msft.net (10.84.1.14) with Microsoft SMTP Server (TLS) id 14.3.158.2; Mon, 23 Dec 2013 02:36:31 +0000 Received: from titan.ap.freescale.net (titan.ap.freescale.net [10.192.208.233]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id rBN2aRni026839; Sun, 22 Dec 2013 19:36:28 -0700 From: Dongsheng Wang To: , Subject: [PATCH] powerpc/mpic_timer: fix the time calculation is not accurate Date: Mon, 23 Dec 2013 10:33:45 +0800 Message-ID: <1387766025-46101-1-git-send-email-dongsheng.wang@freescale.com> X-Mailer: git-send-email 1.8.5 MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-FOPE-CONNECTOR: Id%0$Dn%*$RO%0$TLS%0$FQDN%$TlsDn% X-FOPE-CONNECTOR: Id%0$Dn%FREESCALE.MAIL.ONMICROSOFT.COM$RO%1$TLS%0$FQDN%$TlsDn% Cc: linuxppc-dev@lists.ozlabs.org, Wang Dongsheng X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" From: Wang Dongsheng 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 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);