来自PL的zynq linux IRQ

时间:2018-07-12 21:22:20

标签: linux-device-driver interrupt-handling device-tree zynq irq

我正在使用zynq板,向z转动,并且添加了两个来自PL的中断,我使用:编辑了设备树:

amba_pl {
        #address-cells = <0x1>;
        #size-cells = <0x1>;
        compatible = "simple-bus";
        ranges;

        gpio1@43c20000 {
            #gpio-cells = <0x2>;
            #interrupt-cells = <0x2>;
            compatible = "generic-uio";
            gpio-controller;
            interrupt-controller;
            interrupt-parent = <&intc>;
            interrupts = <0x0 0x20 0x4>;
            reg = <0x43c20000 0x10000>;
            xlnx,all-inputs = <0x1>;
            xlnx,all-inputs-2 = <0x0>;
            xlnx,all-outputs = <0x0>;
            xlnx,all-outputs-2 = <0x0>;
            xlnx,dout-default = <0x0>;
            xlnx,dout-default-2 = <0x0>;
            xlnx,gpio-width = <0x3>;
            xlnx,gpio2-width = <0x20>;
            xlnx,interrupt-present = <0x1>;
            xlnx,is-dual = <0x0>;
            xlnx,tri-default = <0xffffffff>;
            xlnx,tri-default-2 = <0xffffffff>;
        };
        gpio2@43c30000 {
            #gpio-cells = <0x2>;
            #interrupt-cells = <0x2>;
            compatible = "generic-uio";
            gpio-controller;
            interrupt-controller;
            interrupt-parent = <&intc>;
            interrupts = <0x0 0x21 0x4>;
            reg = <0x43c30000 0x10000>;
            xlnx,all-inputs = <0x1>;
            xlnx,all-inputs-2 = <0x0>;
            xlnx,all-outputs = <0x0>;
            xlnx,all-outputs-2 = <0x0>;
            xlnx,dout-default = <0x0>;
            xlnx,dout-default-2 = <0x0>;
            xlnx,gpio-width = <0x3>;
            xlnx,gpio2-width = <0x20>;
            xlnx,interrupt-present = <0x1>;
            xlnx,is-dual = <0x0>;
            xlnx,tri-default = <0xffffffff>;
            xlnx,tri-default-2 = <0xffffffff>;
        };

};

它被映射到中断,cat / proc / interrupts

57:52 0 GIC 57 cdns-i2c

61:1 0 GIC 61 SII902x_det

62:0 0 GIC 62逻辑vc

63:0 0 GIC 63 0-0053

64:2 0 GIC 64 gpio1

65:2 0 GIC 65 gpio2

然后我用中断创建了一个模块,并将它们注册到96和97 (64 + 32)和(65 + 32),代码为:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_address.h>

#include <asm/exception.h>
#include <asm/mach/irq.h>

//#define INTERRUPT 96
#define INTERRUPT 96

MODULE_LICENSE("GPL");

static irqreturn_t interrupt_hook(int irq, void *dev_id, struct pt_regs *regs) {
    printk("interrupt_hook!!\n");

    return IRQ_HANDLED;
}

static int __init clcdint_init(void) {
    unsigned int irq;
    unsigned int irqflags;
    int ret;

    irq = INTERRUPT;
    irqflags = IRQF_TRIGGER_RISING;

    ret = request_irq(irq, interrupt_hook, irqflags, "int-test", NULL);

    if(ret != 0) {
            printk("ERROR: IRQ request failed %d", irq);
            printk(" - code %d , EIO %d , EINVAL %d\n", ret, EIO, EINVAL);
    }

    printk("clcdint_init\n");
    return 0;
}

module_init(clcdint_init);

static void __exit clcdint_exit(void) {
    unsigned int irq;
    irq=INTERRUPT;
    free_irq(irq, NULL);
    printk("clcdint_exit\n");
}

module_exit(clcdint_exit);

然后将其映射,我正在通过计数器和板上带有指示正确操作的led的开关生成IRQ,功能映射到:

96:0 0 zynq-gpio 0完整测试

97:1 0 zynq-gpio 1 int-test2

在insmod之后我得到 \ 0x1b [0; 31mZ-turn#\ 0x1b [m insmod driverirq146.ko 成功:注册IRQ 97 clcdint_init2

但是IRQ并不经常发生,正如您在/ proc / interrupts计数器中看到的那样,它发生一次或两次,也许是在软件方面,如果有人提出任何建议。

0 个答案:

没有答案