// SPDX-License-Identifier: GPL-2.01// SPDX-FileCopyrightText: Copyright 2025 Collabora ltd.23use crate::bindings;4use crate::prelude::*;56/// Flags to be used when registering IRQ handlers.7///8/// Flags can be used to request specific behaviors when registering an IRQ9/// handler, and can be combined using the `|`, `&`, and `!` operators to10/// further control the system's behavior.11///12/// A common use case is to register a shared interrupt, as sharing the line13/// between devices is increasingly common in modern systems and is even14/// required for some buses. This requires setting [`Flags::SHARED`] when15/// requesting the interrupt. Other use cases include setting the trigger type16/// through `Flags::TRIGGER_*`, which determines when the interrupt fires, or17/// controlling whether the interrupt is masked after the handler runs by using18/// [`Flags::ONESHOT`].19///20/// If an invalid combination of flags is provided, the system will refuse to21/// register the handler, and lower layers will enforce certain flags when22/// necessary. This means, for example, that all the23/// [`crate::irq::Registration`] for a shared interrupt have to agree on24/// [`Flags::SHARED`] and on the same trigger type, if set.25#[derive(Clone, Copy, PartialEq, Eq)]26pub struct Flags(c_ulong);2728impl Flags {29/// Use the interrupt line as already configured.30pub const TRIGGER_NONE: Flags = Flags::new(bindings::IRQF_TRIGGER_NONE);3132/// The interrupt is triggered when the signal goes from low to high.33pub const TRIGGER_RISING: Flags = Flags::new(bindings::IRQF_TRIGGER_RISING);3435/// The interrupt is triggered when the signal goes from high to low.36pub const TRIGGER_FALLING: Flags = Flags::new(bindings::IRQF_TRIGGER_FALLING);3738/// The interrupt is triggered while the signal is held high.39pub const TRIGGER_HIGH: Flags = Flags::new(bindings::IRQF_TRIGGER_HIGH);4041/// The interrupt is triggered while the signal is held low.42pub const TRIGGER_LOW: Flags = Flags::new(bindings::IRQF_TRIGGER_LOW);4344/// Allow sharing the IRQ among several devices.45pub const SHARED: Flags = Flags::new(bindings::IRQF_SHARED);4647/// Set by callers when they expect sharing mismatches to occur.48pub const PROBE_SHARED: Flags = Flags::new(bindings::IRQF_PROBE_SHARED);4950/// Flag to mark this interrupt as timer interrupt.51pub const TIMER: Flags = Flags::new(bindings::IRQF_TIMER);5253/// Interrupt is per CPU.54pub const PERCPU: Flags = Flags::new(bindings::IRQF_PERCPU);5556/// Flag to exclude this interrupt from irq balancing.57pub const NOBALANCING: Flags = Flags::new(bindings::IRQF_NOBALANCING);5859/// Interrupt is used for polling (only the interrupt that is registered60/// first in a shared interrupt is considered for performance reasons).61pub const IRQPOLL: Flags = Flags::new(bindings::IRQF_IRQPOLL);6263/// Interrupt is not re-enabled after the hardirq handler finished. Used by64/// threaded interrupts which need to keep the irq line disabled until the65/// threaded handler has been run.66pub const ONESHOT: Flags = Flags::new(bindings::IRQF_ONESHOT);6768/// Do not disable this IRQ during suspend. Does not guarantee that this69/// interrupt will wake the system from a suspended state.70pub const NO_SUSPEND: Flags = Flags::new(bindings::IRQF_NO_SUSPEND);7172/// Force enable it on resume even if [`Flags::NO_SUSPEND`] is set.73pub const FORCE_RESUME: Flags = Flags::new(bindings::IRQF_FORCE_RESUME);7475/// Interrupt cannot be threaded.76pub const NO_THREAD: Flags = Flags::new(bindings::IRQF_NO_THREAD);7778/// Resume IRQ early during syscore instead of at device resume time.79pub const EARLY_RESUME: Flags = Flags::new(bindings::IRQF_EARLY_RESUME);8081/// If the IRQ is shared with a [`Flags::NO_SUSPEND`] user, execute this82/// interrupt handler after suspending interrupts. For system wakeup devices83/// users need to implement wakeup detection in their interrupt handlers.84pub const COND_SUSPEND: Flags = Flags::new(bindings::IRQF_COND_SUSPEND);8586/// Don't enable IRQ or NMI automatically when users request it. Users will87/// enable it explicitly by `enable_irq` or `enable_nmi` later.88pub const NO_AUTOEN: Flags = Flags::new(bindings::IRQF_NO_AUTOEN);8990/// Exclude from runnaway detection for IPI and similar handlers, depends on91/// `PERCPU`.92pub const NO_DEBUG: Flags = Flags::new(bindings::IRQF_NO_DEBUG);9394pub(crate) fn into_inner(self) -> c_ulong {95self.096}9798const fn new(value: u32) -> Self {99build_assert!(value as u64 <= c_ulong::MAX as u64);100Self(value as c_ulong)101}102}103104impl core::ops::BitOr for Flags {105type Output = Self;106fn bitor(self, rhs: Self) -> Self::Output {107Self(self.0 | rhs.0)108}109}110111impl core::ops::BitAnd for Flags {112type Output = Self;113fn bitand(self, rhs: Self) -> Self::Output {114Self(self.0 & rhs.0)115}116}117118impl core::ops::Not for Flags {119type Output = Self;120fn not(self) -> Self::Output {121Self(!self.0)122}123}124125126