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
55
56pub mod resource;
57
58extern crate alloc;
59use alloc::vec::Vec;
60
61use super::*;
62use resource::*;
63
64/// Struct representing platform device information.
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(name: &'static str, id: usize, compatible: Vec<&'static str>, resources: Vec<PlatformDeviceResource>) -> Self {
106 Self {
107 name,
108 id,
109 compatible,
110 resources,
111 }
112 }
113
114 /// Get the `PlatformDeviceResource` associated with the device.
115 ///
116 /// # Returns
117 ///
118 /// A reference to a vector of `PlatformDeviceResource` objects.
119 ///
120 pub fn get_resources(&self) -> &Vec<PlatformDeviceResource> {
121 &self.resources
122 }
123}
124
125impl DeviceInfo for PlatformDeviceInfo {
126 fn name(&self) -> &'static str {
127 self.name
128 }
129
130 fn id(&self) -> usize {
131 self.id
132 }
133
134 fn compatible(&self) -> Vec<&'static str> {
135 self.compatible.clone()
136 }
137
138 fn as_any(&self) -> &dyn Any {
139 self
140 }
141}
142
143pub struct PlatformDeviceDriver {
144 name: &'static str,
145 probe_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
146 remove_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
147 compatible: Vec<&'static str>, // Change to Vec<&'static str>
148}
149
150impl PlatformDeviceDriver {
151 pub fn new(
152 name: &'static str,
153 probe_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
154 remove_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
155 compatible: Vec<&'static str>,
156 ) -> Self {
157 Self {
158 name,
159 probe_fn,
160 remove_fn,
161 compatible,
162 }
163 }
164}
165
166impl DeviceDriver for PlatformDeviceDriver {
167 fn name(&self) -> &'static str {
168 self.name
169 }
170
171 fn match_table(&self) -> Vec<&'static str> {
172 self.compatible.clone()
173 }
174
175 fn probe(&self, device: &dyn DeviceInfo) -> Result<(), &'static str> {
176 // Downcast the device to a `PlatformDeviceInfo`
177 let platform_device_info = device.as_any()
178 .downcast_ref::<PlatformDeviceInfo>()
179 .ok_or("Failed to downcast to PlatformDeviceInfo")?;
180 // Call the probe function
181 (self.probe_fn)(platform_device_info)
182 }
183
184 fn remove(&self, _device: &dyn DeviceInfo) -> Result<(), &'static str> {
185 Ok(())
186 }
187}
188
189
190#[cfg(test)]
191mod tests {
192 use alloc::vec;
193
194 use super::*;
195
196 #[test_case]
197 fn test_probe_success() {
198 let device = PlatformDeviceInfo::new("test_device", 1, vec!["test,compatible"], vec![]);
199 let driver = PlatformDeviceDriver::new(
200 "test_driver",
201 |device_info| {
202 assert_eq!(device_info.name(), "test_device");
203 Ok(())
204 },
205 |_device| Ok(()),
206 vec!["test,compatible"],
207 );
208
209 let result = driver.probe(&device);
210 assert!(result.is_ok());
211 }
212
213 #[test_case]
214 fn test_probe_failure() {
215 struct DummyDevice;
216 impl DeviceInfo for DummyDevice {
217 fn name(&self) -> &'static str { "dummy" }
218 fn id(&self) -> usize { 0 }
219 fn compatible(&self) -> Vec<&'static str> { vec![] }
220 fn as_any(&self) -> &dyn Any { self }
221 }
222
223 let device = DummyDevice;
224 let driver = PlatformDeviceDriver::new(
225 "test_driver",
226 |_device| Ok(()),
227 |_device| Ok(()),
228 vec!["test,compatible"],
229 );
230
231 let result = driver.probe(&device);
232 assert!(result.is_err());
233 }
234}