Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp4407543imu; Fri, 30 Nov 2018 17:01:17 -0800 (PST) X-Google-Smtp-Source: AFSGD/XstRSYMB3PlQFh6R10QLhr3joEEMGHZmdIEtUIk1jgziUgEWQJbdB6JI18IpHXFUSASmlM X-Received: by 2002:a63:7e5b:: with SMTP id o27mr6539048pgn.214.1543626077028; Fri, 30 Nov 2018 17:01:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543626077; cv=none; d=google.com; s=arc-20160816; b=06Rlw7CvZCkl6V/Q/x3E1+ha+39u42smS+NFhrt6FbN/QI5AadMTUIq01L/cwVlOHG ChiiViH0k4BJdkC7rcHdUq5OB45A/XieINYbT/BUntmJdrU8Hztk2seLSm3z5toemGoa rX+vuTDlO00EOybqtVpW8g6t1u52Nytuq4yA9eOT+HtfcNeyFmpuh48PXSrT9qhisTRp ose2FpcR7TnYyd86YwJrF8E+GkURD6AN08wo1ALVGY42c+KvRJzHQJHzTVzHjAlygob8 7WHOH989QqQ/9+UcFBl98D/xOI9EMY2n1FrxcLsWf4Td4edmAebuV/RFn5OIGi2aIllQ fLZw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:subject:from:references:in-reply-to :message-id:cc:to; bh=uckTY2V12lDADdPCygP9DNd+8QsPZIRD0RMbQ27Cqb4=; b=aLQIQJXxFbbPB9PjHAIR6FtPZGgvpuXJx3De+Vw0e50FrB7wdpXcbQ0LzpqQUb6DS8 juhWQsgS2J0mm6a/+qMwxkiHlmNdmXePk3pzr+aw60TEIHBwwLjbO2GN7jRTXWbpnDAJ PHR0tvAkUX0tNhTIt4rTKGaocp7SuWZ3yflEWd07ub4PA4e32avXLy/YmQdwM/w0/T7o 00hmvidC118U0/3K2UiHYZdd6jRUH02NO0N7+fDChGlngMcV41yrGPBYmMFhVqZxwjCf XgGlM5zhWvIHmrVr0DW8T9QX8bWfYNlfwOWN+yxaZldXu0W9guhs+M2o03WkaicJLqG/ B9ow== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id cc16si7572721plb.377.2018.11.30.17.01.02; Fri, 30 Nov 2018 17:01:16 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727026AbeLAMLc (ORCPT + 99 others); Sat, 1 Dec 2018 07:11:32 -0500 Received: from kvm5.telegraphics.com.au ([98.124.60.144]:38156 "EHLO kvm5.telegraphics.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726691AbeLAMLb (ORCPT ); Sat, 1 Dec 2018 07:11:31 -0500 Received: by kvm5.telegraphics.com.au (Postfix, from userid 502) id 3EB41281F5; Fri, 30 Nov 2018 20:00:15 -0500 (EST) To: Geert Uytterhoeven , Philip Blundell Cc: Andreas Schwab , Arnd Bergmann , Stephen N Chivers , Thomas Gleixner , Kars de Jong , Daniel Lezcano , Michael Schmitz , John Stultz , Linus Walleij , linux-m68k@lists.linux-m68k.org, linux-kernel@vger.kernel.org Message-Id: <2aa62fd1164340976feb6e5e58a3c960083a3d95.1543625590.git.fthain@telegraphics.com.au> In-Reply-To: References: From: Finn Thain Subject: [PATCH v4 09/14] m68k: hp300: Handle timer counter overflow Date: Sat, 01 Dec 2018 11:53:10 +1100 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Because hp300_read_clk() never checks the timer interrupt flag it may fail to notice that the timer has wrapped, allowing the clock to jump backwards. This is not a new problem. This is resolved by checking the interrupt flag and, if need be, taking wrap-around into account. The interrupt handler clears the flag when it eventually executes. Signed-off-by: Finn Thain --- TODO: find a spare counter for the clocksource, rather than hanging it off the HZ timer. Changed since v3: - Use clk_offset variable to track the offset when the irq check is skipped. --- arch/m68k/hp300/time.c | 46 +++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c index 90982803a629..bfee13e1d0fe 100644 --- a/arch/m68k/hp300/time.c +++ b/arch/m68k/hp300/time.c @@ -30,7 +30,7 @@ static struct clocksource hp300_clk = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static u32 clk_total; +static u32 clk_total, clk_offset; /* Clock hardware definitions */ @@ -41,9 +41,12 @@ static u32 clk_total; #define CLKCR3 CLKCR1 #define CLKSR CLKCR2 #define CLKMSB1 0x5 +#define CLKLSB1 0x7 #define CLKMSB2 0x9 #define CLKMSB3 0xD +#define CLKSR_INT1 BIT(0) + /* This is for machines which generate the exact clock. */ #define HP300_TIMER_CLOCK_FREQ 250000 @@ -60,6 +63,7 @@ static irqreturn_t hp300_tick(int irq, void *dev_id) in_8(CLOCKBASE + CLKSR); asm volatile ("movpw %1@(5),%0" : "=d" (tmp) : "a" (CLOCKBASE)); clk_total += INTVAL; + clk_offset = 0; timer_routine(0, NULL); local_irq_restore(flags); @@ -70,24 +74,28 @@ static irqreturn_t hp300_tick(int irq, void *dev_id) static u64 hp300_read_clk(struct clocksource *cs) { - unsigned long flags; - unsigned char lsb, msb1, msb2; - u32 ticks; - - local_irq_save(flags); - /* Read current timer 1 value */ - msb1 = in_8(CLOCKBASE + 5); - lsb = in_8(CLOCKBASE + 7); - msb2 = in_8(CLOCKBASE + 5); - if (msb1 != msb2) - /* A carry happened while we were reading. Read it again */ - lsb = in_8(CLOCKBASE + 7); - - ticks = INTVAL - ((msb2 << 8) | lsb); - ticks += clk_total; - local_irq_restore(flags); - - return ticks; + unsigned long flags; + unsigned char lsb, msb, msb_new; + u32 ticks; + + local_irq_save(flags); + /* Read current timer 1 value */ + msb = in_8(CLOCKBASE + CLKMSB1); +again: + if ((in_8(CLOCKBASE + CLKSR) & CLKSR_INT1) && msb > 0) + clk_offset = INTVAL; + lsb = in_8(CLOCKBASE + CLKLSB1); + msb_new = in_8(CLOCKBASE + CLKMSB1); + if (msb_new != msb) { + msb = msb_new; + goto again; + } + + ticks = INTVAL - ((msb << 8) | lsb); + ticks += clk_offset + clk_total; + local_irq_restore(flags); + + return ticks; } void __init hp300_sched_init(irq_handler_t vector) -- 2.18.1