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}