2005-04-17 02:20:36 +04:00
/*
2009-05-08 11:44:00 +04:00
* arch / sh / kernel / time . c
2005-04-17 02:20:36 +04:00
*
* Copyright ( C ) 1999 Tetsuya Okada & Niibe Yutaka
* Copyright ( C ) 2000 Philipp Rumpf < prumpf @ tux . org >
2009-04-28 18:12:10 +04:00
* Copyright ( C ) 2002 - 2009 Paul Mundt
2005-04-17 02:20:36 +04:00
* Copyright ( C ) 2002 M . R . Brown < mrbrown @ linux - sh . org >
*
2009-05-08 11:44:00 +04: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-17 02:20:36 +04:00
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/profile.h>
2006-12-06 05:24:48 +03:00
# include <linux/timex.h>
# include <linux/sched.h>
2007-05-09 12:33:24 +04:00
# include <linux/clockchips.h>
2009-04-15 14:50:12 +04:00
# include <linux/platform_device.h>
2008-08-06 13:37:07 +04:00
# include <linux/smp.h>
2009-04-27 12:34:39 +04:00
# include <linux/rtc.h>
2006-01-17 09:14:17 +03:00
# include <asm/clock.h>
2005-04-17 02:20:36 +04:00
# include <asm/rtc.h>
2006-01-17 09:14:17 +03:00
2006-09-27 12:45:01 +04: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 11:36:13 +04:00
2009-08-14 17:47:31 +04:00
void read_persistent_clock ( struct timespec * ts )
2009-05-08 11:36:13 +04:00
{
2009-08-25 02:32:39 +04:00
rtc_sh_get_time ( ts ) ;
2009-05-08 11:36:13 +04:00
}
2010-03-04 20:04:38 +03:00
# ifdef CONFIG_GENERIC_CMOS_UPDATE
2009-05-08 11:36:13 +04:00
int update_persistent_clock ( struct timespec now )
{
return rtc_sh_set_time ( now . tv_sec ) ;
}
# endif
2005-04-17 02:20:36 +04:00
2016-05-30 21:57:52 +03:00
static int rtc_generic_get_time ( struct device * dev , struct rtc_time * tm )
2009-04-27 12:34:39 +04:00
{
2016-05-30 21:57:52 +03:00
struct timespec tv ;
2009-04-27 12:34:39 +04:00
2016-05-30 21:57:52 +03:00
rtc_sh_get_time ( & tv ) ;
rtc_time_to_tm ( tv . tv_sec , tm ) ;
return 0 ;
2009-04-27 12:34:39 +04:00
}
2016-05-30 21:57:52 +03:00
static int rtc_generic_set_time ( struct device * dev , struct rtc_time * tm )
2009-04-27 12:34:39 +04:00
{
unsigned long secs ;
rtc_tm_to_time ( tm , & secs ) ;
2016-05-30 21:57:52 +03:00
if ( ( rtc_sh_set_time = = null_rtc_set_time ) | |
( rtc_sh_set_time ( secs ) < 0 ) )
return - EOPNOTSUPP ;
return 0 ;
2009-04-27 12:34:39 +04:00
}
2016-05-30 21:57:52 +03:00
static const struct rtc_class_ops rtc_generic_ops = {
. read_time = rtc_generic_get_time ,
. set_time = rtc_generic_set_time ,
} ;
2009-04-27 12:34:39 +04:00
2009-04-28 18:12:10 +04:00
static int __init rtc_generic_init ( void )
{
struct platform_device * pdev ;
if ( rtc_sh_get_time = = null_rtc_get_time )
return - ENODEV ;
2016-05-30 21:57:52 +03:00
pdev = platform_device_register_data ( NULL , " rtc-generic " , - 1 ,
& rtc_generic_ops ,
sizeof ( rtc_generic_ops ) ) ;
2009-04-28 18:12:10 +04:00
2014-08-07 03:03:43 +04:00
return PTR_ERR_OR_ZERO ( pdev ) ;
2009-04-28 18:12:10 +04:00
}
2016-04-22 21:07:01 +03:00
device_initcall ( rtc_generic_init ) ;
2009-04-28 18:12:10 +04:00
2007-05-09 12:33:24 +04:00
void ( * board_time_init ) ( void ) ;
2006-12-01 07:23:47 +03:00
2009-07-29 17:43:58 +04:00
static void __init sh_late_time_init ( void )
2009-04-28 12:19:50 +04:00
{
2009-06-14 14:45:40 +04:00
/*
* Make sure all compiled - in early timers register themselves .
2009-06-14 15:02:30 +04: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 14:45:40 +04:00
*/
early_platform_driver_register_all ( " earlytimer " ) ;
2009-06-14 15:02:30 +04:00
early_platform_driver_probe ( " earlytimer " , 2 , 0 ) ;
2009-04-28 12:19:50 +04:00
}
2009-07-29 17:43:58 +04:00
2009-04-28 12:19:50 +04:00
void __init time_init ( void )
{
if ( board_time_init )
board_time_init ( ) ;
clk_init ( ) ;
2009-07-29 17:43:58 +04:00
late_time_init = sh_late_time_init ;
2009-04-28 12:19:50 +04:00
}