继之前的分析:中断调用asm_do_IRQ,程序接着往下:
//5 调用desc->handle_irq函数处理
asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
struct pt_regs *old_regs = set_irq_regs(regs);
struct irq_desc *desc = irq_desc + irq;
desc_handle_irq(irq, desc);
desc->handle_irq(irq, desc);
//到这里为止可以告一段落了,因为上面的部分可以说就想是内核将事物的共性抽象出来
//写成一套通用的处理过程,接着往下就是按照不同的用户需求将各自的处理函数
//传给desc->handle_irq就好了,这个就好比每个房子在建造的时候都要埋好电线(抽象的共性),
//但是按照每个房主的喜好不同,我们可以装白炽灯,节能灯或是彩灯等等。
//当我们想换灯泡时,就把原来的灯泡拆下来,换上其他的灯泡就好了
//那么接着往下就是个他接上一个我们自己需要的处理函数。。
//那么当一个程序执行一个中断是就会调用desc->handle_irq(irq, desc)处理函数
//那么我们反推回去看看desc->handle_irq(irq, desc)是怎么被这个程序调用的
void __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
const char *name)
desc->handle_irq = handle;
//可见指定好这一步上面的函数就可以进入到handle函数中进行处理了
set_irq_handler(unsigned int irq, irq_flow_handler_t handle)
{
__set_irq_handler(irq, handle, 0, NULL);
}
void __init s3c24xx_init_irq(void)
set_irq_handler(irqno, handle_edge_irq);
static void __init bast_init(void)
.init_irq = s3c24xx_init_irq,
//static void __init bast_init(void)这个函数是在mach-bast.c中
//那么很明显初始化函数static void __init bast_init(void)
//会调用s3c24xx_init_irq
//最终会传入处理函数handle_edge_irq给desc->handle_irq,
//这样asm_do_IRQ函数就可以调用handle_edge_irq函数了
handle_edge_irq(unsigned int irq, struct irq_desc *desc)
desc->chip->ack(irq);
struct irqaction *action = desc->action;
action_ret = handle_IRQ_event(irq, action);
ret = action->handler(irq, action->dev_id);
//构造action结构体并且加入调用action->handler(irq, action->dev_id)函数
//这个函数是系统给我们自己定义的。。用于处理用户的需求,
//到这里第一阶段的分析结束了
//从上面的分析可知我们只要加入一个用户自定义的处理函数,
//系统就会根据中断号调用相应的处理函数,这个函数不是孤立的定义,
//他是以action结构体方式连接到链表中提供给系统调用的
//由此可见s3c24xx_init_irq设置了不同的中断号和对应的中断处理函数
//用户只需要在对应的中断号,对应的处理函数类型。。
//添加action结构体系统既可以调用我们的处理函数
//下面是两个重要的结构体类型 irq_desc, irqaction
struct irq_desc {
irq_flow_handler_t handle_irq;
struct irq_chip *chip;
struct msi_desc *msi_desc;
void *handler_data;
void *chip_data;
struct irqaction *action; /* IRQ action list */
unsigned int status; /* IRQ status */
unsigned int depth; /* nested irq disables */
unsigned int wake_depth; /* nested wake enables */
unsigned int irq_count; /* For detecting broken IRQs */
unsigned int irqs_unhandled;
spinlock_t lock;
#ifdef CONFIG_SMP
cpumask_t affinity;
unsigned int cpu;
#endif
#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
cpumask_t pending_mask;
#endif
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir;
#endif
const char *name;
} ____cacheline_internodealigned_in_smp;
extern struct irq_desc irq_desc[NR_IRQS];
struct irqaction {
irq_handler_t handler;
unsigned long flags;
cpumask_t mask;
const char *name;
void *dev_id;
struct irqaction *next;
int irq;
struct proc_dir_entry *dir;
};
阅读(1243) | 评论(0) | 转发(0) |