参考文章:https://www.cnblogs.com/hoys/archive/2012/05/30/2525996.html
- Setup_irq
Setup_irq通常是直接注册irqaction,并没针对相应中断线进行错误检测,如该irq 线是否已经被占用等。因此setup_irq通常只用在特定的中断线上,如System timer。除系统时钟驱动外,大部份驱动还是通过request_irq注册中断。
/**
* setup_irq - setup an interrupt
* @irq: Interrupt line to setup
* @act: irqaction for the interrupt
*
* Used to statically setup interrupts in the early boot process.
*/
int setup_irq(unsigned int irq, struct irqaction *act)
{
int retval;
struct irq_desc *desc = irq_to_desc(irq);
if (WARN_ON(irq_settings_is_per_cpu_devid(desc)))
return -EINVAL;
chip_bus_lock(desc);
retval = __setup_irq(irq, desc, act);
chip_bus_sync_unlock(desc);
return retval;
}
用法示例:
static irqreturn_t timer3_interrupt(int irq, void *dev_id)
{
__raw_writel(0x01, REG_TIMER_ISR(TIMER3)); /* clear TIF0 */
nuc_timer3_func();
return IRQ_HANDLED;
}
static struct irqaction timer3_irq = {
.name = "timer3",
.flags = IRQF_TIMER | IRQF_IRQPOLL,
.handler = timer3_interrupt,
};
setup_irq(IRQ_TIMER3, &timer3_irq );
- remove_irq
与setup_irq对应的应该是remove_irq,而不是free_irq,不然在卸载终端的时候会一直报错。特别注意。
/**
* remove_irq - free an interrupt
* @irq: Interrupt line to free
* @act: irqaction for the interrupt
*
* Used to remove interrupts statically setup by the early boot process.
*/
void remove_irq(unsigned int irq, struct irqaction *act)
{
struct irq_desc *desc = irq_to_desc(irq);
if (desc && !WARN_ON(irq_settings_is_per_cpu_devid(desc)))
__free_irq(irq, act->dev_id);
}
示例用法
remove_irq(IRQ_TIMER3,&timer3_irq );