在 <linux/interrupt.h>, 实现中断注册接口:
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags,
const char *dev_name,
void *dev_id);
注册的中断信息可以在 /proc/interrupts 中查看
void free_irq(unsigned int irq, void *dev_id);
从 request_irq 返回给请求函数的返回值是 0 指示成功, 或是一个负的错误码. 函数返回 -EBUSY 来指示另一个驱动已经使用请求的中断. 函数的参数如下:
unsigned int irq
请求的中断号
irqreturn_t (*handler)
安装的处理函数指针.
unsigned long flags
一个与中断管理相关的选项的位掩码(后面描述).
const char *dev_name
这个传递给 request_irq 的字串用在 /proc/interrupts 来显示中断的拥有者。
void *dev_id
用作共享中断线的指针. 它是一个独特的标识, 用在当释放中断线时以及可能还被驱动用来指向它自己的私有数据区(来标识哪个设备在中断). 如果中断没有被共享, dev_id 可以设置为 NULL, 但是使用这个项指向设备结构不管如何是个好主意. 我们将在"实现一个处理"一节中看到 dev_id 的一个实际应用.
flags 中可以设置的位如下:
SA_INTERRUPT
当置位了, 这表示一个"快速"中断处理. 即在当前处理器上禁止中断来执行。 SA_INTERRUPT 只是打算用在几个, 特殊的情况例如时钟中断, 其他情况不建议使用它。
SA_SHIRQ
这个位表示中断可以在设备间共享.
中断处理可以在驱动初始化时或者在设备第一次打开时安装. 但不建议在模块的初始化函数中安装
调用 request_irq 的正确位置是当设备第一次打开时, 在硬件被指示来产生中断前. 调用 free_irq
的位置是设备最后一次被关闭时, 在硬件被告知不要再中断处理器之后. 这个技术的缺点是你需要保持一个每设备的打开计数,
以便于你知道什么时候中断可以被禁止. |