xref: /DragonOS/kernel/src/driver/base/platform/subsys.rs (revision fae6e9ade46a52976ad5d099643d51cc20876448)
1 use alloc::{
2     string::{String, ToString},
3     sync::{Arc, Weak},
4 };
5 use intertrait::cast::CastArc;
6 use log::error;
7 
8 use super::{
9     platform_bus_device, platform_device::PlatformDevice, platform_driver::PlatformDriver,
10 };
11 use crate::{
12     driver::{
13         acpi::acpi_manager,
14         base::{
15             device::{bus::Bus, driver::Driver, Device},
16             kobject::KObject,
17             subsys::SubSysPrivate,
18         },
19     },
20     filesystem::{
21         sysfs::{Attribute, AttributeGroup},
22         vfs::syscall::ModeType,
23     },
24 };
25 use system_error::SystemError;
26 
27 #[derive(Debug)]
28 pub struct PlatformBus {
29     private: SubSysPrivate,
30 }
31 
32 impl PlatformBus {
33     pub fn new() -> Arc<Self> {
34         let w: Weak<Self> = Weak::new();
35         let private = SubSysPrivate::new("platform".to_string(), Some(w), None, &[]);
36         let bus = Arc::new(Self { private });
37         bus.subsystem()
38             .set_bus(Some(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>))));
39 
40         return bus;
41     }
42 }
43 
44 impl Bus for PlatformBus {
45     fn name(&self) -> String {
46         return "platform".to_string();
47     }
48 
49     fn dev_name(&self) -> String {
50         return self.name();
51     }
52 
53     fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
54         return &[&PlatformDeviceAttrGroup];
55     }
56 
57     fn subsystem(&self) -> &SubSysPrivate {
58         return &self.private;
59     }
60 
61     fn probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> {
62         let drv = device.driver().ok_or(SystemError::EINVAL)?;
63         let pdrv = drv.cast::<dyn PlatformDriver>().map_err(|_|{
64             error!("PlatformBus::probe() failed: device.driver() is not a PlatformDriver. Device: '{:?}'", device.name());
65             SystemError::EINVAL
66         })?;
67 
68         let pdev = device.clone().cast::<dyn PlatformDevice>().map_err(|_| {
69             error!(
70                 "PlatformBus::probe() failed: device is not a PlatformDevice. Device: '{:?}'",
71                 device.name()
72             );
73             SystemError::EINVAL
74         })?;
75 
76         return pdrv.probe(&pdev);
77     }
78 
79     fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
80         todo!()
81     }
82 
83     fn sync_state(&self, _device: &Arc<dyn Device>) {
84         todo!()
85     }
86 
87     fn shutdown(&self, _device: &Arc<dyn Device>) {
88         todo!()
89     }
90 
91     fn resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
92         todo!()
93     }
94 
95     ///
96     /// match platform device to platform driver.
97     ///
98     /// ## 参数
99     ///
100     /// * `device` - platform device
101     /// * `driver` - platform driver
102     ///
103     /// ## 返回
104     ///
105     /// - `Ok(true)` - 匹配成功
106     /// - `Ok(false)` - 匹配失败
107     /// - `Err(_)` - 由于内部错误导致匹配失败
108     ///
109     /// Platform device IDs are assumed to be encoded like this:
110     /// "<name><instance>", where <name> is a short description of the type of
111     /// device, like "pci" or "floppy", and <instance> is the enumerated
112     /// instance of the device, like '0' or '42'.  Driver IDs are simply
113     /// "<name>".  So, extract the <name> from the platform_device structure,
114     /// and compare it against the name of the driver. Return whether they match
115     /// or not.
116     ///
117     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/platform.c#1331
118     ///
119     ///
120     fn match_device(
121         &self,
122         device: &Arc<dyn Device>,
123         driver: &Arc<dyn Driver>,
124     ) -> Result<bool, SystemError> {
125         // 尝试从 ACPI 中匹配
126         if let Ok(x) = acpi_manager().driver_match_device(driver, device) {
127             if x {
128                 return Ok(true);
129             }
130         }
131 
132         // 尝试从 ID table 中匹配
133         if let Some(drv_id_table) = driver.id_table() {
134             let pdev = device
135                 .clone()
136                 .cast::<dyn PlatformDevice>()
137                 .map_err(|_| SystemError::EINVAL)?;
138             if drv_id_table.name().eq(&pdev.name()) {
139                 return Ok(true);
140             }
141         }
142 
143         // 尝试根据设备名称匹配
144         return Ok(device.name().eq(&driver.name()));
145     }
146 
147     fn root_device(&self) -> Option<Weak<dyn Device>> {
148         let root_device = platform_bus_device() as Arc<dyn Device>;
149         return Some(Arc::downgrade(&root_device));
150     }
151 }
152 
153 #[derive(Debug)]
154 pub struct PlatformDeviceAttrGroup;
155 
156 impl AttributeGroup for PlatformDeviceAttrGroup {
157     fn name(&self) -> Option<&str> {
158         None
159     }
160 
161     fn attrs(&self) -> &[&'static dyn Attribute] {
162         // todo: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/platform.c?r=&mo=38425&fi=1511#1311
163         return &[];
164     }
165 
166     fn is_visible(&self, _kobj: Arc<dyn KObject>, attr: &dyn Attribute) -> Option<ModeType> {
167         return Some(attr.mode());
168     }
169 }
170