xref: /DragonOS/kernel/src/driver/rtc/class.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
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)]
sys_class_rtc_instance() -> Option<&'static Arc<RtcClass>>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)]
fbmem_init() -> Result<(), SystemError>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";
new() -> Arc<Self>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 {
name(&self) -> &'static str66     fn name(&self) -> &'static str {
67         return Self::NAME;
68     }
69 
dev_kobj(&self) -> Option<Arc<dyn KObject>>70     fn dev_kobj(&self) -> Option<Arc<dyn KObject>> {
71         Some(sys_dev_char_kset() as Arc<dyn KObject>)
72     }
73 
set_dev_kobj(&self, _kobj: Arc<dyn KObject>)74     fn set_dev_kobj(&self, _kobj: Arc<dyn KObject>) {
75         unimplemented!("RtcClass::set_dev_kobj");
76     }
77 
subsystem(&self) -> &SubSysPrivate78     fn subsystem(&self) -> &SubSysPrivate {
79         return &self.subsystem;
80     }
81 }
82 
83 /// 注册rtc通用设备
rtc_register_device(dev: &Arc<RtcGeneralDevice>) -> Result<(), SystemError>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 
rtc_hctosys(dev: &Arc<RtcGeneralDevice>)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