Skip to content

Commit

Permalink
rust: use #[vtable] for kernel::irq::Chip
Browse files Browse the repository at this point in the history
Signed-off-by: Gary Guo <[email protected]>
  • Loading branch information
nbdd0121 committed Jul 3, 2022
1 parent 5292e21 commit bd2ae95
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 43 deletions.
3 changes: 1 addition & 2 deletions drivers/gpio/gpio_pl061_rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,10 @@ impl gpio::ChipWithIrqChip for PL061Device {
}
}

#[vtable]
impl irq::Chip for PL061Device {
type Data = Ref<DeviceData>;

kernel::declare_irq_chip_operations!(set_type, set_wake);

fn set_type(
data: RefBorrow<'_, DeviceData>,
irq_data: &mut LockedIrqData,
Expand Down
5 changes: 4 additions & 1 deletion rust/kernel/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,12 @@ mod irqchip {
/// data is passed as context.
struct IrqChipAdapter<T: irq::Chip>(PhantomData<T>);

#[vtable]
impl<T: irq::Chip> irq::Chip for IrqChipAdapter<T> {
type Data = *mut bindings::gpio_chip;
const TO_USE: irq::ToUse = T::TO_USE;

const HAS_SET_TYPE: bool = T::HAS_SET_TYPE;
const HAS_SET_WAKE: bool = T::HAS_SET_WAKE;

fn ack(gc: *mut bindings::gpio_chip, irq_data: &irq::IrqData) {
// SAFETY: `IrqChipAdapter` is a private struct, only used when the data stored in the
Expand Down
44 changes: 4 additions & 40 deletions rust/kernel/irq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#![allow(dead_code)]

use crate::prelude::*;
use crate::{bindings, error::from_kernel_result, types::PointerWrapper, Error, Result};
use core::ops::Deref;

Expand Down Expand Up @@ -95,14 +96,11 @@ pub enum ExtraResult {
/// It is a trait for the functions defined in [`struct irq_chip`].
///
/// [`struct irq_chip`]: ../../../include/linux/irq.h
#[vtable]
pub trait Chip: Sized {
/// The type of the context data stored in the irq chip and made available on each callback.
type Data: PointerWrapper;

/// The methods to use to populate [`struct irq_chip`]. This is typically populated with
/// [`declare_irq_chip_operations`].
const TO_USE: ToUse;

/// Called at the start of a new interrupt.
fn ack(data: <Self::Data as PointerWrapper>::Borrowed<'_>, irq_data: &IrqData);

Expand Down Expand Up @@ -144,49 +142,15 @@ pub(crate) unsafe fn init_chip<T: Chip>(chip: &mut bindings::irq_chip) {
chip.irq_mask = Some(irq_mask_callback::<T>);
chip.irq_unmask = Some(irq_unmask_callback::<T>);

if T::TO_USE.set_type {
if T::HAS_SET_TYPE {
chip.irq_set_type = Some(irq_set_type_callback::<T>);
}

if T::TO_USE.set_wake {
if T::HAS_SET_WAKE {
chip.irq_set_wake = Some(irq_set_wake_callback::<T>);
}
}

/// Represents which fields of [`struct irq_chip`] should be populated with pointers.
///
/// This is typically populated with the [`declare_irq_chip_operations`] macro.
pub struct ToUse {
/// The `irq_set_type` field of [`struct irq_chip`].
pub set_type: bool,

/// The `irq_set_wake` field of [`struct irq_chip`].
pub set_wake: bool,
}

/// A constant version where all values are to set to `false`, that is, all supported fields will
/// be set to null pointers.
pub const USE_NONE: ToUse = ToUse {
set_type: false,
set_wake: false,
};

/// Defines the [`Chip::TO_USE`] field based on a list of fields to be populated.
#[macro_export]
macro_rules! declare_irq_chip_operations {
() => {
const TO_USE: $crate::irq::ToUse = $crate::irq::USE_NONE;
};
($($i:ident),+) => {
#[allow(clippy::needless_update)]
const TO_USE: $crate::irq::ToUse =
$crate::irq::ToUse {
$($i: true),+ ,
..$crate::irq::USE_NONE
};
};
}

/// Enables or disables power-management wake-on for the given irq number.
pub fn set_wake(irq: u32, on: bool) -> Result {
// SAFETY: Just an FFI call, there are no extra requirements for safety.
Expand Down

0 comments on commit bd2ae95

Please sign in to comment.