ARM架构下无DTS时硬件中断映射VIRQ及虚拟设备分配软件触发SPI方法
ARM架构无设备树时硬件中断映射到虚拟中断(VIRQ)
- 静态定义硬件中断资源:在平台设备初始化代码中,通过
struct resource指定硬件中断号(HWIRQ),将其绑定到平台设备上:
static struct resource my_device_resources[] = { { .start = 32, // 目标硬件中断号 .end = 32, .flags = IORESOURCE_IRQ, }, }; static struct platform_device my_platform_dev = { .name = "my-custom-device", .id = -1, .num_resources = ARRAY_SIZE(my_device_resources), .resource = my_device_resources, }; static int __init my_dev_init(void) { return platform_device_register(&my_platform_dev); } module_init(my_dev_init);
- 驱动中完成映射与中断申请:在驱动probe函数里,提取平台设备的中断资源,根据架构需求完成HWIRQ到VIRQ的映射,再申请中断:
static irqreturn_t my_irq_handler(int irq, void *dev_id) { // 中断处理逻辑 return IRQ_HANDLED; } static int my_driver_probe(struct platform_device *pdev) { struct resource *irq_res; int virq, ret; irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq_res) return -ENODEV; // 部分ARM架构(如带GIC的ARMv7)可省略手动映射,直接用platform_get_irq获取VIRQ virq = irq_create_mapping(NULL, irq_res->start); if (!virq) return -EINVAL; ret = request_irq(virq, my_irq_handler, IRQF_TRIGGER_RISING, "my-dev-irq", pdev); if (ret) { irq_dispose_mapping(virq); return ret; } return 0; }
虚拟设备无设备树节点时分配软件触发的共享处理器中断(SPI)
- 确认GIC支持:确保系统使用的GIC版本为v2及以上,这类GIC原生支持软件触发SPI,SPI的HWIRQ范围通常为32~1019(具体以GIC配置为准)。
- 动态分配SPI中断号:调用内核API分配可用的SPI中断:
int virq = irq_alloc_descs(-1, 32, 1, 0); if (virq <= 0) { pr_err("Failed to allocate SPI IRQ\n"); return virq; }
- 配置为软件触发模式:通过GIC芯片操作设置中断触发类型为软件触发:
struct irq_chip *gic_chip = irq_get_chip(virq); if (!gic_chip) { irq_free_desc(virq); return -ENODEV; } irq_set_status_flags(virq, IRQ_LEVEL); irq_set_chip_and_handler(virq, gic_chip, handle_level_irq); // 设置触发类型为上升沿(软件触发常用配置) if (gic_chip->irq_set_type) { gic_chip->irq_set_type(virq, IRQ_TYPE_EDGE_RISING); }
- 申请与触发中断:在虚拟设备中申请该中断,之后可通过内核API手动触发:
static irqreturn_t virtual_irq_handler(int irq, void *dev_id) { // 虚拟设备中断处理逻辑 return IRQ_HANDLED; } // 申请中断 int ret = request_irq(virq, virtual_irq_handler, IRQF_SHARED, "virtual-spi-irq", my_virtual_dev); if (ret) { irq_free_desc(virq); return ret; } // 软件触发中断 irq_set_irqchip_state(virq, IRQCHIP_STATE_PENDING, true);
内容的提问来源于stack exchange,提问作者Li Chen
相关产品推荐
相关产品推荐

