Open KRolander opened 4 years ago
Hi Roland,
Sorry, I must have missed this issue when you filed it. Didn't see it until now...
I'm a little puzzled too. According to the Zynq TRM, IRQ 61 belongs to the PL (61 - 32 = 29).
Looking at the upstream dts for zynq-7000, dmac interrupts look like this: interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3", "dma4", "dma5", "dma6", "dma7"; interrupts = <0 13 4>, <0 14 4>, <0 15 4>, <0 16 4>, <0 17 4>, <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>;
Which seems OK...
Did you find a solution for this already?
Thanks, Edgar
Hi Edgard, no problem, fortunatly I found a solution and I found that IRQ 61 belongs to the PL (61 - 32 = 29) as well thank you.
So basically when we want to write a device driver subscribing on an IRQ of the Zynq in the Co-Simulation let's do in this way:
First of all we need an IRQ handler:
static irqreturn_t irq_handler(int irq, void *dev_id)
{
wait_queue_flag = 1;
wake_up_interruptible(&wait_queue_flag);
return IRQ_HANDLED;
}
After we have to map the IRQ, so in the device init_module we need something like this:
int init_module(void)
{
struct device_node *np;
np = of_find_node_by_name(NULL, "rp_wires_in");
int irq = irq_of_parse_and_map(np, 0);
printk("====>>> IRQ num is : %d", irq);
result = request_irq(irq, (irq_handler_t) irq_handler, 0x81, DEV_NAME, (void *)(irq_handler));
if (result != 0)
{
printk("[test_irq] IRQ %d cannot be registered", irq);
free_irq(irq, (void *)(irq_handler0));
}
else
{
printk("[device] IRQ %d is done", irq);
}
}
Remarque:
rp_wires_in
is the node name in the DTS containing the IRQs and the PS-PL remote-ports to the.
0x81 in request_irq(irq, (irq_handler_t) irq_handler, 0x81, DEV_NAME, (void *)(irq_handler));
it's equal to say that the IRQ is a shared edge one, you can also use this flag: IRQ_SHARED_EDGE
instead of using the numerical value.
In irq_of_parse_and_map(np, 0) => 0 refers to your_systemc_module.irq(zynq.pl2ps_irq[0]);
for zynq.pl2ps_irq[1]
you need irq_of_parse_and_map(np, 1)
and so on...
So the IRQs in the DTS correspond to the SystemC ports in this way:
interrupts = <
0x0 29 0x4 ========> zynq.pl2ps_irq[0]
0x0 30 0x4 ========> zynq.pl2ps_irq[1]
0x0 31 0x4 ========> zynq.pl2ps_irq[2]
0x0 32 0x4 ========> zynq.pl2ps_irq[3]
0x0 33 0x4 ========> zynq.pl2ps_irq[4]
0x0 34 0x4 ========> zynq.pl2ps_irq[5]
0x0 35 0x4 ========> zynq.pl2ps_irq[6]
0x0 36 0x4 ========> zynq.pl2ps_irq[7]
0x0 52 0x4 ========> zynq.pl2ps_irq[8]
0x0 53 0x4 ========> zynq.pl2ps_irq[9]
0x0 54 0x4 ========> zynq.pl2ps_irq[10]
0x0 55 0x4 ========> zynq.pl2ps_irq[11]
0x0 56 0x4 ========> zynq.pl2ps_irq[12]
0x0 57 0x4 ========> zynq.pl2ps_irq[13]
0x0 58 0x4 ========> zynq.pl2ps_irq[14]
0x0 59 0x4 ========> zynq.pl2ps_irq[15]
>;
So basically everithing work fine, I could generate IRQs in PL and subscribe on them by the Device Driver on the PS side :)
Best Regards Roland
Dear all,
My aim is to write a Kernel Device Driver that allows to do operations when an IRQ is sent by the debug module.
In zynq_demo.cc the debug module's IRQ port is binded with the IRQ port of the zynq module :
debug.irq(zynq.pl2ps_irq[0]);
. I found that the IRQ signals are set intorp_wires_in.wires_in
(rp_wires_in.wires_in[i]((pl2ps_irq[i])
) members of thexilinx_zynq
class.After studying the Device Tree Source of remote ports of the zynq-7000
zynq-pl-remoteport.dtsi
I found that therp_wires_in@0
node corresponds to therp_wires_in.wires_in[i]
of thexilinw_zynq class
. In therp_wires_in@0
node there are the following interrupts :I guess that the interruption 29 (
0x0 29 0x4
) corresponds to the first IRQ of the zynq moduledebug.irq(zynq.pl2ps_irq[0])
.In my Kernel Device Driver (test_irq) when I initialize the driver I use the request_irq function to subscribe to the IRQ 29 :
After loading the module
isnmod test_irq.ko
I have the follwong error :The most surprising line of this error is:
[ 29.701282] genirq: Flags mismatch irq 29. 00000084 (test_irq) vs. 00000004 (f8003000.dmac)
that tells us that the f8003000.dmac requiers the IRQ (an the IRQ is not shared), that is quiet strange because in the Device Tree Source in the dmac node the IRQ 29 is not declared:After this error I declared a new IRQ (37) in the node
rp_wires_in@0
so IRQ 37 corresponds todebug.irq(zynq.pl2ps_irq[8])
if I'm not wrong? After loading the module I have no error. In the/proc/interrupts
I can see that my moduletest_irq
has been subscribed to the IRQ 37 as we can see the log ofcat /proc/interrupts
:The device test_irq is subscribed to IRQ 37, when the debug module writes on its irq port (
irq.write(1);
) the deviceirq_handler
function should be called to print the message: [test_irq] Shared IRQ: Interrupt Occurred, but theirq_handler
function is not called.Do you have any idea, how to solve this problem ? Maybe I should use offsets between the IRQs of
dmac_s
andrp_wires_in
? Or is it an issue of QEMU ?Thank You, Best Regards
Roland