2005-04-17 02:20:36 +04:00
/*
* linux / arch / arm / kernel / time . c
*
* Copyright ( C ) 1991 , 1992 , 1995 Linus Torvalds
* Modifications for ARM ( C ) 1994 - 2001 Russell King
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* This file contains the ARM - specific time handling details :
* reading the RTC at bootup , etc . . .
*/
2013-09-04 14:24:03 +04:00
# include <linux/clk-provider.h>
# include <linux/clocksource.h>
# include <linux/errno.h>
2011-07-22 18:58:34 +04:00
# include <linux/export.h>
2005-04-17 02:20:36 +04:00
# include <linux/init.h>
2013-09-04 14:24:03 +04:00
# include <linux/interrupt.h>
# include <linux/irq.h>
# include <linux/kernel.h>
# include <linux/profile.h>
2009-10-07 17:09:06 +04:00
# include <linux/sched.h>
2013-09-04 14:24:03 +04:00
# include <linux/sched_clock.h>
2005-04-17 02:20:36 +04:00
# include <linux/smp.h>
2013-09-04 14:24:03 +04:00
# include <linux/time.h>
2005-04-17 02:20:36 +04:00
# include <linux/timex.h>
# include <linux/timer.h>
2010-12-20 13:18:36 +03:00
# include <asm/mach/arch.h>
2005-04-17 02:20:36 +04:00
# include <asm/mach/time.h>
2013-09-04 14:24:03 +04:00
# include <asm/stacktrace.h>
# include <asm/thread_info.h>
2005-04-17 02:20:36 +04:00
2011-06-10 17:58:30 +04:00
# if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || \
defined ( CONFIG_NVRAM ) | | defined ( CONFIG_NVRAM_MODULE )
2005-04-17 02:20:36 +04:00
/* this needs a better home */
DEFINE_SPINLOCK ( rtc_lock ) ;
EXPORT_SYMBOL ( rtc_lock ) ;
2007-01-18 00:11:27 +03:00
# endif /* pc-style 'CMOS' RTC support */
2005-04-17 02:20:36 +04:00
/* change this if you have some constant time drift */
# define USECS_PER_JIFFY (1000000 / HZ)
# ifdef CONFIG_SMP
unsigned long profile_pc ( struct pt_regs * regs )
{
2009-02-11 15:07:53 +03:00
struct stackframe frame ;
2005-04-17 02:20:36 +04:00
2009-02-11 15:07:53 +03:00
if ( ! in_lock_functions ( regs - > ARM_pc ) )
return regs - > ARM_pc ;
2005-04-17 02:20:36 +04:00
2014-06-03 22:48:58 +04:00
arm_get_current_stackframe ( regs , & frame ) ;
2009-02-11 15:07:53 +03:00
do {
int ret = unwind_frame ( & frame ) ;
if ( ret < 0 )
return 0 ;
} while ( in_lock_functions ( frame . pc ) ) ;
return frame . pc ;
2005-04-17 02:20:36 +04:00
}
EXPORT_SYMBOL ( profile_pc ) ;
# endif
2007-03-14 19:33:24 +03:00
# ifndef CONFIG_GENERIC_CLOCKEVENTS
2005-04-17 02:20:36 +04:00
/*
* Kernel system timer support .
*/
2006-10-06 21:53:39 +04:00
void timer_tick ( void )
2005-04-17 02:20:36 +04:00
{
2006-10-06 22:58:24 +04:00
profile_tick ( CPU_PROFILING ) ;
2011-01-27 17:59:21 +03:00
xtime_update ( 1 ) ;
2005-04-17 02:20:36 +04:00
# ifndef CONFIG_SMP
2006-10-25 16:59:16 +04:00
update_process_times ( user_mode ( get_irq_regs ( ) ) ) ;
2005-04-17 02:20:36 +04:00
# endif
}
2007-03-14 19:33:24 +03:00
# endif
2005-04-17 02:20:36 +04:00
2012-05-05 22:28:44 +04:00
static void dummy_clock_access ( struct timespec * ts )
{
ts - > tv_sec = 0 ;
ts - > tv_nsec = 0 ;
}
static clock_access_fn __read_persistent_clock = dummy_clock_access ;
static clock_access_fn __read_boot_clock = dummy_clock_access ; ;
void read_persistent_clock ( struct timespec * ts )
{
__read_persistent_clock ( ts ) ;
}
void read_boot_clock ( struct timespec * ts )
{
__read_boot_clock ( ts ) ;
}
int __init register_persistent_clock ( clock_access_fn read_boot ,
clock_access_fn read_persistent )
{
/* Only allow the clockaccess functions to be registered once */
if ( __read_persistent_clock = = dummy_clock_access & &
__read_boot_clock = = dummy_clock_access ) {
if ( read_boot )
__read_boot_clock = read_boot ;
if ( read_persistent )
__read_persistent_clock = read_persistent ;
return 0 ;
}
return - EINVAL ;
}
2005-04-17 02:20:36 +04:00
void __init time_init ( void )
{
2013-09-04 14:24:03 +04:00
if ( machine_desc - > init_time ) {
2013-03-25 20:14:57 +04:00
machine_desc - > init_time ( ) ;
2013-09-04 14:24:03 +04:00
} else {
# ifdef CONFIG_COMMON_CLK
of_clk_init ( NULL ) ;
# endif
2013-03-25 20:14:57 +04:00
clocksource_of_init ( ) ;
2013-09-04 14:24:03 +04:00
}
2005-04-17 02:20:36 +04:00
}