Linux芯片级移植与底层驱动(基于3.7.4内核) 中断控制器
|
与local_irq_disable()和local_irq_enable()不同,disable_irq()、enable_irq()针对的则是外部的中断控制器。在内核中,透过irq_chip结构体来描述中断控制器。该结构体内部封装了中断mask、unmask、ack等成员函数,其定义于include/linux/irq.h: 303struct irq_chip { 304 const char *name; 305 unsigned int (*irq_startup)(struct irq_data *data); 306 void (*irq_shutdown)(struct irq_data *data); 307 void (*irq_enable)(struct irq_data *data); 308 void (*irq_disable)(struct irq_data *data); 309 310 void (*irq_ack)(struct irq_data *data); 311 void (*irq_mask)(struct irq_data *data); 312 void (*irq_mask_ack)(struct irq_data *data); 313 void (*irq_unmask)(struct irq_data *data); 314 void (*irq_eoi)(struct irq_data *data); 315 316 int (*irq_set_affinity)(struct irq_data *data, const struct cpumask *dest, bool force); 317 int (*irq_retrigger)(struct irq_data *data); 318 int (*irq_set_type)(struct irq_data *data, unsigned int flow_type); 319 int (*irq_set_wake)(struct irq_data *data, unsigned int on); 334}; 各个芯片公司会将芯片内部的中断控制器实现为irq_chip驱动的形式。受限于中断控制器硬件的能力,这些成员函数并不一定需要全部实现,有时候只需要实现其中的部分函数即可。譬如drivers/pinctrl/pinctrl-sirf.c驱动中的 1438static struct irq_chip sirfsoc_irq_chip = { 1439 .name = "sirf-gpio-irq", 1440 .irq_ack = sirfsoc_gpio_irq_ack, 1441 .irq_mask = sirfsoc_gpio_irq_mask, 1442 .irq_unmask = sirfsoc_gpio_irq_unmask, 1443 .irq_set_type = sirfsoc_gpio_irq_type, 1444}; 我们只实现了其中的ack、mask、unmask和set_type成员函数,ack函数用于清中断,mask、unmask用于中断屏蔽和取消中断屏蔽、set_type则用于配置中断的触发方式,如高电平、低电平、上升沿、下降沿等。至于enable_irq()的时候,虽然没有实现irq_enable成员函数,但是内核会间接调用到irq_unmask成员函数,这点从kernel/irq/chip.c可以看出: 192void irq_enable(struct irq_desc *desc) 193{ 194 irq_state_clr_disabled(desc); 195 if (desc->irq_data.chip->irq_enable) 196 desc->irq_data.chip->irq_enable(&desc->irq_data); 197 else 198 desc->irq_data.chip->irq_unmask(&desc->irq_data); 199 irq_state_clr_masked(desc); 200} (编辑:佛山站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

