int irq_set_irq_wake(unsigned int irq, unsigned int on) 使中断能够冲睡眠状态唤醒,并改变当前的
的状态使其处于唤醒状态.
其使用的例程如下:
static int cw1200_sdio_pm(struct hwbus_priv *self, bool suspend)
{
int ret = 0;
if (self->pdata->irq)
ret = irq_set_irq_wake(self->pdata->irq, suspend);
return ret;
}
其源码分析如下:
int irq_set_irq_wake(unsigned int irq, unsigned int on)
{
unsigned long flags;
struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
int ret = 0;
#中断描述符为null的话,直接退出
if (!desc)
return -EINVAL;
/* wakeup-capable irqs can be shared between drivers that
* don't need to have the same sleep mode behaviors.
*/
#假定这里的形参on为1
if (on) {
if (desc->wake_depth++ == 0) {
#如果当前的中断深度为0.说明当前已经没有enable_irq和disable_irq的嵌套了。
#这里调用chip函数来设置wake
ret = set_irq_wake_real(irq, on);
if (ret)
desc->wake_depth = 0;
else
#在flag上或上IRQD_WAKEUP_STATE
irqd_set(&desc->irq_data, IRQD_WAKEUP_STATE);
}
} else {
if (desc->wake_depth == 0) {
WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
} else if (--desc->wake_depth == 0) {
ret = set_irq_wake_real(irq, on);
if (ret)
desc->wake_depth = 1;
else
irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE);
}
}
irq_put_desc_busunlock(desc, flags);
return ret;
}
static int set_irq_wake_real(unsigned int irq, unsigned int on)
{
struct irq_desc *desc = irq_to_desc(irq);
int ret = -ENXIO;
#flag中如果包含IRQCHIP_SKIP_SET_WAKE,则说明要忽略wakeup,则直接退出
if (irq_desc_get_chip(desc)->flags & IRQCHIP_SKIP_SET_WAKE)
return 0;
#如果chip的irq_set_wake 不为null的话,则调用chip的irq_set_wake来设置wakeup
if (desc->irq_data.chip->irq_set_wake)
ret = desc->irq_data.chip->irq_set_wake(&desc->irq_data, on);
return ret;
}
中断API之irq_set_irq_wake
最新推荐文章于 2024-08-21 17:03:07 发布