本文共 1869 字,大约阅读时间需要 6 分钟。
int irq_activate(struct irq_desc *desc)用于激活一个中断目前看到只有在__setup_irq中被调用其源码分析如下:int irq_activate(struct irq_desc *desc){ #得到中断描述符的成员变量irq_data struct irq_data *d = irq_desc_get_irq_data(desc); #检查irq_data中是否包含IRQD_AFFINITY_MANAGED 标志,如果没有包含的IRQD_AFFINITY_MANAGED的话,再调用irq_domain_activate_irq #否则直接返回0 if (!irqd_affinity_is_managed(d)) return irq_domain_activate_irq(d, false); return 0;}int irq_domain_activate_irq(struct irq_data *irq_data, bool early){ int ret = 0; #检查irq_data中是否包含IRQD_ACTIVATED,如果没有包含,则调用__irq_domain_activate_irq if (!irqd_is_activated(irq_data)) ret = __irq_domain_activate_irq(irq_data, early); #如果上一句执行成功,则ret等于0,则在irq_data中设置IRQD_ACTIVATED if (!ret) irqd_set_activated(irq_data); return ret;}static int __irq_domain_activate_irq(struct irq_data *irqd, bool early){ int ret = 0; #这里要求形参struct irq_data *irqd 和irqd的成员变量domain 不能为null,因为最终过的active 是通过具体的domain来实现的. if (irqd && irqd->domain) { struct irq_domain *domain = irqd->domain; #这里有个递归调用,一直递归直到找到irq的顶层,如果存在上层的话,这里会递归调用__irq_domain_activate_irq if (irqd->parent_data) ret = __irq_domain_activate_irq(irqd->parent_data, early); #这个if条件是递归的出口,可以看到最终的irq_active是通过调用domain->ops->activate来实现的 if (!ret && domain->ops->activate) { ret = domain->ops->activate(domain, irqd, early); /* Rollback in case of error */ if (ret && irqd->parent_data) #如果domain->ops->activate 返回1的话,就表明可能执行错误了,调用__irq_domain_deactivate_irq 来执行回滚操作. __irq_domain_deactivate_irq(irqd->parent_data); } } return ret;}__irq_domain_deactivate_irq 也是一个递归操作,最终也是调用domain的ops->deactivate 来进行.static void __irq_domain_deactivate_irq(struct irq_data *irq_data){ if (irq_data && irq_data->domain) { struct irq_domain *domain = irq_data->domain; if (domain->ops->deactivate) domain->ops->deactivate(domain, irq_data); if (irq_data->parent_data) __irq_domain_deactivate_irq(irq_data->parent_data); }}
转载地址:http://vgjmi.baihongyu.com/