From patchwork Wed Jan 15 13:07:07 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prashant Gaikwad X-Patchwork-Id: 3491751 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 947BD9F2E9 for ; Wed, 15 Jan 2014 13:07:54 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B790B200EC for ; Wed, 15 Jan 2014 13:07:49 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 118AD20166 for ; Wed, 15 Jan 2014 13:07:48 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W3QC6-0006yH-84; Wed, 15 Jan 2014 13:07:42 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1W3QC3-0006mm-Kw; Wed, 15 Jan 2014 13:07:39 +0000 Received: from hqemgate16.nvidia.com ([216.228.121.65]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W3QBz-0006lj-Sw for linux-arm-kernel@lists.infradead.org; Wed, 15 Jan 2014 13:07:36 +0000 Received: from hqnvupgp08.nvidia.com (Not Verified[216.228.121.13]) by hqemgate16.nvidia.com id ; Wed, 15 Jan 2014 05:07:34 -0800 Received: from hqemhub02.nvidia.com ([172.20.12.94]) by hqnvupgp08.nvidia.com (PGP Universal service); Wed, 15 Jan 2014 05:06:52 -0800 X-PGP-Universal: processed; by hqnvupgp08.nvidia.com on Wed, 15 Jan 2014 05:06:52 -0800 Received: from localhost.localdomain (172.20.144.16) by hqemhub02.nvidia.com (172.20.150.31) with Microsoft SMTP Server (TLS) id 8.3.327.1; Wed, 15 Jan 2014 05:07:09 -0800 From: Prashant Gaikwad To: , , , Subject: [PATCH] arch_timer: Move delay timer to drivers clocksource Date: Wed, 15 Jan 2014 18:37:07 +0530 Message-ID: <1389791227-24097-1-git-send-email-pgaikwad@nvidia.com> X-Mailer: git-send-email 1.7.4.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140115_080736_096107_47E6BEF1 X-CRM114-Status: GOOD ( 23.42 ) X-Spam-Score: -2.2 (--) Cc: Prashant Gaikwad , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Now arch timer is registerd using generic sched timer, delay timer registration is the only part remaining in arch ports. Move this part to drivers clocksource and remove arch timer from arch ports. Signed-off-by: Prashant Gaikwad --- arch/arm/include/asm/arch_timer.h | 1 - arch/arm/kernel/Makefile | 1 - arch/arm/kernel/arch_timer.c | 44 ---------------------------------- arch/arm64/include/asm/arch_timer.h | 5 ---- arch/arm64/include/asm/delay.h | 32 ++++++++++++++++++++++++ arch/arm64/include/asm/timex.h | 5 +-- arch/arm64/kernel/time.c | 9 ------- arch/arm64/lib/delay.c | 26 ++++++++++++++++++++ drivers/clocksource/arm_arch_timer.c | 12 ++++++++- 9 files changed, 71 insertions(+), 64 deletions(-) delete mode 100644 arch/arm/kernel/arch_timer.c create mode 100644 arch/arm64/include/asm/delay.h diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index 0704e0c..61ad692 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -10,7 +10,6 @@ #include #ifdef CONFIG_ARM_ARCH_TIMER -int arch_timer_arch_init(void); /* * These register accessors are marked inline so the compiler can diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index a30fc9b..6b51cf9 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_SMP) += smp_tlb.o endif obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o -obj-$(CONFIG_ARM_ARCH_TIMER) += arch_timer.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c deleted file mode 100644 index 1791f12..0000000 --- a/arch/arm/kernel/arch_timer.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * linux/arch/arm/kernel/arch_timer.c - * - * Copyright (C) 2011 ARM Ltd. - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include - -#include - -#include - -static unsigned long arch_timer_read_counter_long(void) -{ - return arch_timer_read_counter(); -} - -static struct delay_timer arch_delay_timer; - -static void __init arch_timer_delay_timer_register(void) -{ - /* Use the architected timer for the delay loop. */ - arch_delay_timer.read_current_timer = arch_timer_read_counter_long; - arch_delay_timer.freq = arch_timer_get_rate(); - register_current_timer_delay(&arch_delay_timer); -} - -int __init arch_timer_arch_init(void) -{ - u32 arch_timer_rate = arch_timer_get_rate(); - - if (arch_timer_rate == 0) - return -ENXIO; - - arch_timer_delay_timer_register(); - - return 0; -} diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index 9400596..48e06bd 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -145,9 +145,4 @@ static inline u64 arch_counter_get_cntvct(void) return cval; } -static inline int arch_timer_arch_init(void) -{ - return 0; -} - #endif diff --git a/arch/arm64/include/asm/delay.h b/arch/arm64/include/asm/delay.h new file mode 100644 index 0000000..ea90d99 --- /dev/null +++ b/arch/arm64/include/asm/delay.h @@ -0,0 +1,32 @@ + +/* + * Copyright (c) 2014, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ASM_ARM64_DELAY_H +#define __ASM_ARM64_DELAY_H + +#include + +struct delay_timer { + unsigned long (*read_current_timer)(void); + unsigned long freq; +}; + +/* Delay-loop timer registration. */ +#define ARCH_HAS_READ_CURRENT_TIMER +extern void register_current_timer_delay(const struct delay_timer *timer); + +#endif /* defined(_ARM64_DELAY_H) */ diff --git a/arch/arm64/include/asm/timex.h b/arch/arm64/include/asm/timex.h index 81a076e..ca4bdfb 100644 --- a/arch/arm64/include/asm/timex.h +++ b/arch/arm64/include/asm/timex.h @@ -16,13 +16,12 @@ #ifndef __ASM_TIMEX_H #define __ASM_TIMEX_H -#include - /* * Use the current timer as a cycle counter since this is what we use for * the delay loop. */ -#define get_cycles() arch_counter_get_cntvct() +typedef unsigned long cycles_t; +#define get_cycles() ({ cycles_t c; read_current_timer(&c) ? 0 : c; }) #include diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c index 29c39d5..213d1a3 100644 --- a/arch/arm64/kernel/time.c +++ b/arch/arm64/kernel/time.c @@ -63,14 +63,5 @@ EXPORT_SYMBOL(profile_pc); void __init time_init(void) { - u32 arch_timer_rate; - clocksource_of_init(); - - arch_timer_rate = arch_timer_get_rate(); - if (!arch_timer_rate) - panic("Unable to initialise architected timer.\n"); - - /* Calibrate the delay loop directly */ - lpj_fine = arch_timer_rate / HZ; } diff --git a/arch/arm64/lib/delay.c b/arch/arm64/lib/delay.c index dad4ec9..cde0a28 100644 --- a/arch/arm64/lib/delay.c +++ b/arch/arm64/lib/delay.c @@ -24,6 +24,19 @@ #include #include +static const struct delay_timer *delay_timer; +static bool delay_calibrated; + +int read_current_timer(unsigned long *timer_val) +{ + if (!delay_timer) + return -ENXIO; + + *timer_val = delay_timer->read_current_timer(); + return 0; +} +EXPORT_SYMBOL(read_current_timer); + void __delay(unsigned long cycles) { cycles_t start = get_cycles(); @@ -53,3 +66,16 @@ void __ndelay(unsigned long nsecs) __const_udelay(nsecs * 0x5UL); /* 2**32 / 1000000000 (rounded up) */ } EXPORT_SYMBOL(__ndelay); + +void register_current_timer_delay(const struct delay_timer *timer) +{ + if (!delay_calibrated) { + pr_info("Switching to timer-based delay loop\n"); + delay_timer = timer; + lpj_fine = timer->freq / HZ; + + delay_calibrated = true; + } else { + pr_info("Ignoring duplicate/late registration of read_current_timer delay\n"); + } +} diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 57e823c..8ee9918 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -422,6 +422,16 @@ struct timecounter *arch_timer_get_timecounter(void) return &timecounter; } +static struct delay_timer arch_delay_timer; + +static void __init arch_delay_timer_register(void) +{ + /* Use the architected timer for the delay loop. */ + arch_delay_timer.read_current_timer = arch_timer_read_counter(); + arch_delay_timer.freq = arch_timer_rate; + register_current_timer_delay(&arch_delay_timer); +} + static void __init arch_counter_register(unsigned type) { u64 start_count; @@ -630,7 +640,7 @@ static void __init arch_timer_common_init(void) arch_timer_banner(arch_timers_present); arch_counter_register(arch_timers_present); - arch_timer_arch_init(); + arch_delay_timer_register(); } static void __init arch_timer_init(struct device_node *np)