1、数据结构分析
(1)中断描述符结构 struct irq_desc:
1)打开CONFIG_SPARSE_IRQ宏(中断编号不连续),中断描述符以radix-
tree 来组织,用户在初始化时进行动态分配,然后再插入 radix-tree 中;
2)关闭CONFIG_SPARSE_IRQ宏(中断编号连续),中断描述符以数组的
形式组织,并且已经分配好;
3)不管哪种形式,最终都可以通过linuxirq号来找到对应的中断描述符;
(2)struct irq_chip 用于对中断控制器的硬件操作;struct irq_domain 与中断控制器对应,完成的工作是硬件中断号到Linux irq的映射;struct irq_domain_ops是中断中对应的操作函数;这三者主要在中断控制器驱动中进行初始化设置。
(3)struct irqaction 中handler的设置,用于指向我们设备驱动程序中的中断处理函数,在设备申请注册中断的过程中进行设置
(4)结构体之间的关系
struct irq_desc 包含 struct irqaction 和 struct irq_data
struct irq_data 包含 struct irq_domain 和 struct irq_chip
struct irq_domain 包含 struct irq_domain ops
struct irqaction 包含 设备驱动中的中断处理函数——irq_handler_t
(5)中断的处理主要有以下几个功能模块:
1)硬件中断号到Linux irq 中断号的映射,并创建好 irq_desc中断描述符;
2)中断注册时,先获取设备的中断号,根据中断号找到对应的irq_desc,并将设备的中断处理函数添加到irq_desc中;
3)设备触发中断信号时,根据硬件中断号得到Linux irq中断号,找到对应的irq_desc,最终调用到设备的中断处理函数;
2、设备硬件中断号到Linux irq 中断号的映射
(1)platform_get_irq(struct platform_device *dev,unsigned int num)
/**drivers\base\Platform.c **/
platform_get_irq(struct platform_device *dev,unsigned int num)
---→_platform_get_irq(dev,num)
---→of_irq_get(dev->dev.of_node,num)
// 返回 Linux irq number-driverslof\Irq.c
---→of_irq_parse_one(dev,index,&oirq)
// 从设备数据中解析中断信息
---→irq_find_host(oirq.np)
// 遍历 irq_domain_list链表,找到匹配的irq_domain
---→irq_create_of_mapping(&oirq) // kernel\irq\lrqdomain.c
// irq_of_parse_and_map也可以调用到该函数,其将中断映射到Linux 空间;irq_of_parse_and_map是个wrapper,更容易调用——drivers\of\Irq.c
(2) irq_create_of_mapping(&oirq)