Linux内核模块中如何从设备树IRQ号获取GPIO引脚号(irq_to_gpio已废弃)
问题
irq_to_gpio()函数已被移除,目前无法使用。现有设备树定义如下:
interrupts = <GIC_SPI 14 IRQ_TYPE_EDGE_BOTH>;
平台分配的IRQ编号为56,请问在Linux内核模块中,有没有有效的现代方法可以获取对应的GPIO引脚号(即14)?虽然可以在gpios节点中重复定义引脚号,但会造成信息冗余。
回答
没有通用的内核API可以直接从IRQ编号反向映射到对应的GPIO引脚号。原因在于GPIO与IRQ的映射关系是硬件平台或GPIO控制器特有的,内核并没有维护一套全局的反向关联数据结构。
可以参考以下几种处理方式:
- 依赖控制器私有接口:如果你的GPIO控制器驱动提供了私有查询接口(部分平台驱动会实现这类功能),可以尝试调用这些接口获取引脚号,但这种方式不具备通用性,换平台或驱动后会失效。
- 优化设备树结构避免冗余:这是更符合现代内核规范的做法,通过设备树的节点引用机制,只定义一次引脚信息,让设备节点直接引用即可,示例如下:
这样只需在gpio_controller: gpio@xxx { compatible = "vendor,gpio-controller"; #gpio-cells = <2>; #interrupt-cells = <2>; interrupt-controller; my_gpio_pin: gpio-pin-14 { gpios = <14 0>; interrupts = <14 IRQ_TYPE_EDGE_BOTH>; }; }; my_device: device@yyy { compatible = "vendor,my-device"; gpios = <&my_gpio_pin>; interrupt-parent = <&gpio_controller>; interrupts = <&my_gpio_pin>; };my_gpio_pin节点中定义一次引脚编号,设备节点通过引用该节点来获取GPIO和中断信息,完全避免了重复定义。 - 通过GPIO descriptor操作(无需引脚号):如果你的需求只是操作该GPIO而非必须获取引脚号,可以尝试从IRQ数据中提取GPIO descriptor:先调用
irq_get_irq_data()获取irq_data结构,再从中获取对应的irq_chip。若该中断芯片由GPIO控制器提供,部分驱动会将GPIO descriptor存储在irq_data的私有字段中,但这种方式同样依赖具体驱动实现,不具备通用性。
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

