中断API之enable_irq
1 void enable_irq(unsigned int irq) 用于使能一个irq。 2 void disable_irq(unsigned int irq)则用于禁止一个irq 3 4 其使用的例程如下: 5 static void cp_poll_controller(struct net_device *dev) 6 { 7 struct cp_private *cp = netdev_priv(dev); 8 const int irq = cp->pdev->irq; 9 10 disable_irq(irq); 11 cp_interrupt(irq, dev); 12 enable_irq(irq); 13 } 14 从本例中可以看到这个函数一般和disable_irq 配合使用。 15 其源码分析如下: 16 void enable_irq(unsigned int irq) 17 { 18 unsigned long flags; 19 #根据irq得到其对应的中断描述符 20 struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL); 21 #描述符为null,则直接退出. 22 if (!desc) 23 return; 24 #中断描述符如果没有对应的chip,则打印error 信息,并退出 25 if (WARN(!desc->irq_data.chip, 26 KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq)) 27 goto out; 28 #继续调用__enable_irq 使能中断 29 __enable_irq(desc); 30 out: 31 irq_put_desc_busunlock(desc, flags); 32 } 33 34 35 void __enable_irq(struct irq_desc *desc) 36 { 37 switch (desc->depth) { 38 case 0: 39 err_out: 40 WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", 41 irq_desc_get_irq(desc)); 42 break; 43 #正常情况下第一个调用enable_irq的时候desc->depth 应该是1,如果是0的话,后面进行--操作的话就成负数了 44 case 1: { 45 #如果正处于suspend的过程中,则直接退出 46 if (desc->istate & IRQS_SUSPENDED) 47 goto err_out; 48 这三个函数后面详细分析 49 /* Prevent probing on this irq: */ 50 irq_settings_set_noprobe(desc); 51 #通过chip来使能irq 52 irq_enable(desc); 53 check_irq_resend(desc); 54 /* fall-through */ 55 } 56 #从这里可以知道enable_irq 是可以嵌套的,即同一个irq 可以多次调用enable_irq 57 default: 58 desc->depth--; 59 } 60 } 61 62 static inline void irq_settings_set_noprobe(struct irq_desc *desc) 63 { 64 #只是或上一个_IRQ_NOPROBE flag 65 desc->status_use_accessors |= _IRQ_NOPROBE; 66 } 67 68 void irq_enable(struct irq_desc *desc) 69 { 70 irq_state_clr_disabled(desc); 71 #正常情况下回调用chip来使能irq 72 if (desc->irq_data.chip->irq_enable) 73 desc->irq_data.chip->irq_enable(&desc->irq_data); 74 else 75 desc->irq_data.chip->irq_unmask(&desc->irq_data); 76 irq_state_clr_masked(desc); 77 }
来源:https://blog.csdn.net/tiantao2012/article/details/78908163