美文网首页android_display
Linux内核中断之获取中断号

Linux内核中断之获取中断号

作者: 小田BSP | 来源:发表于2021-05-06 23:11 被阅读0次

    Linux内核中可使用platform_get_irq()函数获取dts文件中设置的中断号。

    函数原型:int platform_get_irq(struct platform_device *dev, unsigned int num)

    定义文件:drivers\base\platform.c

    一、调用流程

    中断号获取函数platform_get_irq()调用流程如下:

    platform_get_irq()->
        of_irq_get()->
            of_irq_parse_one()                  ## 解析dts中中断相关属性,填充结构体of_phandle_args中的args[]参数
            irq_create_of_mapping()->           
                of_phandle_args_to_fwspec()     ## 将of_phandle_args->args[]赋值给fwspec->param[],给translate使用
                irq_create_fwspec_mapping()->   
                    irq_domain_translate()->    ## 获取中断号和中断触发类型
                        translate()->           ## 对应某个版本的gic处理函数
    

    rk3399使用的是GICv3,对应irq_domain->name

    文件:drivers/irqchip/irq-gic-v3.c

    translate()函数实现如下:

    static const struct irq_domain_ops gic_irq_domain_ops = {
        .translate = gic_irq_domain_translate,  ## .translate的实现函数
        ...
    };
    
    static int gic_irq_domain_translate(struct irq_domain *d,
                        struct irq_fwspec *fwspec,
                        unsigned long *hwirq,
                        unsigned int *type)
    {
            ...
            switch (fwspec->param[0]) {
            case 0:         /* SPI */
                *hwirq = fwspec->param[1] + 32;  ## 中断号
                break;
            case 1:         /* PPI */
                *hwirq = fwspec->param[1] + 16; ## 中断号
                break;
            case GIC_IRQ_TYPE_LPI:  /* LPI */
                *hwirq = fwspec->param[1];     ## 中断号
                break;
            default:
                return -EINVAL;
            }
            *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; ## 中断触发类型
            ...
    }
    

    二、应用举例

    RockPI 4A单板Debian系统Linux 4.4内核中的获取HDMI中断号为例。

    1、查找中断号

    从手册“Rockchip RK3399 TRM V1.3 Part1.pdf”中,可以查到HDMI_IRQ中断号,即55。

    RK3399中断

    2、dts配置

    文件:arch/arm64/boot/dts/rockchip/rk3399.dtsi

        hdmi: hdmi@ff940000 {
            compatible = "rockchip,rk3399-dw-hdmi";
            ...
            interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH 0>;
            ...
        }
    

    hdmi使用的是GIC_SPI中断,按照gic_irq_domain_translate()函数中处理,需要将中断号55减去32,得到dts中的中断号23。

    注:interrupts = <中断类型 中断号 中断触发类型 中断分区(对应哪个CPU cluster,PPI类型中断特有)>

    3、驱动函数

    文件:drivers\gpu\drm\rockchip\dw_hdmi-rockchip.c

    static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
                     void *data)
    {
        ...
        irq = platform_get_irq(pdev, 0);
        ...
    }
    

    此时,irq返回值为55。

    后续会介绍GIC和中断注册等实现函数。

    相关文章

      网友评论

        本文标题:Linux内核中断之获取中断号

        本文链接:https://www.haomeiwen.com/subject/ftmjdltx.html