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