a.int irq :中断号。
b.void *dev_id :与request_irq()的参数dev_id一致,可以根据这个设备id号得到相应设备的数据结构,进而得到相应设备的信息和相关数据。
c.返回值:中断程序的返回值是一个特殊类型 rqreturn_t。但是中断程序的返回值却只有两个值IRQ_NONE和IRQ_HANDLED。
IRQ_NONE:中断程序接收到中断信号后发现这并不是注册时指定的中断原发出的中断信号。
IRQ_HANDLED:接收到了准确的中断信号,并且作了相应正确的处理。
一般 中断处理程序要做什么service,主要取决于产生的设备和该设备为什么要发送中断。
John哥说明:
1.当一个给定的中断处理程序正在执行时,这条中断线上的其它中断都会被屏蔽。but,所有其他中断线上的中断都是打开的。因此这些不同中断线上的其他中断都能被处理。
2.request_irq()函数可能会睡眠,所以,不能在中断上下文或其它不允许阻塞的代码中调用该函数。
4.在深入分析request_irq()函数之前,先来看几个重要的数据结构。
A.irqaction的数据结构(用irqaction结构体来描述一个具体的中断服务例程)
113struct irqaction {
114 irq_handler_t handler;
115 unsigned long flags;
116 const char *name;
117 void *dev_id;
118 struct irqaction *next;
119 int irq;
120 struct proc_dir_entry *dir;
121 irq_handler_t thread_fn;
122 struct task_struct *thread;
123 unsigned long thread_flags;
124};
125
113struct irqaction {
114 irq_handler_t handler;
115 unsigned long flags;
116 const char *name;
117 void *dev_id;
118 struct irqaction *next;
119 int irq;
120 struct proc_dir_entry *dir;
121 irq_handler_t thread_fn;
122 struct task_struct *thread;
123 unsigned long thread_flags;
124};
125
1>handler:指向具体的一个中断服务例程。
2>flags:表示中断标志位,对应于request_irq()函数中所传递的第三个参数,可取IRQF_DISABLED、IRQF_SAMPLE_RANDOM和IRQF_SHARED其中之一。
3>name:请求中断的设备名称,对应request_irq()函数中所传递的第四个参数
4>dev_id: 共享中断时有用。 对应于request_irq()函数中所传递的第五个参数,可取任意值,但必须唯一能够代表发出中断请求的设备,通常取描述该设备的结构体。
5>strct irqaction *next:指向irqaction描述符的下一个元素。用一条链表将共享同一条中断线上的中断服务例程链接起来。
6>irq:所申请的中断号
7>dir:指向proc/irq/NN/name entry
8>thread_fn:指向具体的一个线程化的中断。
9>thread:指向线程中断的指针。
10>thread_flags:线程中断的标志。
B.irq_desc的数据结构体
每个中断向量都有它自己的irq_desc 描述符。即用irq_desc来描述中断向量。所有的这些中断描述符组织在一起就形成了irq_desc irq_desc[NR_IRQS]数组
175struct irq_desc {
176 unsigned int irq;
177 struct timer_rand_state *timer_rand_state;
178 unsigned int *kstat_irqs;
179#ifdef CONFIG_INTR_REMAP
180 struct irq_2_iommu *irq_2_iommu;
181#endif
182 irq_flow_handler_t handle_irq;
183 struct irq_chip *chip;
184 struct msi_desc *msi_desc;
185 void *handler_data;
186 void *chip_data;
187 struct irqaction *action; /* IRQ action list */
188 unsigned int status; /* IRQ status */
189
190 unsigned int depth; /* nested irq disables */
191 unsigned int wake_depth; /* nested wake enables */
192 unsigned int irq_count; /* For detecting broken IRQs */
193 unsigned long last_unhandled; /* Aging timer for unhandled count */
194 unsigned int irqs_unhandled;
195 raw_spinlock_t lock;
196#ifdef CONFIG_SMP
197 cpumask_var_t affinity;
198 const struct cpumask *affinity_hint;
199 unsigned int node;
200#ifdef CONFIG_GENERIC_PENDING_IRQ
201 cpumask_var_t pending_mask;
202#endif
203#endif
204 atomic_t threads_active;
205 wait_queue_head_t wait_for_threads;
206#ifdef CONFIG_PROC_FS
207 struct proc_dir_entry *dir;
208#endif
209 const char *name;
210} ____cacheline_internodealigned_in_smp;
211
212extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
213 struct irq_desc *desc, int node);
214extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
215
216#ifndef CONFIG_SPARSE_IRQ
217extern struct irq_desc irq_desc[NR_IRQS];
175struct irq_desc {
176 unsigned int irq;
177 struct timer_rand_state *timer_rand_state;
178 unsigned int *kstat_irqs;
179#ifdef CONFIG_INTR_REMAP
180 struct irq_2_iommu *irq_2_iommu;
181#endif
182 irq_flow_handler_t handle_irq;
183 struct irq_chip *chip;
184 struct msi_desc *msi_desc;
185 void *handler_data;
186 void *chip_data;
187 struct irqaction *action; /* IRQ action list */
188 unsigned int status; /* IRQ status */
189
190 unsigned int depth; /* nested irq disables */
191 unsigned int wake_depth; /* nested wake enables */
192 unsigned int irq_count; /* For detecting broken IRQs */
193 unsigned long last_unhandled; /* Aging timer for unhandled count */
194 unsigned int irqs_unhandled;
195 raw_spinlock_t lock;
196#ifdef CONFIG_SMP
197 cpumask_var_t affinity;
198 const struct cpumask *affinity_hint;
199 unsigned int node;
200#ifdef CONFIG_GENERIC_PENDING_IRQ
201 cpumask_var_t pending_mask;
202#endif
203#endif
204 atomic_t threads_active;
205 wait_queue_head_t wait_for_threads;
206#ifdef CONFIG_PROC_FS
207 struct proc_dir_entry *dir;
208#endif
209 const char *name;
210} ____cacheline_internodealigned_in_smp;
211
212extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
213 struct irq_desc *desc, int node);
214extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
215
216#ifndef CONFIG_SPARSE_IRQ
217extern struct irq_desc irq_desc[NR_IRQS];
1>irq:表示这个描述符所对应的中断号。
2>handle_irq:指向该IRQ线的公共服务程序(即该IRQ所对应的中断处理程序。