无法为PCI共享中断线注册中断的问题求助
问题分析与解决方案
注册共享IRQ返回-EINVAL(无效参数),常见原因及修复方式如下:
1. 确保dev_id是唯一且非空的有效指针
你定义了ptdk_dummy_device结构体,但如果代码里的dummy是未初始化的指针(仅声明未分配内存),会被内核判定为无效参数。
修复方式:
- 静态分配全局唯一实例:
static ptdk_dummy_device dummy = { .i = 0 }; // 全局唯一标识
- 或动态分配内存(模块退出时需释放):
static ptdk_dummy_device *dummy; static int __init ptdk_init(void) { dummy = kmalloc(sizeof(*dummy), GFP_KERNEL); if (!dummy) { return -ENOMEM; } // 后续request_threaded_irq调用 } static void __exit ptdk_exit(void) { free_irq(17, dummy); if (dummy) { kfree(dummy); } }
关键:dev_id必须是这条IRQ线上的唯一标识,不能与b43或其他共享驱动的dev_id重复。
2. 匹配中断触发类型
共享IRQ要求所有注册驱动使用相同的触发类型(如电平触发、边沿触发)。b43驱动注册时可能指定了特定触发标志,你未指定的话,内核默认类型可能与b43不匹配,导致注册失败。
修复方式:
先通过cat /proc/irq/17/irq查看b43的触发类型,再在request_threaded_irq中添加对应标志。例如b43用高电平触发:
ptdk_could_not_register = request_threaded_irq(17, (irq_handler_t)ptdk_irq_handler, (irq_handler_t)ptdk_threaded_irq_handler, IRQF_SHARED | IRQF_TRIGGER_LEVEL_HIGH, "ptdk", dummy);
3. 保证顶半部处理函数返回值合规
共享IRQ的顶半部处理函数必须返回以下值之一:
IRQ_HANDLED:确认是本设备产生的中断IRQ_NONE:非本设备中断,转交其他共享驱动IRQ_WAKE_THREAD:需唤醒线程处理时返回
示例合规函数:
static irqreturn_t ptdk_irq_handler(int irq, void *dev_id) { // 检查是否为本设备中断(通过硬件寄存器判断) if (!is_my_device_interrupt()) { return IRQ_NONE; } clear_my_device_interrupt(); // 快速清中断标志 return IRQ_WAKE_THREAD; }
4. 确认IRQ确实支持共享
通过cat /proc/irq/17/flags查看输出,若包含shared则说明该IRQ线确实支持共享;若未包含,需排查硬件或中断控制器的限制。
内容的提问来源于stack exchange,提问作者as43z
相关产品推荐
相关产品推荐

