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; 55985c0679SMarc Zyngier do { 56*fe13f95bSAKASHI Takahiro int ret = unwind_frame(NULL, &frame); 57985c0679SMarc Zyngier if (ret < 0) 58985c0679SMarc Zyngier return 0; 59985c0679SMarc Zyngier } while (in_lock_functions(frame.pc)); 60985c0679SMarc Zyngier 61985c0679SMarc Zyngier return frame.pc; 62985c0679SMarc Zyngier } 63985c0679SMarc Zyngier EXPORT_SYMBOL(profile_pc); 64985c0679SMarc Zyngier 65985c0679SMarc Zyngier void __init time_init(void) 66985c0679SMarc Zyngier { 671aee5d7aSMark Rutland u32 arch_timer_rate; 681aee5d7aSMark Rutland 69bc3ee18aSChanho Min of_clk_init(NULL); 703722ed23SMarc Zyngier clocksource_probe(); 711aee5d7aSMark Rutland 729358d755SLorenzo Pieralisi tick_setup_hrtimer_broadcast(); 739358d755SLorenzo Pieralisi 741aee5d7aSMark Rutland arch_timer_rate = arch_timer_get_rate(); 750583fe47SRob Herring if (!arch_timer_rate) 760583fe47SRob Herring panic("Unable to initialise architected timer.\n"); 771aee5d7aSMark Rutland 781aee5d7aSMark Rutland /* Calibrate the delay loop directly */ 791aee5d7aSMark Rutland lpj_fine = arch_timer_rate / HZ; 80985c0679SMarc Zyngier } 81