一、设备树信息

①、#interrupt-cells,指定中断源的信息 cells 个数。
②、interrupt-controller,表示当前节点为中断控制器。
③、interrupts,指定中断号,触发方式等。
④、interrupt-parent,指定父中断,也就是中断控制器。


二、中断的注册过程
    1)终端号分成软件中断号和硬件中断号。
    2)void __init of_irq_init(const struct of_device_id *matches)     =>> gic 初始化
    3)在gpio-mxc中,有:
        mxc_gpio_probe
            port->irq_high = platform_get_irq(pdev, 1);
            port->irq = platform_get_irq(pdev, 0);

        这个 1和0的区别是interrupts属性下的中断1和中断0
            gpio1: gpio@0209c000 {
                compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
                reg = <0x0209c000 0x4000>;
                interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
                         <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
                gpio-controller;
                #gpio-cells = <2>;
                interrupt-controller;
                #interrupt-cells = <2>;
            };

    4)irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());     //分配软件中断号和desc,创建联系

        irq_base是这和GPIO中的32个引脚对应的中断的软中断起始号。
        1.
                #define irq_alloc_descs(irq, from, cnt, node)    \
                    __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE)
        2.
                alloc_descs(start, cnt, node, owner);
        3.
                for (i = 0; i < cnt; i++) {
                        desc = alloc_desc(start + i, node, owner);     // desc_set_defaults(irq, desc, node, owner); 将irq保存到desc->irq_data.irq
                        if (!desc)
                            goto err;
                        mutex_lock(&sparse_irq_lock);
                        irq_insert_desc(start + i, desc);           //radix_tree_insert(&irq_desc_tree, irq, desc);    创建irq和desc的关系,保存在全局数据irq_desc_tree中
                        mutex_unlock(&sparse_irq_lock);
                }

    5)port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, &irq_domain_simple_ops, NULL);
        1.
                void irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base,  irq_hw_number_t hwirq_base, int count)
        2.
                int irq_domain_associate(struct irq_domain *domain, unsigned int virq, irq_hw_number_t hwirq)
        3.
                struct irq_data *irq_data = irq_get_irq_data(virq);  //获取desc->irq_data
                irq_data->hwirq = hwirq;
                irq_data->domain = domain;
                radix_tree_insert(&domain->revmap_tree, hwirq, irq_data);   //创建硬件中断号和desc->irq_data的关系,保存在domain->revmap_tree,软件中断号在之前就保存在desc->irq_data.irq中,建立了软硬件中断号的联系。
    6)mxc_gpio_init_gc(port, irq_base);
        1.初始化了某个引脚中断的desc->handler  !!!
三、调用过程

硬件中断 (GPIO1.1 电平变化)
      1)GPIO 控制器 (mxc_gpio) 标记中断状态
      2)GPIO 控制器触发其 GIC 中断线 (e.g., SPI 66)
      3)GIC 接收中断 SPI 66
        4) CPU 异常 -> gic_handle_irq() ,找到全局的domain
    5)handle_domain_irq(gic->domain, irqnr, regs);   //这里的irqnr是硬件中断号GIC_SPI 67
    6)int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, bool lookup, struct pt_regs *regs)
    7)if (lookup)
        irq = irq_find_mapping(domain, hwirq);   //这里的irq是软件中断号
    8) 在 irq_find_mapping函数中,有
        data = radix_tree_lookup(&domain->revmap_tree, hwirq);
        rcu_read_unlock();
        return data ? data->irq : 0;
    9) generic_handle_irq(irq);
        a) 找到了软件中断号,进而就可以找到irq_desc
        struct irq_desc *desc = irq_to_desc(irq);

        if (!desc)
        return -EINVAL;
        generic_handle_irq_desc(irq, desc);
    b)static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
    c)generic_handle_irq(irq_find_mapping(port->domain, irqoffset));   //其中irq_find_mapping(port->domain, irqoffset)又找到gpio某个引脚的中断的软件中断号
    d)进而调用到我们注册的中断函数

        -> 查找 SPI 66 的 irq_desc -> 调用其 ->handle_irq (即 mxc_gpio_irq_handler)
          -> mxc_gpio_irq_handler: 读取 GPIO ISR, 发现 bit1 (GPIO1.1) 触发
            -> 计算/映射 GPIO1.1 的 Linux 虚拟中断号 (virq)
            -> generic_handle_irq(GPIO1.1 的 virq)  // <--- 你的 callback 是在这里被调用的!
              -> 查找 GPIO1.1 virq 的 irq_desc -> 调用其 ->handle_irq (e.g., handle_edge_irq)
                -> 遍历 action 链表 -> 调用 action->handler (即你的 callback 函数)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐