xref: /linux/arch/arm64/kernel/time.c (revision ba5d08c0ea785d5710c5a1e7dc3182b7124d63c0)
1985c0679SMarc Zyngier /*
2985c0679SMarc Zyngier  * Based on arch/arm/kernel/time.c
3985c0679SMarc Zyngier  *
4985c0679SMarc Zyngier  * Copyright (C) 1991, 1992, 1995  Linus Torvalds
5985c0679SMarc Zyngier  * Modifications for ARM (C) 1994-2001 Russell King
6985c0679SMarc Zyngier  * Copyright (C) 2012 ARM Ltd.
7985c0679SMarc Zyngier  *
8985c0679SMarc Zyngier  * This program is free software; you can redistribute it and/or modify
9985c0679SMarc Zyngier  * it under the terms of the GNU General Public License version 2 as
10985c0679SMarc Zyngier  * published by the Free Software Foundation.
11985c0679SMarc Zyngier  *
12985c0679SMarc Zyngier  * This program is distributed in the hope that it will be useful,
13985c0679SMarc Zyngier  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14985c0679SMarc Zyngier  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15985c0679SMarc Zyngier  * GNU General Public License for more details.
16985c0679SMarc Zyngier  *
17985c0679SMarc Zyngier  * You should have received a copy of the GNU General Public License
18985c0679SMarc Zyngier  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19985c0679SMarc Zyngier  */
20985c0679SMarc Zyngier 
219358d755SLorenzo Pieralisi #include <linux/clockchips.h>
22985c0679SMarc Zyngier #include <linux/export.h>
23985c0679SMarc Zyngier #include <linux/kernel.h>
24985c0679SMarc Zyngier #include <linux/interrupt.h>
25985c0679SMarc Zyngier #include <linux/time.h>
26985c0679SMarc Zyngier #include <linux/init.h>
27985c0679SMarc Zyngier #include <linux/sched.h>
28985c0679SMarc Zyngier #include <linux/smp.h>
29985c0679SMarc Zyngier #include <linux/timex.h>
30985c0679SMarc Zyngier #include <linux/errno.h>
31985c0679SMarc Zyngier #include <linux/profile.h>
32985c0679SMarc Zyngier #include <linux/syscore_ops.h>
33985c0679SMarc Zyngier #include <linux/timer.h>
34985c0679SMarc Zyngier #include <linux/irq.h>
351aee5d7aSMark Rutland #include <linux/delay.h>
360583fe47SRob Herring #include <linux/clocksource.h>
37bc3ee18aSChanho Min #include <linux/clk-provider.h>
38b09ca1ecSHanjun Guo #include <linux/acpi.h>
39985c0679SMarc Zyngier 
401aee5d7aSMark Rutland #include <clocksource/arm_arch_timer.h>
41985c0679SMarc Zyngier 
42985c0679SMarc Zyngier #include <asm/thread_info.h>
43985c0679SMarc Zyngier #include <asm/stacktrace.h>
44985c0679SMarc Zyngier 
45985c0679SMarc Zyngier unsigned long profile_pc(struct pt_regs *regs)
46985c0679SMarc Zyngier {
47985c0679SMarc Zyngier 	struct stackframe frame;
48985c0679SMarc Zyngier 
49985c0679SMarc Zyngier 	if (!in_lock_functions(regs->pc))
50985c0679SMarc Zyngier 		return regs->pc;
51985c0679SMarc Zyngier 
52985c0679SMarc Zyngier 	frame.fp = regs->regs[29];
53985c0679SMarc Zyngier 	frame.sp = regs->sp;
54985c0679SMarc Zyngier 	frame.pc = regs->pc;
5520380bb3SAKASHI Takahiro #ifdef CONFIG_FUNCTION_GRAPH_TRACER
5620380bb3SAKASHI Takahiro 	frame.graph = -1; /* no task info */
5720380bb3SAKASHI Takahiro #endif
58985c0679SMarc Zyngier 	do {
59fe13f95bSAKASHI Takahiro 		int ret = unwind_frame(NULL, &frame);
60985c0679SMarc Zyngier 		if (ret < 0)
61985c0679SMarc Zyngier 			return 0;
62985c0679SMarc Zyngier 	} while (in_lock_functions(frame.pc));
63985c0679SMarc Zyngier 
64985c0679SMarc Zyngier 	return frame.pc;
65985c0679SMarc Zyngier }
66985c0679SMarc Zyngier EXPORT_SYMBOL(profile_pc);
67985c0679SMarc Zyngier 
68985c0679SMarc Zyngier void __init time_init(void)
69985c0679SMarc Zyngier {
701aee5d7aSMark Rutland 	u32 arch_timer_rate;
711aee5d7aSMark Rutland 
72bc3ee18aSChanho Min 	of_clk_init(NULL);
73*ba5d08c0SDaniel Lezcano 	timer_probe();
741aee5d7aSMark Rutland 
759358d755SLorenzo Pieralisi 	tick_setup_hrtimer_broadcast();
769358d755SLorenzo Pieralisi 
771aee5d7aSMark Rutland 	arch_timer_rate = arch_timer_get_rate();
780583fe47SRob Herring 	if (!arch_timer_rate)
790583fe47SRob Herring 		panic("Unable to initialise architected timer.\n");
801aee5d7aSMark Rutland 
811aee5d7aSMark Rutland 	/* Calibrate the delay loop directly */
821aee5d7aSMark Rutland 	lpj_fine = arch_timer_rate / HZ;
83985c0679SMarc Zyngier }
84