2006-03-27 13:16:37 +04:00
/*
* RTC subsystem , initialize system time on startup
*
* Copyright ( C ) 2005 Tower Technologies
* Author : Alessandro Zummo < a . zummo @ towertech . it >
*
* 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 .
*/
# include <linux/rtc.h>
/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
* whether it stores the most close value or the value with partial
* seconds truncated . However , it is important that we use it to store
* the truncated value . This is because otherwise it is necessary ,
* in an rtc sync function , to read both xtime . tv_sec and
* xtime . tv_nsec . On some processors ( i . e . ARM ) , an atomic read
* of > 32 bits is not possible . So storing the most close value would
* slow down the sync API . So here we have the truncated value and
* the best guess is to add 0.5 s .
*/
2010-03-11 02:20:35 +03:00
int rtc_hctosys_ret = - ENODEV ;
2006-03-27 13:16:37 +04:00
static int __init rtc_hctosys ( void )
{
2010-03-11 02:20:35 +03:00
int err = - ENODEV ;
2006-03-27 13:16:37 +04:00
struct rtc_time tm ;
2010-03-11 02:20:35 +03:00
struct timespec tv = {
. tv_nsec = NSEC_PER_SEC > > 1 ,
} ;
2007-05-08 11:33:30 +04:00
struct rtc_device * rtc = rtc_class_open ( CONFIG_RTC_HCTOSYS_DEVICE ) ;
2006-03-27 13:16:37 +04:00
2007-05-08 11:33:30 +04:00
if ( rtc = = NULL ) {
2010-03-11 02:20:35 +03:00
pr_err ( " %s: unable to open rtc device (%s) \n " ,
2006-03-27 13:16:37 +04:00
__FILE__ , CONFIG_RTC_HCTOSYS_DEVICE ) ;
2010-03-11 02:20:35 +03:00
goto err_open ;
2006-03-27 13:16:37 +04:00
}
2007-05-08 11:33:30 +04:00
err = rtc_read_time ( rtc , & tm ) ;
2010-03-11 02:20:35 +03:00
if ( err ) {
dev_err ( rtc - > dev . parent ,
" hctosys: unable to read the hardware clock \n " ) ;
goto err_read ;
2006-03-27 13:16:37 +04:00
2010-03-11 02:20:35 +03:00
}
2006-03-27 13:16:37 +04:00
2010-03-11 02:20:35 +03:00
err = rtc_valid_tm ( & tm ) ;
if ( err ) {
dev_err ( rtc - > dev . parent ,
" hctosys: invalid date/time \n " ) ;
goto err_invalid ;
}
2006-03-27 13:16:37 +04:00
2010-03-11 02:20:35 +03:00
rtc_tm_to_time ( & tm , & tv . tv_sec ) ;
2006-03-27 13:16:37 +04:00
2010-03-11 02:20:35 +03:00
do_settimeofday ( & tv ) ;
2006-03-27 13:16:37 +04:00
2010-03-11 02:20:35 +03:00
dev_info ( rtc - > dev . parent ,
" setting system clock to "
" %d-%02d-%02d %02d:%02d:%02d UTC (%u) \n " ,
tm . tm_year + 1900 , tm . tm_mon + 1 , tm . tm_mday ,
tm . tm_hour , tm . tm_min , tm . tm_sec ,
( unsigned int ) tv . tv_sec ) ;
err_invalid :
err_read :
2007-05-08 11:33:30 +04:00
rtc_class_close ( rtc ) ;
2006-03-27 13:16:37 +04:00
2010-03-11 02:20:35 +03:00
err_open :
rtc_hctosys_ret = err ;
return err ;
2006-03-27 13:16:37 +04:00
}
late_initcall ( rtc_hctosys ) ;