Skip to content

Commit 86d6c6d

Browse files
committed
rust: device: Add support for locking the device
Signed-off-by: Janne Grunau <j@jannau.net>
1 parent 758595c commit 86d6c6d

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

rust/helpers/device.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,13 @@ void rust_helper_dev_set_drvdata(struct device *dev, void *data)
2525
{
2626
dev_set_drvdata(dev, data);
2727
}
28+
29+
void rust_helper_device_lock(struct device *dev)
30+
{
31+
device_lock(dev);
32+
}
33+
34+
void rust_helper_device_unlock(struct device *dev)
35+
{
36+
device_unlock(dev);
37+
}

rust/kernel/device.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
use crate::{
88
bindings,
9-
types::{ARef, ForeignOwnable, Opaque},
9+
types::{ARef, ForeignOwnable, NotThreadSafe, Opaque},
1010
};
1111
use core::{fmt, marker::PhantomData, ptr};
1212

@@ -398,6 +398,35 @@ impl<Ctx: DeviceContext> Device<Ctx> {
398398
// defined as a `#[repr(transparent)]` wrapper around `fwnode_handle`.
399399
Some(unsafe { &*fwnode_handle.cast() })
400400
}
401+
402+
/// Locks the [`Device`] for exclusive access.
403+
pub fn lock(&self) -> Guard<'_, Ctx> {
404+
// SAFETY: `self` is always valid by the type invariant.
405+
unsafe { bindings::device_lock(self.as_raw()) };
406+
407+
Guard {
408+
dev: self,
409+
_not_send: NotThreadSafe,
410+
}
411+
}
412+
}
413+
414+
/// A lock guard.
415+
///
416+
/// The lock is unlocked when the guard goes out of scope.
417+
#[must_use = "the lock unlocks immediately when the guard is unused"]
418+
pub struct Guard<'a, Ctx: DeviceContext = Normal> {
419+
dev: &'a Device<Ctx>,
420+
_not_send: NotThreadSafe,
421+
}
422+
423+
impl<Ctx: DeviceContext> Drop for Guard<'_, Ctx> {
424+
fn drop(&mut self) {
425+
// SAFETY:
426+
// - `self.xa.xa` is always valid by the type invariant.
427+
// - The caller holds the lock, so it is safe to unlock it.
428+
unsafe { bindings::device_unlock(self.dev.as_raw()) };
429+
}
401430
}
402431

403432
// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic

0 commit comments

Comments
 (0)