UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Contributor
Contributor
716 Views
Registered: ‎04-06-2018

IRQ Handler kernel level from PL

Jump to solution

here I am again, with another silly question , I hope.

I want to generate an interruption from my PL, actually two,

so , they are physically connected to concat and goes to IRQ_F2P[4:0], they are ln3 and ln4.

I changed my devicetree , and they are showing up in the /proc/interrupts

 

57:         32          0       GIC  57  cdns-i2c
 61:          0          0       GIC  61  SII902x_det
 62:          0          0       GIC  62  xilinx-vdma-controller
 63:          0          0       GIC  63  0-0053
 64:          1          0       GIC  64  gpio1
 65:          2          0       GIC  65  gpio2
 72:          0          0       GIC  72  f8003000.dmac

 

then I kinda figure out two numbers for them in my kernel level IRQ SW ,

96 and 97 , then  I am able to register them with my module :

57:         32          0       GIC  57  cdns-i2c
 61:          0          0       GIC  61  SII902x_det
 62:          0          0       GIC  62  xilinx-vdma-controller
 63:          0          0       GIC  63  0-0053
 64:          1          0       GIC  64  gpio1
 65:          2          0       GIC  65  gpio2
 72:          0          0       GIC  72  f8003000.dmac
 73:          0          0       GIC  73  f8003000.dmac
 74:          0          0       GIC  74  f8003000.dmac
 75:          0          0       GIC  75  f8003000.dmac
 82:        814          0       GIC  82  xuartps
 96:          0          0  zynq-gpio   0  int-test
 97:          1          0  zynq-gpio   1  int-test2
146:          0          0  zynq-gpio  50  K1
IPI1:          0      52126  Timer broadcast interrupts

 

another tests show :

 

ls -l /proc/irq/97/
total 0
-r--r--r--    1 root     root             0 Jan  1 04:25 affinity_hint
dr-xr-xr-x    2 root     root             0 Jan  1 04:25 int-test2
-r--r--r--    1 root     root             0 Jan  1 04:25 node
-rw-r--r--    1 root     root             0 Jan  1 04:25 smp_affinity
-rw-r--r--    1 root     root             0 Jan  1 04:25 smp_affinity_list
-r--r--r--    1 root     root             0 Jan  1 04:25 spurious

 

which int-test2 is my handler at the kernel space.

 

BUT only IRQ happens and only ONCE , i see it in my serial cutecom console :

 

\0x1b[0;31mZ-turn#\0x1b[m random: nonblocking pool is initialized

\0x1b[0;31mZ-turn#\0x1b[m \0x1b[0;31mZ-turn#\0x1b[m \0x1b[0;31mZ-turn#\0x1b[m \0x1b[0;31mZ-turn#\0x1b[m \0x1b[0;31mZ-turn#\0x1b[m interrupt_hook!!

xilaxitimer_init: Registered IRQ 97

clcdint_init2

clcdint_init

 

you are able to see the IRQ counter incremented at the /proc/interrupts

 

96:          0          0  zynq-gpio   0  int-test
 97:          1          0  zynq-gpio   1  int-test2

 

97 BTW comes from a switch that I manually trigger , 96 is supposed to be a counter but it is not happening ,

the switch is happening at least once , but does not repeat.

 

maybe is my code , which 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 97

MODULE_LICENSE("GPL");

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

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

    irq = INTERRUPT;
    irqflags = IRQF_NO_SUSPEND;

    ret = request_irq(irq, interrupt_hook2, irqflags, "int-test2", NULL);

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

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

module_init(clcdint_init2);

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

module_exit(clcdint_exit2);

 

 

 

 

I am wondering if I need to clean the IRQ at the handler function,

and how to do it ?

 

Any other idea ?

 

 

 

 

 

 

IRQVIVADO1.png
0 Kudos
1 Solution

Accepted Solutions
Contributor
Contributor
693 Views
Registered: ‎04-06-2018

Re: IRQ Handler kernel level from PL

Jump to solution

I managed to make it work by re-compiling the KERNKEL with the option selected :

Device Drivers > Userspace I/O drivers > Userspace I/I platform with generic IRQ handling .

Then I use a code in the userspace to handle the IRQ via /dev/uio0 : the code is from :

link_to_devuio0handler

 

and finally the counter of the IRQ is counting at /proc/interrupts and the handler is being called.

kernelconfig1.png
kernelconfig2.png
kernelconfig3.png
2 Replies
Contributor
Contributor
608 Views
Registered: ‎04-06-2018

Re: IRQ Handler kernel level from PL

Jump to solution

I noticed that I am using the wrong interrupt number , and it is actually 32 and 33 for my two custom interrupts. Then the interrupts are registered under GIC :

 

32:          0          0       GIC  32  int-test


 33:          0          0       GIC  33  int-test2

 

but it is still not firing the IRQ handler , but then I used /dev/uio0 , to talk to the PL, and handle my IRQ from the PL.

The code that I used is based on:

 

https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html

0 Kudos
Contributor
Contributor
694 Views
Registered: ‎04-06-2018

Re: IRQ Handler kernel level from PL

Jump to solution

I managed to make it work by re-compiling the KERNKEL with the option selected :

Device Drivers > Userspace I/O drivers > Userspace I/I platform with generic IRQ handling .

Then I use a code in the userspace to handle the IRQ via /dev/uio0 : the code is from :

link_to_devuio0handler

 

and finally the counter of the IRQ is counting at /proc/interrupts and the handler is being called.

kernelconfig1.png
kernelconfig2.png
kernelconfig3.png