基于设备树的内核中断子系统分析(二)

内核版本:linux-4.19.8

本文以s3c2440处理器为例,分析内核中断子系统具体函数调用过程。

一、中断控制子系统的初始化

1、irq_desc初始化,是对struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp这个数组的初始化,

start_kernel
	early_irq_init();
int __init early_irq_init(void)
{
	int count, i, node = first_online_node;
	struct irq_desc *desc;

	init_irq_default_affinity();

	printk(KERN_INFO "NR_IRQS: %d\n", NR_IRQS);

	desc = irq_desc;//irq_desc数组指针
	count = ARRAY_SIZE(irq_desc);

	for (i = 0; i < count; i++) {
		desc[i].kstat_irqs = alloc_percpu(unsigned int);//每个cpu的irq统计数据
		alloc_masks(&desc[i], node);
		raw_spin_lock_init(&desc[i].lock);
		lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
		desc_set_defaults(i, &desc[i], node, NULL, NULL);//初始化每一项irq_desc
	}
	return arch_early_irq_init();
}

2、irq domain注册

   在drivers/irqchip/irq-s3c24xx.c中存在这样一个函数,采用宏定义在段属性中,如下所示:

int __init s3c2410_init_intc_of(struct device_node *np,
            struct device_node *interrupt_parent){
    return s3c_init_intc_of(np, interrupt_parent,
                s3c2410_ctrl, ARRAY_SIZE(s3c2410_ctrl));
}
IRQCHIP_DECLARE(s3c2410_irq, "samsung,s3c2410-irq", s3c2410_init_intc_of);

#define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
#define OF_DECLARE_2(table, name, compat, fn) \
        _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
#define _OF_DECLARE(table, name, compat, fn, fn_type)           \
    static const struct of_device_id __of_table_##name      \
        __used __section(__##table##_of_table)          \
         = { .compatible = compat,              \
             .data = (fn == (fn_type)NULL) ? fn : fn  }

展开为:
    static const struct of_device_id __of_table_s3c2410_irq     \
        __used __section("__irqchip_of_table")          \
         = { .compatible = "samsung,s3c2410-irq",               \
             .data = s3c2410_init_intc_of  }

它定义了一个of_device_id结构体, 段属性为"__irqchip_of_table", 在编译内核时这些段被放在__irqchip_of_table地址处。即__irqchip_of_table起始地址处,放置了一个或多个 of_device_id, 它含有compatible成员;设备树中的设备节点含有compatible属性,如果双方的compatible相同, 并且设备节点含有"interrupt-controller"属性,则调用of_device_id中的函数来处理该设备节点。所以: IRQCHIP_DECLARE 是用来声明设备树中的中断控制器的处理函数。

我们分析内核启动:

start_kernel
	init_IRQ();
		if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq)
			irqchip_init();
				of_irq_init(__irqchip_of_table);
of_irq_init
	for_each_matching_node_and_match(np, matches, &match) //查找device node是否匹配__irqchip_of_table
	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
	list_add_tail(&desc->list, &intc_desc_list);
	while (!list_empty(&intc_desc_list)) {
		ret = desc->irq_init_cb(desc->dev,desc->interrupt_parent);//调用初始化函数,初始化处理器的父中断控制器
	}

如上面分析所示,当内核启动在初始化IRQ时,发现设备树和__irqchip_of_table这个段属性中,双方的compatible相同, 并且设备节点含有"interrupt-controller"属性,则调用of_device_id中的函数来处理。即调用s3c2410_in

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值