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