xref: /DragonOS/kernel/src/exception/irqdesc.rs (revision 196b75dc17b5cc2ed84301bce776e496ddfe1ed1)
13bc96fa4SLoGin use core::{any::Any, fmt::Debug};
23bc96fa4SLoGin 
33bc96fa4SLoGin use alloc::{
4*196b75dcSLoGin     collections::{btree_map, BTreeMap},
5*196b75dcSLoGin     string::{String, ToString},
63bc96fa4SLoGin     sync::{Arc, Weak},
73bc96fa4SLoGin     vec::Vec,
83bc96fa4SLoGin };
93bc96fa4SLoGin use system_error::SystemError;
103bc96fa4SLoGin 
113bc96fa4SLoGin use crate::{
123bc96fa4SLoGin     arch::CurrentIrqArch,
133bc96fa4SLoGin     driver::base::{
143bc96fa4SLoGin         device::DeviceId,
153bc96fa4SLoGin         kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
163bc96fa4SLoGin         kset::KSet,
173bc96fa4SLoGin     },
183bc96fa4SLoGin     filesystem::kernfs::KernFSInode,
193bc96fa4SLoGin     libs::{
203bc96fa4SLoGin         rwlock::{RwLockReadGuard, RwLockWriteGuard},
213bc96fa4SLoGin         spinlock::{SpinLock, SpinLockGuard},
223bc96fa4SLoGin     },
233bc96fa4SLoGin     process::ProcessControlBlock,
243bc96fa4SLoGin };
253bc96fa4SLoGin 
263bc96fa4SLoGin use super::{
273bc96fa4SLoGin     dummychip::no_irq_chip,
283bc96fa4SLoGin     handle::bad_irq_handler,
293bc96fa4SLoGin     irqdata::{IrqCommonData, IrqData, IrqStatus},
30*196b75dcSLoGin     sysfs::{irq_sysfs_del, IrqKObjType},
313bc96fa4SLoGin     HardwareIrqNumber, InterruptArch, IrqNumber,
323bc96fa4SLoGin };
333bc96fa4SLoGin 
343bc96fa4SLoGin /// 中断流处理程序
353bc96fa4SLoGin pub trait IrqFlowHandler: Debug + Send + Sync {
363bc96fa4SLoGin     fn handle(&self, irq_desc: &Arc<IrqDesc>);
373bc96fa4SLoGin }
383bc96fa4SLoGin 
393bc96fa4SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdesc.h#55
403bc96fa4SLoGin #[derive(Debug)]
413bc96fa4SLoGin pub struct IrqDesc {
423bc96fa4SLoGin     inner: SpinLock<InnerIrqDesc>,
433bc96fa4SLoGin 
443bc96fa4SLoGin     handler: SpinLock<Option<&'static dyn IrqFlowHandler>>,
453bc96fa4SLoGin 
463bc96fa4SLoGin     kobj_state: LockedKObjectState,
473bc96fa4SLoGin }
483bc96fa4SLoGin 
493bc96fa4SLoGin impl IrqDesc {
503bc96fa4SLoGin     #[inline(never)]
513bc96fa4SLoGin     pub fn new(irq: IrqNumber, name: Option<String>, irqd_flags: IrqStatus) -> Arc<Self> {
523bc96fa4SLoGin         // 初始化的过程参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#392
533bc96fa4SLoGin         let common_data = Arc::new(IrqCommonData::new());
543bc96fa4SLoGin         let irq_data = Arc::new(IrqData::new(
553bc96fa4SLoGin             irq,
563bc96fa4SLoGin             HardwareIrqNumber::new(irq.data()),
573bc96fa4SLoGin             common_data.clone(),
583bc96fa4SLoGin             no_irq_chip(),
593bc96fa4SLoGin         ));
603bc96fa4SLoGin 
613bc96fa4SLoGin         irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED);
623bc96fa4SLoGin         common_data.irqd_set(IrqStatus::IRQD_IRQ_MASKED);
633bc96fa4SLoGin 
643bc96fa4SLoGin         let irq_desc = IrqDesc {
653bc96fa4SLoGin             inner: SpinLock::new(InnerIrqDesc {
663bc96fa4SLoGin                 common_data,
673bc96fa4SLoGin                 irq_data,
68*196b75dcSLoGin                 desc_internal_state: IrqDescState::empty(),
693bc96fa4SLoGin                 actions: Vec::new(),
703bc96fa4SLoGin                 name,
713bc96fa4SLoGin                 parent_irq: None,
723bc96fa4SLoGin                 depth: 1,
733bc96fa4SLoGin                 wake_depth: 0,
743bc96fa4SLoGin                 kern_inode: None,
753bc96fa4SLoGin                 kset: None,
763bc96fa4SLoGin                 parent_kobj: None,
773bc96fa4SLoGin             }),
783bc96fa4SLoGin             handler: SpinLock::new(None),
793bc96fa4SLoGin             kobj_state: LockedKObjectState::new(Some(KObjectState::INITIALIZED)),
803bc96fa4SLoGin         };
813bc96fa4SLoGin 
823bc96fa4SLoGin         irq_desc.set_handler(bad_irq_handler());
833bc96fa4SLoGin         irq_desc.inner().irq_data.irqd_set(irqd_flags);
843bc96fa4SLoGin 
853bc96fa4SLoGin         return Arc::new(irq_desc);
863bc96fa4SLoGin     }
873bc96fa4SLoGin 
883bc96fa4SLoGin     pub fn set_handler(&self, handler: &'static dyn IrqFlowHandler) {
893bc96fa4SLoGin         let mut guard = self.handler.lock_irqsave();
903bc96fa4SLoGin         *guard = Some(handler);
913bc96fa4SLoGin     }
923bc96fa4SLoGin 
933bc96fa4SLoGin     fn inner(&self) -> SpinLockGuard<InnerIrqDesc> {
943bc96fa4SLoGin         self.inner.lock_irqsave()
953bc96fa4SLoGin     }
963bc96fa4SLoGin 
97*196b75dcSLoGin     pub fn actions(&self) -> Vec<Arc<IrqAction>> {
98*196b75dcSLoGin         self.inner().actions.clone()
99*196b75dcSLoGin     }
100*196b75dcSLoGin 
1013bc96fa4SLoGin     pub fn irq(&self) -> IrqNumber {
1023bc96fa4SLoGin         self.inner().irq_data.irq()
1033bc96fa4SLoGin     }
104*196b75dcSLoGin 
105*196b75dcSLoGin     pub fn hardware_irq(&self) -> HardwareIrqNumber {
106*196b75dcSLoGin         self.inner().irq_data.hardware_irq()
107*196b75dcSLoGin     }
108*196b75dcSLoGin 
109*196b75dcSLoGin     pub fn irq_data(&self) -> Arc<IrqData> {
110*196b75dcSLoGin         self.inner().irq_data.clone()
111*196b75dcSLoGin     }
112*196b75dcSLoGin 
113*196b75dcSLoGin     /// 标记当前irq描述符已经被添加到sysfs
114*196b75dcSLoGin     pub fn mark_in_sysfs(&self) {
115*196b75dcSLoGin         self.inner()
116*196b75dcSLoGin             .desc_internal_state
117*196b75dcSLoGin             .insert(IrqDescState::IRQS_SYSFS);
118*196b75dcSLoGin     }
119*196b75dcSLoGin 
120*196b75dcSLoGin     pub fn mark_not_in_sysfs(&self) {
121*196b75dcSLoGin         self.inner()
122*196b75dcSLoGin             .desc_internal_state
123*196b75dcSLoGin             .remove(IrqDescState::IRQS_SYSFS);
124*196b75dcSLoGin     }
125*196b75dcSLoGin 
126*196b75dcSLoGin     /// 判断当前描述符是否已经添加到了sysfs
127*196b75dcSLoGin     pub fn in_sysfs(&self) -> bool {
128*196b75dcSLoGin         self.inner()
129*196b75dcSLoGin             .desc_internal_state
130*196b75dcSLoGin             .contains(IrqDescState::IRQS_SYSFS)
131*196b75dcSLoGin     }
132*196b75dcSLoGin 
133*196b75dcSLoGin     pub fn name(&self) -> Option<String> {
134*196b75dcSLoGin         self.inner().name.clone()
135*196b75dcSLoGin     }
1363bc96fa4SLoGin }
1373bc96fa4SLoGin 
1383bc96fa4SLoGin #[allow(dead_code)]
1393bc96fa4SLoGin #[derive(Debug)]
1403bc96fa4SLoGin struct InnerIrqDesc {
1413bc96fa4SLoGin     /// per irq and chip data passed down to chip functions
1423bc96fa4SLoGin     common_data: Arc<IrqCommonData>,
1433bc96fa4SLoGin     irq_data: Arc<IrqData>,
1443bc96fa4SLoGin     actions: Vec<Arc<IrqAction>>,
1453bc96fa4SLoGin     name: Option<String>,
1463bc96fa4SLoGin     parent_irq: Option<IrqNumber>,
1473bc96fa4SLoGin     /// nested irq disables
1483bc96fa4SLoGin     depth: u32,
1493bc96fa4SLoGin     /// nested wake enables
1503bc96fa4SLoGin     wake_depth: u32,
151*196b75dcSLoGin     desc_internal_state: IrqDescState,
1523bc96fa4SLoGin 
1533bc96fa4SLoGin     kern_inode: Option<Arc<KernFSInode>>,
1543bc96fa4SLoGin     kset: Option<Arc<KSet>>,
1553bc96fa4SLoGin     parent_kobj: Option<Weak<dyn KObject>>,
1563bc96fa4SLoGin }
1573bc96fa4SLoGin 
1583bc96fa4SLoGin impl KObject for IrqDesc {
1593bc96fa4SLoGin     fn as_any_ref(&self) -> &dyn Any {
1603bc96fa4SLoGin         self
1613bc96fa4SLoGin     }
1623bc96fa4SLoGin 
1633bc96fa4SLoGin     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
1643bc96fa4SLoGin         self.inner().kern_inode = inode;
1653bc96fa4SLoGin     }
1663bc96fa4SLoGin 
1673bc96fa4SLoGin     fn inode(&self) -> Option<Arc<KernFSInode>> {
1683bc96fa4SLoGin         self.inner().kern_inode.clone()
1693bc96fa4SLoGin     }
1703bc96fa4SLoGin 
1713bc96fa4SLoGin     fn parent(&self) -> Option<Weak<dyn KObject>> {
1723bc96fa4SLoGin         self.inner().parent_kobj.clone()
1733bc96fa4SLoGin     }
1743bc96fa4SLoGin 
1753bc96fa4SLoGin     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
1763bc96fa4SLoGin         self.inner().parent_kobj = parent;
1773bc96fa4SLoGin     }
1783bc96fa4SLoGin 
1793bc96fa4SLoGin     fn kset(&self) -> Option<Arc<KSet>> {
1803bc96fa4SLoGin         self.inner().kset.clone()
1813bc96fa4SLoGin     }
1823bc96fa4SLoGin 
1833bc96fa4SLoGin     fn set_kset(&self, kset: Option<Arc<KSet>>) {
1843bc96fa4SLoGin         self.inner().kset = kset;
1853bc96fa4SLoGin     }
1863bc96fa4SLoGin 
1873bc96fa4SLoGin     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
1883bc96fa4SLoGin         Some(&IrqKObjType)
1893bc96fa4SLoGin     }
1903bc96fa4SLoGin 
1913bc96fa4SLoGin     fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {}
1923bc96fa4SLoGin 
1933bc96fa4SLoGin     fn name(&self) -> String {
194*196b75dcSLoGin         self.inner().irq_data.irq().data().to_string()
1953bc96fa4SLoGin     }
1963bc96fa4SLoGin 
1973bc96fa4SLoGin     fn set_name(&self, _name: String) {}
1983bc96fa4SLoGin 
1993bc96fa4SLoGin     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
2003bc96fa4SLoGin         self.kobj_state.read()
2013bc96fa4SLoGin     }
2023bc96fa4SLoGin 
2033bc96fa4SLoGin     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
2043bc96fa4SLoGin         self.kobj_state.write()
2053bc96fa4SLoGin     }
2063bc96fa4SLoGin 
2073bc96fa4SLoGin     fn set_kobj_state(&self, state: KObjectState) {
2083bc96fa4SLoGin         *self.kobj_state_mut() = state;
2093bc96fa4SLoGin     }
2103bc96fa4SLoGin }
2113bc96fa4SLoGin 
212*196b75dcSLoGin bitflags! {
213*196b75dcSLoGin     /// Bit masks for desc->desc_internal_state
214*196b75dcSLoGin     struct IrqDescState: u32 {
215*196b75dcSLoGin         /// autodetection in progress
216*196b75dcSLoGin         const IRQS_AUTODETECT = 0x00000001;
217*196b75dcSLoGin         /// was disabled due to spurious interrupt detection
218*196b75dcSLoGin         const IRQS_SPURIOUS_DISABLED = 0x00000002;
219*196b75dcSLoGin         /// polling in progress
220*196b75dcSLoGin         const IRQS_POLL_INPROGRESS = 0x00000008;
221*196b75dcSLoGin         /// irq is not unmasked in primary handler
222*196b75dcSLoGin         const IRQS_ONESHOT = 0x00000020;
223*196b75dcSLoGin         /// irq is replayed
224*196b75dcSLoGin         const IRQS_REPLAY = 0x00000040;
225*196b75dcSLoGin         /// irq is waiting
226*196b75dcSLoGin         const IRQS_WAITING = 0x00000080;
227*196b75dcSLoGin         /// irq is pending and replayed later
228*196b75dcSLoGin         const IRQS_PENDING = 0x00000200;
229*196b75dcSLoGin         /// irq is suspended
230*196b75dcSLoGin         const IRQS_SUSPENDED = 0x00000800;
231*196b75dcSLoGin         /// irq line is used to deliver NMIs
232*196b75dcSLoGin         const IRQS_NMI = 0x00002000;
233*196b75dcSLoGin         /// descriptor has been added to sysfs
234*196b75dcSLoGin         const IRQS_SYSFS = 0x00004000;
235*196b75dcSLoGin     }
236*196b75dcSLoGin }
237*196b75dcSLoGin 
2383bc96fa4SLoGin /// 每个中断的响应动作的描述符
2393bc96fa4SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/interrupt.h#118
2403bc96fa4SLoGin #[allow(dead_code)]
2413bc96fa4SLoGin #[derive(Debug)]
2423bc96fa4SLoGin pub struct IrqAction {
2433bc96fa4SLoGin     inner: SpinLock<InnerIrqAction>,
2443bc96fa4SLoGin }
2453bc96fa4SLoGin 
2463bc96fa4SLoGin impl IrqAction {
2473bc96fa4SLoGin     #[allow(dead_code)]
2483bc96fa4SLoGin     pub fn new(
2493bc96fa4SLoGin         irq: IrqNumber,
2503bc96fa4SLoGin         name: String,
2513bc96fa4SLoGin         handler: Option<&'static dyn IrqFlowHandler>,
2523bc96fa4SLoGin     ) -> Arc<Self> {
2533bc96fa4SLoGin         let action = IrqAction {
2543bc96fa4SLoGin             inner: SpinLock::new(InnerIrqAction {
2553bc96fa4SLoGin                 dev_id: None,
2563bc96fa4SLoGin                 handler,
2573bc96fa4SLoGin                 thread_fn: None,
2583bc96fa4SLoGin                 thread: None,
2593bc96fa4SLoGin                 secondary: None,
2603bc96fa4SLoGin                 irq,
2613bc96fa4SLoGin                 flags: IrqHandleFlags::empty(),
2623bc96fa4SLoGin                 name,
2633bc96fa4SLoGin             }),
2643bc96fa4SLoGin         };
2653bc96fa4SLoGin 
2663bc96fa4SLoGin         return Arc::new(action);
2673bc96fa4SLoGin     }
268*196b75dcSLoGin 
269*196b75dcSLoGin     pub fn name(&self) -> String {
270*196b75dcSLoGin         self.inner().name.clone()
271*196b75dcSLoGin     }
272*196b75dcSLoGin 
273*196b75dcSLoGin     fn inner(&self) -> SpinLockGuard<InnerIrqAction> {
274*196b75dcSLoGin         self.inner.lock_irqsave()
275*196b75dcSLoGin     }
2763bc96fa4SLoGin }
2773bc96fa4SLoGin 
2783bc96fa4SLoGin #[allow(dead_code)]
2793bc96fa4SLoGin #[derive(Debug)]
2803bc96fa4SLoGin struct InnerIrqAction {
2813bc96fa4SLoGin     /// cookie to identify the device
2823bc96fa4SLoGin     dev_id: Option<DeviceId>,
2833bc96fa4SLoGin     /// 中断处理程序
2843bc96fa4SLoGin     handler: Option<&'static dyn IrqFlowHandler>,
2853bc96fa4SLoGin     /// interrupt handler function for threaded interrupts
2863bc96fa4SLoGin     thread_fn: Option<&'static dyn IrqFlowHandler>,
2873bc96fa4SLoGin     /// thread pointer for threaded interrupts
2883bc96fa4SLoGin     thread: Option<Arc<ProcessControlBlock>>,
2893bc96fa4SLoGin     /// pointer to secondary irqaction (force threading)
2903bc96fa4SLoGin     secondary: Option<Arc<IrqAction>>,
2913bc96fa4SLoGin     /// 中断号
2923bc96fa4SLoGin     irq: IrqNumber,
2933bc96fa4SLoGin     flags: IrqHandleFlags,
2943bc96fa4SLoGin     /// name of the device
2953bc96fa4SLoGin     name: String,
2963bc96fa4SLoGin }
2973bc96fa4SLoGin 
2983bc96fa4SLoGin // 定义IrqFlags位标志
2993bc96fa4SLoGin bitflags! {
3003bc96fa4SLoGin     /// 这些标志仅由内核在中断处理例程中使用。
3013bc96fa4SLoGin     pub struct IrqHandleFlags: u32 {
3023bc96fa4SLoGin         /// IRQF_SHARED - 允许多个设备共享中断
3033bc96fa4SLoGin         const IRQF_SHARED = 0x00000080;
3043bc96fa4SLoGin         /// IRQF_PROBE_SHARED - 当预期出现共享不匹配时,由调用者设置
3053bc96fa4SLoGin         const IRQF_PROBE_SHARED = 0x00000100;
3063bc96fa4SLoGin         /// IRQF_TIMER - 标记此中断为定时器中断
3073bc96fa4SLoGin         const __IRQF_TIMER = 0x00000200;
3083bc96fa4SLoGin         /// IRQF_PERCPU - 中断是每个CPU的
3093bc96fa4SLoGin         const IRQF_PERCPU = 0x00000400;
3103bc96fa4SLoGin         /// IRQF_NOBALANCING - 将此中断从中断平衡中排除
3113bc96fa4SLoGin         const IRQF_NOBALANCING = 0x00000800;
3123bc96fa4SLoGin         /// IRQF_IRQPOLL - 中断用于轮询(出于性能原因,只有在共享中断中首次注册的中断会被考虑)
3133bc96fa4SLoGin         const IRQF_IRQPOLL = 0x00001000;
3143bc96fa4SLoGin         /// IRQF_ONESHOT - 在硬中断处理程序完成后,不会重新启用中断。由需要在运行线程处理程序之前保持中断线路禁用的线程中断使用。
3153bc96fa4SLoGin         const IRQF_ONESHOT = 0x00002000;
3163bc96fa4SLoGin         /// IRQF_NO_SUSPEND - 在挂起期间不禁用此IRQ。不能保证此中断会从挂起状态唤醒系统。
3173bc96fa4SLoGin         const IRQF_NO_SUSPEND = 0x00004000;
3183bc96fa4SLoGin         /// IRQF_FORCE_RESUME - 即使设置了IRQF_NO_SUSPEND,也强制在恢复时启用它
3193bc96fa4SLoGin         const IRQF_FORCE_RESUME = 0x00008000;
3203bc96fa4SLoGin         /// IRQF_NO_THREAD - 中断不能被线程化
3213bc96fa4SLoGin         const IRQF_NO_THREAD = 0x00010000;
3223bc96fa4SLoGin         /// IRQF_EARLY_RESUME - 在syscore而不是在设备恢复时间早期恢复IRQ。
3233bc96fa4SLoGin         const IRQF_EARLY_RESUME = 0x00020000;
3243bc96fa4SLoGin         /// IRQF_COND_SUSPEND - 如果IRQ与NO_SUSPEND用户共享,则在挂起中断后执行此中断处理程序。对于系统唤醒设备用户,需要在他们的中断处理程序中实现唤醒检测。
3253bc96fa4SLoGin         const IRQF_COND_SUSPEND = 0x00040000;
3263bc96fa4SLoGin         /// IRQF_NO_AUTOEN - 当用户请求时,不会自动启用IRQ或NMI。用户稍后会通过enable_irq()或enable_nmi()显式启用它。
3273bc96fa4SLoGin         const IRQF_NO_AUTOEN = 0x00080000;
3283bc96fa4SLoGin         /// IRQF_NO_DEBUG - 从IPI和类似处理程序的逃逸检测中排除,取决于IRQF_PERCPU。
3293bc96fa4SLoGin         const IRQF_NO_DEBUG = 0x00100000;
3303bc96fa4SLoGin         const IRQF_TIMER = Self::__IRQF_TIMER.bits | Self::IRQF_NO_SUSPEND.bits | Self::IRQF_NO_THREAD.bits;
3313bc96fa4SLoGin     }
3323bc96fa4SLoGin }
3333bc96fa4SLoGin 
3343bc96fa4SLoGin #[inline(never)]
3353bc96fa4SLoGin pub(super) fn early_irq_init() -> Result<(), SystemError> {
3363bc96fa4SLoGin     let irqcnt = CurrentIrqArch::probe_total_irq_num();
3373bc96fa4SLoGin     let mut manager = IrqDescManager::new();
3383bc96fa4SLoGin     for i in 0..irqcnt {
3393bc96fa4SLoGin         let irq_desc = IrqDesc::new(IrqNumber::new(i), None, IrqStatus::empty());
3403bc96fa4SLoGin         manager.insert(IrqNumber::new(i), irq_desc);
3413bc96fa4SLoGin     }
3423bc96fa4SLoGin 
343*196b75dcSLoGin     unsafe {
344*196b75dcSLoGin         IRQ_DESC_MANAGER = Some(manager);
345*196b75dcSLoGin     }
346*196b75dcSLoGin 
3473bc96fa4SLoGin     return CurrentIrqArch::arch_early_irq_init();
3483bc96fa4SLoGin }
3493bc96fa4SLoGin 
350*196b75dcSLoGin static mut IRQ_DESC_MANAGER: Option<IrqDescManager> = None;
351*196b75dcSLoGin 
352*196b75dcSLoGin /// 获取中断描述符管理器的引用
353*196b75dcSLoGin #[inline(always)]
354*196b75dcSLoGin pub(super) fn irq_desc_manager() -> &'static IrqDescManager {
355*196b75dcSLoGin     return unsafe { IRQ_DESC_MANAGER.as_ref().unwrap() };
356*196b75dcSLoGin }
357*196b75dcSLoGin 
3583bc96fa4SLoGin pub(super) struct IrqDescManager {
3593bc96fa4SLoGin     irq_descs: BTreeMap<IrqNumber, Arc<IrqDesc>>,
3603bc96fa4SLoGin }
3613bc96fa4SLoGin 
3623bc96fa4SLoGin impl IrqDescManager {
3633bc96fa4SLoGin     fn new() -> Self {
3643bc96fa4SLoGin         IrqDescManager {
3653bc96fa4SLoGin             irq_descs: BTreeMap::new(),
3663bc96fa4SLoGin         }
3673bc96fa4SLoGin     }
3683bc96fa4SLoGin 
3693bc96fa4SLoGin     /// 查找中断描述符
3703bc96fa4SLoGin     #[allow(dead_code)]
3713bc96fa4SLoGin     pub fn lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>> {
3723bc96fa4SLoGin         self.irq_descs.get(&irq).map(|desc| desc.clone())
3733bc96fa4SLoGin     }
3743bc96fa4SLoGin 
3753bc96fa4SLoGin     fn insert(&mut self, irq: IrqNumber, desc: Arc<IrqDesc>) {
3763bc96fa4SLoGin         self.irq_descs.insert(irq, desc);
3773bc96fa4SLoGin     }
378*196b75dcSLoGin 
379*196b75dcSLoGin     /// 释放中断描述符
380*196b75dcSLoGin     #[allow(dead_code)]
381*196b75dcSLoGin     fn free_desc(&mut self, irq: IrqNumber) {
382*196b75dcSLoGin         if let Some(desc) = self.irq_descs.get(&irq) {
383*196b75dcSLoGin             irq_sysfs_del(desc);
384*196b75dcSLoGin             self.irq_descs.remove(&irq);
385*196b75dcSLoGin         }
386*196b75dcSLoGin     }
387*196b75dcSLoGin 
388*196b75dcSLoGin     /// 迭代中断描述符
389*196b75dcSLoGin     pub fn iter_descs(&self) -> btree_map::Iter<'_, IrqNumber, Arc<IrqDesc>> {
390*196b75dcSLoGin         self.irq_descs.iter()
391*196b75dcSLoGin     }
3923bc96fa4SLoGin }
393