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