xref: /DragonOS/kernel/src/driver/base/platform/platform_device.rs (revision a03c4f9dee5705207325c56629c0ccd219168f10)
106d5e247SLoGin use alloc::{
206d5e247SLoGin     string::{String, ToString},
306d5e247SLoGin     sync::{Arc, Weak},
406d5e247SLoGin };
5*a03c4f9dSLoGin use ida::IdAllocator;
606d5e247SLoGin 
706d5e247SLoGin use crate::{
8*a03c4f9dSLoGin     driver::base::{
906d5e247SLoGin         device::{
1006d5e247SLoGin             bus::{Bus, BusState},
11*a03c4f9dSLoGin             device_manager,
12*a03c4f9dSLoGin             driver::Driver,
1306d5e247SLoGin             Device, DeviceNumber, DevicePrivateData, DeviceType, IdTable,
1406d5e247SLoGin         },
1506d5e247SLoGin         kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
1606d5e247SLoGin         kset::KSet,
1706d5e247SLoGin     },
1806d5e247SLoGin     filesystem::kernfs::KernFSInode,
1906d5e247SLoGin     libs::{
2006d5e247SLoGin         rwlock::{RwLockReadGuard, RwLockWriteGuard},
2106d5e247SLoGin         spinlock::SpinLock,
2206d5e247SLoGin     },
23*a03c4f9dSLoGin     syscall::SystemError,
2406d5e247SLoGin };
25b087521eSChiichen 
26*a03c4f9dSLoGin use super::{super::device::DeviceState, platform_bus, platform_bus_device, CompatibleTable};
27*a03c4f9dSLoGin 
28*a03c4f9dSLoGin /// 平台设备id分配器
29*a03c4f9dSLoGin static PLATFORM_DEVID_IDA: IdAllocator = IdAllocator::new(i32::MAX as usize);
30*a03c4f9dSLoGin 
31*a03c4f9dSLoGin #[inline(always)]
32*a03c4f9dSLoGin pub fn platform_device_manager() -> &'static PlatformDeviceManager {
33*a03c4f9dSLoGin     &PlatformDeviceManager
34*a03c4f9dSLoGin }
35*a03c4f9dSLoGin 
36*a03c4f9dSLoGin /// 没有平台设备id
37*a03c4f9dSLoGin pub const PLATFORM_DEVID_NONE: i32 = -1;
38*a03c4f9dSLoGin /// 请求自动分配这个平台设备id
39*a03c4f9dSLoGin pub const PLATFORM_DEVID_AUTO: i32 = -2;
402a7d773dSTingHuang 
412a7d773dSTingHuang /// @brief: 实现该trait的设备实例应挂载在platform总线上,
422a7d773dSTingHuang ///         同时应该实现Device trait
43*a03c4f9dSLoGin ///
44*a03c4f9dSLoGin /// ## 注意
45*a03c4f9dSLoGin ///
46*a03c4f9dSLoGin /// 应当在所有实现这个trait的结构体上方,添加 `#[cast_to([sync] PlatformDriver)]`,
47*a03c4f9dSLoGin /// 否则运行时将报错“该对象不是PlatformDriver”
482a7d773dSTingHuang pub trait PlatformDevice: Device {
49*a03c4f9dSLoGin     fn pdev_name(&self) -> &str;
50*a03c4f9dSLoGin     /// 返回平台设备id,以及这个id是否是自动生成的
51*a03c4f9dSLoGin     ///
52*a03c4f9dSLoGin     /// 请注意,如果当前设备还没有id,应该返回
53*a03c4f9dSLoGin     /// (PLATFORM_DEVID_NONE, false)
54*a03c4f9dSLoGin     fn pdev_id(&self) -> (i32, bool) {
55*a03c4f9dSLoGin         (PLATFORM_DEVID_NONE, false)
56*a03c4f9dSLoGin     }
57*a03c4f9dSLoGin 
58*a03c4f9dSLoGin     /// 设置平台设备id
59*a03c4f9dSLoGin     fn set_pdev_id(&self, id: i32);
60*a03c4f9dSLoGin     /// 设置id是否为自动分配
61*a03c4f9dSLoGin     fn set_pdev_id_auto(&self, id_auto: bool);
62*a03c4f9dSLoGin 
630663027bSTingHuang     fn compatible_table(&self) -> CompatibleTable;
642a7d773dSTingHuang     /// @brief: 判断设备是否初始化
652a7d773dSTingHuang     /// @parameter: None
662a7d773dSTingHuang     /// @return: 如果已经初始化,返回true,否则,返回false
672a7d773dSTingHuang     fn is_initialized(&self) -> bool;
682a7d773dSTingHuang 
692a7d773dSTingHuang     /// @brief: 设置设备状态
702a7d773dSTingHuang     /// @parameter set_state: 设备状态
712a7d773dSTingHuang     /// @return: None
722a7d773dSTingHuang     fn set_state(&self, set_state: DeviceState);
732a7d773dSTingHuang }
7406d5e247SLoGin 
7506d5e247SLoGin #[derive(Debug)]
76*a03c4f9dSLoGin pub struct PlatformDeviceManager;
77*a03c4f9dSLoGin 
78*a03c4f9dSLoGin impl PlatformDeviceManager {
79*a03c4f9dSLoGin     /// platform_device_add - add a platform device to device hierarchy
80*a03c4f9dSLoGin     pub fn device_add(&self, pdev: Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
81*a03c4f9dSLoGin         if pdev.parent().is_none() {
82*a03c4f9dSLoGin             pdev.set_parent(Some(Arc::downgrade(
83*a03c4f9dSLoGin                 &(platform_bus_device() as Arc<dyn KObject>),
84*a03c4f9dSLoGin             )));
85*a03c4f9dSLoGin         }
86*a03c4f9dSLoGin 
87*a03c4f9dSLoGin         pdev.set_bus(Some(platform_bus() as Arc<dyn Bus>));
88*a03c4f9dSLoGin 
89*a03c4f9dSLoGin         let id = pdev.pdev_id().0;
90*a03c4f9dSLoGin         match id {
91*a03c4f9dSLoGin             PLATFORM_DEVID_NONE => {
92*a03c4f9dSLoGin                 pdev.set_name(format!("{}", pdev.pdev_name()));
93*a03c4f9dSLoGin             }
94*a03c4f9dSLoGin             PLATFORM_DEVID_AUTO => {
95*a03c4f9dSLoGin                 let id = PLATFORM_DEVID_IDA.alloc().ok_or(SystemError::EOVERFLOW)?;
96*a03c4f9dSLoGin                 pdev.set_pdev_id(id as i32);
97*a03c4f9dSLoGin                 pdev.set_pdev_id_auto(true);
98*a03c4f9dSLoGin                 pdev.set_name(format!("{}.{}.auto", pdev.pdev_name(), pdev.pdev_id().0));
99*a03c4f9dSLoGin             }
100*a03c4f9dSLoGin             _ => {
101*a03c4f9dSLoGin                 pdev.set_name(format!("{}.{}", pdev.pdev_name(), id));
102*a03c4f9dSLoGin             }
103*a03c4f9dSLoGin         }
104*a03c4f9dSLoGin 
105*a03c4f9dSLoGin         // todo: 插入资源: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/platform.c?fi=platform_device_add#691
106*a03c4f9dSLoGin         let r = device_manager().add_device(pdev.clone() as Arc<dyn Device>);
107*a03c4f9dSLoGin         if r.is_ok() {
108*a03c4f9dSLoGin             pdev.set_state(DeviceState::Initialized);
109*a03c4f9dSLoGin             return Ok(()); // success
110*a03c4f9dSLoGin         } else {
111*a03c4f9dSLoGin             // failed
112*a03c4f9dSLoGin             let pdevid = pdev.pdev_id();
113*a03c4f9dSLoGin             if pdevid.1 {
114*a03c4f9dSLoGin                 PLATFORM_DEVID_IDA.free(pdevid.0 as usize);
115*a03c4f9dSLoGin                 pdev.set_pdev_id(PLATFORM_DEVID_AUTO);
116*a03c4f9dSLoGin             }
117*a03c4f9dSLoGin 
118*a03c4f9dSLoGin             return r;
119*a03c4f9dSLoGin         }
120*a03c4f9dSLoGin     }
121*a03c4f9dSLoGin }
122*a03c4f9dSLoGin 
123*a03c4f9dSLoGin #[derive(Debug)]
12406d5e247SLoGin #[cast_to([sync] Device)]
12506d5e247SLoGin pub struct PlatformBusDevice {
12606d5e247SLoGin     inner: SpinLock<InnerPlatformBusDevice>,
12706d5e247SLoGin     kobj_state: LockedKObjectState,
12806d5e247SLoGin }
12906d5e247SLoGin 
13006d5e247SLoGin impl PlatformBusDevice {
13106d5e247SLoGin     /// @brief: 创建一个加锁的platform总线实例
13206d5e247SLoGin     /// @parameter: None
13306d5e247SLoGin     /// @return: platform总线实例
13406d5e247SLoGin     pub fn new(
13506d5e247SLoGin         data: DevicePrivateData,
13606d5e247SLoGin         parent: Option<Weak<dyn KObject>>,
13706d5e247SLoGin     ) -> Arc<PlatformBusDevice> {
13806d5e247SLoGin         return Arc::new(PlatformBusDevice {
13906d5e247SLoGin             inner: SpinLock::new(InnerPlatformBusDevice::new(data, parent)),
140*a03c4f9dSLoGin             kobj_state: LockedKObjectState::new(None),
14106d5e247SLoGin         });
14206d5e247SLoGin     }
14306d5e247SLoGin 
14406d5e247SLoGin     /// @brief: 获取总线的匹配表
14506d5e247SLoGin     /// @parameter: None
14606d5e247SLoGin     /// @return: platform总线匹配表
14706d5e247SLoGin     #[inline]
14806d5e247SLoGin     #[allow(dead_code)]
14906d5e247SLoGin     fn compatible_table(&self) -> CompatibleTable {
15006d5e247SLoGin         CompatibleTable::new(vec!["platform"])
15106d5e247SLoGin     }
15206d5e247SLoGin 
15306d5e247SLoGin     /// @brief: 判断总线是否初始化
15406d5e247SLoGin     /// @parameter: None
15506d5e247SLoGin     /// @return: 已初始化,返回true,否则,返回false
15606d5e247SLoGin     #[inline]
15706d5e247SLoGin     #[allow(dead_code)]
15806d5e247SLoGin     fn is_initialized(&self) -> bool {
15906d5e247SLoGin         let state = self.inner.lock().state;
16006d5e247SLoGin         match state {
16106d5e247SLoGin             BusState::Initialized => true,
16206d5e247SLoGin             _ => false,
16306d5e247SLoGin         }
16406d5e247SLoGin     }
16506d5e247SLoGin 
16606d5e247SLoGin     /// @brief: 设置总线状态
16706d5e247SLoGin     /// @parameter set_state: 总线状态BusState
16806d5e247SLoGin     /// @return: None
16906d5e247SLoGin     #[inline]
17006d5e247SLoGin     #[allow(dead_code)]
17106d5e247SLoGin     fn set_state(&self, set_state: BusState) {
17206d5e247SLoGin         let state = &mut self.inner.lock().state;
17306d5e247SLoGin         *state = set_state;
17406d5e247SLoGin     }
17506d5e247SLoGin 
17606d5e247SLoGin     /// @brief: 获取总线状态
17706d5e247SLoGin     /// @parameter: None
17806d5e247SLoGin     /// @return: 总线状态
17906d5e247SLoGin     #[inline]
18006d5e247SLoGin     #[allow(dead_code)]
18106d5e247SLoGin     fn get_state(&self) -> BusState {
18206d5e247SLoGin         let state = self.inner.lock().state;
18306d5e247SLoGin         return state;
18406d5e247SLoGin     }
18506d5e247SLoGin }
18606d5e247SLoGin 
18706d5e247SLoGin #[allow(dead_code)]
18806d5e247SLoGin #[derive(Debug, Clone)]
18906d5e247SLoGin pub struct InnerPlatformBusDevice {
19006d5e247SLoGin     name: String,
19106d5e247SLoGin     data: DevicePrivateData,
19206d5e247SLoGin     state: BusState,                   // 总线状态
19306d5e247SLoGin     parent: Option<Weak<dyn KObject>>, // 总线的父对象
19406d5e247SLoGin 
19506d5e247SLoGin     kernfs_inode: Option<Arc<KernFSInode>>,
19606d5e247SLoGin     /// 当前设备挂载到的总线
19706d5e247SLoGin     bus: Option<Arc<dyn Bus>>,
19806d5e247SLoGin     /// 当前设备已经匹配的驱动
199*a03c4f9dSLoGin     driver: Option<Weak<dyn Driver>>,
20006d5e247SLoGin }
20106d5e247SLoGin 
20206d5e247SLoGin impl InnerPlatformBusDevice {
20306d5e247SLoGin     pub fn new(data: DevicePrivateData, parent: Option<Weak<dyn KObject>>) -> Self {
20406d5e247SLoGin         Self {
20506d5e247SLoGin             data,
20606d5e247SLoGin             name: "platform".to_string(),
20706d5e247SLoGin             state: BusState::NotInitialized,
20806d5e247SLoGin             parent,
20906d5e247SLoGin             kernfs_inode: None,
21006d5e247SLoGin             bus: None,
21106d5e247SLoGin             driver: None,
21206d5e247SLoGin         }
21306d5e247SLoGin     }
21406d5e247SLoGin }
21506d5e247SLoGin 
21606d5e247SLoGin impl KObject for PlatformBusDevice {
21706d5e247SLoGin     fn as_any_ref(&self) -> &dyn core::any::Any {
21806d5e247SLoGin         self
21906d5e247SLoGin     }
22006d5e247SLoGin 
22106d5e247SLoGin     fn parent(&self) -> Option<Weak<dyn KObject>> {
22206d5e247SLoGin         self.inner.lock().parent.clone()
22306d5e247SLoGin     }
22406d5e247SLoGin 
22506d5e247SLoGin     fn inode(&self) -> Option<Arc<KernFSInode>> {
22606d5e247SLoGin         self.inner.lock().kernfs_inode.clone()
22706d5e247SLoGin     }
22806d5e247SLoGin 
22906d5e247SLoGin     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
23006d5e247SLoGin         self.inner.lock().kernfs_inode = inode;
23106d5e247SLoGin     }
23206d5e247SLoGin 
23306d5e247SLoGin     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
23406d5e247SLoGin         None
23506d5e247SLoGin     }
23606d5e247SLoGin 
237*a03c4f9dSLoGin     fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {
238*a03c4f9dSLoGin         todo!("platform_bus_device::set_kobj_type")
239*a03c4f9dSLoGin     }
240*a03c4f9dSLoGin 
24106d5e247SLoGin     fn kset(&self) -> Option<Arc<KSet>> {
24206d5e247SLoGin         None
24306d5e247SLoGin     }
24406d5e247SLoGin 
24506d5e247SLoGin     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
24606d5e247SLoGin         self.kobj_state.read()
24706d5e247SLoGin     }
24806d5e247SLoGin 
24906d5e247SLoGin     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
25006d5e247SLoGin         self.kobj_state.write()
25106d5e247SLoGin     }
25206d5e247SLoGin 
25306d5e247SLoGin     fn set_kobj_state(&self, state: KObjectState) {
25406d5e247SLoGin         *self.kobj_state.write() = state;
25506d5e247SLoGin     }
25606d5e247SLoGin 
25706d5e247SLoGin     fn name(&self) -> String {
25806d5e247SLoGin         self.inner.lock().name.clone()
25906d5e247SLoGin     }
26006d5e247SLoGin 
26106d5e247SLoGin     fn set_name(&self, name: String) {
26206d5e247SLoGin         self.inner.lock().name = name;
26306d5e247SLoGin     }
26406d5e247SLoGin 
26506d5e247SLoGin     fn set_kset(&self, _kset: Option<Arc<KSet>>) {
26606d5e247SLoGin         todo!()
26706d5e247SLoGin     }
26806d5e247SLoGin 
26906d5e247SLoGin     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
27006d5e247SLoGin         self.inner.lock().parent = parent;
27106d5e247SLoGin     }
27206d5e247SLoGin }
27306d5e247SLoGin 
27406d5e247SLoGin /// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型
27506d5e247SLoGin impl Device for PlatformBusDevice {
27606d5e247SLoGin     #[inline]
27706d5e247SLoGin     #[allow(dead_code)]
27806d5e247SLoGin     fn dev_type(&self) -> DeviceType {
27906d5e247SLoGin         return DeviceType::Bus;
28006d5e247SLoGin     }
28106d5e247SLoGin 
28206d5e247SLoGin     #[inline]
28306d5e247SLoGin     #[allow(dead_code)]
28406d5e247SLoGin     fn id_table(&self) -> IdTable {
28506d5e247SLoGin         IdTable::new("platform".to_string(), DeviceNumber::new(0))
28606d5e247SLoGin     }
28706d5e247SLoGin 
28806d5e247SLoGin     fn bus(&self) -> Option<Arc<dyn Bus>> {
28906d5e247SLoGin         self.inner.lock().bus.clone()
29006d5e247SLoGin     }
29106d5e247SLoGin 
292*a03c4f9dSLoGin     fn set_bus(&self, bus: Option<Arc<dyn Bus>>) {
293*a03c4f9dSLoGin         self.inner.lock().bus = bus;
294*a03c4f9dSLoGin     }
295*a03c4f9dSLoGin 
29606d5e247SLoGin     fn driver(&self) -> Option<Arc<dyn Driver>> {
297*a03c4f9dSLoGin         self.inner.lock().driver.clone()?.upgrade()
29806d5e247SLoGin     }
29906d5e247SLoGin 
30006d5e247SLoGin     #[inline]
30106d5e247SLoGin     fn is_dead(&self) -> bool {
30206d5e247SLoGin         false
30306d5e247SLoGin     }
30406d5e247SLoGin 
305*a03c4f9dSLoGin     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
30606d5e247SLoGin         self.inner.lock().driver = driver;
30706d5e247SLoGin     }
308*a03c4f9dSLoGin 
309*a03c4f9dSLoGin     fn can_match(&self) -> bool {
310*a03c4f9dSLoGin         todo!()
311*a03c4f9dSLoGin     }
312*a03c4f9dSLoGin 
313*a03c4f9dSLoGin     fn set_can_match(&self, _can_match: bool) {
314*a03c4f9dSLoGin         todo!()
315*a03c4f9dSLoGin     }
316*a03c4f9dSLoGin 
317*a03c4f9dSLoGin     fn state_synced(&self) -> bool {
318*a03c4f9dSLoGin         todo!()
319*a03c4f9dSLoGin     }
32006d5e247SLoGin }
321