xref: /DragonOS/kernel/src/driver/rtc/class.rs (revision 418ad41fd84c15ed7e132e56970150ac38fc24a9)
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, PosixTimeSpec},
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: PosixTimeSpec = 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