9
9
use crate :: {
10
10
bindings, c_types,
11
11
error:: { Error , Result } ,
12
+ from_kernel_result,
12
13
of:: OfMatchTable ,
13
- pr_info,
14
14
str:: CStr ,
15
15
types:: PointerWrapper ,
16
16
} ;
@@ -30,18 +30,30 @@ pub struct Registration {
30
30
// (it is fine for multiple threads to have a shared reference to it).
31
31
unsafe impl Sync for Registration { }
32
32
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
+ }
36
42
}
37
43
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
+ }
41
53
}
42
54
43
55
impl Registration {
44
- fn register (
56
+ fn register < P : PlatformDriver > (
45
57
self : Pin < & mut Self > ,
46
58
name : & ' static CStr ,
47
59
of_match_table : Option < OfMatchTable > ,
@@ -59,8 +71,8 @@ impl Registration {
59
71
this. of_table = Some ( ptr) ;
60
72
this. pdrv . driver . of_match_table = ptr. cast ( ) ;
61
73
}
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 > ) ;
64
76
// SAFETY:
65
77
// - `this.pdrv` lives at least until the call to `platform_driver_unregister()` returns.
66
78
// - `name` pointer has static lifetime.
@@ -81,13 +93,13 @@ impl Registration {
81
93
/// Registers a platform device.
82
94
///
83
95
/// Returns a pinned heap-allocated representation of the registration.
84
- pub fn new_pinned (
96
+ pub fn new_pinned < P : PlatformDriver > (
85
97
name : & ' static CStr ,
86
98
of_match_tbl : Option < OfMatchTable > ,
87
99
module : & ' static crate :: ThisModule ,
88
100
) -> Result < Pin < Box < Self > > > {
89
101
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) ?;
91
103
Ok ( r)
92
104
}
93
105
}
@@ -107,3 +119,20 @@ impl Drop for Registration {
107
119
}
108
120
}
109
121
}
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