use core::{fmt::Display, result};
use semx_cpumask::Cpumask;
#[derive(Debug)]
pub enum IrqError {
Invalid,
NotSupported,
}
pub type Result<T> = result::Result<T, IrqError>;
impl Display for IrqError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let error = match self {
Self::Invalid => "Invalid args",
Self::NotSupported => "Not supported",
};
write!(f, "{error}")
}
}
bitflags::bitflags! {
#[derive(Clone, Copy, Default)]
pub struct IrqType: u32 {
const IRQ_TYPE_NONE = 0;
const IRQ_TYPE_EDGE_RISING = 0x1;
const IRQ_TYPE_EDGE_FALLING = 0x2;
const IRQ_TYPE_EDGE_BOTH = IrqType::IRQ_TYPE_EDGE_RISING.bits() | IrqType::IRQ_TYPE_EDGE_FALLING.bits();
const IRQ_TYPE_LEVEL_HIGH = 0x4;
const IRQ_TYPE_LEVEL_LOW = 0x8;
const IRQ_TYPE_LEVEL_MASK = IrqType::IRQ_TYPE_LEVEL_HIGH.bits() | IrqType::IRQ_TYPE_LEVEL_LOW.bits();
const IRQ_TYPE_MASK = IrqType::IRQ_TYPE_EDGE_BOTH.bits() | IrqType::IRQ_TYPE_LEVEL_MASK.bits();
}
}
#[derive(Clone, Copy)]
pub enum IrqchipIrqState {
Pending,
Active,
Masked,
LineLevel,
}
pub trait IrqchipImpl {
const NAME: &'static str;
const IRQS_MAX: usize;
fn irq_ack(&self, _hwirq: u32) {}
fn irq_eoi(&self, hwirq: u32);
fn irq_disable(&self, hwirq: u32);
fn irq_enable(&self, hwirq: u32);
fn irq_set_affinity(&self, _hwirq: u32, _cpumask: &Cpumask) -> Result<()> {
Ok(())
}
fn irq_set_type(&self, _hwirq: u32, _irq_type: IrqType) -> Result<()> {
Ok(())
}
fn irq_get_irqchip_state(&self, _hwirq: u32, _which: IrqchipIrqState) -> Result<bool> {
Err(IrqError::NotSupported)
}
fn irq_set_irqchip_state(
&self,
_hwirq: u32,
_which: IrqchipIrqState,
_state: bool,
) -> Result<()> {
Err(IrqError::NotSupported)
}
fn ipi_send_single(&self, hwirq: u32, cpu: usize) {
let cpumask = Cpumask::from_cpu(cpu);
self.ipi_send_mask(hwirq, &cpumask);
}
fn ipi_send_mask(&self, hwirq: u32, cpumask: &Cpumask);
fn irq_handler(&self);
fn irq_init(&self);
fn irq_init_cpu(&self) {}
}