Linux內核中可以使用platform_get_irq()
函數獲取dts
文件中設置的中斷號。app
函數原型:int platform_get_irq(struct platform_device *dev, unsigned int num)
dom
定義文件:drivers\base\platform.c
函數
1、調用流程
中斷號獲取函數platform_get_irq()
調用流程以下:spa
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
。code
文件:drivers/irqchip/irq-gic-v3.c
。orm
translate()
函數實現以下:blog
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; ## 中斷觸發類型 ... }
2、應用舉例
以RockPI 4A
單板Debian
系統Linux 4.4內核中的獲取HDMI
中斷號爲例。ip
一、查找中斷號get
從手冊「Rockchip RK3399 TRM V1.3 Part1.pdf」中,能夠查到HDMI_IRQ
中斷號,即55。原型
二、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類型中斷特有)>
三、驅動函數
文件: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
和中斷註冊等實現函數。