博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
中断API之request_irq/request_threaded_irq
阅读量:4214 次
发布时间:2019-05-26

本文共 4557 字,大约阅读时间需要 15 分钟。

request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)这个函数用于为申请一个中断。其源码分析如下:static inline int __must_checkrequest_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev){	return request_threaded_irq(irq, handler, NULL, flags, name, dev);}可见这个函数只是request_threaded_irq的一个包装.形参详细说明如下:irq:要申请的中断号handle:中断处理函数thread_fn:中断线程化。可见这里没有办法通过request_irq 来实现中断线程化,要申请支持中断线程化的			只能直接调用request_threaded_irqdevname:要申请中断dev的name,其实一个字符串dev_id:一个void * 变量,主要用于给中断传递参数和共享中断的caseirq_flags:中断支持的flag。总共支持的flag如下: * IRQF_SHARED - allow sharing the irq among several devices * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur * IRQF_TIMER - Flag to mark this interrupt as timer interrupt * IRQF_PERCPU - Interrupt is per cpu * IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing * IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is *                registered first in an shared interrupt is considered for *                performance reasons) * IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished. *                Used by threaded interrupts which need to keep the *                irq line disabled until the threaded handler has been run. * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend.  Does not guarantee *                   that this interrupt will wake the system from a suspended *                   state.  See Documentation/power/suspend-and-interrupts.txt * IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set * IRQF_NO_THREAD - Interrupt cannot be threaded * IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device *                resume time. * IRQF_COND_SUSPEND - If the IRQ is shared with a NO_SUSPEND user, execute this *                interrupt handler after suspending interrupts. For system *                wakeup devices users need to implement wakeup detection in *                their interrupt handlers.int request_threaded_irq(unsigned int irq, irq_handler_t handler,			 irq_handler_t thread_fn, unsigned long irqflags,			 const char *devname, void *dev_id)用于申请irq对应的中断或者中断线程化。其源码分析如下:int request_threaded_irq(unsigned int irq, irq_handler_t handler,			 irq_handler_t thread_fn, unsigned long irqflags,			 const char *devname, void *dev_id){	struct irqaction *action;	struct irq_desc *desc;	int retval;	#如果irq number等于#define IRQ_NOTCONNECTED	(1U << 31) 则退出,从这里看出irq number最大就是IRQ_NOTCONNECTED	if (irq == IRQ_NOTCONNECTED)		return -ENOTCONN;	/*	 * Sanity-check: shared interrupts must pass in a real dev-ID,	 * otherwise we'll have trouble later trying to figure out	 * which interrupt is which (messes up the interrupt freeing	 * logic etc).	 *	 * Also IRQF_COND_SUSPEND only makes sense for shared interrupts and	 * it cannot be set along with IRQF_NO_SUSPEND.	 */	 #irq的flag之间有依赖,这理解就是检查依赖。	if (((irqflags & IRQF_SHARED) && !dev_id) ||	    (!(irqflags & IRQF_SHARED) && (irqflags & IRQF_COND_SUSPEND)) ||	    ((irqflags & IRQF_NO_SUSPEND) && (irqflags & IRQF_COND_SUSPEND)))		return -EINVAL;	#得到中断号对应的中断描述符	desc = irq_to_desc(irq);	if (!desc)		return -EINVAL;	#检查是否设置_IRQ_NOREQUEST和_IRQ_PER_CPU_DEVID	if (!irq_settings_can_request(desc) ||	    WARN_ON(irq_settings_is_per_cpu_devid(desc)))		return -EINVAL;	#handler和thread_fn 不能同时为null,如果handle为 null,且thread_fn不为null,则给handler 赋予一个默认函数。	if (!handler) {		if (!thread_fn)			return -EINVAL;		handler = irq_default_primary_handler;	}	#申请一个irqaction 结构体,这个结构体会在free_irq 的时候释放	action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);	if (!action)		return -ENOMEM;	#给irqaction 的个个成员变量赋值	action->handler = handler;	action->thread_fn = thread_fn;	action->flags = irqflags;	action->name = devname;	action->dev_id = dev_id;	#为这个irq使能power	retval = irq_chip_pm_get(&desc->irq_data);	if (retval < 0) {		kfree(action);		return retval;	}	#内部函数,主要用于注册irqaction。	retval = __setup_irq(irq, desc, action);	if (retval) {		irq_chip_pm_put(&desc->irq_data);		kfree(action->secondary);		kfree(action);	}#share irq debug,一般情况下不打开这个宏#ifdef CONFIG_DEBUG_SHIRQ_FIXME	if (!retval && (irqflags & IRQF_SHARED)) {		/*		 * It's a shared IRQ -- the driver ought to be prepared for it		 * to happen immediately, so let's make sure....		 * We disable the irq to make sure that a 'real' IRQ doesn't		 * run in parallel with our fake.		 */		unsigned long flags;		disable_irq(irq);		local_irq_save(flags);		handler(irq, dev_id);		local_irq_restore(flags);		enable_irq(irq);	}#endif	return retval;}

转载地址:http://wgjmi.baihongyu.com/

你可能感兴趣的文章
MySQL必知必会 -- 数据检索
查看>>
MySQL必知必会 -- 排序检索数据 ORDER BY
查看>>
POJ 3087 解题报告
查看>>
POJ 2536 解题报告
查看>>
POJ 1154 解题报告
查看>>
POJ 1661 解题报告
查看>>
POJ 1101 解题报告
查看>>
ACM POJ catalogues[转载]
查看>>
ACM经历总结[转载]
查看>>
C/C++文件操作[转载]
查看>>
小米笔试:最大子数组乘积
查看>>
常见的排序算法
查看>>
5.PyTorch实现逻辑回归(二分类)
查看>>
hdu 3460 Ancient Printer(trie tree)
查看>>
KMP求前缀函数(next数组)
查看>>
KMP
查看>>
poj 3863Business Center
查看>>
Android编译系统简要介绍和学习计划
查看>>
Android编译系统环境初始化过程分析
查看>>
user2eng 笔记
查看>>