Skip to content

Commit 22fe6d2

Browse files
author
Sven Van Asbroeck
committed
rust-core/platdev: add simple PlatformDriver trait
Add the `PlatformDriver` trait, which driver writers may implement in order to define a platform driver in the kernel. For sake of simplicity and ease of review, `PlatformDriver` consists of two functions for now - `probe()` and `remove()`. Signed-off-by: Sven Van Asbroeck <[email protected]>
1 parent 7fde08b commit 22fe6d2

File tree

1 file changed

+41
-12
lines changed

1 file changed

+41
-12
lines changed

rust/kernel/platdev.rs

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
use crate::{
1010
bindings, c_types,
1111
error::{Error, Result},
12+
from_kernel_result,
1213
of::OfMatchTable,
13-
pr_info,
1414
str::CStr,
1515
types::PointerWrapper,
1616
};
@@ -30,18 +30,30 @@ pub struct Registration {
3030
// (it is fine for multiple threads to have a shared reference to it).
3131
unsafe impl Sync for Registration {}
3232

33-
extern "C" fn probe_callback(_pdev: *mut bindings::platform_device) -> c_types::c_int {
34-
pr_info!("Rust platform_device probed\n");
35-
0
33+
extern "C" fn probe_callback<P: PlatformDriver>(
34+
pdev: *mut bindings::platform_device,
35+
) -> c_types::c_int {
36+
from_kernel_result! {
37+
// SAFETY: `pdev` is guaranteed to be a valid, non-null pointer.
38+
let device_id = unsafe { (*pdev).id };
39+
P::probe(device_id)?;
40+
Ok(0)
41+
}
3642
}
3743

38-
extern "C" fn remove_callback(_pdev: *mut bindings::platform_device) -> c_types::c_int {
39-
pr_info!("Rust platform_device removed\n");
40-
0
44+
extern "C" fn remove_callback<P: PlatformDriver>(
45+
pdev: *mut bindings::platform_device,
46+
) -> c_types::c_int {
47+
from_kernel_result! {
48+
// SAFETY: `pdev` is guaranteed to be a valid, non-null pointer.
49+
let device_id = unsafe { (*pdev).id };
50+
P::remove(device_id)?;
51+
Ok(0)
52+
}
4153
}
4254

4355
impl Registration {
44-
fn register(
56+
fn register<P: PlatformDriver>(
4557
self: Pin<&mut Self>,
4658
name: &'static CStr,
4759
of_match_table: Option<OfMatchTable>,
@@ -59,8 +71,8 @@ impl Registration {
5971
this.of_table = Some(ptr);
6072
this.pdrv.driver.of_match_table = ptr.cast();
6173
}
62-
this.pdrv.probe = Some(probe_callback);
63-
this.pdrv.remove = Some(remove_callback);
74+
this.pdrv.probe = Some(probe_callback::<P>);
75+
this.pdrv.remove = Some(remove_callback::<P>);
6476
// SAFETY:
6577
// - `this.pdrv` lives at least until the call to `platform_driver_unregister()` returns.
6678
// - `name` pointer has static lifetime.
@@ -81,13 +93,13 @@ impl Registration {
8193
/// Registers a platform device.
8294
///
8395
/// Returns a pinned heap-allocated representation of the registration.
84-
pub fn new_pinned(
96+
pub fn new_pinned<P: PlatformDriver>(
8597
name: &'static CStr,
8698
of_match_tbl: Option<OfMatchTable>,
8799
module: &'static crate::ThisModule,
88100
) -> Result<Pin<Box<Self>>> {
89101
let mut r = Pin::from(Box::try_new(Self::default())?);
90-
r.as_mut().register(name, of_match_tbl, module)?;
102+
r.as_mut().register::<P>(name, of_match_tbl, module)?;
91103
Ok(r)
92104
}
93105
}
@@ -107,3 +119,20 @@ impl Drop for Registration {
107119
}
108120
}
109121
}
122+
123+
/// Trait for implementers of platform drivers.
124+
///
125+
/// Implement this trait whenever you create a platform driver.
126+
pub trait PlatformDriver {
127+
/// Platform driver probe.
128+
///
129+
/// Called when a new platform device is added or discovered.
130+
/// Implementers should attempt to initialize the device here.
131+
fn probe(device_id: i32) -> Result;
132+
133+
/// Platform driver remove.
134+
///
135+
/// Called when a platform device is removed.
136+
/// Implementers should prepare the device for complete removal here.
137+
fn remove(device_id: i32) -> Result;
138+
}

0 commit comments

Comments
 (0)