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