2005-04-16 15:20:36 -07:00
/*
2009-05-08 16:44:00 +09:00
* arch / sh / kernel / time . c
2005-04-16 15:20:36 -07:00
*
* Copyright ( C ) 1999 Tetsuya Okada & Niibe Yutaka
* Copyright ( C ) 2000 Philipp Rumpf < prumpf @ tux . org >
2009-04-28 23:12:10 +09:00
* Copyright ( C ) 2002 - 2009 Paul Mundt
2005-04-16 15:20:36 -07:00
* Copyright ( C ) 2002 M . R . Brown < mrbrown @ linux - sh . org >
*
2009-05-08 16:44:00 +09:00
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
2005-04-16 15:20:36 -07:00
*/
# include <linux/kernel.h>
2006-01-16 22:14:17 -08:00
# include <linux/module.h>
2005-04-16 15:20:36 -07:00
# include <linux/init.h>
# include <linux/profile.h>
2006-12-06 11:24:48 +09:00
# include <linux/timex.h>
# include <linux/sched.h>
2007-05-09 17:33:24 +09:00
# include <linux/clockchips.h>
2009-04-15 10:50:12 +00:00
# include <linux/platform_device.h>
2008-08-06 18:37:07 +09:00
# include <linux/smp.h>
2009-04-27 17:34:39 +09:00
# include <linux/rtc.h>
2006-01-16 22:14:17 -08:00
# include <asm/clock.h>
2009-07-03 10:08:05 +00:00
# include <asm/hwblk.h>
2005-04-16 15:20:36 -07:00
# include <asm/rtc.h>
2006-01-16 22:14:17 -08:00
2006-09-27 17:45:01 +09:00
/* Dummy RTC ops */
static void null_rtc_get_time ( struct timespec * tv )
{
tv - > tv_sec = mktime ( 2000 , 1 , 1 , 0 , 0 , 0 ) ;
tv - > tv_nsec = 0 ;
}
static int null_rtc_set_time ( const time_t secs )
{
return 0 ;
}
void ( * rtc_sh_get_time ) ( struct timespec * ) = null_rtc_get_time ;
int ( * rtc_sh_set_time ) ( const time_t ) = null_rtc_set_time ;
2009-05-08 16:36:13 +09:00
2009-08-14 15:47:31 +02:00
void read_persistent_clock ( struct timespec * ts )
2009-05-08 16:36:13 +09:00
{
2009-08-25 07:32:39 +09:00
rtc_sh_get_time ( ts ) ;
2009-05-08 16:36:13 +09:00
}
2010-03-05 02:04:38 +09:00
# ifdef CONFIG_GENERIC_CMOS_UPDATE
2009-05-08 16:36:13 +09:00
int update_persistent_clock ( struct timespec now )
{
return rtc_sh_set_time ( now . tv_sec ) ;
}
# endif
2005-04-16 15:20:36 -07:00
2009-04-27 17:34:39 +09:00
unsigned int get_rtc_time ( struct rtc_time * tm )
{
if ( rtc_sh_get_time ! = null_rtc_get_time ) {
struct timespec tv ;
rtc_sh_get_time ( & tv ) ;
rtc_time_to_tm ( tv . tv_sec , tm ) ;
}
return RTC_24H ;
}
EXPORT_SYMBOL ( get_rtc_time ) ;
int set_rtc_time ( struct rtc_time * tm )
{
unsigned long secs ;
rtc_tm_to_time ( tm , & secs ) ;
return rtc_sh_set_time ( secs ) ;
}
EXPORT_SYMBOL ( set_rtc_time ) ;
2009-04-28 23:12:10 +09:00
static int __init rtc_generic_init ( void )
{
struct platform_device * pdev ;
if ( rtc_sh_get_time = = null_rtc_get_time )
return - ENODEV ;
pdev = platform_device_register_simple ( " rtc-generic " , - 1 , NULL , 0 ) ;
if ( IS_ERR ( pdev ) )
return PTR_ERR ( pdev ) ;
return 0 ;
}
module_init ( rtc_generic_init ) ;
2007-05-09 17:33:24 +09:00
void ( * board_time_init ) ( void ) ;
2006-12-01 13:23:47 +09:00
2009-07-29 22:43:58 +09:00
static void __init sh_late_time_init ( void )
2009-04-28 08:19:50 +00:00
{
2009-06-14 19:45:40 +09:00
/*
* Make sure all compiled - in early timers register themselves .
2009-06-14 20:02:30 +09:00
*
* Run probe ( ) for two " earlytimer " devices , these will be the
* clockevents and clocksource devices respectively . In the event
* that only a clockevents device is available , we - ENODEV on the
* clocksource and the jiffies clocksource is used transparently
* instead . No error handling is necessary here .
2009-06-14 19:45:40 +09:00
*/
early_platform_driver_register_all ( " earlytimer " ) ;
2009-06-14 20:02:30 +09:00
early_platform_driver_probe ( " earlytimer " , 2 , 0 ) ;
2009-04-28 08:19:50 +00:00
}
2009-07-29 22:43:58 +09:00
2009-04-28 08:19:50 +00:00
void __init time_init ( void )
{
if ( board_time_init )
board_time_init ( ) ;
2009-07-03 10:08:05 +00:00
hwblk_init ( ) ;
2009-04-28 08:19:50 +00:00
clk_init ( ) ;
2009-07-29 22:43:58 +09:00
late_time_init = sh_late_time_init ;
2009-04-28 08:19:50 +00:00
}