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