kernel/irq 通用中断子系统机制与原理详解

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; // affinity、msi_desc 等
struct irq_data irq_data; // chip、hwirq、状态
unsigned int __percpu *kstat_irqs; // 每 CPU 中断计数
irq_flow_handler_t handle_irq; // flow handler 函数
struct irqaction *action; // handler 链表头
unsigned int depth; // disable 嵌套深度
raw_spinlock_t lock;
struct cpumask *affinity; // SMP 亲和性
struct mutex request_mutex; // request/free 序列化
const char *name;
// ...
};

3.2 struct irq_data — chip 层数据

1
2
3
4
5
6
7
8
9
struct irq_data {
u32 mask; // chip 内 bit mask
unsigned int irq; // Linux virq 号
unsigned long hwirq; // 硬件 IRQ 号
struct irq_chip *chip; // 关联的 irq_chip
struct irq_domain *domain; // 所属 domain
void *chip_data; // chip 私有数据
// state: disabled/masked/inprogress/...
};

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; // 是否需 ack
void (*irq_mask)(struct irq_data *);
void (*irq_unmask)(struct irq_data *);
void (*irq_eoi)(struct irq_data *); // End Of Interrupt
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; // IRQCHIP_* 标志
};

3.4 struct irqaction — 驱动 handler

1
2
3
4
5
6
7
8
9
10
11
12
13
struct irqaction {
irq_handler_t handler; // 硬中断 handler
irq_handler_t thread_fn; // 线程化 handler(可选)
struct irqaction *next; // 共享 IRQ 链表
irq_handler_t *secondary; // 辅助 handler
void *dev_id; // 设备标识(free_irq 用)
void *percpu_dev_id;
const char *name;
struct task_struct *thread; // IRQ 线程
unsigned int flags; // IRQF_* 标志
unsigned long thread_flags; // IRQTF_* 内部标志
// ...
};

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; // 最大 hwirq
unsigned int revmap_size;
unsigned int *revmap; // hwirq → virq 反向映射
struct irq_domain *parent; // 层级 domain
// ...
};

四、中断处理流程

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); // 释放锁调用 handler

ret = handle_irq_event_percpu(desc); // 遍历 action 链

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); // 唤醒 IRQ 内核线程
}

五、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); // ONESHOT: 线程完成前保持 masked

handle_irq_event(desc); // 调用 driver handler

cond_unmask_eoi_irq(desc, chip); // chip->irq_eoi() + 条件 unmask
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; // 边沿可能 pending
mask_ack_irq(desc); // mask + ack

if (desc->action && !irqd_irq_disabled())
handle_irq_event(desc);

// 若 pending 且 unmasked → 重新处理
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, // 硬中断 handler(可为 NULL)
irq_handler_t thread_fn, // 线程 handler
unsigned long flags,
const char *name, void *dev_id)
{
// 分配 irqaction
// __setup_irq(irq, desc, action)
}

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)    // depth++,depth==1 时 mask
void enable_irq(unsigned int irq) // depth--,depth==0 时 unmask + resend
void synchronize_irq(unsigned int irq) // 等待 handler 完成

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 链移除
→ 若无 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
// 驱动 probe 中
domain = irq_domain_add_simple(node, max_irq, irq_base, &chip, chip_data);
virq = irq_create_of_mapping(irq_spec); // 解析 interrupt-parent + interrupts
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
// 动态分配 irq_desc,radix tree 索引
struct irq_desc *irq_alloc_desc(irq, node, affinity, owner, ...)
// allocated_irqs bitmap 跟踪
#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;
// PCI 特定字段
};

struct msi_device_data {
struct xa_array __store; // msi_desc 存储
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[]; // 多种 trigger 类型
u32 mask_cache;
u32 wake_enabled;
};

struct irq_chip_type {
struct irq_chip chip;
struct irq_chip_regs regs; // mask/enable/ack/disable 寄存器偏移
u32 type; // IRQ_TYPE_* 组合
u32 handler; // handle_level/edge_irq
u32 *mask_cache;
};

提供标准回调:irq_gc_mask_set_bitirq_gc_unmask_enable_regirq_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
// arch/arm64/kernel/irq.c
asmlinkage void __exception_irq_entry handle_arch_irq(struct pt_regs *regs)
{
generic_handle_arch_irq(regs);
}

// init 阶段
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 中断管理的核心框架:

  1. irq_desc — 每个 IRQ 的中央描述符,关联 chip、handler、affinity
  2. Flow Handler — 抽象 edge/level/fasteoi 等中断流控制语义
  3. irq_chip — 硬件控制器操作抽象(mask/unmask/eoi/set_affinity)
  4. irq_domain — hwirq ↔ virq 映射,支持 DeviceTree 和层级 domain
  5. request_irq — 驱动注册 handler,支持共享、线程化、ONESHOT
  6. MSI — PCIe 消息中断管理,与 GIC ITS 配合
  7. Affinity/Migration — SMP 中断路由、CPU hotplug 迁移
  8. 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

文章互动

阅读 --

留言

0 条留言

正在加载留言…