1/* 2 * Based on arch/arm/kernel/time.c 3 * 4 * Copyright (C) 1991, 1992, 1995 Linus Torvalds 5 * Modifications for ARM (C) 1994-2001 Russell King 6 * Copyright (C) 2012 ARM Ltd. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21#include <linux/export.h> 22#include <linux/kernel.h> 23#include <linux/interrupt.h> 24#include <linux/time.h> 25#include <linux/init.h> 26#include <linux/sched.h> 27#include <linux/smp.h> 28#include <linux/timex.h> 29#include <linux/errno.h> 30#include <linux/profile.h> 31#include <linux/syscore_ops.h> 32#include <linux/timer.h> 33#include <linux/irq.h> 34#include <linux/delay.h> 35 36#include <clocksource/arm_arch_timer.h> 37 38#include <asm/thread_info.h> 39#include <asm/stacktrace.h> 40 41#ifdef CONFIG_SMP 42unsigned long profile_pc(struct pt_regs *regs) 43{ 44 struct stackframe frame; 45 46 if (!in_lock_functions(regs->pc)) 47 return regs->pc; 48 49 frame.fp = regs->regs[29]; 50 frame.sp = regs->sp; 51 frame.pc = regs->pc; 52 do { 53 int ret = unwind_frame(&frame); 54 if (ret < 0) 55 return 0; 56 } while (in_lock_functions(frame.pc)); 57 58 return frame.pc; 59} 60EXPORT_SYMBOL(profile_pc); 61#endif 62 63static u64 sched_clock_mult __read_mostly; 64 65unsigned long long notrace sched_clock(void) 66{ 67 return arch_timer_read_counter() * sched_clock_mult; 68} 69 70int read_current_timer(unsigned long *timer_value) 71{ 72 *timer_value = arch_timer_read_counter(); 73 return 0; 74} 75 76void __init time_init(void) 77{ 78 u32 arch_timer_rate; 79 80 if (arch_timer_init()) 81 panic("Unable to initialise architected timer.\n"); 82 83 arch_timer_rate = arch_timer_get_rate(); 84 85 /* Cache the sched_clock multiplier to save a divide in the hot path. */ 86 sched_clock_mult = NSEC_PER_SEC / arch_timer_rate; 87 88 /* Calibrate the delay loop directly */ 89 lpj_fine = arch_timer_rate / HZ; 90} 91