kernel/device/platform/mod.rs
1//! Platform device driver module.
2//!
3//! This module provides the implementation of platform device drivers, including
4//! device information and driver management. It defines the `PlatformDeviceInfo` and
5//! `PlatformDeviceDriver` structs, which represent the device information and driver
6//! respectively.
7//!
8//! The module implements the `Device` and `DeviceDriver` traits for platform devices,
9//! allowing them to be integrated into the device management system.
10//!
11//! # Components
12//!
13//! - `PlatformDeviceInfo`: Stores information about a platform device, including its name,
14//! ID, and compatible device strings.
15//!
16//! - `PlatformDeviceDriver`: Implements a driver for platform devices, containing resources,
17//! probe and remove functions, and compatibility information.
18//!
19//! # Submodules
20//!
21//! - `resource`: Defines platform-specific device resources.
22//!
23//! # Examples
24//!
25//! ```rust
26//! // Creating a platform device info
27//! let device_info = PlatformDeviceInfo::new(
28//! "example_device",
29//! 1,
30//! vec!["example,device-v1", "example,device-v2"],
31//! Vec::new() // Add resources as an empty vector
32//! );
33//!
34//! // Creating a platform device driver
35//! let driver = PlatformDeviceDriver::new(
36//! "example_driver",
37//! |device_info| { /* probe implementation */ Ok(()) },
38//! |device_info| { /* remove implementation */ Ok(()) },
39//! vec!["example,device-v1", "example,device-v2"]
40//! );
41//! ```
42//!
43//! # Implementation Details
44//!
45//! Platform devices are hardware components that are directly connected to the
46//! system bus or integrated into the SoC. They are typically discovered during
47//! boot time through firmware tables (like ACPI or Device Tree).
48//!
49//! The driver model allows for dynamic matching between devices and their drivers
50//! based on the compatible strings, enabling a flexible plug-and-play architecture.
51//! respectively. The module also includes the `Device` and `DeviceDriver` traits,
52//! which define the interface for device information and drivers.
53//!
54
55pub mod resource;
56
57extern crate alloc;
58use alloc::vec::Vec;
59
60use super::*;
61use resource::*;
62
63/// Struct representing platform device information.
64#[derive(Debug)]
65pub struct PlatformDeviceInfo {
66 name: &'static str,
67 id: usize,
68 compatible: Vec<&'static str>,
69 resources: Vec<PlatformDeviceResource>,
70}
71
72/// Information about a platform device.
73///
74/// This structure holds the basic identifying information for platform devices,
75/// including a name, unique identifier, compatibility strings, and resources.
76///
77/// # Fields
78/// - `name`: A static string representing the name of the device
79/// - `id`: A unique identifier for the device
80/// - `compatible`: A list of compatibility strings that describe compatible drivers
81/// - `resources`: A list of resources associated with the device
82///
83/// # Examples
84///
85/// ```
86/// let device_info = PlatformDeviceInfo::new(
87/// "uart0",
88/// 0,
89/// vec!["ns16550a", "uart"],
90/// Vec::new() // Add resources as an empty vector
91/// );
92///
93impl PlatformDeviceInfo {
94 /// Creates a new `PlatformDeviceInfo` instance.
95 ///
96 /// # Arguments
97 ///
98 /// * `name` - Static string identifier for the device
99 /// * `id` - Unique identifier number
100 /// * `compatible` - List of compatible device identifiers
101 ///
102 /// # Returns
103 ///
104 /// A new `PlatformDeviceInfo` instance with the provided values.
105 pub fn new(
106 name: &'static str,
107 id: usize,
108 compatible: Vec<&'static str>,
109 resources: Vec<PlatformDeviceResource>,
110 ) -> Self {
111 Self {
112 name,
113 id,
114 compatible,
115 resources,
116 }
117 }
118
119 /// Get the `PlatformDeviceResource` associated with the device.
120 ///
121 /// # Returns
122 ///
123 /// A reference to a vector of `PlatformDeviceResource` objects.
124 ///
125 pub fn get_resources(&self) -> &Vec<PlatformDeviceResource> {
126 &self.resources
127 }
128}
129
130impl DeviceInfo for PlatformDeviceInfo {
131 fn name(&self) -> &'static str {
132 self.name
133 }
134
135 fn id(&self) -> usize {
136 self.id
137 }
138
139 fn compatible(&self) -> Vec<&'static str> {
140 self.compatible.clone()
141 }
142
143 fn as_any(&self) -> &dyn Any {
144 self
145 }
146}
147
148pub struct PlatformDeviceDriver {
149 name: &'static str,
150 probe_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
151 remove_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
152 compatible: Vec<&'static str>, // Change to Vec<&'static str>
153}
154
155impl PlatformDeviceDriver {
156 pub fn new(
157 name: &'static str,
158 probe_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
159 remove_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
160 compatible: Vec<&'static str>,
161 ) -> Self {
162 Self {
163 name,
164 probe_fn,
165 remove_fn,
166 compatible,
167 }
168 }
169}
170
171impl DeviceDriver for PlatformDeviceDriver {
172 fn name(&self) -> &'static str {
173 self.name
174 }
175
176 fn match_table(&self) -> Vec<&'static str> {
177 self.compatible.clone()
178 }
179
180 fn probe(&self, device: &dyn DeviceInfo) -> Result<(), &'static str> {
181 // Downcast the device to a `PlatformDeviceInfo`
182 let platform_device_info = device
183 .as_any()
184 .downcast_ref::<PlatformDeviceInfo>()
185 .ok_or("Failed to downcast to PlatformDeviceInfo")?;
186 // Call the probe function
187 (self.probe_fn)(platform_device_info)
188 }
189
190 fn remove(&self, _device: &dyn DeviceInfo) -> Result<(), &'static str> {
191 Ok(())
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use alloc::vec;
198
199 use super::*;
200
201 #[test_case]
202 fn test_probe_success() {
203 let device = PlatformDeviceInfo::new("test_device", 1, vec!["test,compatible"], vec![]);
204 let driver = PlatformDeviceDriver::new(
205 "test_driver",
206 |device_info| {
207 assert_eq!(device_info.name(), "test_device");
208 Ok(())
209 },
210 |_device| Ok(()),
211 vec!["test,compatible"],
212 );
213
214 let result = driver.probe(&device);
215 assert!(result.is_ok());
216 }
217
218 #[test_case]
219 fn test_probe_failure() {
220 struct DummyDevice;
221 impl DeviceInfo for DummyDevice {
222 fn name(&self) -> &'static str {
223 "dummy"
224 }
225 fn id(&self) -> usize {
226 0
227 }
228 fn compatible(&self) -> Vec<&'static str> {
229 vec![]
230 }
231 fn as_any(&self) -> &dyn Any {
232 self
233 }
234 }
235
236 let device = DummyDevice;
237 let driver = PlatformDeviceDriver::new(
238 "test_driver",
239 |_device| Ok(()),
240 |_device| Ok(()),
241 vec!["test,compatible"],
242 );
243
244 let result = driver.probe(&device);
245 assert!(result.is_err());
246 }
247}