Struct ThreadedRegistration

Source
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>

Source

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.

Source

pub fn handler(&self) -> &T

Returns a reference to the handler that was registered with the system.

Source

pub fn try_synchronize(&self) -> Result

Wait for pending IRQ handlers on other CPUs.

This will attempt to access the inner Devres container.

Source

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>

Source§

type PinData = __ThePinData<T>

Source§

unsafe fn __pin_data() -> Self::PinData

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Init<T> for T

Source§

unsafe fn __init(self, slot: *mut T) -> Result<(), Infallible>

Initializes slot. Read more
Source§

fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
where F: FnOnce(&mut T) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PinInit<T> for T

Source§

unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), Infallible>

Initializes slot. Read more
Source§

fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
where F: FnOnce(Pin<&mut T>) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.