How to require irq for ep dma writting completed?

In jetson sdk 32.5,

I write a pcie driver running on an endpoint device. The code is like this:

in the driver thread:

while (true) {



static int dma_write(struct data_transfer *transfer)
int channel = 0;
u32 val = 0;
unsigned long now, timeout = msecs_to_jiffies(1000);

/* program registers */
/* Enable Write Engine */
dma_common_wr(ep->dma_base, DMA_WRITE_ENGINE_EN_OFF_ENABLE,

/* Un Mask DONE and ABORT interrupts */
val = dma_common_rd(ep->dma_base, DMA_WRITE_INT_MASK_OFF);
val &= ~(1 << channel);     /* DONE */
val &= ~(1 << ((channel) + 16));    /* ABORT */
dma_common_wr(ep->dma_base, val, DMA_WRITE_INT_MASK_OFF);

val = dma_channel_rd(ep->dma_base, channel, DMA_CH_CONTROL1_OFF_WRCH);
val = DMA_CH_CONTROL1_OFF_WRCH_LIE; //non linklist mode
dma_channel_wr(ep->dma_base, channel, val, DMA_CH_CONTROL1_OFF_WRCH);

//non linklist mode
dma_channel_wr(ep->dma_base, channel, transfer->request_tlen,

dma_channel_wr(ep->dma_base, channel,
               (transfer->src_iova_addr & 0xFFFFFFFF),
dma_channel_wr(ep->dma_base, channel,
               ((transfer->src_iova_addr >> 32) & 0xFFFFFFFF),

dma_channel_wr(ep->dma_base, channel,
               (transfer->dst_iova_addr & 0xFFFFFFFF),
dma_channel_wr(ep->dma_base, channel,
               ((transfer->dst_iova_addr >> 32) & 0xFFFFFFFF),

/* ring the door bell with channel number */
dma_common_wr8(ep->dma_base, channel, DMA_WRITE_DOORBELL_OFF);

now = jiffies;
while (true) {
    val = dma_common_rd(ep->dma_base, DMA_WRITE_INT_STATUS_OFF);
    if (BIT(channel) & val) {
        dma_common_wr(ep->dma_base, BIT(channel), DMA_WRITE_INT_CLEAR_OFF);

    if (time_after(jiffies, now + timeout)) {
        printk("DMA write timed out & poll end\n");
                           DMA_WRITE_DOORBELL_OFF_WR_STOP | channel,
        return -ETIMEDOUT;

return 0;


My question is that I want to use interrupt by request_irq method instead of polling DMA_WRITE_INT_STATUS_OFF register. The cpu utilization reaches 99% when polling DMA_WRITE_INT_STATUS_OFF register. What I should do to relize it?

On the endpoint device, in the driver, I request irq as follows:
irq = platform_get_irq_byname(pdev, “intr”);
ret = request_irq(irq, ep_irq_dma, IRQF_SHARED, “ep_dma”, ep);

But I test it, no interrupts generated when dma write transmission completed.

What’s wrong about it?

I want to use the first way “Done local interrupt (pin) asserted”, not the forth way “Polling DMA_WRITE_INT_STATUS_OFF”.