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 .
*/
2015-04-16 22:46:14 +03:00
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2006-03-27 13:16:37 +04:00
# 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 .
*/
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 ;
2015-01-22 05:31:53 +03:00
struct timespec64 tv64 = {
2010-03-11 02:20:35 +03:00
. 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 ) {
2015-04-16 22:46:14 +03:00
pr_info ( " unable to open rtc device (%s) \n " ,
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
2015-01-22 05:31:53 +03:00
tv64 . tv_sec = rtc_tm_to_time64 ( & tm ) ;
2006-03-27 13:16:37 +04:00
2015-01-22 05:31:53 +03:00
err = do_settimeofday64 ( & tv64 ) ;
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 "
2015-01-22 05:31:53 +03:00
" %d-%02d-%02d %02d:%02d:%02d UTC (%lld) \n " ,
2010-03-11 02:20:35 +03:00
tm . tm_year + 1900 , tm . tm_mon + 1 , tm . tm_mday ,
tm . tm_hour , tm . tm_min , tm . tm_sec ,
2015-01-22 05:31:53 +03:00
( long long ) tv64 . tv_sec ) ;
2010-03-11 02:20:35 +03:00
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 ) ;