1. IRQ domain注册

中断控制器初始化的过程中,要向中断子系统注册irq domain。核心函数__irq_domain_add

gic-v2使用irq_domain_create_linear,gic-v3则使用irq_domain_add_tree

__irq_domain_add的实现在kernel/irq/irqdomain.c,逻辑并不复杂,主要就是申请struct irq_domain结构体和对各个成员进行赋值,细节可以自己分析。

 1/// kernel/irq/irqdomain.c
 2/**
 3 * __irq_domain_add() - Allocate a new irq_domain data structure
 4 * @fwnode: firmware node for the interrupt controller
 5 * @size: Size of linear map; 0 for radix mapping only
 6 * @hwirq_max: Maximum number of interrupts supported by controller
 7 * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no
 8 *              direct mapping
 9 * @ops: domain callbacks
10 * @host_data: Controller private data pointer
11 *
12 * Allocates and initializes an irq_domain structure.
13 * Returns pointer to IRQ domain, or NULL on failure.
14 */
15struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
16                    irq_hw_number_t hwirq_max, int direct_max,
17                    const struct irq_domain_ops *ops,
18                    void *host_data)
19{
20    struct irq_domain *domain;
21
22    domain = __irq_domain_create(fwnode, size, hwirq_max, direct_max,
23                     ops, host_data);
24    if (domain)
25        /// 将domain添加到irq_domain_list链表
26        __irq_domain_publish(domain);
27
28    return domain;
29}
30EXPORT_SYMBOL_GPL(__irq_domain_add);

2. irq_domain_ops的调用关系

注册irq domain后,就可以调用irq_domain_ops的回调函数,各个成员的调用关系如下:

注意有些回调只会在使能CONFIG_IRQ_DOMAIN_HIERARCHY时才会调用,如irq_domain_check_hierarchy

__irq_domain_add的最后,会调用irq_domain_check_hierarchy

1/// kernel/irq/irqdomain.c
2static void irq_domain_check_hierarchy(struct irq_domain *domain)
3{
4    /* Hierarchy irq_domains must implement callback alloc() */
5    if (domain->ops->alloc)
6        domain->flags |= IRQ_DOMAIN_FLAG_HIERARCHY;
7}