I am working with a zynq board , z-turn, and I added two interruptions coming from PL, I edited my device tree with :
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>;
};
};
and it is mapped to the interruptions , cat /proc/interrupts
57: 52 0 GIC 57 cdns-i2c
61: 1 0 GIC 61 SII902x_det
62: 0 0 GIC 62 logicvc
63: 0 0 GIC 63 0-0053
64: 2 0 GIC 64 gpio1
65: 2 0 GIC 65 gpio2
then I created a module with my interruption and I register them to 96 and 97 (64 + 32) and (65 + 32), the code is :
#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);
then it is mapped , I am generating the IRQ via a counter and a switch in the board with leds indicating the correct operation, the functions are mapped to:
96: 0 0 zynq-gpio 0 int-test
97: 1 0 zynq-gpio 1 int-test2
right after the insmod I get \0x1b[0;31mZ-turn#\0x1b[m insmod driverirq146.ko SUCCESS: Registered IRQ 97 clcdint_init2
but the IRQ is not happening frequently , it happens once or twice as you see in the counter of the /proc/interrupts , maybe it is in the software side , if anybody has any tip.