void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action)
和void irq_pm_remove_action(struct irq_desc *desc, struct irqaction *action)
是一对函数.
其中irq_pm_install_action 是在__setup_irq 中调用的。而irq_pm_remove_action 是在free_irq中调用的.
这两个函数的实现比较简单,直接看起源码实现
/*
* Called from __setup_irq() with desc->lock held after @action has
* been installed in the action chain.
*/
void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action)
{
#中断描述符成员变量nr_actions 子加1
desc->nr_actions++;
#形参struct irqaction *action 成员变量flags如果包含IRQF_FORCE_RESUME,则中断描述符成员变量desc->force_resume_depth 子加1
if (action->flags & IRQF_FORCE_RESUME)
desc->force_resume_depth++;
#从这里看到中断描述符的force_resume_depth 应该要等于nr_actions。负责会通过WARN_ON_ONCE 打印当前的callstack
WARN_ON_ONCE(desc->force_resume_depth &&
desc->force_resume_depth != desc->nr_actions);
#同样是根据形参struct irqaction *action 成员变量flags 是否包含IRQF_NO_SUSPEND 或者 IRQF_COND_SUSPEND,让中断描述符对应的成员变量子加1
if (action->flags & IRQF_NO_SUSPEND)
desc->no_suspend_depth++;
else if (action->flags & IRQF_COND_SUSPEND)
desc->cond_suspend_depth++;
#从这里可以确定中断描述符中的cond_suspend_depth加上cond_suspend_depth 要等于nr_actions ?
WARN_ON_ONCE(desc->no_suspend_depth &&
(desc->no_suspend_depth +
desc->cond_suspend_depth) != desc->nr_actions);
}
/*
* Called from __free_irq() with desc->lock held after @action has
* been removed from the action chain.
*/
void irq_pm_remove_action(struct irq_desc *desc, struct irqaction *action)
{
#和irq_pm_install_action 对应,nr_actions 首先子减1
desc->nr_actions--;
#可以看出flags 分成resume 和suspend 两类。根据形参struct irqaction *action 的成员变量flags是否包含特定的bit,来让中断描述符对应
#的成员变量子减1.
if (action->flags & IRQF_FORCE_RESUME)
desc->force_resume_depth--;
if (action->flags & IRQF_NO_SUSPEND)
desc->no_suspend_depth--;
else if (action->flags & IRQF_COND_SUSPEND)
desc->cond_suspend_depth--;
}
中断API之irq_pm_install_action/irq_pm_remove_action
最新推荐文章于 2022-01-22 16:53:55 发布