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