xref: /DragonOS/kernel/src/driver/base/platform/platform_device.rs (revision 28fe4ad2a0b0d8b5abf1f0cb402b1c3204b42242)
106d5e247SLoGin use alloc::{
206d5e247SLoGin     string::{String, ToString},
306d5e247SLoGin     sync::{Arc, Weak},
406d5e247SLoGin };
5a03c4f9dSLoGin use ida::IdAllocator;
606d5e247SLoGin 
706d5e247SLoGin use crate::{
8a03c4f9dSLoGin     driver::base::{
908a2ee40SLoGin         class::Class,
1006d5e247SLoGin         device::{
1106d5e247SLoGin             bus::{Bus, BusState},
12a03c4f9dSLoGin             device_manager,
13a03c4f9dSLoGin             driver::Driver,
14*28fe4ad2S黄铭涛             Device, DeviceCommonData, DevicePrivateData, DeviceType, IdTable,
1506d5e247SLoGin         },
16*28fe4ad2S黄铭涛         kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
1706d5e247SLoGin         kset::KSet,
1806d5e247SLoGin     },
1906d5e247SLoGin     filesystem::kernfs::KernFSInode,
2006d5e247SLoGin     libs::{
2106d5e247SLoGin         rwlock::{RwLockReadGuard, RwLockWriteGuard},
22*28fe4ad2S黄铭涛         spinlock::{SpinLock, SpinLockGuard},
2306d5e247SLoGin     },
2406d5e247SLoGin };
2591e9d4abSLoGin use system_error::SystemError;
26b087521eSChiichen 
27a03c4f9dSLoGin use super::{super::device::DeviceState, platform_bus, platform_bus_device, CompatibleTable};
28a03c4f9dSLoGin 
29a03c4f9dSLoGin /// 平台设备id分配器
307b32f508SLoGin static PLATFORM_DEVID_IDA: IdAllocator = IdAllocator::new(0, i32::MAX as usize);
31a03c4f9dSLoGin 
32a03c4f9dSLoGin #[inline(always)]
platform_device_manager() -> &'static PlatformDeviceManager33a03c4f9dSLoGin pub fn platform_device_manager() -> &'static PlatformDeviceManager {
34a03c4f9dSLoGin     &PlatformDeviceManager
35a03c4f9dSLoGin }
36a03c4f9dSLoGin 
37a03c4f9dSLoGin /// 没有平台设备id
38a03c4f9dSLoGin pub const PLATFORM_DEVID_NONE: i32 = -1;
39a03c4f9dSLoGin /// 请求自动分配这个平台设备id
40a03c4f9dSLoGin pub const PLATFORM_DEVID_AUTO: i32 = -2;
412a7d773dSTingHuang 
422a7d773dSTingHuang /// @brief: 实现该trait的设备实例应挂载在platform总线上,
432a7d773dSTingHuang ///         同时应该实现Device trait
44a03c4f9dSLoGin ///
45a03c4f9dSLoGin /// ## 注意
46a03c4f9dSLoGin ///
47c566df45SLoGin /// 应当在所有实现这个trait的结构体上方,添加 `#[cast_to([sync] PlatformDevice)]`,
48c566df45SLoGin /// 否则运行时将报错“该对象不是PlatformDevice”
492a7d773dSTingHuang pub trait PlatformDevice: Device {
pdev_name(&self) -> &str50a03c4f9dSLoGin     fn pdev_name(&self) -> &str;
51a03c4f9dSLoGin     /// 返回平台设备id,以及这个id是否是自动生成的
52a03c4f9dSLoGin     ///
53a03c4f9dSLoGin     /// 请注意,如果当前设备还没有id,应该返回
54a03c4f9dSLoGin     /// (PLATFORM_DEVID_NONE, false)
pdev_id(&self) -> (i32, bool)55a03c4f9dSLoGin     fn pdev_id(&self) -> (i32, bool) {
56a03c4f9dSLoGin         (PLATFORM_DEVID_NONE, false)
57a03c4f9dSLoGin     }
58a03c4f9dSLoGin 
59a03c4f9dSLoGin     /// 设置平台设备id
set_pdev_id(&self, id: i32)60a03c4f9dSLoGin     fn set_pdev_id(&self, id: i32);
61a03c4f9dSLoGin     /// 设置id是否为自动分配
set_pdev_id_auto(&self, id_auto: bool)62a03c4f9dSLoGin     fn set_pdev_id_auto(&self, id_auto: bool);
63a03c4f9dSLoGin 
642a7d773dSTingHuang     /// @brief: 判断设备是否初始化
652a7d773dSTingHuang     /// @parameter: None
662a7d773dSTingHuang     /// @return: 如果已经初始化,返回true,否则,返回false
67bd70d2d1SLoGin     #[allow(dead_code)]
is_initialized(&self) -> bool682a7d773dSTingHuang     fn is_initialized(&self) -> bool;
692a7d773dSTingHuang 
702a7d773dSTingHuang     /// @brief: 设置设备状态
712a7d773dSTingHuang     /// @parameter set_state: 设备状态
722a7d773dSTingHuang     /// @return: None
set_state(&self, set_state: DeviceState)732a7d773dSTingHuang     fn set_state(&self, set_state: DeviceState);
742a7d773dSTingHuang }
7506d5e247SLoGin 
7606d5e247SLoGin #[derive(Debug)]
77a03c4f9dSLoGin pub struct PlatformDeviceManager;
78a03c4f9dSLoGin 
79a03c4f9dSLoGin impl PlatformDeviceManager {
80a03c4f9dSLoGin     /// platform_device_add - add a platform device to device hierarchy
device_add(&self, pdev: Arc<dyn PlatformDevice>) -> Result<(), SystemError>81a03c4f9dSLoGin     pub fn device_add(&self, pdev: Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
82*28fe4ad2S黄铭涛         if pdev.dev_parent().is_none() {
83*28fe4ad2S黄铭涛             pdev.set_dev_parent(Some(Arc::downgrade(
84*28fe4ad2S黄铭涛                 &(platform_bus_device() as Arc<dyn Device>),
85a03c4f9dSLoGin             )));
86a03c4f9dSLoGin         }
87a03c4f9dSLoGin 
88c566df45SLoGin         pdev.set_bus(Some(Arc::downgrade(&(platform_bus() as Arc<dyn Bus>))));
89a03c4f9dSLoGin 
90a03c4f9dSLoGin         let id = pdev.pdev_id().0;
91a03c4f9dSLoGin         match id {
92a03c4f9dSLoGin             PLATFORM_DEVID_NONE => {
93b5b571e0SLoGin                 pdev.set_name(pdev.pdev_name().to_string());
94a03c4f9dSLoGin             }
95a03c4f9dSLoGin             PLATFORM_DEVID_AUTO => {
96a03c4f9dSLoGin                 let id = PLATFORM_DEVID_IDA.alloc().ok_or(SystemError::EOVERFLOW)?;
97a03c4f9dSLoGin                 pdev.set_pdev_id(id as i32);
98a03c4f9dSLoGin                 pdev.set_pdev_id_auto(true);
99a03c4f9dSLoGin                 pdev.set_name(format!("{}.{}.auto", pdev.pdev_name(), pdev.pdev_id().0));
100a03c4f9dSLoGin             }
101a03c4f9dSLoGin             _ => {
102a03c4f9dSLoGin                 pdev.set_name(format!("{}.{}", pdev.pdev_name(), id));
103a03c4f9dSLoGin             }
104a03c4f9dSLoGin         }
105a03c4f9dSLoGin 
106e7071df6SLoGin         // todo: 插入资源: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/platform.c?fi=platform_device_add#691
107a03c4f9dSLoGin         let r = device_manager().add_device(pdev.clone() as Arc<dyn Device>);
108a03c4f9dSLoGin         if r.is_ok() {
109a03c4f9dSLoGin             pdev.set_state(DeviceState::Initialized);
110a03c4f9dSLoGin             return Ok(()); // success
111a03c4f9dSLoGin         } else {
112a03c4f9dSLoGin             // failed
113a03c4f9dSLoGin             let pdevid = pdev.pdev_id();
114a03c4f9dSLoGin             if pdevid.1 {
115a03c4f9dSLoGin                 PLATFORM_DEVID_IDA.free(pdevid.0 as usize);
116a03c4f9dSLoGin                 pdev.set_pdev_id(PLATFORM_DEVID_AUTO);
117a03c4f9dSLoGin             }
118a03c4f9dSLoGin 
119a03c4f9dSLoGin             return r;
120a03c4f9dSLoGin         }
121a03c4f9dSLoGin     }
122a03c4f9dSLoGin }
123a03c4f9dSLoGin 
124a03c4f9dSLoGin #[derive(Debug)]
12506d5e247SLoGin #[cast_to([sync] Device)]
12606d5e247SLoGin pub struct PlatformBusDevice {
12706d5e247SLoGin     inner: SpinLock<InnerPlatformBusDevice>,
12806d5e247SLoGin     kobj_state: LockedKObjectState,
12906d5e247SLoGin }
13006d5e247SLoGin 
13106d5e247SLoGin impl PlatformBusDevice {
13206d5e247SLoGin     /// @brief: 创建一个加锁的platform总线实例
13306d5e247SLoGin     /// @parameter: None
13406d5e247SLoGin     /// @return: platform总线实例
new( data: DevicePrivateData, parent: Option<Weak<dyn KObject>>, ) -> Arc<PlatformBusDevice>13506d5e247SLoGin     pub fn new(
13606d5e247SLoGin         data: DevicePrivateData,
13706d5e247SLoGin         parent: Option<Weak<dyn KObject>>,
13806d5e247SLoGin     ) -> Arc<PlatformBusDevice> {
139*28fe4ad2S黄铭涛         let platform_bus_device = Self {
140*28fe4ad2S黄铭涛             inner: SpinLock::new(InnerPlatformBusDevice::new(data)),
141a03c4f9dSLoGin             kobj_state: LockedKObjectState::new(None),
142*28fe4ad2S黄铭涛         };
143*28fe4ad2S黄铭涛         platform_bus_device.set_parent(parent);
144*28fe4ad2S黄铭涛         return Arc::new(platform_bus_device);
14506d5e247SLoGin     }
14606d5e247SLoGin 
14706d5e247SLoGin     /// @brief: 获取总线的匹配表
14806d5e247SLoGin     /// @parameter: None
14906d5e247SLoGin     /// @return: platform总线匹配表
15006d5e247SLoGin     #[inline]
15106d5e247SLoGin     #[allow(dead_code)]
compatible_table(&self) -> CompatibleTable15206d5e247SLoGin     fn compatible_table(&self) -> CompatibleTable {
15306d5e247SLoGin         CompatibleTable::new(vec!["platform"])
15406d5e247SLoGin     }
15506d5e247SLoGin 
15606d5e247SLoGin     /// @brief: 判断总线是否初始化
15706d5e247SLoGin     /// @parameter: None
15806d5e247SLoGin     /// @return: 已初始化,返回true,否则,返回false
15906d5e247SLoGin     #[inline]
16006d5e247SLoGin     #[allow(dead_code)]
is_initialized(&self) -> bool16106d5e247SLoGin     fn is_initialized(&self) -> bool {
16206d5e247SLoGin         let state = self.inner.lock().state;
163b5b571e0SLoGin         matches!(state, BusState::Initialized)
16406d5e247SLoGin     }
16506d5e247SLoGin 
16606d5e247SLoGin     /// @brief: 设置总线状态
16706d5e247SLoGin     /// @parameter set_state: 总线状态BusState
16806d5e247SLoGin     /// @return: None
16906d5e247SLoGin     #[inline]
17006d5e247SLoGin     #[allow(dead_code)]
set_state(&self, set_state: BusState)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)]
get_state(&self) -> BusState18106d5e247SLoGin     fn get_state(&self) -> BusState {
18206d5e247SLoGin         let state = self.inner.lock().state;
18306d5e247SLoGin         return state;
18406d5e247SLoGin     }
185*28fe4ad2S黄铭涛 
inner(&self) -> SpinLockGuard<InnerPlatformBusDevice>186*28fe4ad2S黄铭涛     fn inner(&self) -> SpinLockGuard<InnerPlatformBusDevice> {
187*28fe4ad2S黄铭涛         self.inner.lock()
188*28fe4ad2S黄铭涛     }
18906d5e247SLoGin }
19006d5e247SLoGin 
19106d5e247SLoGin #[allow(dead_code)]
192*28fe4ad2S黄铭涛 #[derive(Debug)]
19306d5e247SLoGin pub struct InnerPlatformBusDevice {
19406d5e247SLoGin     name: String,
19506d5e247SLoGin     data: DevicePrivateData,
19606d5e247SLoGin     state: BusState, // 总线状态
197*28fe4ad2S黄铭涛     kobject_common: KObjectCommonData,
198*28fe4ad2S黄铭涛     device_common: DeviceCommonData,
19906d5e247SLoGin }
20006d5e247SLoGin 
20106d5e247SLoGin impl InnerPlatformBusDevice {
new(data: DevicePrivateData) -> Self202*28fe4ad2S黄铭涛     pub fn new(data: DevicePrivateData) -> Self {
20306d5e247SLoGin         Self {
20406d5e247SLoGin             data,
20506d5e247SLoGin             name: "platform".to_string(),
20606d5e247SLoGin             state: BusState::NotInitialized,
207*28fe4ad2S黄铭涛             kobject_common: KObjectCommonData::default(),
208*28fe4ad2S黄铭涛             device_common: DeviceCommonData::default(),
20906d5e247SLoGin         }
21006d5e247SLoGin     }
21106d5e247SLoGin }
21206d5e247SLoGin 
21306d5e247SLoGin impl KObject for PlatformBusDevice {
as_any_ref(&self) -> &dyn core::any::Any21406d5e247SLoGin     fn as_any_ref(&self) -> &dyn core::any::Any {
21506d5e247SLoGin         self
21606d5e247SLoGin     }
21706d5e247SLoGin 
parent(&self) -> Option<Weak<dyn KObject>>21806d5e247SLoGin     fn parent(&self) -> Option<Weak<dyn KObject>> {
219*28fe4ad2S黄铭涛         self.inner().kobject_common.parent.clone()
22006d5e247SLoGin     }
22106d5e247SLoGin 
inode(&self) -> Option<Arc<KernFSInode>>22206d5e247SLoGin     fn inode(&self) -> Option<Arc<KernFSInode>> {
223*28fe4ad2S黄铭涛         self.inner().kobject_common.kern_inode.clone()
22406d5e247SLoGin     }
22506d5e247SLoGin 
set_inode(&self, inode: Option<Arc<KernFSInode>>)22606d5e247SLoGin     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
227*28fe4ad2S黄铭涛         self.inner().kobject_common.kern_inode = inode;
22806d5e247SLoGin     }
22906d5e247SLoGin 
kobj_type(&self) -> Option<&'static dyn KObjType>23006d5e247SLoGin     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
231*28fe4ad2S黄铭涛         self.inner().kobject_common.kobj_type
23206d5e247SLoGin     }
23306d5e247SLoGin 
set_kobj_type(&self, ktype: Option<&'static dyn KObjType>)234d7f5742aSLoGin     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
235*28fe4ad2S黄铭涛         self.inner().kobject_common.kobj_type = ktype;
236a03c4f9dSLoGin     }
237a03c4f9dSLoGin 
kset(&self) -> Option<Arc<KSet>>23806d5e247SLoGin     fn kset(&self) -> Option<Arc<KSet>> {
239*28fe4ad2S黄铭涛         self.inner().kobject_common.kset.clone()
24006d5e247SLoGin     }
24106d5e247SLoGin 
kobj_state(&self) -> RwLockReadGuard<KObjectState>24206d5e247SLoGin     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
24306d5e247SLoGin         self.kobj_state.read()
24406d5e247SLoGin     }
24506d5e247SLoGin 
kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>24606d5e247SLoGin     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
24706d5e247SLoGin         self.kobj_state.write()
24806d5e247SLoGin     }
24906d5e247SLoGin 
set_kobj_state(&self, state: KObjectState)25006d5e247SLoGin     fn set_kobj_state(&self, state: KObjectState) {
25106d5e247SLoGin         *self.kobj_state.write() = state;
25206d5e247SLoGin     }
25306d5e247SLoGin 
name(&self) -> String25406d5e247SLoGin     fn name(&self) -> String {
255*28fe4ad2S黄铭涛         self.inner().name.clone()
25606d5e247SLoGin     }
25706d5e247SLoGin 
set_name(&self, name: String)25806d5e247SLoGin     fn set_name(&self, name: String) {
259*28fe4ad2S黄铭涛         self.inner().name = name;
26006d5e247SLoGin     }
26106d5e247SLoGin 
set_kset(&self, kset: Option<Arc<KSet>>)262d7f5742aSLoGin     fn set_kset(&self, kset: Option<Arc<KSet>>) {
263*28fe4ad2S黄铭涛         self.inner().kobject_common.kset = kset;
26406d5e247SLoGin     }
26506d5e247SLoGin 
set_parent(&self, parent: Option<Weak<dyn KObject>>)26606d5e247SLoGin     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
267*28fe4ad2S黄铭涛         self.inner().kobject_common.parent = parent;
26806d5e247SLoGin     }
26906d5e247SLoGin }
27006d5e247SLoGin 
27106d5e247SLoGin /// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型
27206d5e247SLoGin impl Device for PlatformBusDevice {
27306d5e247SLoGin     #[inline]
27406d5e247SLoGin     #[allow(dead_code)]
dev_type(&self) -> DeviceType27506d5e247SLoGin     fn dev_type(&self) -> DeviceType {
27606d5e247SLoGin         return DeviceType::Bus;
27706d5e247SLoGin     }
27806d5e247SLoGin 
27906d5e247SLoGin     #[inline]
id_table(&self) -> IdTable28006d5e247SLoGin     fn id_table(&self) -> IdTable {
281c566df45SLoGin         IdTable::new("platform".to_string(), None)
28206d5e247SLoGin     }
28306d5e247SLoGin 
bus(&self) -> Option<Weak<dyn Bus>>284c566df45SLoGin     fn bus(&self) -> Option<Weak<dyn Bus>> {
285*28fe4ad2S黄铭涛         self.inner().device_common.bus.clone()
28606d5e247SLoGin     }
28706d5e247SLoGin 
set_bus(&self, bus: Option<Weak<dyn Bus>>)288c566df45SLoGin     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
289*28fe4ad2S黄铭涛         self.inner().device_common.bus = bus;
290a03c4f9dSLoGin     }
291a03c4f9dSLoGin 
driver(&self) -> Option<Arc<dyn Driver>>29206d5e247SLoGin     fn driver(&self) -> Option<Arc<dyn Driver>> {
293*28fe4ad2S黄铭涛         self.inner().device_common.driver.clone()?.upgrade()
29406d5e247SLoGin     }
29506d5e247SLoGin 
29606d5e247SLoGin     #[inline]
is_dead(&self) -> bool29706d5e247SLoGin     fn is_dead(&self) -> bool {
29806d5e247SLoGin         false
29906d5e247SLoGin     }
30006d5e247SLoGin 
set_driver(&self, driver: Option<Weak<dyn Driver>>)301a03c4f9dSLoGin     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
302*28fe4ad2S黄铭涛         self.inner().device_common.driver = driver;
30306d5e247SLoGin     }
304a03c4f9dSLoGin 
can_match(&self) -> bool305a03c4f9dSLoGin     fn can_match(&self) -> bool {
306a03c4f9dSLoGin         todo!()
307a03c4f9dSLoGin     }
308a03c4f9dSLoGin 
set_can_match(&self, _can_match: bool)309a03c4f9dSLoGin     fn set_can_match(&self, _can_match: bool) {
310a03c4f9dSLoGin         todo!()
311a03c4f9dSLoGin     }
312a03c4f9dSLoGin 
state_synced(&self) -> bool313a03c4f9dSLoGin     fn state_synced(&self) -> bool {
314a03c4f9dSLoGin         todo!()
315a03c4f9dSLoGin     }
31608a2ee40SLoGin 
set_class(&self, class: Option<Weak<dyn Class>>)317*28fe4ad2S黄铭涛     fn set_class(&self, class: Option<Weak<dyn Class>>) {
318*28fe4ad2S黄铭涛         self.inner().device_common.class = class;
319*28fe4ad2S黄铭涛     }
320*28fe4ad2S黄铭涛 
dev_parent(&self) -> Option<Weak<dyn Device>>321*28fe4ad2S黄铭涛     fn dev_parent(&self) -> Option<Weak<dyn Device>> {
322*28fe4ad2S黄铭涛         self.inner().device_common.get_parent_weak_or_clear()
323*28fe4ad2S黄铭涛     }
324*28fe4ad2S黄铭涛 
set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>)325*28fe4ad2S黄铭涛     fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
326*28fe4ad2S黄铭涛         self.inner().device_common.parent = dev_parent;
32708a2ee40SLoGin     }
32806d5e247SLoGin }
329