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