xref: /linux/arch/arm64/kernel/time.c (revision caab277b1de0a22b675c4c95fc7b285ec2eb5bf5)
1*caab277bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2985c0679SMarc Zyngier /*
3985c0679SMarc Zyngier  * Based on arch/arm/kernel/time.c
4985c0679SMarc Zyngier  *
5985c0679SMarc Zyngier  * Copyright (C) 1991, 1992, 1995  Linus Torvalds
6985c0679SMarc Zyngier  * Modifications for ARM (C) 1994-2001 Russell King
7985c0679SMarc Zyngier  * Copyright (C) 2012 ARM Ltd.
8985c0679SMarc Zyngier  */
9985c0679SMarc Zyngier 
109358d755SLorenzo Pieralisi #include <linux/clockchips.h>
11985c0679SMarc Zyngier #include <linux/export.h>
12985c0679SMarc Zyngier #include <linux/kernel.h>
13985c0679SMarc Zyngier #include <linux/interrupt.h>
14985c0679SMarc Zyngier #include <linux/time.h>
15985c0679SMarc Zyngier #include <linux/init.h>
16985c0679SMarc Zyngier #include <linux/sched.h>
17985c0679SMarc Zyngier #include <linux/smp.h>
18985c0679SMarc Zyngier #include <linux/timex.h>
19985c0679SMarc Zyngier #include <linux/errno.h>
20985c0679SMarc Zyngier #include <linux/profile.h>
21985c0679SMarc Zyngier #include <linux/syscore_ops.h>
22985c0679SMarc Zyngier #include <linux/timer.h>
23985c0679SMarc Zyngier #include <linux/irq.h>
241aee5d7aSMark Rutland #include <linux/delay.h>
250583fe47SRob Herring #include <linux/clocksource.h>
26bc3ee18aSChanho Min #include <linux/clk-provider.h>
27b09ca1ecSHanjun Guo #include <linux/acpi.h>
28985c0679SMarc Zyngier 
291aee5d7aSMark Rutland #include <clocksource/arm_arch_timer.h>
30985c0679SMarc Zyngier 
31985c0679SMarc Zyngier #include <asm/thread_info.h>
32985c0679SMarc Zyngier #include <asm/stacktrace.h>
33985c0679SMarc Zyngier 
34985c0679SMarc Zyngier unsigned long profile_pc(struct pt_regs *regs)
35985c0679SMarc Zyngier {
36985c0679SMarc Zyngier 	struct stackframe frame;
37985c0679SMarc Zyngier 
38985c0679SMarc Zyngier 	if (!in_lock_functions(regs->pc))
39985c0679SMarc Zyngier 		return regs->pc;
40985c0679SMarc Zyngier 
41985c0679SMarc Zyngier 	frame.fp = regs->regs[29];
42985c0679SMarc Zyngier 	frame.pc = regs->pc;
4320380bb3SAKASHI Takahiro #ifdef CONFIG_FUNCTION_GRAPH_TRACER
44a448276cSSteven Rostedt (VMware) 	frame.graph = 0;
4520380bb3SAKASHI Takahiro #endif
46985c0679SMarc Zyngier 	do {
47fe13f95bSAKASHI Takahiro 		int ret = unwind_frame(NULL, &frame);
48985c0679SMarc Zyngier 		if (ret < 0)
49985c0679SMarc Zyngier 			return 0;
50985c0679SMarc Zyngier 	} while (in_lock_functions(frame.pc));
51985c0679SMarc Zyngier 
52985c0679SMarc Zyngier 	return frame.pc;
53985c0679SMarc Zyngier }
54985c0679SMarc Zyngier EXPORT_SYMBOL(profile_pc);
55985c0679SMarc Zyngier 
56985c0679SMarc Zyngier void __init time_init(void)
57985c0679SMarc Zyngier {
581aee5d7aSMark Rutland 	u32 arch_timer_rate;
591aee5d7aSMark Rutland 
60bc3ee18aSChanho Min 	of_clk_init(NULL);
61ba5d08c0SDaniel Lezcano 	timer_probe();
621aee5d7aSMark Rutland 
639358d755SLorenzo Pieralisi 	tick_setup_hrtimer_broadcast();
649358d755SLorenzo Pieralisi 
651aee5d7aSMark Rutland 	arch_timer_rate = arch_timer_get_rate();
660583fe47SRob Herring 	if (!arch_timer_rate)
670583fe47SRob Herring 		panic("Unable to initialise architected timer.\n");
681aee5d7aSMark Rutland 
691aee5d7aSMark Rutland 	/* Calibrate the delay loop directly */
701aee5d7aSMark Rutland 	lpj_fine = arch_timer_rate / HZ;
71985c0679SMarc Zyngier }
72