加入收藏 | 设为首页 | 会员中心 | 我要投稿 佛山站长网 (https://www.0757zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux芯片级移植与底层驱动(基于3.7.4内核) 中断控制器

发布时间:2016-11-14 01:35:48 所属栏目:Linux 来源:网络整理
导读:3.中断控制器驱动 在Linux内核中,各个设备驱动可以简单地调用request_irq()、enable_irq()、disable_irq()、local_irq_disable()、local_irq_enable()等通用AP

与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}

(编辑:佛山站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读