xref: /DragonOS/kernel/src/driver/rtc/class.rs (revision da152319797436368304cbc3f85a3b9ec049134b)
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