中断API之enable_irq

void enable_irq(unsigned int irq) 用于使能一个irq。
void disable_irq(unsigned int irq)则用于禁止一个irq

其使用的例程如下:
static void cp_poll_controller(struct net_device *dev)
{
	struct cp_private *cp = netdev_priv(dev);
	const int irq = cp->pdev->irq;

	disable_irq(irq);
	cp_interrupt(irq, dev);
	enable_irq(irq);
}
从本例中可以看到这个函数一般和disable_irq 配合使用。
其源码分析如下:
void enable_irq(unsigned int irq)
{
	unsigned long flags;
	#根据irq得到其对应的中断描述符
	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
	#描述符为null,则直接退出.
	if (!desc)
		return;
	#中断描述符如果没有对应的chip,则打印error 信息,并退出
	if (WARN(!desc->irq_data.chip,
		 KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq))
		goto out;
	#继续调用__enable_irq 使能中断
	__enable_irq(desc);
out:
	irq_put_desc_busunlock(desc, flags);
}


void __enable_irq(struct irq_desc *desc)
{
	switch (desc->depth) {
	case 0:
 err_out:
		WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n",
		     irq_desc_get_irq(desc));
		break;
	#正常情况下第一个调用enable_irq的时候desc->depth 应该是1,如果是0的话,后面进行--操作的话就成负数了
	case 1: {
	#如果正处于suspend的过程中,则直接退出
		if (desc->istate & IRQS_SUSPENDED)
			goto err_out;
		这三个函数后面详细分析
		/* Prevent probing on this irq: */
		irq_settings_set_noprobe(desc);
		#通过chip来使能irq
		irq_enable(desc);
		check_irq_resend(desc);
		/* fall-through */
	}
	#从这里可以知道enable_irq 是可以嵌套的,即同一个irq 可以多次调用enable_irq
	default:
		desc->depth--;
	}
}

static inline void irq_settings_set_noprobe(struct irq_desc *desc)
{
	#只是或上一个_IRQ_NOPROBE flag
	desc->status_use_accessors |= _IRQ_NOPROBE;
}

void irq_enable(struct irq_desc *desc)
{
	irq_state_clr_disabled(desc);
	#正常情况下回调用chip来使能irq
	if (desc->irq_data.chip->irq_enable)
		desc->irq_data.chip->irq_enable(&desc->irq_data);
	else
		desc->irq_data.chip->irq_unmask(&desc->irq_data);
	irq_state_clr_masked(desc);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值