Skip to content

Commit 698569d

Browse files
authored
Merge pull request #301 from TheSven73/rust-for-linux-pdev-pr3
Simple Rust driver that touches real hardware: PR 3/6
2 parents ed19a55 + fa6f1ba commit 698569d

File tree

2 files changed

+57
-13
lines changed

2 files changed

+57
-13
lines changed

drivers/char/hw_random/bcm2835_rng_rust.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use alloc::boxed::Box;
99
use core::pin::Pin;
1010
use kernel::of::OfMatchTable;
11+
use kernel::platdev::PlatformDriver;
1112
use kernel::prelude::*;
1213
use kernel::{c_str, platdev};
1314

@@ -19,6 +20,20 @@ module! {
1920
license: b"GPL v2",
2021
}
2122

23+
struct RngDriver;
24+
25+
impl PlatformDriver for RngDriver {
26+
fn probe(device_id: i32) -> Result {
27+
pr_info!("probing discovered hwrng with id {}\n", device_id);
28+
Ok(())
29+
}
30+
31+
fn remove(device_id: i32) -> Result {
32+
pr_info!("removing hwrng with id {}\n", device_id);
33+
Ok(())
34+
}
35+
}
36+
2237
struct RngModule {
2338
_pdev: Pin<Box<platdev::Registration>>,
2439
}
@@ -27,7 +42,7 @@ impl KernelModule for RngModule {
2742
fn init() -> Result<Self> {
2843
let of_match_tbl = OfMatchTable::new(&c_str!("brcm,bcm2835-rng"))?;
2944

30-
let pdev = platdev::Registration::new_pinned(
45+
let pdev = platdev::Registration::new_pinned::<RngDriver>(
3146
c_str!("bcm2835-rng-rust"),
3247
Some(of_match_tbl),
3348
&THIS_MODULE,

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)