Skip to content

Commit f307587

Browse files
hoshinolinamarcan
authored andcommitted
rust: drm: Add Device and Driver abstractions
Add the initial abstractions for DRM drivers and devices. These go together in one commit since they are fairly tightly coupled types. A few things have been stubbed out, to be implemented as further bits of the DRM subsystem are introduced. Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 3408383 commit f307587

5 files changed

Lines changed: 410 additions & 6 deletions

File tree

rust/bindings/bindings_helper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66
* Sorted alphabetically.
77
*/
88

9+
#include <drm/drm_device.h>
10+
#include <drm/drm_drv.h>
911
#include <drm/drm_ioctl.h>
1012
#include <linux/delay.h>
1113
#include <linux/device.h>
1214
#include <linux/dma-mapping.h>
1315
#include <linux/errname.h>
1416
#include <linux/slab.h>
17+
#include <linux/fs.h>
1518
#include <linux/io-pgtable.h>
1619
#include <linux/ktime.h>
1720
#include <linux/lockdep.h>

rust/kernel/drm/device.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// SPDX-License-Identifier: GPL-2.0 OR MIT
2+
3+
//! DRM device.
4+
//!
5+
//! C header: [`include/linux/drm/drm_device.h`](../../../../include/linux/drm/drm_device.h)
6+
7+
use crate::{
8+
bindings, device, drm,
9+
types::{AlwaysRefCounted, ForeignOwnable},
10+
};
11+
use core::cell::UnsafeCell;
12+
use core::marker::PhantomData;
13+
use core::ptr::NonNull;
14+
15+
/// A typed DRM device with a specific driver. The device is always reference-counted.
16+
#[repr(transparent)]
17+
pub struct Device<T: drm::drv::Driver> {
18+
pub(super) drm: UnsafeCell<bindings::drm_device>,
19+
_p: PhantomData<T>,
20+
}
21+
22+
impl<T: drm::drv::Driver> Device<T> {
23+
#[allow(dead_code, clippy::mut_from_ref)]
24+
pub(crate) unsafe fn raw_mut(&self) -> &mut bindings::drm_device {
25+
unsafe { &mut *self.drm.get() }
26+
}
27+
28+
// Not intended to be called externally, except via declare_drm_ioctls!()
29+
#[doc(hidden)]
30+
pub unsafe fn borrow<'a>(raw: *const bindings::drm_device) -> &'a Self {
31+
unsafe { &*(raw as *const Self) }
32+
}
33+
34+
/// Returns a borrowed reference to the user data associated with this Device.
35+
pub fn data(&self) -> <T::Data as ForeignOwnable>::Borrowed<'_> {
36+
// SAFETY: dev_private is guaranteed to be initialized for all
37+
// Device objects exposed to users.
38+
unsafe { T::Data::borrow((*self.drm.get()).dev_private) }
39+
}
40+
}
41+
42+
// SAFETY: DRM device objects are always reference counted and the get/put functions
43+
// satisfy the requirements.
44+
unsafe impl<T: drm::drv::Driver> AlwaysRefCounted for Device<T> {
45+
fn inc_ref(&self) {
46+
unsafe { bindings::drm_dev_get(&self.drm as *const _ as *mut _) };
47+
}
48+
49+
unsafe fn dec_ref(obj: NonNull<Self>) {
50+
// SAFETY: The Device<T> type has the same layout as drm_device,
51+
// so we can just cast.
52+
unsafe { bindings::drm_dev_put(obj.as_ptr() as *mut _) };
53+
}
54+
}
55+
56+
// SAFETY: `Device` only holds a pointer to a C device, which is safe to be used from any thread.
57+
unsafe impl<T: drm::drv::Driver> Send for Device<T> {}
58+
59+
// SAFETY: `Device` only holds a pointer to a C device, references to which are safe to be used
60+
// from any thread.
61+
unsafe impl<T: drm::drv::Driver> Sync for Device<T> {}
62+
63+
// Make drm::Device work for dev_info!() and friends
64+
unsafe impl<T: drm::drv::Driver> device::RawDevice for Device<T> {
65+
fn raw_device(&self) -> *mut bindings::device {
66+
// SAFETY: dev is initialized by C for all Device objects
67+
unsafe { (*self.drm.get()).dev }
68+
}
69+
}

0 commit comments

Comments
 (0)