Hello,
I am trying to trigger interrupts from a DMA transfer completion in EVM K2H but cannot configure it right.
I have written a character device kernel module for servicing all the interrupts and it works fine already for GPIO. Next I began to add the DMA support on it, but I receive:
genirq Flags mismatch irq 315. 00000080 (MyInterrupt) vs. 00000000 (2530000.i2c)
According to the K2H data sheet, 315 should be the IRQ for the EDMA0 channel 0 completion. I have also tried with 314 which should be global completion interrupt for EDMA0, but it does nothing, not even any error. Should I use some mapping from HW IRQ to Linux interrupt numbering? This is done for the GPIO, see my code below.
When I trigger the DMA transfer on channel 0, the data is copied right and the IPR register bit 0 sets to "1" as expected. Only the interrupt handler is not called.
With the GPIO I do it like this:
static irqreturn_t r_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
// my interrupt handler, this is called when I do a pulse into the pin, so it works perfectly
// however, with the EDMA this is never called
}
To achieve the above I configure the GPIO interrupt for pin 0 like this:
gpio_request(0, "MyInterrupt"); // GPIO pin 0
// This returns 540 although it is 120 in the K2H data sheet:
irq_any_gpio = gpio_to_irq(0); // interrupt number for GPIO pin 0
request_irq(irq_any_gpio, (irq_handler_t ) r_irq_handler, IRQF_TRIGGER_FALLING, "MyInterrupt", "/dev/mydevice");
irq_set_irq_type(irq_any_gpio, IRQ_TYPE_EDGE_FALLING);
So far so good!
Then I do it for the EDMA in a somewhat similar way:
irq_edma = 315; // According to the data sheet this is EDMACC_0_TC_0 for ARM CorePac
// When calling request_irq this produces the error "genirq Flags mismatch irq 315. 00000080 (MyInterrupt) vs. 00000000 (2530000.i2c)" Why "I2C" ??? Is 315 mapped to I2C instead of EDMA?
// irq_edma = 314; // According to the data sheet this is EDMACC_0_GINT, for ARM CorePac, When calling request_irq this does not give any errors but does not work either
request_irq(irq_edma, (irq_handler_t ) r_irq_handler_edma, IRQF_SHARED, "MyInterrupt", "/dev/mydevice");
// irq_set_irq_type(irq_edma, IRQ_TYPE_NONE); // I do not know if this is needed for EDMA interrupts. It gives errors about the 2nd parameter if tried to do so.
Please give me some advice.
Best regards,
Ari