kernel/irq 通用中断子系统机制与原理详解
源码路径:rk3588/kernel-6.1/kernel/irq/
内核版本:Linux 6.1(RK3588 平台)
平台:RK3588(4×Cortex-A76 + 4×Cortex-A55 big.LITTLE,ARM64)
该目录实现 Linux 内核 Generic IRQ(通用中断) 子系统的核心框架,统一管理从硬件中断信号到驱动 handler 的完整路径:IRQ 描述符、flow handler、irq_chip 抽象、irq_domain 映射、MSI、亲和性、线程化中断等。
架构分工:kernel/irq/ 提供 与架构无关 的中断管理逻辑;ARM64 入口汇编、set_handle_irq() 及 GIC 驱动位于 arch/arm64/ 与 drivers/irqchip/。
目录
一、源码目录结构
1.1 编译依赖(Makefile)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o obj-$(CONFIG_IRQ_TIMINGS) += timings.o obj-$(CONFIG_GENERIC_IRQ_CHIP) += generic-chip.o obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o obj-$(CONFIG_IRQ_DOMAIN) += irqdomain.o obj-$(CONFIG_IRQ_SIM) += irq_sim.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o obj-$(CONFIG_GENERIC_IRQ_MIGRATION) += cpuhotplug.o obj-$(CONFIG_PM_SLEEP) += pm.o obj-$(CONFIG_GENERIC_MSI_IRQ) += msi.o obj-$(CONFIG_GENERIC_IRQ_IPI) += ipi.o obj-$(CONFIG_SMP) += affinity.o obj-$(CONFIG_GENERIC_IRQ_DEBUGFS) += debugfs.o obj-$(CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR) += matrix.o
|
1.2 源文件
| 文件 |
行数 |
功能 |
irqdesc.c |
~996 |
IRQ 描述符分配/释放、sparse irq、sysfs |
manage.c |
~2934 |
request/free_irq、线程化中断、enable/disable、亲和性 |
irqdomain.c |
~2006 |
irq_domain 创建、hw→linux IRQ 映射、DeviceTree |
chip.c |
~1607 |
flow handler、mask/unmask、startup/shutdown |
handle.c |
~242 |
事件分发、线程唤醒、arch_irq 入口 |
msi.c |
~1042 |
MSI/MSI-X 描述符与 domain 管理 |
timings.c |
~958 |
中断时序统计(延迟分析) |
generic-chip.c |
~668 |
可配置 generic irq_chip 库 |
proc.c |
~538 |
/proc/interrupts 实现 |
spurious.c |
~478 |
虚假/丢失中断检测与恢复 |
matrix.c |
~513 |
IRQ 矩阵分配器(x2APIC 等) |
ipi.c |
~345 |
跨 CPU IPI 中断管理 |
pm.c |
~260 |
休眠/唤醒中断状态保存 |
irq_sim.c |
~250 |
模拟中断(测试用) |
cpuhotplug.c |
~233 |
CPU 热插拔时 IRQ 迁移 |
migration.c |
~119 |
pending affinity 迁移 |
resend.c |
~184 |
软件重发 pending 中断 |
affinity.c |
~128 |
多队列 IRQ 亲和性 mask 生成 |
autoprobe.c |
~184 |
IRQ 自动探测 |
devres.c |
~284 |
devres 托管 request_irq |
dummychip.c |
~64 |
空 irq_chip 占位 |
debugfs.c |
~261 |
debugfs 调试接口 |
internals.h |
~516 |
内部 API、状态位定义 |
settings.h |
~188 |
irq_settings 宏 |
二、整体架构
2.1 分层模型
1 2 3 4
| 硬件中断线 内核 IRQ 框架 驱动 ───────── ───────────── ──── Device ──→ IRQ Chip ──→ irq_domain ──→ irq_desc ──→ irqaction.handler (GIC/GPIO) (mask/eoi) (hw→virq) (flow handler) (driver ISR)
|
2.2 关键层次
| 层次 |
组件 |
职责 |
| 架构入口 |
handle_arch_irq / generic_handle_arch_irq |
汇编 trap → C 入口,irq_enter/exit |
| Flow Handler |
handle_fasteoi_irq 等 |
中断流控制:mask/ack/unmask/eoi |
| Event Handler |
handle_irq_event |
调用 irqaction 链 |
| Driver Handler |
request_irq() 注册的函数 |
设备特定 ISR |
| IRQ Chip |
struct irq_chip |
硬件操作:mask/unmask/eoi/set_type |
| IRQ Domain |
struct irq_domain |
硬件 IRQ 号 → Linux virq 映射 |
2.3 RK3588 典型硬件栈
1 2 3 4 5 6
| 外设 (UART/Ethernet/PCIe) → GICv3 SPI/PPI/SGI (drivers/irqchip/irq-gic-v3.c) → GIC ITS (MSI, irq-gic-v3-its.c) — PCIe MSIs → irq_domain (gic_irq_domain) → kernel/irq/ 通用框架 → 驱动 request_irq() handler
|
三、核心数据结构
3.1 struct irq_desc — 中断描述符
每个 Linux IRQ 号对应一个 irq_desc:
1 2 3 4 5 6 7 8 9 10 11 12 13
| struct irq_desc { struct irq_common_data irq_common_data; struct irq_data irq_data; unsigned int __percpu *kstat_irqs; irq_flow_handler_t handle_irq; struct irqaction *action; unsigned int depth; raw_spinlock_t lock; struct cpumask *affinity; struct mutex request_mutex; const char *name; };
|
3.2 struct irq_data — chip 层数据
1 2 3 4 5 6 7 8 9
| struct irq_data { u32 mask; unsigned int irq; unsigned long hwirq; struct irq_chip *chip; struct irq_domain *domain; void *chip_data; };
|
3.3 struct irq_chip — 硬件中断控制器
1 2 3 4 5 6 7 8 9 10 11 12
| struct irq_chip { const char *name; unsigned int irq_ack; void (*irq_mask)(struct irq_data *); void (*irq_unmask)(struct irq_data *); void (*irq_eoi)(struct irq_data *); int (*irq_set_type)(struct irq_data *, unsigned int); int (*irq_set_affinity)(struct irq_data *, const struct cpumask *, bool); int (*irq_startup)(struct irq_data *); void (*irq_shutdown)(struct irq_data *); unsigned long flags; };
|
3.4 struct irqaction — 驱动 handler
1 2 3 4 5 6 7 8 9 10 11 12 13
| struct irqaction { irq_handler_t handler; irq_handler_t thread_fn; struct irqaction *next; irq_handler_t *secondary; void *dev_id; void *percpu_dev_id; const char *name; struct task_struct *thread; unsigned int flags; unsigned long thread_flags; };
|
3.5 struct irq_domain — 映射域
1 2 3 4 5 6 7 8 9 10
| struct irq_domain { struct list_head link; const char *name; const struct irq_domain_ops *ops; irq_hw_number_t hwirq_max; unsigned int revmap_size; unsigned int *revmap; struct irq_domain *parent; };
|
四、中断处理流程
4.1 总体路径
1 2 3 4 5 6 7 8 9 10 11 12 13
| CPU 收到 IRQ 异常 → arch/arm64: el1h_64_irq_handler (entry.S) → generic_handle_arch_irq(regs) [handle.c] → irq_enter() → handle_arch_irq(regs) [GIC driver] → gic_handle_irq() → generic_handle_domain_irq(domain, hwirq) → irq_find_mapping() → virq → generic_handle_irq_desc(desc) → desc->handle_irq(desc) [flow handler] → handle_irq_event(desc) → action->handler(irq, dev_id) → irq_exit()
|
4.2 handle_irq_event(handle.c)
1 2 3 4 5 6 7 8 9 10 11 12
| irqreturn_t handle_irq_event(struct irq_desc *desc) { desc->istate &= ~IRQS_PENDING; irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS); raw_spin_unlock(&desc->lock);
ret = handle_irq_event_percpu(desc);
raw_spin_lock(&desc->lock); irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS); return ret; }
|
4.3 handler 返回值
| 返回值 |
含义 |
IRQ_NONE |
未处理(可能是共享 IRQ 或非本设备) |
IRQ_HANDLED |
已处理 |
IRQ_WAKE_THREAD |
唤醒 thread_fn 线程继续处理 |
4.4 线程化中断唤醒
1 2 3 4 5 6
| void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action) { desc->threads_oneshot |= action->thread_mask; atomic_inc(&desc->threads_active); wake_up_process(action->thread); }
|
五、Flow Handler 类型
Flow handler 定义中断 流控制语义(何时 mask/ack/unmask/eoi):
| Handler |
适用场景 |
行为 |
handle_simple_irq |
无 chip 控制 |
直接 handle_irq_event |
handle_level_irq |
电平触发 |
mask → handler → unmask |
handle_edge_irq |
边沿触发 |
ack → handler → unmask(可能 pending) |
handle_fasteoi_irq |
GIC 等现代控制器 |
handler → chip->irq_eoi() |
handle_fasteoi_nmi |
NMI 线 |
NMI-safe 版 fasteoi |
handle_edge_eoi_irq |
Cell 等 |
边沿 + EOI |
handle_bad_irq |
未配置/错误 |
计数 + ack_bad_irq |
5.1 handle_fasteoi_irq(RK3588 GIC 最常用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void handle_fasteoi_irq(struct irq_desc *desc) { raw_spin_lock(&desc->lock);
if (!desc->action || irqd_irq_disabled(&desc->irq_data)) { desc->istate |= IRQS_PENDING; mask_irq(desc); goto out; }
kstat_incr_irqs_this_cpu(desc); if (desc->istate & IRQS_ONESHOT) mask_irq(desc);
handle_irq_event(desc);
cond_unmask_eoi_irq(desc, chip); out: raw_spin_unlock(&desc->lock); }
|
5.2 handle_edge_irq
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void handle_edge_irq(struct irq_desc *desc) { raw_spin_lock(&desc->lock); desc->istate &= stale flags; desc->istate |= IRQS_PENDING; mask_ack_irq(desc);
if (desc->action && !irqd_irq_disabled()) handle_irq_event(desc);
cond_unmask_irq(desc); raw_spin_unlock(&desc->lock); }
|
六、IRQ 注册与管理(manage.c)
6.1 request_threaded_irq
1 2 3 4 5 6 7 8 9
| int request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn, unsigned long flags, const char *name, void *dev_id) { }
|
6.2 __setup_irq 核心步骤
1 2 3 4 5 6 7 8 9 10
| __setup_irq(irq, desc, new) → try_module_get(desc->owner) → 检查 trigger type、nested thread → irq_setup_forced_threading() // CONFIG_IRQ_FORCED_THREADING → setup_irq_thread() // 创建 IRQ 内核线程 → 链入 desc->action 链表(支持共享 IRQ) → irq_settings 配置 ONESHOT 等 → irq_startup() / activate // 启动硬件中断 → register_handler_proc() // /proc/irq/N/ → wake_up_and_wait_for_irq_thread_ready()
|
6.3 IRQF 标志
| 标志 |
说明 |
IRQF_SHARED |
多驱动共享同一 IRQ |
IRQF_TRIGGER_RISING/FALLING/HIGH/LOW |
触发类型 |
IRQF_ONESHOT |
线程 handler 完成前保持 masked |
IRQF_NO_THREAD |
禁止强制线程化 |
IRQF_NO_SUSPEND |
休眠时不 disable |
IRQF_EARLY_RESUME |
早恢复 |
IRQF_COND_SUSPEND |
条件 suspend |
6.4 enable/disable
1 2 3
| void disable_irq(unsigned int irq) void enable_irq(unsigned int irq) void synchronize_irq(unsigned int irq)
|
depth 支持嵌套 disable/enable,引用计数语义。
6.5 free_irq
1 2 3 4
| const void *free_irq(unsigned int irq, void *dev_id) → __free_irq(desc, dev_id) → 若无 action 剩余 → irq_shutdown() → kfree(action) + 停止 IRQ 线程
|
七、IRQ Domain 映射(irqdomain.c)
7.1 概念
IRQ Domain 解决硬件 IRQ 号与 Linux 虚拟 IRQ(virq)的映射:
1 2 3
| hwirq (GIC INTID 32~1019) ←→ virq (Linux IRQ 动态分配) ↑ irq_domain ↑ irq_find_mapping(domain, hwirq)
|
7.2 主要 API
| API |
功能 |
__irq_domain_add() |
创建 irq_domain |
irq_create_mapping() |
hwirq → 分配 virq 并关联 |
irq_find_mapping() |
hwirq → 查找已有 virq |
irq_domain_create_simple() |
简单线性映射 domain |
irq_domain_add_legacy() |
固定偏移 legacy 映射 |
irq_alloc_descs() |
批量分配 virq |
irq_domain_alloc_irqs() |
层级 domain 分配 |
7.3 DeviceTree 集成
1 2 3 4
| domain = irq_domain_add_simple(node, max_irq, irq_base, &chip, chip_data); virq = irq_create_of_mapping(irq_spec); request_irq(virq, handler, flags, name, dev);
|
7.4 层级 Domain
1 2 3
| Root Domain (GIC) └── PCI MSI Domain (ITS) └── Device MSI
|
CONFIG_IRQ_DOMAIN_HIERARCHY 支持多级 domain 嵌套。
八、IRQ Chip 操作(chip.c)
8.1 生命周期
1 2 3 4 5 6 7 8 9 10 11 12 13
| irq_startup(desc) // 首次 enable → chip->irq_startup() 或 irq_enable() → unmask_irq()
irq_shutdown(desc) // 最后 disable → mask_irq() → chip->irq_shutdown()
irq_enable(desc) // depth 归零时 → chip->irq_enable/unmask
irq_disable(desc) // depth 递增到 1 时 → chip->irq_disable/mask
|
8.2 mask/unmask
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| void mask_irq(struct irq_desc *desc) { if (!irqd_irq_masked(&desc->irq_data)) { desc->irq_data.chip->irq_mask(&desc->irq_data); irqd_set(&desc->irq_data, IRQD_IRQ_MASKED); } }
void unmask_irq(struct irq_desc *desc) { if (irqd_irq_masked(&desc->irq_data)) { desc->irq_data.chip->irq_unmask(&desc->irq_data); irqd_clear(&desc->irq_data, IRQD_IRQ_MASKED); } }
|
8.3 SPARSE IRQ 描述符管理(irqdesc.c)
1 2 3 4 5 6 7
| #ifdef CONFIG_SPARSE_IRQ
struct irq_desc *irq_alloc_desc(irq, node, affinity, owner, ...)
#else struct irq_desc irq_desc[NR_IRQS]; #endif
|
ARM64/RK3588 启用 CONFIG_SPARSE_IRQ,IRQ 号动态分配,节省内存。
九、MSI 中断(msi.c)
9.1 概述
MSI(Message Signaled Interrupts) 让 PCIe 等设备通过写内存地址触发中断,替代传统 INTx 线。
9.2 核心结构
1 2 3 4 5 6 7 8 9 10 11 12 13
| struct msi_desc { struct device *dev; unsigned int msi_index; unsigned int nvec_used; struct irq_affinity_desc *affinity; };
struct msi_device_data { struct xa_array __store; struct mutex mutex; struct irq_domain *domain; };
|
9.3 RK3588 PCIe MSI 路径
1 2 3 4 5
| PCIe Device → ITS (Interrupt Translation Service, GICv3) → irq-gic-v3-its.c → msi_domain (kernel/irq/msi.c) → virq 分配 + request_irq()
|
十、Generic IRQ Chip(generic-chip.c)
为 MMIO 中断控制器(GPIO 中断、SoC 内部 INTC)提供可配置 irq_chip 实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| struct irq_chip_generic { raw_spinlock_t lock; void __iomem *reg_base; struct irq_chip_type chip_types[]; u32 mask_cache; u32 wake_enabled; };
struct irq_chip_type { struct irq_chip chip; struct irq_chip_regs regs; u32 type; u32 handler; u32 *mask_cache; };
|
提供标准回调:irq_gc_mask_set_bit、irq_gc_unmask_enable_reg、irq_gc_eoi 等,减少驱动重复代码。
十一、亲和性与迁移
11.1 IRQ Affinity
1 2 3 4
| int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask) → irq_do_set_affinity(data, mask, force) → chip->irq_set_affinity() → 或 pending 到 pending_mask
|
11.2 Pending Migration(migration.c)
中断上下文中无法安全修改 affinity 时,标记 IRQD_SETAFFINITY_PENDING:
1 2 3 4 5 6 7
| void irq_move_masked_irq(struct irq_data *idata) { if (!irqd_is_setaffinity_pending(data)) return; irqd_clr_move_pending(data); chip->irq_set_affinity(data, desc->pending_mask, false); }
|
在下次 interrupt 的 mask 阶段执行实际迁移。
11.3 CPU Hotplug(cpuhotplug.c)
CPU offline 前:
- 将 IRQ affinity 从 offline CPU 迁移到其他 CPU
- 清理 pending_mask
11.4 多队列 Affinity(affinity.c)
1 2
| struct irq_affinity_desc * irq_create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd)
|
为 multiqueue 设备(网卡多队列等)生成 per-vector 亲和性 mask,在可用 CPU 间均匀分布。
十二、其他模块
12.1 虚假中断检测(spurious.c)
- 跟踪
irqs_unhandled 计数
- 超过阈值(100000/300s)自动 disable 该 IRQ
irqfixup 启动参数启用 poll 恢复机制
- 防止中断风暴拖垮系统
12.2 IPI(ipi.c)
1 2 3
| int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest) int ipi_send_single(unsigned int virq, unsigned int cpu) int ipi_send_mask(unsigned int virq, const struct cpumask *dest)
|
ARM64 使用 GIC SGI(Software Generated Interrupt)实现核间 IPI。
12.3 /proc/interrupts(proc.c)
1 2 3 4 5
| CPU0 CPU4 CPU5 27: 0 0 0 GICv3 27 Level arch_timer 32: 123456 0 0 GICv3 32 Level rk_uart IPI0: 567890 456789 345678 Rescheduling interrupts IPI1: 12345 12340 12350 Function call interrupts
|
12.4 电源管理(pm.c)
- suspend:保存 IRQ 状态,disable 非 wake IRQ
- resume:restore 状态,resend pending
IRQF_NO_SUSPEND / IRQF_FORCE_RESUME 控制
12.5 devres(devres.c)
1
| devm_request_irq(dev, irq, handler, flags, name, dev_id)
|
设备移除时自动 free_irq,防止资源泄漏。
12.6 IRQ Timings(timings.c)
记录中断到达时间间隔,用于 中断延迟分析 和 debug。
12.7 Matrix Allocator(matrix.c)
用于 x2APIC 等场景的 IRQ 向量矩阵分配,避免冲突。
十三、RK3588/ARM64 平台说明
13.1 Kconfig 支持
1 2 3 4 5 6 7 8 9 10
| # arch/arm64/Kconfig(RK3588 启用项) select GENERIC_IRQ_IPI # IPI 支持 select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW # /proc/interrupts select GENERIC_IRQ_SHOW_LEVEL select HARDIRQS_SW_RESEND select IRQ_DOMAIN # irq_domain 框架 select IRQ_FORCED_THREADING # 可选强制线程化 select SPARSE_IRQ # 动态 IRQ 号 select GENERIC_IRQ_MIGRATION # CPU hotplug 迁移
|
13.2 GICv3 中断控制器
| 组件 |
文件 |
说明 |
| GICv3 Distributor/Redistributor |
drivers/irqchip/irq-gic-v3.c |
主中断控制器 |
| GICv3 ITS |
drivers/irqchip/irq-gic-v3-its.c |
PCIe MSI 翻译 |
| GIC 公共代码 |
drivers/irqchip/irq-gic-common.c |
共享逻辑 |
| GICv3 PM |
drivers/irqchip/irq-gic-pm.c |
休眠支持 |
RK3588 使用 ARM GICv3:
- SGI 0-15:软件生成中断(IPI)
- PPI 16-31:每核私有(arch_timer、性能监控)
- SPI 32+:共享外设中断(UART、EMMC、Ethernet 等)
13.3 中断入口
1 2 3 4 5 6 7 8
| asmlinkage void __exception_irq_entry handle_arch_irq(struct pt_regs *regs) { generic_handle_arch_irq(regs); }
set_handle_irq(handle_arch_irq);
|
13.4 big.LITTLE 亲和性
- GICv3 affinity routing 可将 SPI 路由到特定 CPU 或 CPU 组
- RK3588 8 核:中断默认 spread 到所有 CPU,驱动可通过
irq_set_affinity_hint() 优化
- 高 IOPS 设备(NVMe、千兆网卡)通常绑定 A76 大核
13.5 强制线程化
CONFIG_IRQ_FORCED_THREADING + 启动参数 threadirqs:
- 所有非 per-CPU、非 ONESHOT 的 hard handler 自动线程化
- 减少 hardirq 关中断时间,改善 RT 延迟
- 调试用途,生产环境一般不用
十四、完整中断处理时序
以 RK3588 UART 接收中断 为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| [硬件] UART RX FIFO 达到阈值 → 触发 SPI 中断线 → GICv3
[ARM64 入口] el1h_64_irq_handler (entry.S) → 保存 pt_regs → generic_handle_arch_irq(regs) → irq_enter() // RCU/lockdep/tracing
[ GIC 驱动 ] gic_handle_irq() → 读取 IAR 寄存器 → hwirq = 125 → generic_handle_domain_irq(gic_domain, 125) → virq = irq_find_mapping(domain, 125) // 如 virq=32
[ Flow Handler ] generic_handle_irq_desc(desc) → handle_fasteoi_irq(desc) // GIC 使用 fasteoi → kstat_incr_irqs_this_cpu() → handle_irq_event(desc) → desc->lock 释放 → serial8250_interrupt(32, dev_id) → 读取 FIFO → push 到 tty flip buffer → return IRQ_HANDLED → desc->lock 重新获取 → gic_eoi_irq() // 写 EOIR 寄存器 → irq_exit() // 可能触发 preempt/schedule
[ 用户态 ] tty flip buffer → line discipline → 用户 read() 返回数据
|
十五、总结
kernel/irq 是 Linux 中断管理的核心框架:
- irq_desc — 每个 IRQ 的中央描述符,关联 chip、handler、affinity
- Flow Handler — 抽象 edge/level/fasteoi 等中断流控制语义
- irq_chip — 硬件控制器操作抽象(mask/unmask/eoi/set_affinity)
- irq_domain — hwirq ↔ virq 映射,支持 DeviceTree 和层级 domain
- request_irq — 驱动注册 handler,支持共享、线程化、ONESHOT
- MSI — PCIe 消息中断管理,与 GIC ITS 配合
- Affinity/Migration — SMP 中断路由、CPU hotplug 迁移
- Spurious 检测 — 自动 disable 异常中断源
RK3588 通过 GICv3 + Generic IRQ 框架管理全部硬件中断,是 UART、网络、存储、PCIe 等驱动 request_irq() 的底层支撑。
附录:源文件清单
| 文件 |
行数 |
分类 |
manage.c |
~2934 |
IRQ 注册/enable/affinity |
irqdomain.c |
~2006 |
IRQ Domain 映射 |
chip.c |
~1607 |
Flow handler / chip 操作 |
irqdesc.c |
~996 |
描述符管理 |
timings.c |
~958 |
中断时序 |
msi.c |
~1042 |
MSI 中断 |
generic-chip.c |
~668 |
Generic irq_chip |
proc.c |
~538 |
/proc/interrupts |
spurious.c |
~478 |
虚假中断 |
matrix.c |
~513 |
矩阵分配器 |
handle.c |
~242 |
事件分发 |
ipi.c |
~345 |
IPI |
| 其他 |
~1500 |
pm/migration/affinity/debug 等 |
RK3588 相关驱动/架构文件:
| 文件 |
功能 |
drivers/irqchip/irq-gic-v3.c |
GICv3 主驱动 |
drivers/irqchip/irq-gic-v3-its.c |
GIC ITS (MSI) |
arch/arm64/kernel/irq.c |
ARM64 IRQ 入口 |
arch/arm64/kernel/entry-common.c |
异常入口公共逻辑 |
include/linux/irqdesc.h |
irq_desc 定义 |
include/linux/irqdomain.h |
irq_domain API |
正在加载留言…