1*da152319SLoGin use alloc::{ 2*da152319SLoGin string::ToString, 3*da152319SLoGin sync::{Arc, Weak}, 4*da152319SLoGin }; 5*da152319SLoGin use system_error::SystemError; 6*da152319SLoGin use unified_init::macros::unified_init; 7*da152319SLoGin 8*da152319SLoGin use crate::{ 9*da152319SLoGin driver::base::{ 10*da152319SLoGin class::{class_manager, Class}, 11*da152319SLoGin device::{device_manager, sys_dev_char_kset}, 12*da152319SLoGin kobject::KObject, 13*da152319SLoGin subsys::SubSysPrivate, 14*da152319SLoGin }, 15*da152319SLoGin init::initcall::INITCALL_SUBSYS, 16*da152319SLoGin time::{timekeeping::do_settimeofday64, TimeSpec}, 17*da152319SLoGin }; 18*da152319SLoGin 19*da152319SLoGin use super::{interface::rtc_read_time, register_default_rtc, sysfs::RtcGeneralDevice}; 20*da152319SLoGin 21*da152319SLoGin /// `/sys/class/rtc` 的 class 实例 22*da152319SLoGin static mut CLASS_RTC_INSTANCE: Option<Arc<RtcClass>> = None; 23*da152319SLoGin 24*da152319SLoGin /// 获取 `/sys/class/rtc` 的 class 实例 25*da152319SLoGin #[inline(always)] 26*da152319SLoGin #[allow(dead_code)] 27*da152319SLoGin pub fn sys_class_rtc_instance() -> Option<&'static Arc<RtcClass>> { 28*da152319SLoGin unsafe { CLASS_RTC_INSTANCE.as_ref() } 29*da152319SLoGin } 30*da152319SLoGin 31*da152319SLoGin /// 初始化帧缓冲区子系统 32*da152319SLoGin #[unified_init(INITCALL_SUBSYS)] 33*da152319SLoGin pub fn fbmem_init() -> Result<(), SystemError> { 34*da152319SLoGin let rtc_class = RtcClass::new(); 35*da152319SLoGin class_manager().class_register(&(rtc_class.clone() as Arc<dyn Class>))?; 36*da152319SLoGin 37*da152319SLoGin unsafe { 38*da152319SLoGin CLASS_RTC_INSTANCE = Some(rtc_class); 39*da152319SLoGin } 40*da152319SLoGin 41*da152319SLoGin return Ok(()); 42*da152319SLoGin } 43*da152319SLoGin 44*da152319SLoGin /// `/sys/class/rtc` 类 45*da152319SLoGin #[derive(Debug)] 46*da152319SLoGin pub struct RtcClass { 47*da152319SLoGin subsystem: SubSysPrivate, 48*da152319SLoGin } 49*da152319SLoGin 50*da152319SLoGin impl RtcClass { 51*da152319SLoGin const NAME: &'static str = "rtc"; 52*da152319SLoGin pub fn new() -> Arc<Self> { 53*da152319SLoGin let r = Self { 54*da152319SLoGin subsystem: SubSysPrivate::new(Self::NAME.to_string(), None, None, &[]), 55*da152319SLoGin }; 56*da152319SLoGin let r = Arc::new(r); 57*da152319SLoGin r.subsystem() 58*da152319SLoGin .set_class(Some(Arc::downgrade(&r) as Weak<dyn Class>)); 59*da152319SLoGin 60*da152319SLoGin return r; 61*da152319SLoGin } 62*da152319SLoGin } 63*da152319SLoGin 64*da152319SLoGin impl Class for RtcClass { 65*da152319SLoGin fn name(&self) -> &'static str { 66*da152319SLoGin return Self::NAME; 67*da152319SLoGin } 68*da152319SLoGin 69*da152319SLoGin fn dev_kobj(&self) -> Option<Arc<dyn KObject>> { 70*da152319SLoGin Some(sys_dev_char_kset() as Arc<dyn KObject>) 71*da152319SLoGin } 72*da152319SLoGin 73*da152319SLoGin fn set_dev_kobj(&self, _kobj: Arc<dyn KObject>) { 74*da152319SLoGin unimplemented!("RtcClass::set_dev_kobj"); 75*da152319SLoGin } 76*da152319SLoGin 77*da152319SLoGin fn subsystem(&self) -> &SubSysPrivate { 78*da152319SLoGin return &self.subsystem; 79*da152319SLoGin } 80*da152319SLoGin } 81*da152319SLoGin 82*da152319SLoGin /// 注册rtc通用设备 83*da152319SLoGin pub(super) fn rtc_register_device(dev: &Arc<RtcGeneralDevice>) -> Result<(), SystemError> { 84*da152319SLoGin device_manager().add_device(dev.clone())?; 85*da152319SLoGin register_default_rtc(dev.clone()); 86*da152319SLoGin // 把硬件时间同步到系统时间 87*da152319SLoGin rtc_hctosys(dev); 88*da152319SLoGin return Ok(()); 89*da152319SLoGin } 90*da152319SLoGin 91*da152319SLoGin fn rtc_hctosys(dev: &Arc<RtcGeneralDevice>) { 92*da152319SLoGin let r = rtc_read_time(dev); 93*da152319SLoGin if let Err(e) = r { 94*da152319SLoGin dev.set_hc2sys_result(Err(e)); 95*da152319SLoGin return; 96*da152319SLoGin } 97*da152319SLoGin 98*da152319SLoGin let time = r.unwrap(); 99*da152319SLoGin let timespec64: TimeSpec = time.into(); 100*da152319SLoGin let r = do_settimeofday64(timespec64); 101*da152319SLoGin dev.set_hc2sys_result(r); 102*da152319SLoGin 103*da152319SLoGin kinfo!( 104*da152319SLoGin "Setting system clock to {} {} UTC ({})", 105*da152319SLoGin time.date_string(), 106*da152319SLoGin time.time_string(), 107*da152319SLoGin timespec64.tv_sec 108*da152319SLoGin ); 109*da152319SLoGin } 110