IRQ number和中断描述符
综述
在linux kernel中,对于每一个外设的IRQ都用struct irq_desc来描述,我们称之中断描述符(struct irq_desc)。linux kernel中会有一个数据结构保存了关于所有IRQ的中断描述符信息,我们称之中断描述符DB。当发生中断后,首先获取触发中断的hwirq,然后通过irq domain翻译成virq,然后通过virq就可以获取对应的中断描述符(以virq为数组irq_desc[virq]的下标获取对应的irq_desc)。调用中断描述符中的handle_irq函数指针遍历irq_desc中链表action的handler来进行中断处理。
init irq_desc
mt6853_r_tee/kernel-4.14/init$ vim main.c +637
asmlinkage __visible void __init start_kernel(void)
early_irq_init();
/* Let arch update nr_irqs and return the nr of preallocated irqs */
initcnt = arch_probe_nr_irqs();/* 预先分配中断数量 */
for (i = 0; i < initcnt; i++) {
desc = alloc_desc(i, node, 0, NULL, NULL);/*分配中断描述符*/
set_bit(i, allocated_irqs);/*设定已经alloc的flag*/
irq_insert_desc(i, desc);/* 插入radix tree 中储存*/
}
Get irq number
如下流程所示:
具体流程如下;
irq_domain_translate(domain, fwspec, &hwirq, &type)/* 这里可以通过dt irq描述里面获取hwirq*/
virq = irq_domain_alloc_descs(-1, 1, hwirq, of_node_to_nid(of_node), NULL);
hint = hwirq % nr_irqs;
virq = __irq_alloc_descs(-1, hint, cnt, node, THIS_MODULE,
from = arch_dynirq_lower_bound(from);
start=bitmap_find_next_zero_area(allocated_irqs,IRQ_BITMAP_BITS,/*virq*/
bitmap_set(allocated_irqs, start, cnt);/* 占用位数组该位,表示irq已经使用*/
/* 以下是通过 radix tree方式以virq为索引key,保存对应irq_desc的方式*/
desc = alloc_desc(start + i, node, flags, mask, owner);
irq_insert_desc(start + i, desc);
Get irq_desc
irq_to_desc(irq)
return radix_tree_lookup(&irq_desc_tree, irq);
可见,这是通过 radix tree 的方式以virq为索引获取的.