256 IRQCHIP_DECLARE(bcm2835_armctrl_ic, "brcm,bcm2835-armctrl-ic",
257 bcm2835_armctrl_of_init);
我们来看看IRQCHIP_DECLARE 的定义.
source/include/linux/irqchip.h#L27
27 #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
继续看OF_DECLARE_2的实现
#if defined(CONFIG_OF)
998 #define _OF_DECLARE(table, name, compat, fn, fn_type) \
999 static const struct of_device_id __of_table_##name \
1000 __used __section(__##table##_of_table) \
1001 = { .compatible = compat, \
1002 .data = (fn == (fn_type)NULL) ? fn : fn }
1003 #else
1004 #define _OF_DECLARE(table, name, compat, fn, fn_type) \
1005 static const struct of_device_id __of_table_##name \
1006 __attribute__((unused)) \
1007 = { .compatible = compat, \
1008 .data = (fn == (fn_type)NULL) ? fn : fn }
1009 #endif
1010
1011 typedef int (*of_init_fn_2)(struct device_node *, struct device_node *);
1012 typedef void (*of_init_fn_1)(struct device_node *);
1013
1014 #define OF_DECLARE_1(table, name, compat, fn) \
1015 _OF_DECLARE(table, name, compat, fn, of_init_fn_1)
1016 #define OF_DECLARE_2(table, name, compat, fn) \
1017 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
在实际使用过程中CONFIG_OF 是定义.
所以OF_DECLARE_2 是1016行的宏_OF_DECLARE来实现的。
再来看999行_OF_DECLARE的实现。有OF_DECLARE_2的第一个参数是table,而在27行table被定义irqchip。所以1000行的section就是irqchip_of_able。
所以256行的bcm2835_armctrl_of_init是被放在irqchip_of_able 中.
明白上面后我们来看irqchip.c的实现.
/drivers/irqchip/irqchip.c
22 static const struct of_device_id
23 irqchip_of_match_end __used __section(__irqchip_of_table_end);
24
25 extern struct of_device_id __irqchip_of_table[];
26
27 void __init irqchip_init(void)
28 {
29 of_irq_init(__irqchip_of_table);
30 acpi_probe_device_table(irqchip);
31 }
而irqchip_init 是被init_IRQ 调用的。而init_IRQ是被 start_kernel调用的,也就是kernel 会在刚开始的初始化函数中调用.
void __init init_IRQ(void)
22 {
23 /*
24 * process the entire interrupt tree in one go
25 * Any external intc will be setup provided DT chains them
26 * properly
27 */
28 irqchip_init();
38 }
调用flow清楚了,我们在来看看of_irq_init 这个函数主要scan和init 匹配的interrupt controller.
这个函数的实现如下:
从500开始找interrupt-controller node。
如果找到,则在512行申请一个of_intc_desc
518行保存irq_init_cb,就是在上面分析的bcm2835_armctrl_of_init
从531开始的循环中主要就是调用bcm2835_armctrl_of_init函数,具体是在548 ret = desc->irq_init_cb(desc->dev,desc->interrupt_parent);调用
489 void __init of_irq_init(const struct of_device_id *matches)
490 {
491 const struct of_device_id *match;
492 struct device_node *np, *parent = NULL;
493 struct of_intc_desc *desc, *temp_desc;
494 struct list_head intc_desc_list, intc_parent_list;
495
496 INIT_LIST_HEAD(&intc_desc_list);
497 INIT_LIST_HEAD(&intc_parent_list);
498
499 for_each_matching_node_and_match(np, matches, &match) {
500 if (!of_find_property(np, "interrupt-controller", NULL) ||
501 !of_device_is_available(np))
502 continue;
503
504 if (WARN(!match->data, "of_irq_init: no init function for %s\n",
505 match->compatible))
506 continue;
507
508 /*
509 * Here, we allocate and populate an of_intc_desc with the node
510 * pointer, interrupt-parent device_node etc.
511 */
512 desc = kzalloc(sizeof(*desc), GFP_KERNEL);
513 if (WARN_ON(!desc)) {
514 of_node_put(np);
515 goto err;
516 }
517
518 desc->irq_init_cb = match->data;
519 desc->dev = of_node_get(np);
520 desc->interrupt_parent = of_irq_find_parent(np);
521 if (desc->interrupt_parent == np)
522 desc->interrupt_parent = NULL;
523 list_add_tail(&desc->list, &intc_desc_list);
524 }
525
526 /*
527 * The root irq controller is the one without an interrupt-parent.
528 * That one goes first, followed by the controllers that reference it,
529 * followed by the ones that reference the 2nd level controllers, etc.
530 */
531 while (!list_empty(&intc_desc_list)) {
532 /*
533 * Process all controllers with the current 'parent'.
534 * First pass will be looking for NULL as the parent.
535 * The assumption is that NULL parent means a root controller.
536 */
537 list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
538 int ret;
539
540 if (desc->interrupt_parent != parent)
541 continue;
542
543 list_del(&desc->list);
544
545 pr_debug("of_irq_init: init %s (%p), parent %p\n",
546 desc->dev->full_name,
547 desc->dev, desc->interrupt_parent);
548 ret = desc->irq_init_cb(desc->dev,
549 desc->interrupt_parent);
550 if (ret) {
551 kfree(desc);
552 continue;
553 }
554
555 /*
556 * This one is now set up; add it to the parent list so
557 * its children can get processed in a subsequent pass.
558 */
559 list_add_tail(&desc->list, &intc_parent_list);
560 }
561
562 /* Get the next pending parent that might have children */
563 desc = list_first_entry_or_null(&intc_parent_list,
564 typeof(*desc), list);
565 if (!desc) {
566 pr_err("of_irq_init: children remain, but no parents\n");
567 break;
568 }
569 list_del(&desc->list);
570 parent = desc->dev;
571 kfree(desc);
572 }
573
574 list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
575 list_del(&desc->list);
576 kfree(desc);
577 }
578 err:
579 list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
580 list_del(&desc->list);
581 of_node_put(desc->dev);
582 kfree(desc);
583 }
584 }
257 bcm2835_armctrl_of_init);
我们来看看IRQCHIP_DECLARE 的定义.
source/include/linux/irqchip.h#L27
27 #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
继续看OF_DECLARE_2的实现
#if defined(CONFIG_OF)
998 #define _OF_DECLARE(table, name, compat, fn, fn_type) \
999 static const struct of_device_id __of_table_##name \
1000 __used __section(__##table##_of_table) \
1001 = { .compatible = compat, \
1002 .data = (fn == (fn_type)NULL) ? fn : fn }
1003 #else
1004 #define _OF_DECLARE(table, name, compat, fn, fn_type) \
1005 static const struct of_device_id __of_table_##name \
1006 __attribute__((unused)) \
1007 = { .compatible = compat, \
1008 .data = (fn == (fn_type)NULL) ? fn : fn }
1009 #endif
1010
1011 typedef int (*of_init_fn_2)(struct device_node *, struct device_node *);
1012 typedef void (*of_init_fn_1)(struct device_node *);
1013
1014 #define OF_DECLARE_1(table, name, compat, fn) \
1015 _OF_DECLARE(table, name, compat, fn, of_init_fn_1)
1016 #define OF_DECLARE_2(table, name, compat, fn) \
1017 _OF_DECLARE(table, name, compat, fn, of_init_fn_2)
在实际使用过程中CONFIG_OF 是定义.
所以OF_DECLARE_2 是1016行的宏_OF_DECLARE来实现的。
再来看999行_OF_DECLARE的实现。有OF_DECLARE_2的第一个参数是table,而在27行table被定义irqchip。所以1000行的section就是irqchip_of_able。
所以256行的bcm2835_armctrl_of_init是被放在irqchip_of_able 中.
明白上面后我们来看irqchip.c的实现.
/drivers/irqchip/irqchip.c
22 static const struct of_device_id
23 irqchip_of_match_end __used __section(__irqchip_of_table_end);
24
25 extern struct of_device_id __irqchip_of_table[];
26
27 void __init irqchip_init(void)
28 {
29 of_irq_init(__irqchip_of_table);
30 acpi_probe_device_table(irqchip);
31 }
而irqchip_init 是被init_IRQ 调用的。而init_IRQ是被 start_kernel调用的,也就是kernel 会在刚开始的初始化函数中调用.
void __init init_IRQ(void)
22 {
23 /*
24 * process the entire interrupt tree in one go
25 * Any external intc will be setup provided DT chains them
26 * properly
27 */
28 irqchip_init();
38 }
调用flow清楚了,我们在来看看of_irq_init 这个函数主要scan和init 匹配的interrupt controller.
这个函数的实现如下:
从500开始找interrupt-controller node。
如果找到,则在512行申请一个of_intc_desc
518行保存irq_init_cb,就是在上面分析的bcm2835_armctrl_of_init
从531开始的循环中主要就是调用bcm2835_armctrl_of_init函数,具体是在548 ret = desc->irq_init_cb(desc->dev,desc->interrupt_parent);调用
489 void __init of_irq_init(const struct of_device_id *matches)
490 {
491 const struct of_device_id *match;
492 struct device_node *np, *parent = NULL;
493 struct of_intc_desc *desc, *temp_desc;
494 struct list_head intc_desc_list, intc_parent_list;
495
496 INIT_LIST_HEAD(&intc_desc_list);
497 INIT_LIST_HEAD(&intc_parent_list);
498
499 for_each_matching_node_and_match(np, matches, &match) {
500 if (!of_find_property(np, "interrupt-controller", NULL) ||
501 !of_device_is_available(np))
502 continue;
503
504 if (WARN(!match->data, "of_irq_init: no init function for %s\n",
505 match->compatible))
506 continue;
507
508 /*
509 * Here, we allocate and populate an of_intc_desc with the node
510 * pointer, interrupt-parent device_node etc.
511 */
512 desc = kzalloc(sizeof(*desc), GFP_KERNEL);
513 if (WARN_ON(!desc)) {
514 of_node_put(np);
515 goto err;
516 }
517
518 desc->irq_init_cb = match->data;
519 desc->dev = of_node_get(np);
520 desc->interrupt_parent = of_irq_find_parent(np);
521 if (desc->interrupt_parent == np)
522 desc->interrupt_parent = NULL;
523 list_add_tail(&desc->list, &intc_desc_list);
524 }
525
526 /*
527 * The root irq controller is the one without an interrupt-parent.
528 * That one goes first, followed by the controllers that reference it,
529 * followed by the ones that reference the 2nd level controllers, etc.
530 */
531 while (!list_empty(&intc_desc_list)) {
532 /*
533 * Process all controllers with the current 'parent'.
534 * First pass will be looking for NULL as the parent.
535 * The assumption is that NULL parent means a root controller.
536 */
537 list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
538 int ret;
539
540 if (desc->interrupt_parent != parent)
541 continue;
542
543 list_del(&desc->list);
544
545 pr_debug("of_irq_init: init %s (%p), parent %p\n",
546 desc->dev->full_name,
547 desc->dev, desc->interrupt_parent);
548 ret = desc->irq_init_cb(desc->dev,
549 desc->interrupt_parent);
550 if (ret) {
551 kfree(desc);
552 continue;
553 }
554
555 /*
556 * This one is now set up; add it to the parent list so
557 * its children can get processed in a subsequent pass.
558 */
559 list_add_tail(&desc->list, &intc_parent_list);
560 }
561
562 /* Get the next pending parent that might have children */
563 desc = list_first_entry_or_null(&intc_parent_list,
564 typeof(*desc), list);
565 if (!desc) {
566 pr_err("of_irq_init: children remain, but no parents\n");
567 break;
568 }
569 list_del(&desc->list);
570 parent = desc->dev;
571 kfree(desc);
572 }
573
574 list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
575 list_del(&desc->list);
576 kfree(desc);
577 }
578 err:
579 list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
580 list_del(&desc->list);
581 of_node_put(desc->dev);
582 kfree(desc);
583 }
584 }