zynq Linux软件中断,Linux Zynq GPIO中断

注册中断:对每一个pin进行循环遍历for (pin_num = 0; pin_num < min_t(int, ZYNQ_GPIO_NR_GPIOS,  (int)chip->ngpio); pin_num++)node

gpio_irq = irq_find_mapping(irq_domain, pin_num); 将GPIO号映射为Linux系统中断号。app

在Linux中断系统中,一个irq_domain表示一个中断控制器,其内中断由0开始编号(尚存在疑问)dom

unsigned int irq_find_mapping(struct irq_domain *domain, irq_hw_number_t hwirq)函数

将一个中断控制器上的某个硬件中断映射为某个Linux系统中断。this

/**

* struct irq_domain - Hardware interrupt number translation object

* @link: Element in global irq_domain list.

* @name: Name of interrupt domain

* @ops: pointer to irq_domain methods

* @host_data: private data pointer for use by owner. Not touched by irq_domain

* core code.

*

* Optional elements

* @of_node: Pointer to device tree nodes associated with the irq_domain. Used

* when decoding device tree interrupt specifiers.

* @gc: Pointer to a list of generic chips. There is a helper function for

* setting up one or more generic chips for interrupt controllers

* drivers using the generic chip library which uses this pointer.

*

* Revmap data, used internally by irq_domain

* @revmap_direct_max_irq: The largest hwirq that can be set for controllers that

* support direct mapping

* @revmap_size: Size of the linear map table @linear_revmap[]

* @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map

* @linear_revmap: Linear table of hwirq->virq reverse mappings

*/

struct irq_domain {

struct list_head link;

const char *name;

const struct irq_domain_ops *ops;

void *host_data;

/* Optional data */

struct device_node *of_node;

struct irq_domain_chip_generic *gc;

/* reverse map data. The linear map gets appended to the irq_domain */

irq_hw_number_t hwirq_max;

unsigned int revmap_direct_max_irq;

unsigned int revmap_size;

struct radix_tree_root revmap_tree;

unsigned int linear_revmap[];

};

revmap_direct_max_irq: 小于该值的中断,Linux中断号和硬件中断号相同,直接返回。spa

revmap_size: 线性反向映射(彷佛要求域内IRQ从零开始,有点矛盾),小于该值的hwirq直接利用linear_revmap作查找。code

不然用radix tree来查找映射。orm

irq_set_chip_and_handler(gpio_irq, &zynq_gpio_irqchip, handle_simple_irq);

ip

调用irq_get_desc_lock(irq, &flags, 0);,获取irq对应的irq_desc。并设定irq_desc的chip:desc->irq_data.chip = chip;ci

调用irq_reserve_irq(irq);,将allocated_irqs中断位图中相应的中断标识为已占用。

调用__irq_set_handler,将irq_desc中的handle_irq设定:desc->handle_irq = handle;

irq_set_chip_data(gpio_irq, (void *)gpio);

这个比较简单,将要用私有的变量关联到irq,desc->irq_data.chip_data = data;

set_irq_flags(gpio_irq, IRQF_VALID);

整体调用:

irq_set_handler_data(irq_num, (void *)gpio);

这里的irq_num是经过irq_num = platform_get_irq(pdev, 0);获取的系统配置文件里面的irq配置。这个函数也简单,实质为:desc->irq_data.handler_data = data;

irq_set_chained_handler(irq_num, zynq_gpio_irqhandler);

这个函数实质为:desc->handle_irq = handle;

最终调用关系为:调用zynq_gpio_irqhandler,而后在该函数中经过调用generic_handle_irq来调用最终的handle_simple_irq。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值