From patchwork Thu Jan 31 12:15:27 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Rutland X-Patchwork-Id: 2073321 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 471EBDF2E5 for ; Thu, 31 Jan 2013 12:35:22 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1U0tK9-0007xg-19; Thu, 31 Jan 2013 12:33:01 +0000 Received: from service87.mimecast.com ([91.220.42.44]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1U0t4h-0005Zw-H7 for linux-arm-kernel@lists.infradead.org; Thu, 31 Jan 2013 12:17:05 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Thu, 31 Jan 2013 12:17:00 +0000 Received: from e106331-lin.cambridge.arm.com ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.0); Thu, 31 Jan 2013 12:16:58 +0000 From: Mark Rutland To: linux-arm-kernel@lists.infradead.org Subject: [PATCHv5 04/16] arm: arch_timer: standardise counter reading Date: Thu, 31 Jan 2013 12:15:27 +0000 Message-Id: <1359634539-9580-5-git-send-email-mark.rutland@arm.com> X-Mailer: git-send-email 1.8.1.1 In-Reply-To: <1359634539-9580-1-git-send-email-mark.rutland@arm.com> References: <1359634539-9580-1-git-send-email-mark.rutland@arm.com> X-OriginalArrivalTime: 31 Jan 2013 12:16:59.0042 (UTC) FILETIME=[DE2AD820:01CDFFAC] X-MC-Unique: 113013112170007801 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130131_071703_775099_D8A4AB77 X-CRM114-Status: GOOD ( 11.32 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [91.220.42.44 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: mark.rutland@arm.com, c.dall@virtualopensystems.com, swarren@nvidia.com, marc.zyngier@arm.com, catalin.marinas@arm.com, sboyd@codeaurora.org, will.deacon@arm.com, santosh.shilimkar@ti.com, thomas.abraham@linaro.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org We're currently inconsistent with respect to our accesses to the physical and virtual counters, mixing and matching the two. This patch introduces and uses a function pointer for accessing the correct counter based on whether we're using physical or virtual interrupts. All current accesses to the counter accessors are redirected through it. When the driver is moved out to drivers/clocksource, there's the possibility that code called before the timer code is initialised will attempt to call arch_timer_read_counter (e.g. sched_clock for AArch64). To avoid having to have to check whether the timer has been initialised either in arch_timer_read_counter or one of it's callers, a default implementation is assigned that simply returns 0. Signed-off-by: Mark Rutland Cc: Catalin Marinas Cc: Marc Zyngier Cc: Santosh Shilimkar Acked-by: Catalin Marinas --- arch/arm/kernel/arch_timer.c | 58 +++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c index 498c29f..eb78f43 100644 --- a/arch/arm/kernel/arch_timer.c +++ b/arch/arm/kernel/arch_timer.c @@ -272,51 +272,37 @@ static int arch_timer_available(void) return 0; } -static u32 notrace arch_counter_get_cntpct32(void) +/* + * Some external users of arch_timer_read_counter (e.g. sched_clock) may try to + * call it before it has been initialised. Rather than incur a performance + * penalty checking for initialisation, provide a default implementation that + * won't lead to time appearing to jump backwards. + */ +static u64 arch_timer_read_zero(void) { - cycle_t cnt = arch_counter_get_cntpct(); - - /* - * The sched_clock infrastructure only knows about counters - * with at most 32bits. Forget about the upper 24 bits for the - * time being... - */ - return (u32)cnt; + return 0; } -static u32 notrace arch_counter_get_cntvct32(void) -{ - cycle_t cnt = arch_counter_get_cntvct(); +u64 (*arch_timer_read_counter)(void) = arch_timer_read_zero; - /* - * The sched_clock infrastructure only knows about counters - * with at most 32bits. Forget about the upper 24 bits for the - * time being... - */ - return (u32)cnt; +static u32 arch_timer_read_counter32(void) +{ + return arch_timer_read_counter(); } static cycle_t arch_counter_read(struct clocksource *cs) { - /* - * Always use the physical counter for the clocksource. - * CNTHCTL.PL1PCTEN must be set to 1. - */ - return arch_counter_get_cntpct(); + return arch_timer_read_counter(); } static unsigned long arch_timer_read_current_timer(void) { - return arch_counter_get_cntpct(); + return arch_timer_read_counter(); } static cycle_t arch_counter_read_cc(const struct cyclecounter *cc) { - /* - * Always use the physical counter for the clocksource. - * CNTHCTL.PL1PCTEN must be set to 1. - */ - return arch_counter_get_cntpct(); + return arch_timer_read_counter(); } static struct clocksource clocksource_counter = { @@ -484,23 +470,23 @@ int __init arch_timer_of_register(void) } } + if (arch_timer_use_virtual) + arch_timer_read_counter = arch_counter_get_cntvct; + else + arch_timer_read_counter = arch_counter_get_cntpct; + return arch_timer_register(); } int __init arch_timer_sched_clock_init(void) { - u32 (*cnt32)(void); int err; err = arch_timer_available(); if (err) return err; - if (arch_timer_use_virtual) - cnt32 = arch_counter_get_cntvct32; - else - cnt32 = arch_counter_get_cntpct32; - - setup_sched_clock(cnt32, 32, arch_timer_rate); + setup_sched_clock(arch_timer_read_counter32, + 32, arch_timer_rate); return 0; }