pub struct ThreadedRegistration<T: ThreadedHandler + 'static> { /* private fields */ }
Expand description
A registration of a threaded IRQ handler for a given IRQ line.
Two callbacks are required: one to handle the IRQ, and one to handle any other work in a separate thread.
The thread handler is only called if the IRQ handler returns
ThreadedIrqReturn::WakeThread
.
§Examples
The following is an example of using ThreadedRegistration
. It uses a
Mutex
to provide interior mutability.
use kernel::c_str;
use kernel::device::{Bound, Device};
use kernel::irq::{
self, Flags, IrqRequest, IrqReturn, ThreadedHandler, ThreadedIrqReturn,
ThreadedRegistration,
};
use kernel::prelude::*;
use kernel::sync::{Arc, Mutex};
// Declare a struct that will be passed in when the interrupt fires. The u32
// merely serves as an example of some internal data.
//
// [`irq::ThreadedHandler::handle`] takes `&self`. This example
// illustrates how interior mutability can be used when sharing the data
// between process context and IRQ context.
#[pin_data]
struct Data {
#[pin]
value: Mutex<u32>,
}
impl ThreadedHandler for Data {
// This will run (in a separate kthread) if and only if
// [`ThreadedHandler::handle`] returns [`WakeThread`], which it does by
// default.
fn handle_threaded(&self, _dev: &Device<Bound>) -> IrqReturn {
let mut data = self.value.lock();
*data += 1;
IrqReturn::Handled
}
}
// Registers a threaded IRQ handler for the given [`IrqRequest`].
//
// This is executing in process context and assumes that `request` was
// previously acquired from a device.
fn register_threaded_irq(
handler: impl PinInit<Data, Error>,
request: IrqRequest<'_>,
) -> Result<Arc<ThreadedRegistration<Data>>> {
let registration =
ThreadedRegistration::new(request, Flags::SHARED, c_str!("my_device"), handler);
let registration = Arc::pin_init(registration, GFP_KERNEL)?;
{
// The data can be accessed from process context too.
let mut data = registration.handler().value.lock();
*data += 1;
}
Ok(registration)
}
§Invariants
- We own an irq handler whose cookie is a pointer to
Self
.
Implementations§
Source§impl<T: ThreadedHandler + 'static> ThreadedRegistration<T>
impl<T: ThreadedHandler + 'static> ThreadedRegistration<T>
Sourcepub fn new<'a>(
request: IrqRequest<'a>,
flags: Flags,
name: &'static CStr,
handler: impl PinInit<T, Error> + 'a,
) -> impl PinInit<Self, Error> + 'a
pub fn new<'a>( request: IrqRequest<'a>, flags: Flags, name: &'static CStr, handler: impl PinInit<T, Error> + 'a, ) -> impl PinInit<Self, Error> + 'a
Registers the IRQ handler with the system for the given IRQ number.
Sourcepub fn handler(&self) -> &T
pub fn handler(&self) -> &T
Returns a reference to the handler that was registered with the system.
Sourcepub fn try_synchronize(&self) -> Result
pub fn try_synchronize(&self) -> Result
Wait for pending IRQ handlers on other CPUs.
This will attempt to access the inner Devres
container.
Sourcepub fn synchronize(&self, dev: &Device<Bound>) -> Result
pub fn synchronize(&self, dev: &Device<Bound>) -> Result
Wait for pending IRQ handlers on other CPUs.
Trait Implementations§
Source§impl<T: ThreadedHandler + 'static> HasPinData for ThreadedRegistration<T>
impl<T: ThreadedHandler + 'static> HasPinData for ThreadedRegistration<T>
Auto Trait Implementations§
impl<T> !Freeze for ThreadedRegistration<T>
impl<T> !RefUnwindSafe for ThreadedRegistration<T>
impl<T> Send for ThreadedRegistration<T>where
T: Send,
impl<T> Sync for ThreadedRegistration<T>
impl<T> !UnwindSafe for ThreadedRegistration<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> PinInit<T> for T
impl<T> PinInit<T> for T
Source§unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), Infallible>
unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), Infallible>
Initializes
slot
. Read more